Skip to content

Commit

Permalink
More rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
mattkleiny committed Jan 30, 2024
1 parent 765f3c4 commit e8624ba
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 41 deletions.
27 changes: 25 additions & 2 deletions modules/graphics/src/rendering/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ impl RenderQueue {
}

/// Sets the render target to the given target.
pub fn set_render_target(&mut self, target_id: TargetId) {
self.enqueue(RenderCommand::SetRenderTarget { target_id });
pub fn set_render_target(&mut self, target: &RenderTarget) {
self.enqueue(RenderCommand::SetRenderTarget { target_id: target.id() });
}

/// Sets the render target to the display.
Expand Down Expand Up @@ -130,6 +130,29 @@ impl RenderQueue {
})
}

/// Blits the given [`RenderTarget`] to the display.
pub fn blit_render_target_to_display(&mut self, target: &RenderTarget, clear_color: Option<Color>) {
self.enqueue(RenderCommand::SetRenderTargetToDisplay);

if let Some(color) = clear_color {
self.enqueue(RenderCommand::ClearColorBuffer { color });
}

// self.enqueue(RenderCommand::SetShader {
// shader_id: target.blit_shader().id(),
// uniforms: Box::new(target.blit_uniforms().clone()),
// blend_state: BlendState::Disabled,
// culling_mode: CullingMode::Disabled,
// scissor_mode: ScissorMode::Disabled,
// });
// self.enqueue(RenderCommand::DrawMesh {
// mesh_id: target.blit_mesh().id(),
// topology: PrimitiveTopology::TriangleList,
// vertex_count: target.blit_mesh().vertices(),
// index_count: target.blit_mesh().indices(),
// });
}

/// Clears all [`RenderCommand`] from the queue.
pub fn clear(&mut self) {
let mut commands = self.commands.lock().unwrap();
Expand Down
61 changes: 30 additions & 31 deletions modules/graphics/src/rendering/culling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,36 @@ pub struct MaterialSortingKey {
flags: MaterialFlags,
}

/// Represents an object that is visible to a camera.
pub struct VisibleObject<'a> {
/// The object itself.
pub object: &'a dyn RenderObject,
/// The material of the object.
pub material: &'a Material,
}

/// A set of visible objects that can be rendered in a scene.
///
/// This is a subset of the objects in a scene that are visible to a specific
/// camera, and can be used to optimize rendering by only rendering the objects
/// that are visible to the camera.
pub struct VisibleObjectSet<'a> {
/// The frustum of the camera that was used to cull the objects.
pub frustum: Frustum,
/// The objects that are visible to the camera.
pub objects: Vec<VisibleObject<'a>>,
}

impl<'a> VisibleObjectSet<'a> {
/// Gets an iterator over the objects in the set.
pub fn group_by_material(&self) -> impl Iterator<Item = (&'a Material, &[VisibleObject<'a>])> {
self
.objects
.chunk_by(|a, b| MaterialSortingKey::from(a.material) == MaterialSortingKey::from(b.material))
.map(|chunk| (chunk[0].material, chunk))
}
}

impl From<&Material> for MaterialSortingKey {
/// Gets the sorting key for the given material.
fn from(material: &Material) -> Self {
Expand Down Expand Up @@ -64,34 +94,3 @@ impl From<&Material> for MaterialSortingKey {
Self { flags }
}
}

/// Represents an object that is visible to a camera, along with it's material
/// properties that are used to render it.
pub struct VisibleObject<'a> {
/// The object itself.
pub object: &'a dyn RenderObject,
/// The sorting key for the material of the object.
pub material: &'a Material,
}

/// A set of visible objects that can be rendered in a scene.
///
/// This is a subset of the objects in a scene that are visible to a specific
/// camera, and can be used to optimize rendering by only rendering the objects
/// that are visible to the camera.
pub struct VisibleObjectSet<'a> {
/// The frustum of the camera that was used to cull the objects.
pub frustum: Frustum,
/// The objects that are visible to the camera.
pub objects: Vec<VisibleObject<'a>>,
}

impl<'a> VisibleObjectSet<'a> {
/// Gets an iterator over the objects in the set.
pub fn group_by_material(&self) -> impl Iterator<Item = (&'a Material, &[VisibleObject<'a>])> {
self
.objects
.chunk_by(|a, b| MaterialSortingKey::from(a.material) == MaterialSortingKey::from(b.material))
.map(|chunk| (chunk[0].material, chunk))
}
}
36 changes: 28 additions & 8 deletions modules/graphics/src/rendering/pipelines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ pub struct RenderFrame<'a> {
}

impl<'a> RenderFrame<'a> {
/// Draws the given objects to the frame.
pub fn draw_scene(&mut self, scene: &dyn RenderScene, camera: &dyn Camera) {
/// Draws the object visible to the given camera.
pub fn draw_camera(&mut self, scene: &dyn RenderScene, camera: &dyn Camera) {
let visible_object_set = scene.cull_visible_objects(camera);

for (material, group) in visible_object_set.group_by_material() {
Expand Down Expand Up @@ -111,21 +111,27 @@ pub mod forward {
impl RenderPass for DepthPass {
fn render_camera(&self, scene: &dyn RenderScene, camera: &dyn Camera, frame: &mut RenderFrame<'_>) {
frame.queue.clear_color_buffer(Color::BLACK);
frame.draw_scene(scene, camera);
frame.draw_camera(scene, camera);
}
}

/// A [`RenderPass`] that renders all objects in the scene to a color target.
struct ColorPass {}
struct ColorPass {
color_target: RenderTarget,
}

impl RenderPass for ColorPass {
fn begin_frame(&self, _scene: &dyn RenderScene, frame: &mut RenderFrame<'_>) {
frame.queue.set_render_target(&self.color_target);
}

fn render_camera(&self, scene: &dyn RenderScene, camera: &dyn Camera, frame: &mut RenderFrame<'_>) {
frame.queue.clear_color_buffer(Color::BLACK);
frame.draw_scene(scene, camera);
frame.draw_camera(scene, camera);
}

fn end_frame(&self, _scene: &dyn RenderScene, _frame: &mut RenderFrame<'_>) {
// TODO: blit the color target to the screen.
fn end_frame(&self, _scene: &dyn RenderScene, frame: &mut RenderFrame<'_>) {
frame.queue.blit_render_target_to_display(&self.color_target, None);
}
}

Expand All @@ -135,7 +141,21 @@ pub mod forward {
MultiPassPipeline {
renderer: Renderer::new(graphics),
queue: RenderQueue::default(),
passes: vec![Box::new(DepthPass {}), Box::new(ColorPass {})],
passes: vec![
Box::new(DepthPass {}),
Box::new(ColorPass {
color_target: RenderTarget::new(graphics, &RenderTargetDescriptor {
color_attachment: RenderTextureDescriptor {
width: 1920,
height: 1080,
options: TextureOptions::default(),
},
depth_attachment: None,
stencil_attachment: None,
})
.unwrap(),
}),
],
}
}
}
Expand Down

0 comments on commit e8624ba

Please sign in to comment.