Allow rendering to non-default framebuffers
This commit is contained in:
parent
62a3fefca4
commit
58d55c5eaa
|
@ -26,7 +26,7 @@ use pathfinder_gpu::resources::ResourceLoader;
|
||||||
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderState, StencilFunc};
|
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderState, StencilFunc};
|
||||||
use pathfinder_gpu::{StencilState, UniformData};
|
use pathfinder_gpu::{StencilState, UniformData};
|
||||||
use pathfinder_renderer::builder::{RenderOptions, RenderTransform, SceneBuilder};
|
use pathfinder_renderer::builder::{RenderOptions, RenderTransform, SceneBuilder};
|
||||||
use pathfinder_renderer::gpu::renderer::{RenderMode, RenderStats, Renderer};
|
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, RenderMode, RenderStats, Renderer};
|
||||||
use pathfinder_renderer::gpu_data::RenderCommand;
|
use pathfinder_renderer::gpu_data::RenderCommand;
|
||||||
use pathfinder_renderer::post::{DEFRINGING_KERNEL_CORE_GRAPHICS, STEM_DARKENING_FACTORS};
|
use pathfinder_renderer::post::{DEFRINGING_KERNEL_CORE_GRAPHICS, STEM_DARKENING_FACTORS};
|
||||||
use pathfinder_renderer::scene::{Scene, SceneDescriptor};
|
use pathfinder_renderer::scene::{Scene, SceneDescriptor};
|
||||||
|
@ -130,10 +130,12 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
let monochrome_scene_color = built_svg.scene.monochrome_color();
|
let monochrome_scene_color = built_svg.scene.monochrome_color();
|
||||||
|
|
||||||
let viewport = window.viewport(options.mode.view(0));
|
let viewport = window.viewport(options.mode.view(0));
|
||||||
let renderer = Renderer::new(device,
|
let dest_framebuffer = DestFramebuffer::Default {
|
||||||
resources,
|
|
||||||
viewport,
|
viewport,
|
||||||
window_size.device_size());
|
window_size: window_size.device_size(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let renderer = Renderer::new(device, resources, dest_framebuffer);
|
||||||
let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone());
|
let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone());
|
||||||
scene_thread_proxy.set_drawable_size(viewport.size());
|
scene_thread_proxy.set_drawable_size(viewport.size());
|
||||||
|
|
||||||
|
@ -207,7 +209,10 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
let view = self.ui.mode.view(render_scene_index);
|
let view = self.ui.mode.view(render_scene_index);
|
||||||
let viewport = self.window.viewport(view);
|
let viewport = self.window.viewport(view);
|
||||||
self.window.make_current(view);
|
self.window.make_current(view);
|
||||||
self.renderer.set_viewport(viewport);
|
self.renderer.set_dest_framebuffer(DestFramebuffer::Default {
|
||||||
|
viewport,
|
||||||
|
window_size: self.window_size.device_size(),
|
||||||
|
});
|
||||||
self.renderer.device.clear(Some(self.background_color().to_f32().0), Some(1.0), Some(0));
|
self.renderer.device.clear(Some(self.background_color().to_f32().0), Some(1.0), Some(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +396,10 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
let view = self.ui.mode.view(render_scene_index);
|
let view = self.ui.mode.view(render_scene_index);
|
||||||
let viewport = self.window.viewport(view);
|
let viewport = self.window.viewport(view);
|
||||||
self.window.make_current(view);
|
self.window.make_current(view);
|
||||||
self.renderer.set_viewport(viewport);
|
self.renderer.set_dest_framebuffer(DestFramebuffer::Default {
|
||||||
|
viewport,
|
||||||
|
window_size: self.window_size.device_size(),
|
||||||
|
});
|
||||||
self.draw_environment(render_scene_index);
|
self.draw_environment(render_scene_index);
|
||||||
self.render_vector_scene();
|
self.render_vector_scene();
|
||||||
|
|
||||||
|
@ -427,7 +435,10 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
if self.options.ui != UIVisibility::None {
|
if self.options.ui != UIVisibility::None {
|
||||||
let viewport = self.window.viewport(View::Mono);
|
let viewport = self.window.viewport(View::Mono);
|
||||||
self.window.make_current(View::Mono);
|
self.window.make_current(View::Mono);
|
||||||
self.renderer.set_viewport(viewport);
|
self.renderer.set_dest_framebuffer(DestFramebuffer::Default {
|
||||||
|
viewport,
|
||||||
|
window_size: self.window_size.device_size(),
|
||||||
|
});
|
||||||
self.renderer.draw_debug_ui();
|
self.renderer.draw_debug_ui();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ pub struct Renderer<D> where D: Device {
|
||||||
pub device: D,
|
pub device: D,
|
||||||
|
|
||||||
// Core data
|
// Core data
|
||||||
|
dest_framebuffer: DestFramebuffer<D>,
|
||||||
fill_program: FillProgram<D>,
|
fill_program: FillProgram<D>,
|
||||||
solid_multicolor_tile_program: SolidTileMulticolorProgram<D>,
|
solid_multicolor_tile_program: SolidTileMulticolorProgram<D>,
|
||||||
alpha_multicolor_tile_program: AlphaTileMulticolorProgram<D>,
|
alpha_multicolor_tile_program: AlphaTileMulticolorProgram<D>,
|
||||||
|
@ -86,16 +87,12 @@ pub struct Renderer<D> where D: Device {
|
||||||
pub debug_ui: DebugUI<D>,
|
pub debug_ui: DebugUI<D>,
|
||||||
|
|
||||||
// Extra info
|
// Extra info
|
||||||
viewport: RectI32,
|
|
||||||
render_mode: RenderMode,
|
render_mode: RenderMode,
|
||||||
use_depth: bool,
|
use_depth: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> Renderer<D> where D: Device {
|
impl<D> Renderer<D> where D: Device {
|
||||||
pub fn new(device: D,
|
pub fn new(device: D, resources: &dyn ResourceLoader, dest_framebuffer: DestFramebuffer<D>)
|
||||||
resources: &dyn ResourceLoader,
|
|
||||||
viewport: RectI32,
|
|
||||||
main_framebuffer_size: Point2DI32)
|
|
||||||
-> Renderer<D> {
|
-> Renderer<D> {
|
||||||
let fill_program = FillProgram::new(&device, resources);
|
let fill_program = FillProgram::new(&device, resources);
|
||||||
|
|
||||||
|
@ -150,10 +147,12 @@ impl<D> Renderer<D> where D: Device {
|
||||||
FILL_COLORS_TEXTURE_HEIGHT);
|
FILL_COLORS_TEXTURE_HEIGHT);
|
||||||
let fill_colors_texture = device.create_texture(TextureFormat::RGBA8, fill_colors_size);
|
let fill_colors_texture = device.create_texture(TextureFormat::RGBA8, fill_colors_size);
|
||||||
|
|
||||||
let debug_ui = DebugUI::new(&device, resources, main_framebuffer_size);
|
let debug_ui = DebugUI::new(&device, resources, dest_framebuffer.window_size(&device));
|
||||||
|
|
||||||
Renderer {
|
Renderer {
|
||||||
device,
|
device,
|
||||||
|
|
||||||
|
dest_framebuffer,
|
||||||
fill_program,
|
fill_program,
|
||||||
solid_monochrome_tile_program,
|
solid_monochrome_tile_program,
|
||||||
alpha_monochrome_tile_program,
|
alpha_monochrome_tile_program,
|
||||||
|
@ -186,7 +185,6 @@ impl<D> Renderer<D> where D: Device {
|
||||||
mask_framebuffer_cleared: false,
|
mask_framebuffer_cleared: false,
|
||||||
buffered_fills: vec![],
|
buffered_fills: vec![],
|
||||||
|
|
||||||
viewport,
|
|
||||||
render_mode: RenderMode::default(),
|
render_mode: RenderMode::default(),
|
||||||
use_depth: false,
|
use_depth: false,
|
||||||
}
|
}
|
||||||
|
@ -242,7 +240,7 @@ impl<D> Renderer<D> where D: Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_debug_ui(&self) {
|
pub fn draw_debug_ui(&self) {
|
||||||
self.device.bind_default_framebuffer(self.viewport);
|
self.bind_main_framebuffer();
|
||||||
self.debug_ui.draw(&self.device);
|
self.debug_ui.draw(&self.device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,8 +256,8 @@ impl<D> Renderer<D> where D: Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_viewport(&mut self, new_viewport: RectI32) {
|
pub fn set_dest_framebuffer(&mut self, new_dest_framebuffer: DestFramebuffer<D>) {
|
||||||
self.viewport = new_viewport;
|
self.dest_framebuffer = new_dest_framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -506,12 +504,12 @@ impl<D> Renderer<D> where D: Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.device.bind_default_framebuffer(self.viewport);
|
self.bind_main_framebuffer();
|
||||||
|
|
||||||
self.device.bind_vertex_array(&self.postprocess_vertex_array.vertex_array);
|
self.device.bind_vertex_array(&self.postprocess_vertex_array.vertex_array);
|
||||||
self.device.use_program(&self.postprocess_program.program);
|
self.device.use_program(&self.postprocess_program.program);
|
||||||
self.device.set_uniform(&self.postprocess_program.framebuffer_size_uniform,
|
self.device.set_uniform(&self.postprocess_program.framebuffer_size_uniform,
|
||||||
UniformData::Vec2(self.viewport.size().to_f32().0));
|
UniformData::Vec2(self.main_viewport().size().to_f32().0));
|
||||||
match defringing_kernel {
|
match defringing_kernel {
|
||||||
Some(ref kernel) => {
|
Some(ref kernel) => {
|
||||||
self.device.set_uniform(&self.postprocess_program.kernel_uniform,
|
self.device.set_uniform(&self.postprocess_program.kernel_uniform,
|
||||||
|
@ -602,7 +600,18 @@ impl<D> Renderer<D> where D: Device {
|
||||||
if self.postprocessing_needed() {
|
if self.postprocessing_needed() {
|
||||||
self.device.bind_framebuffer(self.postprocess_source_framebuffer.as_ref().unwrap());
|
self.device.bind_framebuffer(self.postprocess_source_framebuffer.as_ref().unwrap());
|
||||||
} else {
|
} else {
|
||||||
self.device.bind_default_framebuffer(self.viewport);
|
self.bind_main_framebuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_main_framebuffer(&self) {
|
||||||
|
match self.dest_framebuffer {
|
||||||
|
DestFramebuffer::Default { viewport, .. } => {
|
||||||
|
self.device.bind_default_framebuffer(viewport)
|
||||||
|
}
|
||||||
|
DestFramebuffer::Other(ref framebuffer) => {
|
||||||
|
self.device.bind_framebuffer(framebuffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,12 +655,23 @@ impl<D> Renderer<D> where D: Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_viewport(&self) -> RectI32 {
|
fn draw_viewport(&self) -> RectI32 {
|
||||||
|
let main_viewport = self.main_viewport();
|
||||||
match self.render_mode {
|
match self.render_mode {
|
||||||
RenderMode::Monochrome { defringing_kernel: Some(..), .. } => {
|
RenderMode::Monochrome { defringing_kernel: Some(..), .. } => {
|
||||||
RectI32::new(Point2DI32::default(),
|
let scale = Point2DI32::new(3, 1);
|
||||||
self.viewport.size().scale_xy(Point2DI32::new(3, 1)))
|
RectI32::new(Point2DI32::default(), main_viewport.size().scale_xy(scale))
|
||||||
|
}
|
||||||
|
_ => main_viewport
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main_viewport(&self) -> RectI32 {
|
||||||
|
match self.dest_framebuffer {
|
||||||
|
DestFramebuffer::Default { viewport, .. } => viewport,
|
||||||
|
DestFramebuffer::Other(ref framebuffer) => {
|
||||||
|
let size = self.device.texture_size(self.device.framebuffer_texture(framebuffer));
|
||||||
|
RectI32::new(Point2DI32::default(), size)
|
||||||
}
|
}
|
||||||
_ => self.viewport
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1079,6 +1099,23 @@ impl<D> StencilVertexArray<D> where D: Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum DestFramebuffer<D> where D: Device {
|
||||||
|
Default { viewport: RectI32, window_size: Point2DI32 },
|
||||||
|
Other(D::Framebuffer),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> DestFramebuffer<D> where D: Device {
|
||||||
|
fn window_size(&self, device: &D) -> Point2DI32 {
|
||||||
|
match *self {
|
||||||
|
DestFramebuffer::Default { window_size, .. } => window_size,
|
||||||
|
DestFramebuffer::Other(ref framebuffer) => {
|
||||||
|
device.texture_size(device.framebuffer_texture(framebuffer))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum RenderMode {
|
pub enum RenderMode {
|
||||||
Multicolor,
|
Multicolor,
|
||||||
|
|
Loading…
Reference in New Issue