-
Notifications
You must be signed in to change notification settings - Fork 0
Renderer
If you find this page to be out of date, please report or update it.
The Renderer
has a draw()
method which does not submit any commands to the GPU yet, but put all objects that need to be drawn in certain lists within the Renderer.
Then it has a bunch of render methods which submit commands to the GPU according the objects lists:
-
render_shadow(model, target)
: it renderers a shadowmap onto a framebuffer depth attachment. -
render_geometry(model, target)
: it renderers both color and depth onto a framebuffer which should be the so-called G-buffer.
The following two methods are used to blit a source attachment to another framebuffer color attachment:
-
blit_depth(source, target)
: it renders the depth attachment of the source onto the color attachment of the target. -
blit_color(source, target)
: it renderers the color attachment written by therender_geometry()
method onto the default framebuffer.
The Renderer has also a draw_gui()
method which can be called after rendering/presenting and before calling swap_buffers()
.
The main graphics object (gfx
) has a frame which is taken by the user for drawing.
We can draw things on the frame and then we give it back to gfx
for presenting it to screen.
// Pseudocode
let frame = gfx.next_frame();
renderer.draw(&scene, &frame.default_framebuffer);
gfx.present(frame);
Let us consider multiple framebuffers:
- shadowmap
- geometry (albedo, normal, depth)
- default
Let us introduce two new types:
struct CustomFramebuffer { textures, .., framebuffer }
struct DefaultFramebuffer { framebuffer }
And a trait implemented by both the previous struct
s.
trait DrawableOnto {
fn get_framebuffer(&self) -> gl::Framebuffer;
}
The trait is used by the render/present methods to enable drawing on both custom framebuffers and default framebuffer.
impl Renderer {
fn render_geometry<T: DrawableOnto>(scene: &Model, target: &T);
}
The blit methods borrows a CustomFramebuffer
and blits it onto a DrawableOnto
object, so that could be either another custom framebuffer or the default framebuffer.
impl Renderer {
fn blit_depth<T: DrawableOnto>(&mut self, source: &CustomFramebuffer, target: &T);
fn blit_color<T: DrawableOnto>(&mut self, source: &CustomFramebuffer, target: &T);
}
We probably just need a texture instead of the whole custom framebuffer.
let frame = gfx.next_frame();
renderer.draw(&scene);
renderer.render_shadow(&scene, &frame.shadow_buffer);
renderer.blit(&frame.shadow_buffer, &frame.default_framebuffer);
gfx.present(frame);
// Draw directly onto default framebuffer
renderer.draw(&scene);
renderer.render_geometry(&scene, &frame.default_framebuffer);
gfx.present(frame);
// Draw onto custom framebuffer, then blit to another custom framebuffer, then blit to default.
renderer.draw(&scene);
renderer.render_shadow(&scene, &frame.shadow_buffer);
renderer.blit_depth(&frame.shadow_buffer, &frame.geometry_buffer);
renderer.blit_color(&frame.geometry_buffer, &frame.default_framebuffer);
gfx.present(frame);