diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-08-06 16:49:10 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-08-06 16:49:10 -0700 |
| commit | 26e89267c0d745793d777ad0b1157a5596258515 (patch) | |
| tree | de3d5f79a06a649a46803ba0ecc88375acc2821c /src/graphics/scene.rs | |
| parent | 2c8110d93e04a1bfd976fe20c8c7493a41d51eae (diff) | |
move some modules into a new graphics submodule
Force-Push: yes Change-Id: I5cbdf59870258f099fc6dd47ff2f1566376c1585
Diffstat (limited to 'src/graphics/scene.rs')
| -rw-r--r-- | src/graphics/scene.rs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/graphics/scene.rs b/src/graphics/scene.rs new file mode 100644 index 0000000..e59ae89 --- /dev/null +++ b/src/graphics/scene.rs @@ -0,0 +1,118 @@ +#![deny(unsafe_code)] +use crate::error::*; +use crate::graphics::window_dressing::RenderState; +use crate::linear_algebra::{ Vec3, Vec4, Transformation }; +use crate::shader_data::VertexPushBlock; + +use std::f32::consts::{ TAU }; +use std::mem::size_of; + +use vulkanalia::Device; +use vulkanalia::vk::{ self, HasBuilder, DeviceV1_0 }; + + +#[allow(unsafe_code)] +pub fn generate_scene_commands<'a>(image_index: usize, time: f32, + render_state: &'a RenderState, + device: &Device, extent: &vk::Extent2D) + -> Result<&'a vk::CommandBuffer> +{ + let command_buffer = &render_state.command_buffers[image_index]; + let framebuffer = &render_state.framebuffers[image_index]; + let descriptor_set = &render_state.descriptor_sets[image_index]; + + let inheritance_info = vk::CommandBufferInheritanceInfo::builder(); + + let command_buffer_begin_info = vk::CommandBufferBeginInfo::builder() + .flags(vk::CommandBufferUsageFlags::empty()) + .inheritance_info(&inheritance_info); + + unsafe { + device.begin_command_buffer(*command_buffer, &command_buffer_begin_info) + }?; + + let render_area = vk::Rect2D::builder() + .offset(vk::Offset2D::default()) + .extent(*extent); + + let color_clear_value = vk::ClearValue { + color: vk::ClearColorValue { + float32: [0.0, 0.0, 0.0, 1.0] + } + }; + let depth_clear_value = vk::ClearValue { + depth_stencil: vk::ClearDepthStencilValue { + depth: 1.0, + stencil: 0, + } + }; + let clear_values = [color_clear_value, depth_clear_value]; + + let begin_pass_info = vk::RenderPassBeginInfo::builder() + .render_pass(render_state.render_pass) + .framebuffer(*framebuffer) + .render_area(render_area) + .clear_values(&clear_values); + + unsafe { + device.cmd_begin_render_pass(*command_buffer, &begin_pass_info, + vk::SubpassContents::INLINE) + }; + + unsafe { + device.cmd_bind_pipeline(*command_buffer, + vk::PipelineBindPoint::GRAPHICS, + render_state.pipeline) + }; + + unsafe { + device.cmd_bind_vertex_buffers(*command_buffer, 0, + &[render_state.vertex_buffer], &[0]) + }; + + unsafe { + device.cmd_bind_index_buffer(*command_buffer, render_state.index_buffer, + 0, vk::IndexType::UINT32) + }; + + unsafe { + device.cmd_bind_descriptor_sets(*command_buffer, + vk::PipelineBindPoint::GRAPHICS, + render_state.pipeline_layout, + 0, + &[*descriptor_set], + &[]) + }; + + let scale = Vec3::new(1.0, 1.0, 1.0); + let model = Transformation { + rotation: Vec4::rotation_quaternion(&Vec3::new(0.0, 1.0, 0.0), time % TAU), + translation: Vec3::new(0.0, 0.0, 0.0), + }; + let push_block = VertexPushBlock::<f32> { scale, model }; + let size = size_of::<VertexPushBlock::<f32>>(); + let push_block_bytes = unsafe { + std::slice::from_raw_parts(&push_block as *const VertexPushBlock<f32> + as *const u8, + size) + }; + + unsafe { + device.cmd_push_constants(*command_buffer, render_state.pipeline_layout, + vk::ShaderStageFlags::VERTEX, + 0, + push_block_bytes) + }; + + unsafe { + device.cmd_draw_indexed(*command_buffer, render_state.index_count as u32, + 1, 0, 0, 0) + }; + + unsafe { device.cmd_end_render_pass(*command_buffer) }; + + unsafe { device.end_command_buffer(*command_buffer) }?; + + Ok(command_buffer) +} + |