Use stencil to integrate the vector scene into the 3D environment
This commit is contained in:
parent
3b8ecfd74c
commit
c7a1d9e960
|
@ -390,11 +390,12 @@ impl DemoApp {
|
||||||
color.g(),
|
color.g(),
|
||||||
color.b(),
|
color.b(),
|
||||||
color.a());
|
color.a());
|
||||||
gl::DepthFunc(gl::LESS);
|
gl::DepthFunc(gl::ALWAYS);
|
||||||
gl::DepthMask(gl::FALSE);
|
gl::DepthMask(gl::TRUE);
|
||||||
gl::Enable(gl::DEPTH_TEST);
|
gl::Enable(gl::DEPTH_TEST);
|
||||||
gl::StencilFunc(gl::ALWAYS, 1, !0);
|
gl::StencilFunc(gl::ALWAYS, 2, 2);
|
||||||
gl::StencilOp(gl::KEEP, gl::KEEP, gl::REPLACE);
|
gl::StencilOp(gl::KEEP, gl::KEEP, gl::REPLACE);
|
||||||
|
gl::StencilMask(2);
|
||||||
gl::Enable(gl::STENCIL_TEST);
|
gl::Enable(gl::STENCIL_TEST);
|
||||||
gl::Disable(gl::BLEND);
|
gl::Disable(gl::BLEND);
|
||||||
gl::DrawArrays(gl::LINES, 0, (GRIDLINE_COUNT as GLsizei + 1) * 4);
|
gl::DrawArrays(gl::LINES, 0, (GRIDLINE_COUNT as GLsizei + 1) * 4);
|
||||||
|
@ -419,7 +420,7 @@ impl DemoApp {
|
||||||
gl::DepthFunc(gl::LESS);
|
gl::DepthFunc(gl::LESS);
|
||||||
gl::DepthMask(gl::TRUE);
|
gl::DepthMask(gl::TRUE);
|
||||||
gl::Enable(gl::DEPTH_TEST);
|
gl::Enable(gl::DEPTH_TEST);
|
||||||
gl::StencilFunc(gl::NOTEQUAL, 1, !0);
|
gl::StencilFunc(gl::NOTEQUAL, 2, 2);
|
||||||
gl::StencilOp(gl::KEEP, gl::KEEP, gl::KEEP);
|
gl::StencilOp(gl::KEEP, gl::KEEP, gl::KEEP);
|
||||||
gl::Enable(gl::STENCIL_TEST);
|
gl::Enable(gl::STENCIL_TEST);
|
||||||
gl::Disable(gl::BLEND);
|
gl::Disable(gl::BLEND);
|
||||||
|
@ -442,6 +443,12 @@ impl DemoApp {
|
||||||
self.renderer.disable_subpixel_aa();
|
self.renderer.disable_subpixel_aa();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.ui.threed_enabled {
|
||||||
|
self.renderer.enable_depth();
|
||||||
|
} else {
|
||||||
|
self.renderer.disable_depth();
|
||||||
|
}
|
||||||
|
|
||||||
self.renderer.render_scene(&built_scene);
|
self.renderer.render_scene(&built_scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ use crate::device::{Buffer, BufferTarget, BufferUploadMode, Device, Framebuffer,
|
||||||
use crate::device::{TimerQuery, Uniform, VertexArray, VertexAttr};
|
use crate::device::{TimerQuery, Uniform, VertexArray, VertexAttr};
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use gl::types::{GLfloat, GLint};
|
use gl::types::{GLfloat, GLint};
|
||||||
|
use pathfinder_geometry::basic::point::Point3DF32;
|
||||||
use pathfinder_renderer::gpu_data::{Batch, BuiltScene, SolidTileScenePrimitive};
|
use pathfinder_renderer::gpu_data::{Batch, BuiltScene, SolidTileScenePrimitive};
|
||||||
use pathfinder_renderer::paint::{ColorU, ObjectShader};
|
use pathfinder_renderer::paint::{ColorU, ObjectShader};
|
||||||
use pathfinder_renderer::post::DefringingKernel;
|
use pathfinder_renderer::post::DefringingKernel;
|
||||||
|
@ -52,6 +53,10 @@ pub struct Renderer {
|
||||||
postprocess_vertex_array: PostprocessVertexArray,
|
postprocess_vertex_array: PostprocessVertexArray,
|
||||||
gamma_lut_texture: Texture,
|
gamma_lut_texture: Texture,
|
||||||
|
|
||||||
|
// Stencil shader
|
||||||
|
stencil_program: StencilProgram,
|
||||||
|
stencil_vertex_array: StencilVertexArray,
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
pending_timer_queries: VecDeque<TimerQuery>,
|
pending_timer_queries: VecDeque<TimerQuery>,
|
||||||
free_timer_queries: Vec<TimerQuery>,
|
free_timer_queries: Vec<TimerQuery>,
|
||||||
|
@ -60,6 +65,7 @@ pub struct Renderer {
|
||||||
// Extra info
|
// Extra info
|
||||||
main_framebuffer_size: Size2D<u32>,
|
main_framebuffer_size: Size2D<u32>,
|
||||||
postprocess_options: PostprocessOptions,
|
postprocess_options: PostprocessOptions,
|
||||||
|
use_depth: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
|
@ -69,6 +75,7 @@ impl Renderer {
|
||||||
let mask_tile_program = MaskTileProgram::new(device);
|
let mask_tile_program = MaskTileProgram::new(device);
|
||||||
|
|
||||||
let postprocess_program = PostprocessProgram::new(device);
|
let postprocess_program = PostprocessProgram::new(device);
|
||||||
|
let stencil_program = StencilProgram::new(device);
|
||||||
|
|
||||||
let area_lut_texture = device.create_texture_from_png("area-lut");
|
let area_lut_texture = device.create_texture_from_png("area-lut");
|
||||||
let gamma_lut_texture = device.create_texture_from_png("gamma-lut");
|
let gamma_lut_texture = device.create_texture_from_png("gamma-lut");
|
||||||
|
@ -86,6 +93,7 @@ impl Renderer {
|
||||||
|
|
||||||
let postprocess_vertex_array = PostprocessVertexArray::new(&postprocess_program,
|
let postprocess_vertex_array = PostprocessVertexArray::new(&postprocess_program,
|
||||||
&quad_vertex_positions_buffer);
|
&quad_vertex_positions_buffer);
|
||||||
|
let stencil_vertex_array = StencilVertexArray::new(&stencil_program);
|
||||||
|
|
||||||
let mask_framebuffer_texture = Texture::new_r16f(&Size2D::new(MASK_FRAMEBUFFER_WIDTH,
|
let mask_framebuffer_texture = Texture::new_r16f(&Size2D::new(MASK_FRAMEBUFFER_WIDTH,
|
||||||
MASK_FRAMEBUFFER_HEIGHT));
|
MASK_FRAMEBUFFER_HEIGHT));
|
||||||
|
@ -113,6 +121,9 @@ impl Renderer {
|
||||||
postprocess_vertex_array,
|
postprocess_vertex_array,
|
||||||
gamma_lut_texture,
|
gamma_lut_texture,
|
||||||
|
|
||||||
|
stencil_program,
|
||||||
|
stencil_vertex_array,
|
||||||
|
|
||||||
pending_timer_queries: VecDeque::new(),
|
pending_timer_queries: VecDeque::new(),
|
||||||
free_timer_queries: vec![],
|
free_timer_queries: vec![],
|
||||||
|
|
||||||
|
@ -120,6 +131,7 @@ impl Renderer {
|
||||||
|
|
||||||
main_framebuffer_size: *main_framebuffer_size,
|
main_framebuffer_size: *main_framebuffer_size,
|
||||||
postprocess_options: PostprocessOptions::default(),
|
postprocess_options: PostprocessOptions::default(),
|
||||||
|
use_depth: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,16 +143,18 @@ impl Renderer {
|
||||||
|
|
||||||
self.upload_shaders(&built_scene.shaders);
|
self.upload_shaders(&built_scene.shaders);
|
||||||
|
|
||||||
|
if self.use_depth {
|
||||||
|
self.draw_stencil(&built_scene.quad);
|
||||||
|
}
|
||||||
|
|
||||||
self.upload_solid_tiles(&built_scene.solid_tiles);
|
self.upload_solid_tiles(&built_scene.solid_tiles);
|
||||||
self.draw_solid_tiles(&built_scene);
|
self.draw_solid_tiles(&built_scene);
|
||||||
|
|
||||||
/*
|
|
||||||
for batch in &built_scene.batches {
|
for batch in &built_scene.batches {
|
||||||
self.upload_batch(batch);
|
self.upload_batch(batch);
|
||||||
self.draw_batch_fills(batch);
|
self.draw_batch_fills(batch);
|
||||||
self.draw_batch_mask_tiles(&built_scene, batch);
|
self.draw_batch_mask_tiles(batch);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
if self.postprocessing_needed() {
|
if self.postprocessing_needed() {
|
||||||
self.postprocess();
|
self.postprocess();
|
||||||
|
@ -187,6 +201,16 @@ impl Renderer {
|
||||||
self.postprocess_options.gamma_correction_bg_color = Some(bg_color);
|
self.postprocess_options.gamma_correction_bg_color = Some(bg_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn disable_depth(&mut self) {
|
||||||
|
self.use_depth = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn enable_depth(&mut self) {
|
||||||
|
self.use_depth = true;
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn quad_vertex_positions_buffer(&self) -> &Buffer {
|
pub fn quad_vertex_positions_buffer(&self) -> &Buffer {
|
||||||
&self.quad_vertex_positions_buffer
|
&self.quad_vertex_positions_buffer
|
||||||
|
@ -247,7 +271,7 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_batch_mask_tiles(&mut self, built_scene: &BuiltScene, batch: &Batch) {
|
fn draw_batch_mask_tiles(&mut self, batch: &Batch) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.bind_draw_framebuffer();
|
self.bind_draw_framebuffer();
|
||||||
self.set_main_viewport();
|
self.set_main_viewport();
|
||||||
|
@ -272,26 +296,12 @@ impl Renderer {
|
||||||
FILL_COLORS_TEXTURE_HEIGHT as GLfloat);
|
FILL_COLORS_TEXTURE_HEIGHT as GLfloat);
|
||||||
// FIXME(pcwalton): Fill this in properly!
|
// FIXME(pcwalton): Fill this in properly!
|
||||||
gl::Uniform2f(self.mask_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
gl::Uniform2f(self.mask_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
||||||
gl::Uniform3f(self.mask_tile_program.quad_p0_uniform.location,
|
|
||||||
built_scene.quad[0].x(),
|
|
||||||
built_scene.quad[0].y(),
|
|
||||||
built_scene.quad[0].z());
|
|
||||||
gl::Uniform3f(self.mask_tile_program.quad_p1_uniform.location,
|
|
||||||
built_scene.quad[1].x(),
|
|
||||||
built_scene.quad[1].y(),
|
|
||||||
built_scene.quad[1].z());
|
|
||||||
gl::Uniform3f(self.mask_tile_program.quad_p2_uniform.location,
|
|
||||||
built_scene.quad[2].x(),
|
|
||||||
built_scene.quad[2].y(),
|
|
||||||
built_scene.quad[2].z());
|
|
||||||
gl::Uniform3f(self.mask_tile_program.quad_p3_uniform.location,
|
|
||||||
built_scene.quad[3].x(),
|
|
||||||
built_scene.quad[3].y(),
|
|
||||||
built_scene.quad[3].z());
|
|
||||||
self.enable_blending();
|
self.enable_blending();
|
||||||
self.enable_depth_test();
|
gl::Disable(gl::DEPTH_TEST);
|
||||||
|
self.setup_stencil_mask();
|
||||||
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, batch.mask_tiles.len() as GLint);
|
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, batch.mask_tiles.len() as GLint);
|
||||||
gl::Disable(gl::BLEND);
|
gl::Disable(gl::BLEND);
|
||||||
|
gl::Disable(gl::STENCIL_TEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,28 +325,12 @@ impl Renderer {
|
||||||
FILL_COLORS_TEXTURE_HEIGHT as GLfloat);
|
FILL_COLORS_TEXTURE_HEIGHT as GLfloat);
|
||||||
// FIXME(pcwalton): Fill this in properly!
|
// FIXME(pcwalton): Fill this in properly!
|
||||||
gl::Uniform2f(self.solid_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
gl::Uniform2f(self.solid_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
||||||
gl::Uniform3f(self.solid_tile_program.quad_p0_uniform.location,
|
|
||||||
built_scene.quad[0].x(),
|
|
||||||
built_scene.quad[0].y(),
|
|
||||||
built_scene.quad[0].z());
|
|
||||||
gl::Uniform3f(self.solid_tile_program.quad_p1_uniform.location,
|
|
||||||
built_scene.quad[1].x(),
|
|
||||||
built_scene.quad[1].y(),
|
|
||||||
built_scene.quad[1].z());
|
|
||||||
gl::Uniform3f(self.solid_tile_program.quad_p2_uniform.location,
|
|
||||||
built_scene.quad[2].x(),
|
|
||||||
built_scene.quad[2].y(),
|
|
||||||
built_scene.quad[2].z());
|
|
||||||
gl::Uniform3f(self.solid_tile_program.quad_p3_uniform.location,
|
|
||||||
built_scene.quad[3].x(),
|
|
||||||
built_scene.quad[3].y(),
|
|
||||||
built_scene.quad[3].z());
|
|
||||||
gl::Disable(gl::BLEND);
|
gl::Disable(gl::BLEND);
|
||||||
gl::DepthMask(gl::FALSE);
|
gl::Disable(gl::DEPTH_TEST);
|
||||||
gl::Enable(gl::DEPTH_TEST);
|
self.setup_stencil_mask();
|
||||||
gl::Disable(gl::STENCIL_TEST);
|
|
||||||
let count = built_scene.solid_tiles.len();
|
let count = built_scene.solid_tiles.len();
|
||||||
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, count as GLint);
|
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, count as GLint);
|
||||||
|
gl::Disable(gl::STENCIL_TEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,6 +382,30 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_stencil(&self, quad_positions: &[Point3DF32]) {
|
||||||
|
self.stencil_vertex_array
|
||||||
|
.vertex_buffer
|
||||||
|
.upload(quad_positions, BufferTarget::Vertex, BufferUploadMode::Dynamic);
|
||||||
|
self.bind_draw_framebuffer();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gl::BindVertexArray(self.stencil_vertex_array.vertex_array.gl_vertex_array);
|
||||||
|
gl::UseProgram(self.stencil_program.program.gl_program);
|
||||||
|
gl::ColorMask(gl::FALSE, gl::FALSE, gl::FALSE, gl::FALSE);
|
||||||
|
gl::DepthFunc(gl::LESS);
|
||||||
|
gl::Enable(gl::DEPTH_TEST);
|
||||||
|
gl::StencilFunc(gl::ALWAYS, 1, 1);
|
||||||
|
gl::StencilOp(gl::KEEP, gl::KEEP, gl::REPLACE);
|
||||||
|
gl::StencilMask(1);
|
||||||
|
gl::Enable(gl::STENCIL_TEST);
|
||||||
|
gl::Disable(gl::BLEND);
|
||||||
|
gl::DrawArrays(gl::TRIANGLE_FAN, 0, quad_positions.len() as GLint);
|
||||||
|
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
|
||||||
|
gl::Disable(gl::DEPTH_TEST);
|
||||||
|
gl::Disable(gl::STENCIL_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn bind_draw_framebuffer(&self) {
|
fn bind_draw_framebuffer(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if self.postprocessing_needed() {
|
if self.postprocessing_needed() {
|
||||||
|
@ -443,14 +461,18 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enable_depth_test(&self) {
|
fn setup_stencil_mask(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::DepthMask(gl::FALSE);
|
if self.use_depth {
|
||||||
gl::Enable(gl::DEPTH_TEST);
|
gl::StencilFunc(gl::EQUAL, 1, 1);
|
||||||
|
gl::StencilOp(gl::KEEP, gl::KEEP, gl::KEEP);
|
||||||
|
gl::Enable(gl::STENCIL_TEST);
|
||||||
|
} else {
|
||||||
gl::Disable(gl::STENCIL_TEST);
|
gl::Disable(gl::STENCIL_TEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
struct PostprocessOptions {
|
struct PostprocessOptions {
|
||||||
|
@ -574,10 +596,6 @@ struct SolidTileProgram {
|
||||||
fill_colors_texture_uniform: Uniform,
|
fill_colors_texture_uniform: Uniform,
|
||||||
fill_colors_texture_size_uniform: Uniform,
|
fill_colors_texture_size_uniform: Uniform,
|
||||||
view_box_origin_uniform: Uniform,
|
view_box_origin_uniform: Uniform,
|
||||||
quad_p0_uniform: Uniform,
|
|
||||||
quad_p1_uniform: Uniform,
|
|
||||||
quad_p2_uniform: Uniform,
|
|
||||||
quad_p3_uniform: Uniform,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SolidTileProgram {
|
impl SolidTileProgram {
|
||||||
|
@ -588,10 +606,6 @@ impl SolidTileProgram {
|
||||||
let fill_colors_texture_uniform = Uniform::new(&program, "FillColorsTexture");
|
let fill_colors_texture_uniform = Uniform::new(&program, "FillColorsTexture");
|
||||||
let fill_colors_texture_size_uniform = Uniform::new(&program, "FillColorsTextureSize");
|
let fill_colors_texture_size_uniform = Uniform::new(&program, "FillColorsTextureSize");
|
||||||
let view_box_origin_uniform = Uniform::new(&program, "ViewBoxOrigin");
|
let view_box_origin_uniform = Uniform::new(&program, "ViewBoxOrigin");
|
||||||
let quad_p0_uniform = Uniform::new(&program, "QuadP0");
|
|
||||||
let quad_p1_uniform = Uniform::new(&program, "QuadP1");
|
|
||||||
let quad_p2_uniform = Uniform::new(&program, "QuadP2");
|
|
||||||
let quad_p3_uniform = Uniform::new(&program, "QuadP3");
|
|
||||||
SolidTileProgram {
|
SolidTileProgram {
|
||||||
program,
|
program,
|
||||||
framebuffer_size_uniform,
|
framebuffer_size_uniform,
|
||||||
|
@ -599,10 +613,6 @@ impl SolidTileProgram {
|
||||||
fill_colors_texture_uniform,
|
fill_colors_texture_uniform,
|
||||||
fill_colors_texture_size_uniform,
|
fill_colors_texture_size_uniform,
|
||||||
view_box_origin_uniform,
|
view_box_origin_uniform,
|
||||||
quad_p0_uniform,
|
|
||||||
quad_p1_uniform,
|
|
||||||
quad_p2_uniform,
|
|
||||||
quad_p3_uniform,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -616,10 +626,6 @@ struct MaskTileProgram {
|
||||||
fill_colors_texture_uniform: Uniform,
|
fill_colors_texture_uniform: Uniform,
|
||||||
fill_colors_texture_size_uniform: Uniform,
|
fill_colors_texture_size_uniform: Uniform,
|
||||||
view_box_origin_uniform: Uniform,
|
view_box_origin_uniform: Uniform,
|
||||||
quad_p0_uniform: Uniform,
|
|
||||||
quad_p1_uniform: Uniform,
|
|
||||||
quad_p2_uniform: Uniform,
|
|
||||||
quad_p3_uniform: Uniform,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MaskTileProgram {
|
impl MaskTileProgram {
|
||||||
|
@ -632,10 +638,6 @@ impl MaskTileProgram {
|
||||||
let fill_colors_texture_uniform = Uniform::new(&program, "FillColorsTexture");
|
let fill_colors_texture_uniform = Uniform::new(&program, "FillColorsTexture");
|
||||||
let fill_colors_texture_size_uniform = Uniform::new(&program, "FillColorsTextureSize");
|
let fill_colors_texture_size_uniform = Uniform::new(&program, "FillColorsTextureSize");
|
||||||
let view_box_origin_uniform = Uniform::new(&program, "ViewBoxOrigin");
|
let view_box_origin_uniform = Uniform::new(&program, "ViewBoxOrigin");
|
||||||
let quad_p0_uniform = Uniform::new(&program, "QuadP0");
|
|
||||||
let quad_p1_uniform = Uniform::new(&program, "QuadP1");
|
|
||||||
let quad_p2_uniform = Uniform::new(&program, "QuadP2");
|
|
||||||
let quad_p3_uniform = Uniform::new(&program, "QuadP3");
|
|
||||||
MaskTileProgram {
|
MaskTileProgram {
|
||||||
program,
|
program,
|
||||||
framebuffer_size_uniform,
|
framebuffer_size_uniform,
|
||||||
|
@ -645,10 +647,6 @@ impl MaskTileProgram {
|
||||||
fill_colors_texture_uniform,
|
fill_colors_texture_uniform,
|
||||||
fill_colors_texture_size_uniform,
|
fill_colors_texture_size_uniform,
|
||||||
view_box_origin_uniform,
|
view_box_origin_uniform,
|
||||||
quad_p0_uniform,
|
|
||||||
quad_p1_uniform,
|
|
||||||
quad_p2_uniform,
|
|
||||||
quad_p3_uniform,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -701,3 +699,35 @@ impl PostprocessVertexArray {
|
||||||
PostprocessVertexArray { vertex_array }
|
PostprocessVertexArray { vertex_array }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StencilProgram {
|
||||||
|
program: Program,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StencilProgram {
|
||||||
|
fn new(device: &Device) -> StencilProgram {
|
||||||
|
let program = device.create_program("stencil");
|
||||||
|
StencilProgram { program }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StencilVertexArray {
|
||||||
|
vertex_array: VertexArray,
|
||||||
|
vertex_buffer: Buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StencilVertexArray {
|
||||||
|
fn new(stencil_program: &StencilProgram) -> StencilVertexArray {
|
||||||
|
let (vertex_array, vertex_buffer) = (VertexArray::new(), Buffer::new());
|
||||||
|
unsafe {
|
||||||
|
let position_attr = VertexAttr::new(&stencil_program.program, "Position");
|
||||||
|
|
||||||
|
gl::BindVertexArray(vertex_array.gl_vertex_array);
|
||||||
|
gl::UseProgram(stencil_program.program.gl_program);
|
||||||
|
gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer.gl_buffer);
|
||||||
|
position_attr.configure_float(3, gl::FLOAT, false, 4 * 4, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
StencilVertexArray { vertex_array, vertex_buffer }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ impl RenderTransform {
|
||||||
for point in &mut points {
|
for point in &mut points {
|
||||||
*point = perspective.transform.transform_point(*point);
|
*point = perspective.transform.transform_point(*point);
|
||||||
}
|
}
|
||||||
println!("... PERSPECTIVE quad={:?}", points);
|
//println!("... PERSPECTIVE quad={:?}", points);
|
||||||
|
|
||||||
// Compute depth.
|
// Compute depth.
|
||||||
let quad = [
|
let quad = [
|
||||||
|
@ -182,12 +182,7 @@ impl RenderTransform {
|
||||||
points[2].perspective_divide(),
|
points[2].perspective_divide(),
|
||||||
points[3].perspective_divide(),
|
points[3].perspective_divide(),
|
||||||
];
|
];
|
||||||
println!("barycentric(0, 0) = {:?}", compute_barycentric(&[
|
//println!("... PERSPECTIVE-DIVIDED points = {:?}", quad);
|
||||||
quad[0].to_2d(),
|
|
||||||
quad[1].to_2d(),
|
|
||||||
quad[2].to_2d(),
|
|
||||||
quad[3].to_2d(),
|
|
||||||
], Point2DF32::new(0.0, 0.0)));
|
|
||||||
|
|
||||||
points = PolygonClipper3D::new(points).clip();
|
points = PolygonClipper3D::new(points).clip();
|
||||||
//println!("... CLIPPED quad={:?}", points);
|
//println!("... CLIPPED quad={:?}", points);
|
||||||
|
@ -200,20 +195,6 @@ impl RenderTransform {
|
||||||
inverse_transform.transform_point(point).perspective_divide().to_2d()
|
inverse_transform.transform_point(point).perspective_divide().to_2d()
|
||||||
}).collect();
|
}).collect();
|
||||||
return PreparedRenderTransform::Perspective { perspective, clip_polygon, quad };
|
return PreparedRenderTransform::Perspective { perspective, clip_polygon, quad };
|
||||||
|
|
||||||
fn compute_barycentric(quad: &[Point2DF32], point: Point2DF32) -> [f32; 4] {
|
|
||||||
let (s0, s1) = (quad[0] - point, quad[1] - point);
|
|
||||||
let (s2, s3) = (quad[2] - point, quad[3] - point);
|
|
||||||
let (a0, a1, a2, a3) = (s0.det(s1), s1.det(s2), s2.det(s3), s3.det(s0));
|
|
||||||
let (d0, d1, d2, d3) = (s0.dot(s1), s1.dot(s2), s2.dot(s3), s3.dot(s0));
|
|
||||||
let (r0, r1, r2, r3) = (s0.length(), s1.length(), s2.length(), s3.length());
|
|
||||||
let (t0, t1) = ((r0 * r1 - d0) / a0, (r1 * r2 - d1) / a1);
|
|
||||||
let (t2, t3) = ((r2 * r3 - d2) / a2, (r3 * r0 - d3) / a3);
|
|
||||||
let (u0, u1) = ((t3 + t0) / r0, (t2 + t1) / r1);
|
|
||||||
let (u2, u3) = ((t0 + t2) / r2, (t0 + t3) / r3);
|
|
||||||
let sum = u0 + u1 + u2 + u3;
|
|
||||||
[u0 / sum, u1 / sum, u2 / sum, u3 / sum]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,6 @@ uniform vec2 uStencilTextureSize;
|
||||||
uniform sampler2D uFillColorsTexture;
|
uniform sampler2D uFillColorsTexture;
|
||||||
uniform vec2 uFillColorsTextureSize;
|
uniform vec2 uFillColorsTextureSize;
|
||||||
uniform vec2 uViewBoxOrigin;
|
uniform vec2 uViewBoxOrigin;
|
||||||
uniform vec3 uQuadP0;
|
|
||||||
uniform vec3 uQuadP1;
|
|
||||||
uniform vec3 uQuadP2;
|
|
||||||
uniform vec3 uQuadP3;
|
|
||||||
|
|
||||||
in vec2 aTessCoord;
|
in vec2 aTessCoord;
|
||||||
in vec2 aTileOrigin;
|
in vec2 aTileOrigin;
|
||||||
|
@ -32,21 +28,6 @@ out vec2 vTexCoord;
|
||||||
out float vBackdrop;
|
out float vBackdrop;
|
||||||
out vec4 vColor;
|
out vec4 vColor;
|
||||||
|
|
||||||
float wedge(vec2 a, vec2 b) {
|
|
||||||
return a.x * b.y - a.y * b.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// From "A Quadrilateral Rendering Primitive", Hormann and Tarini 2004.
|
|
||||||
vec4 barycentricQuad(vec2 p) {
|
|
||||||
vec2 s0 = uQuadP0.xy - p, s1 = uQuadP1.xy - p, s2 = uQuadP2.xy - p, s3 = uQuadP3.xy - p;
|
|
||||||
vec4 a = vec4(wedge(s0, s1), wedge(s1, s2), wedge(s2, s3), wedge(s3, s0));
|
|
||||||
vec4 d = vec4(dot(s0, s1), dot(s1, s2), dot(s2, s3), dot(s3, s0));
|
|
||||||
vec4 r = vec4(length(s0), length(s1), length(s2), length(s3));
|
|
||||||
vec4 t = (r * r.yzwx - d) / a;
|
|
||||||
vec4 u = (t.wxyz + t) / r;
|
|
||||||
return u / dot(u, vec4(1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
|
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
|
||||||
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
|
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
|
||||||
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
|
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
|
||||||
|
@ -62,21 +43,11 @@ void main() {
|
||||||
uint tileIndex = uint(gl_InstanceID);
|
uint tileIndex = uint(gl_InstanceID);
|
||||||
vec2 pixelPosition = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
vec2 pixelPosition = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
||||||
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
|
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
|
||||||
|
|
||||||
vec4 lambda = barycentricQuad(position);
|
|
||||||
//vec4 depths = vec4(uQuadP0.z, uQuadP1.z, uQuadP2.z, uQuadP3.z);
|
|
||||||
//float depth = dot(lambda, depths);
|
|
||||||
float red = lambda.x;
|
|
||||||
float green = lambda.y;
|
|
||||||
float blue = lambda.z + 1.0;
|
|
||||||
float depth = 0.0;
|
|
||||||
|
|
||||||
vec2 texCoord = computeTileOffset(tileIndex, uStencilTextureSize.x) + aTessCoord * uTileSize;
|
vec2 texCoord = computeTileOffset(tileIndex, uStencilTextureSize.x) + aTessCoord * uTileSize;
|
||||||
vec2 colorTexCoord = computeFillColorTexCoord(aObject, uFillColorsTextureSize);
|
vec2 colorTexCoord = computeFillColorTexCoord(aObject, uFillColorsTextureSize);
|
||||||
|
|
||||||
vTexCoord = texCoord / uStencilTextureSize;
|
vTexCoord = texCoord / uStencilTextureSize;
|
||||||
vBackdrop = float(aBackdrop);
|
vBackdrop = float(aBackdrop);
|
||||||
//vColor = texture(uFillColorsTexture, colorTexCoord);
|
vColor = texture(uFillColorsTexture, colorTexCoord);
|
||||||
vColor = vec4(red, green, blue, 1.0);
|
gl_Position = vec4(position, 0.0, 1.0);
|
||||||
gl_Position = vec4(position, depth, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,6 @@ uniform vec2 uTileSize;
|
||||||
uniform sampler2D uFillColorsTexture;
|
uniform sampler2D uFillColorsTexture;
|
||||||
uniform vec2 uFillColorsTextureSize;
|
uniform vec2 uFillColorsTextureSize;
|
||||||
uniform vec2 uViewBoxOrigin;
|
uniform vec2 uViewBoxOrigin;
|
||||||
uniform vec3 uQuadP0;
|
|
||||||
uniform vec3 uQuadP1;
|
|
||||||
uniform vec3 uQuadP2;
|
|
||||||
uniform vec3 uQuadP3;
|
|
||||||
|
|
||||||
in vec2 aTessCoord;
|
in vec2 aTessCoord;
|
||||||
in vec2 aTileOrigin;
|
in vec2 aTileOrigin;
|
||||||
|
@ -28,21 +24,6 @@ in uint aObject;
|
||||||
|
|
||||||
out vec4 vColor;
|
out vec4 vColor;
|
||||||
|
|
||||||
float wedge(vec2 a, vec2 b) {
|
|
||||||
return a.x * b.y - a.y * b.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// From "A Quadrilateral Rendering Primitive", Hormann and Tarini 2004.
|
|
||||||
vec4 barycentricQuad(vec2 p) {
|
|
||||||
vec2 s0 = uQuadP0.xy - p, s1 = uQuadP1.xy - p, s2 = uQuadP2.xy - p, s3 = uQuadP3.xy - p;
|
|
||||||
vec4 a = vec4(wedge(s0, s1), wedge(s1, s2), wedge(s2, s3), wedge(s3, s0));
|
|
||||||
vec4 d = vec4(dot(s0, s1), dot(s1, s2), dot(s2, s3), dot(s3, s0));
|
|
||||||
vec4 r = vec4(length(s0), length(s1), length(s2), length(s3));
|
|
||||||
vec4 t = (r * r.yzwx - d) / a;
|
|
||||||
vec4 u = (t.wxyz + t) / r;
|
|
||||||
return u / dot(u, vec4(1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 computeFillColorTexCoord(uint object, vec2 textureSize) {
|
vec2 computeFillColorTexCoord(uint object, vec2 textureSize) {
|
||||||
uint width = uint(textureSize.x);
|
uint width = uint(textureSize.x);
|
||||||
return (vec2(float(object % width), float(object / width)) + vec2(0.5)) / textureSize;
|
return (vec2(float(object % width), float(object / width)) + vec2(0.5)) / textureSize;
|
||||||
|
@ -51,19 +32,8 @@ vec2 computeFillColorTexCoord(uint object, vec2 textureSize) {
|
||||||
void main() {
|
void main() {
|
||||||
vec2 pixelPosition = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
vec2 pixelPosition = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
||||||
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
|
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
|
||||||
|
|
||||||
//vec4 depths = vec4(uQuadP0.z, uQuadP1.z, uQuadP2.z, uQuadP3.z);
|
|
||||||
//float depth = dot(barycentricQuad(position), depths);
|
|
||||||
|
|
||||||
vec4 lambda = barycentricQuad(position);
|
|
||||||
float red = lambda.x;
|
|
||||||
float green = lambda.y;
|
|
||||||
float blue = lambda.z;
|
|
||||||
float depth = 0.0;
|
|
||||||
|
|
||||||
vec2 colorTexCoord = computeFillColorTexCoord(aObject, uFillColorsTextureSize);
|
vec2 colorTexCoord = computeFillColorTexCoord(aObject, uFillColorsTextureSize);
|
||||||
|
|
||||||
//vColor = texture(uFillColorsTexture, colorTexCoord);
|
vColor = texture(uFillColorsTexture, colorTexCoord);
|
||||||
vColor = vec4(red, green, blue, 1.0);
|
gl_Position = vec4(position, 0.0, 1.0);
|
||||||
gl_Position = vec4(position, depth, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
// pathfinder/resources/shaders/stencil.fs.glsl
|
||||||
|
//
|
||||||
|
// Copyright © 2018 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
out vec4 oFragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// This should be color masked out.
|
||||||
|
oFragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
// pathfinder/resources/shaders/stencil.vs.glsl
|
||||||
|
//
|
||||||
|
// Copyright © 2018 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
in vec3 aPosition;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(aPosition, 1.0);
|
||||||
|
}
|
Loading…
Reference in New Issue