Get the native code demo rendering the tiger
This commit is contained in:
parent
a4c2796883
commit
5bbb5a1b74
|
@ -338,8 +338,8 @@ class App {
|
|||
gl.bindTexture(gl.TEXTURE_2D, this.stencilTexture);
|
||||
gl.uniform1i(this.maskTileProgram.uniforms.StencilTexture, 0);
|
||||
gl.uniform2f(this.maskTileProgram.uniforms.StencilTextureSize,
|
||||
STENCIL_FRAMEBUFFER_SIZE.width,
|
||||
STENCIL_FRAMEBUFFER_SIZE.height);
|
||||
STENCIL_FRAMEBUFFER_SIZE.width,
|
||||
STENCIL_FRAMEBUFFER_SIZE.height);
|
||||
gl.activeTexture(gl.TEXTURE1);
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.fillColorsTexture);
|
||||
gl.uniform1i(this.maskTileProgram.uniforms.FillColorsTexture, 1);
|
||||
|
|
|
@ -24,8 +24,7 @@ void main() {
|
|||
vec2 from = vFrom, to = vTo;
|
||||
|
||||
// Determine winding, and sort into a consistent order so we only need to find one root below.
|
||||
bool winding = from.x < to.x;
|
||||
vec2 left = winding ? from : to, right = winding ? to : from;
|
||||
vec2 left = from.x < to.x ? from : to, right = from.x < to.x ? to : from;
|
||||
|
||||
// Shoot a vertical ray toward the curve.
|
||||
vec2 window = clamp(vec2(from.x, to.x), -0.5, 0.5);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/demo2/stencil.vs.glsl
|
||||
// pathfinder/demo3/fill.vs.glsl
|
||||
//
|
||||
// Copyright © 2018 The Pathfinder Project Developers.
|
||||
// Copyright © 2019 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
|
||||
|
@ -38,7 +38,6 @@ void main() {
|
|||
vec2 to = vec2(aToPx & 15u, aToPx >> 4u) + aToSubpx;
|
||||
|
||||
vec2 position;
|
||||
bool zeroArea = !(abs(from.x - to.x) > 0.1) || !(abs(uTileSize.y - min(from.y, to.y)) > 0.1);
|
||||
if (aTessCoord.x < 0.5)
|
||||
position.x = floor(min(from.x, to.x));
|
||||
else
|
||||
|
@ -51,7 +50,7 @@ void main() {
|
|||
vFrom = from - position;
|
||||
vTo = to - position;
|
||||
|
||||
if (zeroArea)
|
||||
if (!(abs(from.x - to.x) > 0.1) || !(abs(uTileSize.y - min(from.y, to.y)) > 0.1))
|
||||
gl_Position = vec4(0.0);
|
||||
else
|
||||
gl_Position = vec4((tileOrigin + position) / uFramebufferSize * 2.0 - 1.0, 0.0, 1.0);
|
||||
|
|
|
@ -22,7 +22,5 @@ out vec4 oFragColor;
|
|||
|
||||
void main() {
|
||||
float coverage = abs(texture(uStencilTexture, vTexCoord).r + vBackdrop);
|
||||
vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
//oFragColor = vec4(vColor.rgb, vColor.a * coverage);
|
||||
oFragColor = vec4(color.rgb, color.a * coverage);
|
||||
oFragColor = vec4(vColor.rgb, vColor.a * coverage);
|
||||
}
|
||||
|
|
|
@ -34,12 +34,18 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
|
|||
return vec2(tileOffset) * uTileSize;
|
||||
}
|
||||
|
||||
vec2 computeFillColorTexCoord(uint object, vec2 textureSize) {
|
||||
uint width = uint(textureSize.x);
|
||||
return (vec2(float(object % width), float(object / width)) + vec2(0.5)) / textureSize;
|
||||
}
|
||||
|
||||
void main() {
|
||||
uint tileIndex = uint(gl_InstanceID);
|
||||
vec2 position = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
||||
vec2 texCoord = computeTileOffset(tileIndex, uStencilTextureSize.x) + aTessCoord * uTileSize;
|
||||
vec2 colorTexCoord = computeFillColorTexCoord(aObject, uFillColorsTextureSize);
|
||||
vTexCoord = texCoord / uStencilTextureSize;
|
||||
vBackdrop = float(aBackdrop);
|
||||
vColor = texture(uFillColorsTexture, vec2(float(aObject) / uFillColorsTextureSize.x, 0.0));
|
||||
vColor = texture(uFillColorsTexture, colorTexCoord);
|
||||
gl_Position = vec4((position / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0), 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -24,8 +24,14 @@ in uint aObject;
|
|||
|
||||
out vec4 vColor;
|
||||
|
||||
vec2 computeFillColorTexCoord(uint object, vec2 textureSize) {
|
||||
uint width = uint(textureSize.x);
|
||||
return (vec2(float(object % width), float(object / width)) + vec2(0.5)) / textureSize;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 position = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
||||
vColor = texture(uFillColorsTexture, vec2(float(aObject) / uFillColorsTextureSize.x, 0.0));
|
||||
vec2 colorTexCoord = computeFillColorTexCoord(aObject, uFillColorsTextureSize);
|
||||
vColor = texture(uFillColorsTexture, colorTexCoord);
|
||||
gl_Position = vec4((position / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0), 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -10,10 +10,11 @@
|
|||
|
||||
use clap::{App, Arg};
|
||||
use euclid::Size2D;
|
||||
use gl::types::{GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
|
||||
use gl::types::{GLchar, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
|
||||
use jemallocator;
|
||||
use pathfinder_renderer::builder::SceneBuilder;
|
||||
use pathfinder_renderer::gpu_data::{Batch, BuiltScene, FillBatchPrimitive};
|
||||
use pathfinder_renderer::gpu_data::{Batch, BuiltScene, SolidTileScenePrimitive};
|
||||
use pathfinder_renderer::paint::ObjectShader;
|
||||
use pathfinder_renderer::scene::Scene;
|
||||
use pathfinder_renderer::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
||||
use pathfinder_renderer::z_buffer::ZBuffer;
|
||||
|
@ -44,10 +45,12 @@ const MASK_TILE_INSTANCE_SIZE: GLint = 8;
|
|||
const MASK_FRAMEBUFFER_WIDTH: u32 = TILE_WIDTH * 256;
|
||||
const MASK_FRAMEBUFFER_HEIGHT: u32 = TILE_HEIGHT * 256;
|
||||
|
||||
// FIXME(pcwalton): Make this dynamic!
|
||||
const MAIN_FRAMEBUFFER_WIDTH: u32 = 800;
|
||||
const MAIN_FRAMEBUFFER_HEIGHT: u32 = 800;
|
||||
|
||||
const FILL_COLORS_TEXTURE_WIDTH: u32 = 256;
|
||||
const FILL_COLORS_TEXTURE_HEIGHT: u32 = 256;
|
||||
|
||||
fn main() {
|
||||
let scene = load_scene();
|
||||
|
||||
|
@ -61,6 +64,7 @@ fn main() {
|
|||
let window =
|
||||
sdl_video.window("Pathfinder Demo", MAIN_FRAMEBUFFER_WIDTH, MAIN_FRAMEBUFFER_HEIGHT)
|
||||
.opengl()
|
||||
.allow_highdpi()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
@ -69,9 +73,11 @@ fn main() {
|
|||
|
||||
let mut sdl_event_pump = sdl_context.event_pump().unwrap();
|
||||
let mut exit = false;
|
||||
while !exit {
|
||||
let mut renderer = Renderer::new();
|
||||
|
||||
let (drawable_width, drawable_height) = window.drawable_size();
|
||||
let mut renderer = Renderer::new(&Size2D::new(drawable_width, drawable_height));
|
||||
|
||||
while !exit {
|
||||
unsafe {
|
||||
gl::ClearColor(1.0, 1.0, 1.0, 1.0);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
@ -190,10 +196,13 @@ struct Renderer {
|
|||
mask_tile_vertex_array: MaskTileVertexArray,
|
||||
solid_tile_vertex_array: SolidTileVertexArray,
|
||||
mask_framebuffer: Framebuffer,
|
||||
fill_colors_texture: Texture,
|
||||
|
||||
main_framebuffer_size: Size2D<u32>,
|
||||
}
|
||||
|
||||
impl Renderer {
|
||||
fn new() -> Renderer {
|
||||
fn new(main_framebuffer_size: &Size2D<u32>) -> Renderer {
|
||||
let fill_program = FillProgram::new();
|
||||
let solid_tile_program = SolidTileProgram::new();
|
||||
let mask_tile_program = MaskTileProgram::new();
|
||||
|
@ -212,6 +221,9 @@ impl Renderer {
|
|||
let mask_framebuffer = Framebuffer::new(&Size2D::new(MASK_FRAMEBUFFER_WIDTH,
|
||||
MASK_FRAMEBUFFER_HEIGHT));
|
||||
|
||||
let fill_colors_texture = Texture::new_rgba(&Size2D::new(FILL_COLORS_TEXTURE_WIDTH,
|
||||
FILL_COLORS_TEXTURE_HEIGHT));
|
||||
|
||||
Renderer {
|
||||
fill_program,
|
||||
solid_tile_program,
|
||||
|
@ -222,10 +234,18 @@ impl Renderer {
|
|||
mask_tile_vertex_array,
|
||||
solid_tile_vertex_array,
|
||||
mask_framebuffer,
|
||||
fill_colors_texture,
|
||||
|
||||
main_framebuffer_size: *main_framebuffer_size,
|
||||
}
|
||||
}
|
||||
|
||||
fn render_scene(&mut self, built_scene: &BuiltScene) {
|
||||
self.upload_shaders(&built_scene.shaders);
|
||||
|
||||
self.upload_solid_tiles(&built_scene.solid_tiles);
|
||||
self.draw_solid_tiles(&built_scene.solid_tiles);
|
||||
|
||||
for batch in &built_scene.batches {
|
||||
self.upload_batch(batch);
|
||||
self.draw_batch_fills(batch);
|
||||
|
@ -233,6 +253,22 @@ impl Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
fn upload_shaders(&mut self, shaders: &[ObjectShader]) {
|
||||
let size = Size2D::new(FILL_COLORS_TEXTURE_WIDTH, FILL_COLORS_TEXTURE_HEIGHT);
|
||||
let mut fill_colors = vec![0; size.width as usize * size.height as usize * 4];
|
||||
for (shader_index, shader) in shaders.iter().enumerate() {
|
||||
fill_colors[shader_index * 4 + 0] = shader.fill_color.r;
|
||||
fill_colors[shader_index * 4 + 1] = shader.fill_color.g;
|
||||
fill_colors[shader_index * 4 + 2] = shader.fill_color.b;
|
||||
fill_colors[shader_index * 4 + 3] = shader.fill_color.a;
|
||||
}
|
||||
self.fill_colors_texture.upload_rgba(&size, &fill_colors);
|
||||
}
|
||||
|
||||
fn upload_solid_tiles(&mut self, solid_tiles: &[SolidTileScenePrimitive]) {
|
||||
self.solid_tile_vertex_array.vertex_buffer.upload(solid_tiles, BufferUploadMode::Dynamic);
|
||||
}
|
||||
|
||||
fn upload_batch(&mut self, batch: &Batch) {
|
||||
self.fill_vertex_array.vertex_buffer.upload(&batch.fills, BufferUploadMode::Dynamic);
|
||||
self.mask_tile_vertex_array.vertex_buffer.upload(&batch.mask_tiles,
|
||||
|
@ -268,13 +304,16 @@ impl Renderer {
|
|||
fn draw_batch_mask_tiles(&mut self, batch: &Batch) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl::Viewport(0, 0, MAIN_FRAMEBUFFER_WIDTH as GLint, MAIN_FRAMEBUFFER_HEIGHT as GLint);
|
||||
gl::Viewport(0,
|
||||
0,
|
||||
self.main_framebuffer_size.width as GLint,
|
||||
self.main_framebuffer_size.height as GLint);
|
||||
|
||||
gl::BindVertexArray(self.mask_tile_vertex_array.gl_vertex_array);
|
||||
gl::UseProgram(self.mask_tile_program.program.gl_program);
|
||||
gl::Uniform2f(self.mask_tile_program.framebuffer_size_uniform.location,
|
||||
MAIN_FRAMEBUFFER_WIDTH as GLfloat,
|
||||
MAIN_FRAMEBUFFER_HEIGHT as GLfloat);
|
||||
self.main_framebuffer_size.width as GLfloat,
|
||||
self.main_framebuffer_size.height as GLfloat);
|
||||
gl::Uniform2f(self.mask_tile_program.tile_size_uniform.location,
|
||||
TILE_WIDTH as GLfloat,
|
||||
TILE_HEIGHT as GLfloat);
|
||||
|
@ -283,6 +322,11 @@ impl Renderer {
|
|||
gl::Uniform2f(self.mask_tile_program.stencil_texture_size_uniform.location,
|
||||
MASK_FRAMEBUFFER_WIDTH as GLfloat,
|
||||
MASK_FRAMEBUFFER_HEIGHT as GLfloat);
|
||||
self.fill_colors_texture.bind(1);
|
||||
gl::Uniform1i(self.mask_tile_program.fill_colors_texture_uniform.location, 1);
|
||||
gl::Uniform2f(self.mask_tile_program.fill_colors_texture_size_uniform.location,
|
||||
FILL_COLORS_TEXTURE_WIDTH as GLfloat,
|
||||
FILL_COLORS_TEXTURE_HEIGHT as GLfloat);
|
||||
// FIXME(pcwalton): Fill this in properly!
|
||||
gl::Uniform2f(self.mask_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
||||
gl::BlendEquation(gl::FUNC_ADD);
|
||||
|
@ -292,6 +336,34 @@ impl Renderer {
|
|||
gl::Disable(gl::BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_solid_tiles(&mut self, solid_tiles: &[SolidTileScenePrimitive]) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl::Viewport(0,
|
||||
0,
|
||||
self.main_framebuffer_size.width as GLint,
|
||||
self.main_framebuffer_size.height as GLint);
|
||||
|
||||
gl::BindVertexArray(self.solid_tile_vertex_array.gl_vertex_array);
|
||||
gl::UseProgram(self.solid_tile_program.program.gl_program);
|
||||
gl::Uniform2f(self.solid_tile_program.framebuffer_size_uniform.location,
|
||||
self.main_framebuffer_size.width as GLfloat,
|
||||
self.main_framebuffer_size.height as GLfloat);
|
||||
gl::Uniform2f(self.solid_tile_program.tile_size_uniform.location,
|
||||
TILE_WIDTH as GLfloat,
|
||||
TILE_HEIGHT as GLfloat);
|
||||
self.fill_colors_texture.bind(0);
|
||||
gl::Uniform1i(self.solid_tile_program.fill_colors_texture_uniform.location, 0);
|
||||
gl::Uniform2f(self.solid_tile_program.fill_colors_texture_size_uniform.location,
|
||||
FILL_COLORS_TEXTURE_WIDTH as GLfloat,
|
||||
FILL_COLORS_TEXTURE_HEIGHT as GLfloat);
|
||||
// FIXME(pcwalton): Fill this in properly!
|
||||
gl::Uniform2f(self.solid_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
||||
gl::Disable(gl::BLEND);
|
||||
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, solid_tiles.len() as GLint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct FillVertexArray {
|
||||
|
@ -587,6 +659,7 @@ impl MaskTileProgram {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Uniform {
|
||||
location: GLint,
|
||||
}
|
||||
|
@ -727,6 +800,26 @@ impl Texture {
|
|||
texture
|
||||
}
|
||||
|
||||
fn new_rgba(size: &Size2D<u32>) -> Texture {
|
||||
let mut texture = Texture { gl_texture: 0 };
|
||||
unsafe {
|
||||
gl::GenTextures(1, &mut texture.gl_texture);
|
||||
texture.bind(0);
|
||||
gl::TexImage2D(gl::TEXTURE_2D,
|
||||
0,
|
||||
gl::RGBA as GLint,
|
||||
size.width as GLsizei,
|
||||
size.height as GLsizei,
|
||||
0,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
ptr::null());
|
||||
}
|
||||
|
||||
texture.set_parameters();
|
||||
texture
|
||||
}
|
||||
|
||||
fn from_png(name: &str) -> Texture {
|
||||
let path = format!("textures/{}.png", name);
|
||||
let image = image::open(&path).unwrap().to_luma();
|
||||
|
@ -757,6 +850,24 @@ impl Texture {
|
|||
}
|
||||
}
|
||||
|
||||
fn upload_rgba(&self, size: &Size2D<u32>, data: &[u8]) {
|
||||
assert!(data.len() >= size.width as usize * size.height as usize * 4);
|
||||
unsafe {
|
||||
self.bind(0);
|
||||
gl::TexImage2D(gl::TEXTURE_2D,
|
||||
0,
|
||||
gl::RGBA as GLint,
|
||||
size.width as GLsizei,
|
||||
size.height as GLsizei,
|
||||
0,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
data.as_ptr() as *const GLvoid);
|
||||
}
|
||||
|
||||
self.set_parameters();
|
||||
}
|
||||
|
||||
fn set_parameters(&self) {
|
||||
self.bind(0);
|
||||
unsafe {
|
||||
|
|
|
@ -161,9 +161,9 @@ impl Sub<Point2DF32> for LineSegmentF32 {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
#[repr(transparent)]
|
||||
pub struct LineSegmentU4(pub u16);
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
#[repr(transparent)]
|
||||
pub struct LineSegmentU8(pub u32);
|
||||
|
|
|
@ -60,7 +60,7 @@ pub struct TileObjectPrimitive {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
#[repr(packed)]
|
||||
pub struct FillBatchPrimitive {
|
||||
pub px: LineSegmentU4,
|
||||
pub subpx: LineSegmentU8,
|
||||
|
|
Loading…
Reference in New Issue