diff options
author | tcmal <me@aria.rip> | 2024-08-25 17:44:21 +0100 |
---|---|---|
committer | tcmal <me@aria.rip> | 2024-08-25 17:44:21 +0100 |
commit | bb1fb24290654394cd0a32c3a6b3d98e5131088d (patch) | |
tree | af926e6132b6e7c4af2d8c3673c331bbdfc33952 /stockton-render/src | |
parent | 4163aaeff0542b1f6b00d31c3d3a61fdbc2dbea5 (diff) |
feat(render): drawing with multiple texture arrays
requires faces to be sorted by depth to work properly, which isn't currently happening
Diffstat (limited to 'stockton-render/src')
-rw-r--r-- | stockton-render/src/draw/buffer.rs | 5 | ||||
-rw-r--r-- | stockton-render/src/draw/context.rs | 150 | ||||
-rw-r--r-- | stockton-render/src/draw/data/stockton.frag | 2 | ||||
-rw-r--r-- | stockton-render/src/draw/texture/loader.rs | 4 | ||||
-rw-r--r-- | stockton-render/src/lib.rs | 7 |
5 files changed, 98 insertions, 70 deletions
diff --git a/stockton-render/src/draw/buffer.rs b/stockton-render/src/draw/buffer.rs index f59431e..006a37b 100644 --- a/stockton-render/src/draw/buffer.rs +++ b/stockton-render/src/draw/buffer.rs @@ -60,6 +60,7 @@ pub(crate) fn create_buffer(device: &mut Device, } pub trait ModifiableBuffer: IndexMut<usize> { + fn get_buffer<'a>(&'a mut self) -> &'a Buffer; fn commit<'a>(&'a mut self, device: &Device, command_queue: &mut CommandQueue, command_pool: &mut CommandPool) -> &'a Buffer; @@ -116,6 +117,10 @@ impl<'a, T: Sized> StagedBuffer<'a, T> { } impl <'a, T: Sized> ModifiableBuffer for StagedBuffer<'a, T> { + fn get_buffer<'b>(&'b mut self) -> &'b Buffer { + &self.buffer + } + fn commit<'b>(&'b mut self, device: &Device, command_queue: &mut CommandQueue, command_pool: &mut CommandPool) -> &'b Buffer { diff --git a/stockton-render/src/draw/context.rs b/stockton-render/src/draw/context.rs index b76bed7..dc7703d 100644 --- a/stockton-render/src/draw/context.rs +++ b/stockton-render/src/draw/context.rs @@ -620,7 +620,7 @@ impl<'a> RenderingContext<'a> { } /// Draw all vertices in the buffer - pub fn draw_vertices(&mut self) -> Result<(), &'static str> { + pub fn draw_vertices<M: MinBSPFeatures<VulkanSystem>>(&mut self, file: &M,faces: &Vec<u32>) -> Result<(), &'static str> { let get_image = &self.get_image[self.current_frame]; let render_complete = &self.render_complete[self.current_frame]; @@ -662,18 +662,10 @@ impl<'a> RenderingContext<'a> { // Commit from staging buffers let (vbufs, ibuf) = { - let vbufref: &<back::Backend as hal::Backend>::Buffer = self.vert_buffer.commit( - &self.device, - &mut self.queue_group.queues[0], - &mut self.cmd_pool - ); + let vbufref: &<back::Backend as hal::Backend>::Buffer = self.vert_buffer.get_buffer(); let vbufs: ArrayVec<[_; 1]> = [(vbufref, SubRange::WHOLE)].into(); - let ibuf = self.index_buffer.commit( - &self.device, - &mut self.queue_group.queues[0], - &mut self.cmd_pool - ); + let ibuf = self.index_buffer.get_buffer(); (vbufs, ibuf) }; @@ -689,16 +681,6 @@ impl<'a> RenderingContext<'a> { ); buffer.bind_graphics_pipeline(&self.pipeline); - let mut descriptor_sets: ArrayVec<[_; 1]> = ArrayVec::new(); - descriptor_sets.push(self.texture_store.get_chunk_descriptor_set(0)); - - buffer.bind_graphics_descriptor_sets( - &self.pipeline_layout, - 0, - descriptor_sets, - &[] - ); - let vp = self.camera.get_matrix().as_slice(); let vp = std::mem::transmute::<&[f32], &[u32]>(vp); @@ -714,12 +696,94 @@ impl<'a> RenderingContext<'a> { range: SubRange::WHOLE, index_type: hal::IndexType::U16 }); - buffer.draw_indexed(0..((self.index_buffer.highest_used as u32 + 1) * 3), 0, 0..1); + + let mut current_chunk = file.get_face(0).texture_idx as usize / 8; + let mut chunk_start = 0; + + let mut curr_vert_idx: usize = 0; + let mut curr_idx_idx: usize = 0; + + for face in faces.into_iter().map(|idx| file.get_face(*idx)) { + if current_chunk != face.texture_idx as usize / 8 { + let mut descriptor_sets: ArrayVec<[_; 1]> = ArrayVec::new(); + descriptor_sets.push(self.texture_store.get_chunk_descriptor_set(current_chunk)); + + buffer.bind_graphics_descriptor_sets( + &self.pipeline_layout, + 0, + descriptor_sets, + &[] + ); + + buffer.draw_indexed(chunk_start as u32 * 3..(curr_idx_idx as u32 * 3) + 1, 0, 0..1); + + chunk_start = curr_idx_idx; + current_chunk = face.texture_idx as usize / 8; + } + + if face.face_type == FaceType::Polygon || face.face_type == FaceType::Mesh { + let base = face.vertices_idx.start; + + for idx in face.meshverts_idx.clone().step_by(3) { + let start_idx: u16 = curr_vert_idx.try_into().unwrap(); + + for idx2 in idx..idx+3 { + let vert = &file.resolve_meshvert(idx2 as u32, base); + let uv = Vector2::new(vert.tex.u[0], vert.tex.v[0]); + + let uvp = UVPoint (vert.position, face.texture_idx.try_into().unwrap(), uv); + self.vert_buffer[curr_vert_idx] = uvp; + + curr_vert_idx += 1; + } + + + self.index_buffer[curr_idx_idx] = (start_idx, start_idx + 1, start_idx + 2); + + curr_idx_idx += 1; + + if curr_vert_idx >= INITIAL_VERT_SIZE.try_into().unwrap() || curr_idx_idx >= INITIAL_INDEX_SIZE.try_into().unwrap() { + println!("out of vertex buffer space!"); + break; + } + } + } else { + // TODO: Other types of faces + } + + if curr_vert_idx >= INITIAL_VERT_SIZE.try_into().unwrap() || curr_idx_idx >= INITIAL_INDEX_SIZE.try_into().unwrap() { + break; + } + } + + let mut descriptor_sets: ArrayVec<[_; 1]> = ArrayVec::new(); + descriptor_sets.push(self.texture_store.get_chunk_descriptor_set(current_chunk)); + buffer.bind_graphics_descriptor_sets( + &self.pipeline_layout, + 0, + descriptor_sets, + &[] + ); + buffer.draw_indexed(chunk_start as u32 * 3..(curr_idx_idx as u32 * 3) + 1, 0, 0..1); + buffer.end_render_pass(); } buffer.finish(); }; + // Update our buffers before we actually start drawing + self.vert_buffer.commit( + &self.device, + &mut self.queue_group.queues[0], + &mut self.cmd_pool + ); + + self.index_buffer.commit( + &self.device, + &mut self.queue_group.queues[0], + &mut self.cmd_pool + ); + // Make submission object let command_buffers = &self.cmd_buffers[image_index..=image_index]; let wait_semaphores: ArrayVec<[_; 1]> = [(get_image, hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT)].into(); @@ -760,48 +824,6 @@ impl<'a> RenderingContext<'a> { pub fn rotate(&mut self, euler: Vector3) { self.camera.rotate(euler) } - - /// Load all active faces into the vertex buffers for drawing - // TODO: This is just a POC, we need to restructure things a lot for actually texturing, etc - pub fn set_active_faces<M: MinBSPFeatures<VulkanSystem>>(&mut self, faces: &Vec<u32>, file: &M) -> () { - let mut curr_vert_idx: usize = 0; - let mut curr_idx_idx: usize = 0; - - for face in faces.into_iter().map(|idx| file.get_face(*idx)) { - if face.face_type == FaceType::Polygon || face.face_type == FaceType::Mesh { - let base = face.vertices_idx.start; - - for idx in face.meshverts_idx.clone().step_by(3) { - let start_idx: u16 = curr_vert_idx.try_into().unwrap(); - - for idx2 in idx..idx+3 { - let vert = &file.resolve_meshvert(idx2 as u32, base); - let uv = Vector2::new(vert.tex.u[0], vert.tex.v[0]); - - let uvp = UVPoint (vert.position, face.texture_idx.try_into().unwrap(), uv); - self.vert_buffer[curr_vert_idx] = uvp; - - curr_vert_idx += 1; - } - - - self.index_buffer[curr_idx_idx] = (start_idx, start_idx + 1, start_idx + 2); - - curr_idx_idx += 1; - - if curr_vert_idx >= INITIAL_VERT_SIZE.try_into().unwrap() || curr_idx_idx >= INITIAL_INDEX_SIZE.try_into().unwrap() { - break; - } - } - } else { - // TODO: Other types of faces - } - - if curr_vert_idx >= INITIAL_VERT_SIZE.try_into().unwrap() || curr_idx_idx >= INITIAL_INDEX_SIZE.try_into().unwrap() { - break; - } - } - } } impl<'a> core::ops::Drop for RenderingContext<'a> { diff --git a/stockton-render/src/draw/data/stockton.frag b/stockton-render/src/draw/data/stockton.frag index 5c6e1d7..336d9fe 100644 --- a/stockton-render/src/draw/data/stockton.frag +++ b/stockton-render/src/draw/data/stockton.frag @@ -11,5 +11,5 @@ layout (location = 0) out vec4 color; void main() { - color = texture(sampler2D(tex[frag_tex], samp[frag_tex]), frag_uv); + color = texture(sampler2D(tex[frag_tex % 8], samp[frag_tex % 8]), frag_uv); }
\ No newline at end of file diff --git a/stockton-render/src/draw/texture/loader.rs b/stockton-render/src/draw/texture/loader.rs index 017030f..b3aa3ae 100644 --- a/stockton-render/src/draw/texture/loader.rs +++ b/stockton-render/src/draw/texture/loader.rs @@ -155,6 +155,10 @@ impl TextureStore { } } + pub fn get_n_chunks(&self) -> usize { + self.chunks.len() + } + pub fn get_chunk_descriptor_set<'a>(&'a self, idx: usize) -> &'a DescriptorSet { &self.chunks[idx].descriptor_set } diff --git a/stockton-render/src/lib.rs b/stockton-render/src/lib.rs index c282967..0db4b76 100644 --- a/stockton-render/src/lib.rs +++ b/stockton-render/src/lib.rs @@ -65,15 +65,12 @@ impl<'a, T: MinBSPFeatures<VulkanSystem>> Renderer<'a, T> { // Get visible faces let faces = get_visible_faces(self.context.camera_pos(), &self.world.map); - // Load them in - self.context.set_active_faces(&faces, &self.world.map); - // Then draw them - if let Err(_) = self.context.draw_vertices() { + if let Err(_) = self.context.draw_vertices(&self.world.map, &faces) { unsafe {self.context.handle_surface_change().unwrap()}; // If it fails twice, then error - self.context.draw_vertices().map_err(|_| FrameError::PresentError)?; + self.context.draw_vertices(&self.world.map, &faces).map_err(|_| FrameError::PresentError)?; } Ok(()) |