From 612c60419043f3ae855febe7bfb5b9f6fbeadcb3 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Sat, 6 Sep 2014 11:45:24 -0700 Subject: [PATCH 1/5] Simplify rectangular texture program Share most of the code between rectangular and texture programs by using a texture space transformation which modifies texture coordinates per-vertex. This also allows the elimination of the flipped texture coordinates, further simplifying things. This is a preliminary step to make it easier to implement masking to layer boundaries. --- src/rendergl.rs | 213 +++++++++++++++--------------------------------- 1 file changed, 66 insertions(+), 147 deletions(-) diff --git a/src/rendergl.rs b/src/rendergl.rs index 5ed3200..737e653 100755 --- a/src/rendergl.rs +++ b/src/rendergl.rs @@ -11,12 +11,12 @@ use color::Color; use layers::Layer; use layers; use scene::Scene; -use texturegl::{Flip, Linear, Nearest, NoFlip, VerticalFlip}; +use texturegl::{Linear, Nearest, VerticalFlip}; use texturegl::{Texture, TextureTarget2D, TextureTargetRectangle}; use tiling::Tile; use platform::surface::NativeCompositingGraphicsContext; -use geom::matrix::{Matrix4, ortho}; +use geom::matrix::{Matrix4, identity, ortho}; use geom::size::Size2D; use libc::c_int; use opengles::gl2::{ARRAY_BUFFER, BLEND, COLOR_BUFFER_BIT, COMPILE_STATUS, FRAGMENT_SHADER}; @@ -28,38 +28,22 @@ use opengles::gl2::{buffer_data, create_program, clear, clear_color, compile_sha use opengles::gl2::{create_shader, draw_arrays, enable, enable_vertex_attrib_array, disable_vertex_attrib_array}; use opengles::gl2::{gen_buffers, get_attrib_location, get_program_iv}; use opengles::gl2::{get_shader_info_log, get_shader_iv, get_uniform_location, line_width}; -use opengles::gl2::{link_program, shader_source, uniform_1i, uniform_2f, uniform_4f}; +use opengles::gl2::{link_program, shader_source, uniform_1i, uniform_4f}; use opengles::gl2::{uniform_matrix_4fv, use_program, vertex_attrib_pointer_f32, viewport}; +use std::fmt; use std::num::Zero; use std::rc::Rc; -static FRAGMENT_2D_SHADER_SOURCE: &'static str = " +static FRAGMENT_SHADER_SOURCE: &'static str = " #ifdef GL_ES precision mediump float; #endif varying vec2 vTextureCoord; - - uniform sampler2D uSampler; - - void main(void) { - gl_FragColor = texture2D(uSampler, vTextureCoord); - } -"; - -#[cfg(not(target_os="android"))] -static FRAGMENT_RECTANGLE_SHADER_SOURCE: &'static str = " - #ifdef GL_ES - precision mediump float; - #endif - - varying vec2 vTextureCoord; - - uniform sampler2DRect uSampler; - uniform vec2 uSize; + uniform samplerType uSampler; void main(void) { - gl_FragColor = texture2DRect(uSampler, vTextureCoord * uSize); + gl_FragColor = samplerFunction(uSampler, vTextureCoord); } "; @@ -80,12 +64,13 @@ static VERTEX_SHADER_SOURCE: &'static str = " uniform mat4 uMVMatrix; uniform mat4 uPMatrix; + uniform mat4 uTextureSpaceTransform; varying vec2 vTextureCoord; void main(void) { gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); - vTextureCoord = aTextureCoord; + vTextureCoord = (uTextureSpaceTransform * vec4(aTextureCoord, 0., 1.)).xy; } "; @@ -103,13 +88,6 @@ static TEXTURE_COORDINATES: [f32, ..8] = [ 1.0, 1.0, ]; -static FLIPPED_TEXTURE_COORDINATES: [f32, ..8] = [ - 0.0, 1.0, - 0.0, 0.0, - 1.0, 1.0, - 1.0, 0.0, -]; - static LINE_QUAD_VERTICES: [f32, ..15] = [ 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, @@ -139,39 +117,47 @@ pub fn load_shader(source_string: &str, shader_type: GLenum) -> GLuint { struct Buffers { textured_quad_vertex_buffer: GLuint, texture_coordinate_buffer: GLuint, - flipped_texture_coordinate_buffer: GLuint, line_quad_vertex_buffer: GLuint, } -struct Texture2DProgram { +struct TextureProgram { id: GLuint, vertex_position_attr: c_int, texture_coord_attr: c_int, modelview_uniform: c_int, projection_uniform: c_int, sampler_uniform: c_int, + texture_space_transform_uniform: c_int, } -impl Texture2DProgram { - fn new() -> Texture2DProgram { +impl TextureProgram { + fn new(sampler_function: &str, sampler_type: &str) -> TextureProgram { + let fragment_shader_source + = format_args!(fmt::format, + "#define samplerFunction {}\n#define samplerType {}\n{}", + sampler_function, + sampler_type, + FRAGMENT_SHADER_SOURCE); + let fragment_shader = load_shader(fragment_shader_source.as_slice(), FRAGMENT_SHADER); let vertex_shader = load_shader(VERTEX_SHADER_SOURCE, VERTEX_SHADER); - let fragment_shader = load_shader(FRAGMENT_2D_SHADER_SOURCE, FRAGMENT_SHADER); let program_id = init_program(vertex_shader, fragment_shader); - Texture2DProgram { + TextureProgram { id: program_id, vertex_position_attr: get_attrib_location(program_id, "aVertexPosition"), texture_coord_attr: get_attrib_location(program_id, "aTextureCoord"), modelview_uniform: get_uniform_location(program_id, "uMVMatrix"), projection_uniform: get_uniform_location(program_id, "uPMatrix"), sampler_uniform: get_uniform_location(program_id, "uSampler"), + texture_space_transform_uniform: + get_uniform_location(program_id, "uTextureSpaceTransform"), } } fn bind_uniforms_and_attributes(&self, - texture: &Texture, transform: &Matrix4, projection_matrix: &Matrix4, + texture_space_transform: &Matrix4, buffers: &Buffers) { uniform_1i(self.sampler_uniform, 0); uniform_matrix_4fv(self.modelview_uniform, false, transform.to_array()); @@ -180,8 +166,12 @@ impl Texture2DProgram { bind_buffer(ARRAY_BUFFER, buffers.textured_quad_vertex_buffer); vertex_attrib_pointer_f32(self.vertex_position_attr as GLuint, 3, false, 0, 0); - bind_texture_coordinate_buffer(buffers, texture.flip); + bind_buffer(ARRAY_BUFFER, buffers.texture_coordinate_buffer); vertex_attrib_pointer_f32(self.texture_coord_attr as GLuint, 2, false, 0, 0); + + uniform_matrix_4fv(self.texture_space_transform_uniform, + false, + texture_space_transform.to_array()); } fn enable_attribute_arrays(&self) { @@ -193,76 +183,22 @@ impl Texture2DProgram { disable_vertex_attrib_array(self.vertex_position_attr as GLuint); disable_vertex_attrib_array(self.texture_coord_attr as GLuint); } -} -struct TextureRectangleProgram { - id: GLuint, - vertex_position_attr: c_int, - texture_coord_attr: c_int, - modelview_uniform: c_int, - projection_uniform: c_int, - sampler_uniform: c_int, - size_uniform: c_int, -} - -impl TextureRectangleProgram { - #[cfg(not(target_os="android"))] - fn new() -> TextureRectangleProgram { - let vertex_shader = load_shader(VERTEX_SHADER_SOURCE, VERTEX_SHADER); - let fragment_shader = load_shader(FRAGMENT_RECTANGLE_SHADER_SOURCE, FRAGMENT_SHADER); - let program_id = init_program(vertex_shader, fragment_shader); - - TextureRectangleProgram { - id: program_id, - vertex_position_attr: get_attrib_location(program_id, "aVertexPosition"), - texture_coord_attr: get_attrib_location(program_id, "aTextureCoord"), - modelview_uniform: get_uniform_location(program_id, "uMVMatrix"), - projection_uniform: get_uniform_location(program_id, "uPMatrix"), - sampler_uniform: get_uniform_location(program_id, "uSampler"), - size_uniform: get_uniform_location(program_id, "uSize"), - } + fn create_2d_program() -> TextureProgram { + TextureProgram::new("texture2D", "sampler2D") } #[cfg(not(target_os="android"))] - fn create_if_necessary() -> Option { + fn create_rectangle_program_if_necessary() -> Option { use opengles::gl2::TEXTURE_RECTANGLE_ARB; enable(TEXTURE_RECTANGLE_ARB); - Some(TextureRectangleProgram::new()) + Some(TextureProgram::new("texture2DRect", "sampler2DRect")) } #[cfg(target_os="android")] - fn create_if_necessary() -> Option { + fn create_rectangle_program_if_necessary() -> Option { None } - - fn bind_uniforms_and_attributes(&self, - texture: &Texture, - transform: &Matrix4, - projection_matrix: &Matrix4, - buffers: &Buffers) { - uniform_1i(self.sampler_uniform, 0); - uniform_2f(self.size_uniform, - texture.size.width as GLfloat, - texture.size.height as GLfloat); - uniform_matrix_4fv(self.modelview_uniform, false, transform.to_array()); - uniform_matrix_4fv(self.projection_uniform, false, projection_matrix.to_array()); - - bind_buffer(ARRAY_BUFFER, buffers.textured_quad_vertex_buffer); - vertex_attrib_pointer_f32(self.vertex_position_attr as GLuint, 3, false, 0, 0); - - bind_texture_coordinate_buffer(buffers, texture.flip); - vertex_attrib_pointer_f32(self.texture_coord_attr as GLuint, 2, false, 0, 0); - } - - fn enable_attribute_arrays(&self) { - enable_vertex_attrib_array(self.vertex_position_attr as GLuint); - enable_vertex_attrib_array(self.texture_coord_attr as GLuint); - } - - fn disable_attribute_arrays(&self) { - disable_vertex_attrib_array(self.vertex_position_attr as GLuint); - disable_vertex_attrib_array(self.texture_coord_attr as GLuint); - } } struct SolidLineProgram { @@ -315,8 +251,8 @@ impl SolidLineProgram { } pub struct RenderContext { - texture_2d_program: Texture2DProgram, - texture_rectangle_program: Option, + texture_2d_program: TextureProgram, + texture_rectangle_program: Option, solid_line_program: SolidLineProgram, buffers: Buffers, @@ -334,9 +270,9 @@ impl RenderContext { enable(BLEND); blend_func(SRC_ALPHA, ONE_MINUS_SRC_ALPHA); - let texture_2d_program = Texture2DProgram::new(); + let texture_2d_program = TextureProgram::create_2d_program(); let solid_line_program = SolidLineProgram::new(); - let texture_rectangle_program = TextureRectangleProgram::create_if_necessary(); + let texture_rectangle_program = TextureProgram::create_rectangle_program_if_necessary(); RenderContext { texture_2d_program: texture_2d_program, @@ -361,14 +297,9 @@ impl RenderContext { bind_buffer(ARRAY_BUFFER, texture_coordinate_buffer); buffer_data(ARRAY_BUFFER, TEXTURE_COORDINATES, STATIC_DRAW); - let flipped_texture_coordinate_buffer = gen_buffers(1)[0]; - bind_buffer(ARRAY_BUFFER, flipped_texture_coordinate_buffer); - buffer_data(ARRAY_BUFFER, FLIPPED_TEXTURE_COORDINATES, STATIC_DRAW); - Buffers { textured_quad_vertex_buffer: textured_quad_vertex_buffer, texture_coordinate_buffer: texture_coordinate_buffer, - flipped_texture_coordinate_buffer: flipped_texture_coordinate_buffer, line_quad_vertex_buffer: line_quad_vertex_buffer, } } @@ -386,34 +317,24 @@ pub fn init_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint { program } -fn bind_texture_coordinate_buffer(buffers: &Buffers, flip: Flip) { - match flip { - NoFlip => bind_buffer(ARRAY_BUFFER, buffers.texture_coordinate_buffer), - VerticalFlip => { - bind_buffer(ARRAY_BUFFER, buffers.flipped_texture_coordinate_buffer) - } - } -} - pub fn bind_and_render_quad(render_context: RenderContext, texture: &Texture, transform: &Matrix4, scene_size: Size2D) { - let program_id = match texture.target { - TextureTarget2D => { - render_context.texture_2d_program.enable_attribute_arrays(); - render_context.texture_2d_program.id - } + let mut texture_coordinates_need_to_be_scaled_by_size = false; + let program = match texture.target { + TextureTarget2D => render_context.texture_2d_program, TextureTargetRectangle(..) => match render_context.texture_rectangle_program { Some(program) => { - program.enable_attribute_arrays(); - program.id + texture_coordinates_need_to_be_scaled_by_size = true; + program } None => fail!("There is no shader program for texture rectangle"), }, }; + program.enable_attribute_arrays(); - use_program(program_id); + use_program(program.id); active_texture(TEXTURE0); // FIXME: This should technically check that the transform @@ -432,35 +353,33 @@ pub fn bind_and_render_quad(render_context: RenderContext, // Set the projection matrix. let projection_matrix = ortho(0.0, scene_size.width, scene_size.height, 0.0, -10.0, 10.0); - // Set uniforms and vertex attribute pointers. - match texture.target { - TextureTarget2D => { - render_context.texture_2d_program. - bind_uniforms_and_attributes(texture, - transform, - &projection_matrix, - &render_context.buffers); - } - TextureTargetRectangle => { - render_context.texture_rectangle_program.unwrap(). - bind_uniforms_and_attributes(texture, - transform, - &projection_matrix, - &render_context.buffers); - } + // We calculate a transformation matrix for the texture coordinates + // which is useful for flipping the texture vertically or scaling the + // coordinates when dealing with GL_ARB_texture_rectangle. + let mut texture_transform: Matrix4 = identity(); + if texture.flip == VerticalFlip { + texture_transform = texture_transform.scale(1.0, -1.0, 1.0); + } + if texture_coordinates_need_to_be_scaled_by_size { + texture_transform = texture_transform.scale(texture.size.width as f32, + texture.size.height as f32, + 1.0); } + if texture.flip == VerticalFlip { + texture_transform = texture_transform.translate(0.0, -1.0, 0.0); + } + + program.bind_uniforms_and_attributes(transform, + &projection_matrix, + &texture_transform, + &render_context.buffers); + // Draw! draw_arrays(TRIANGLE_STRIP, 0, 4); bind_texture(TEXTURE_2D, 0); - match texture.target { - TextureTarget2D => render_context.texture_2d_program.disable_attribute_arrays(), - TextureTargetRectangle(..) => match render_context.texture_rectangle_program { - Some(program) => program.disable_attribute_arrays(), - None => {}, - }, - }; + program.disable_attribute_arrays() } pub fn bind_and_render_quad_lines(render_context: RenderContext, From 9f375c099681b78d85ea74afde280e20d829ae0b Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Sat, 6 Sep 2014 12:38:26 -0700 Subject: [PATCH 2/5] Abstract shader compiler into ShaderProgram struct This simplifies things slightly and better encapsulates the shared logic of shaders. --- src/rendergl.rs | 109 ++++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/src/rendergl.rs b/src/rendergl.rs index 737e653..a13949c 100755 --- a/src/rendergl.rs +++ b/src/rendergl.rs @@ -26,7 +26,7 @@ use opengles::gl2::{LINE_STRIP, TRIANGLE_STRIP, VERTEX_SHADER, GLenum, GLfloat, use opengles::gl2::{GLuint, active_texture, attach_shader, bind_buffer, bind_texture, blend_func}; use opengles::gl2::{buffer_data, create_program, clear, clear_color, compile_shader}; use opengles::gl2::{create_shader, draw_arrays, enable, enable_vertex_attrib_array, disable_vertex_attrib_array}; -use opengles::gl2::{gen_buffers, get_attrib_location, get_program_iv}; +use opengles::gl2::{gen_buffers, get_attrib_location, get_program_info_log, get_program_iv}; use opengles::gl2::{get_shader_info_log, get_shader_iv, get_uniform_location, line_width}; use opengles::gl2::{link_program, shader_source, uniform_1i, uniform_4f}; use opengles::gl2::{uniform_matrix_4fv, use_program, vertex_attrib_pointer_f32, viewport}; @@ -101,27 +101,53 @@ static TILE_DEBUG_BORDER_THICKNESS: uint = 1; static LAYER_DEBUG_BORDER_COLOR: Color = Color { r: 1., g: 0.5, b: 0., a: 1.0 }; static LAYER_DEBUG_BORDER_THICKNESS: uint = 2; -pub fn load_shader(source_string: &str, shader_type: GLenum) -> GLuint { - let shader_id = create_shader(shader_type); - shader_source(shader_id, [ source_string.as_bytes() ]); - compile_shader(shader_id); - - if get_shader_iv(shader_id, COMPILE_STATUS) == (0 as GLint) { - debug!("shader info log: {:s}", get_shader_info_log(shader_id)); - fail!("failed to compile shader"); - } - - return shader_id; -} - struct Buffers { textured_quad_vertex_buffer: GLuint, texture_coordinate_buffer: GLuint, line_quad_vertex_buffer: GLuint, } -struct TextureProgram { +struct ShaderProgram { id: GLuint, +} + +impl ShaderProgram { + pub fn new(vertex_shader_source: &str, fragment_shader_source: &str) -> ShaderProgram { + let id = create_program(); + attach_shader(id, ShaderProgram::compile_shader(fragment_shader_source, FRAGMENT_SHADER)); + attach_shader(id, ShaderProgram::compile_shader(vertex_shader_source, VERTEX_SHADER)); + link_program(id); + if get_program_iv(id, LINK_STATUS) == (0 as GLint) { + fail!("Failed to compile shader program: {:s}", get_program_info_log(id)); + } + + ShaderProgram { + id: id, + } + } + + pub fn compile_shader(source_string: &str, shader_type: GLenum) -> GLuint { + let id = create_shader(shader_type); + shader_source(id, [ source_string.as_bytes() ]); + compile_shader(id); + if get_shader_iv(id, COMPILE_STATUS) == (0 as GLint) { + fail!("Failed to compile shader: {:s}", get_shader_info_log(id)); + } + + return id; + } + + pub fn get_attribute_location(&self, name: &str) -> GLint { + get_attrib_location(self.id, name) + } + + pub fn get_uniform_location(&self, name: &str) -> GLint { + get_uniform_location(self.id, name) + } +} + +struct TextureProgram { + program: ShaderProgram, vertex_position_attr: c_int, texture_coord_attr: c_int, modelview_uniform: c_int, @@ -138,19 +164,15 @@ impl TextureProgram { sampler_function, sampler_type, FRAGMENT_SHADER_SOURCE); - let fragment_shader = load_shader(fragment_shader_source.as_slice(), FRAGMENT_SHADER); - let vertex_shader = load_shader(VERTEX_SHADER_SOURCE, VERTEX_SHADER); - let program_id = init_program(vertex_shader, fragment_shader); - + let program = ShaderProgram::new(VERTEX_SHADER_SOURCE, fragment_shader_source.as_slice()); TextureProgram { - id: program_id, - vertex_position_attr: get_attrib_location(program_id, "aVertexPosition"), - texture_coord_attr: get_attrib_location(program_id, "aTextureCoord"), - modelview_uniform: get_uniform_location(program_id, "uMVMatrix"), - projection_uniform: get_uniform_location(program_id, "uPMatrix"), - sampler_uniform: get_uniform_location(program_id, "uSampler"), - texture_space_transform_uniform: - get_uniform_location(program_id, "uTextureSpaceTransform"), + program: program, + vertex_position_attr: program.get_attribute_location("aVertexPosition"), + texture_coord_attr: program.get_attribute_location("aTextureCoord"), + modelview_uniform: program.get_uniform_location("uMVMatrix"), + projection_uniform: program.get_uniform_location("uPMatrix"), + sampler_uniform: program.get_uniform_location("uSampler"), + texture_space_transform_uniform: program.get_uniform_location("uTextureSpaceTransform"), } } @@ -202,7 +224,7 @@ impl TextureProgram { } struct SolidLineProgram { - id: GLuint, + program: ShaderProgram, vertex_position_attr: c_int, modelview_uniform: c_int, projection_uniform: c_int, @@ -211,16 +233,13 @@ struct SolidLineProgram { impl SolidLineProgram { fn new() -> SolidLineProgram { - let vertex_shader = load_shader(VERTEX_SHADER_SOURCE, VERTEX_SHADER); - let fragment_shader = load_shader(SOLID_COLOR_FRAGMENT_SHADER_SOURCE, FRAGMENT_SHADER); - let program_id = init_program(vertex_shader, fragment_shader); - + let program = ShaderProgram::new(VERTEX_SHADER_SOURCE, SOLID_COLOR_FRAGMENT_SHADER_SOURCE); SolidLineProgram { - id: program_id, - vertex_position_attr: get_attrib_location(program_id, "aVertexPosition"), - modelview_uniform: get_uniform_location(program_id, "uMVMatrix"), - projection_uniform: get_uniform_location(program_id, "uPMatrix"), - color_uniform: get_uniform_location(program_id, "uColor"), + program: program, + vertex_position_attr: program.get_attribute_location("aVertexPosition"), + modelview_uniform: program.get_uniform_location("uMVMatrix"), + projection_uniform: program.get_uniform_location("uPMatrix"), + color_uniform: program.get_uniform_location("uColor"), } } @@ -305,18 +324,6 @@ impl RenderContext { } } -pub fn init_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint { - let program = create_program(); - attach_shader(program, vertex_shader); - attach_shader(program, fragment_shader); - link_program(program); - if get_program_iv(program, LINK_STATUS) == (0 as GLint) { - fail!("failed to initialize program"); - } - - program -} - pub fn bind_and_render_quad(render_context: RenderContext, texture: &Texture, transform: &Matrix4, @@ -334,7 +341,7 @@ pub fn bind_and_render_quad(render_context: RenderContext, }; program.enable_attribute_arrays(); - use_program(program.id); + use_program(program.program.id); active_texture(TEXTURE0); // FIXME: This should technically check that the transform @@ -389,7 +396,7 @@ pub fn bind_and_render_quad_lines(render_context: RenderContext, line_thickness: uint) { let solid_line_program = render_context.solid_line_program; solid_line_program.enable_attribute_arrays(); - use_program(solid_line_program.id); + use_program(solid_line_program.program.id); let projection_matrix = ortho(0.0, scene_size.width, scene_size.height, 0.0, -10.0, 10.0); solid_line_program.bind_uniforms_and_attributes(transform, &projection_matrix, From 7543bb19b3374d5e87182e49d42ab4a416b760c8 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Sat, 6 Sep 2014 13:00:50 -0700 Subject: [PATCH 3/5] Set the SolidLineProgram texture space transform Things seem to function properly without this, but this is more correct. --- src/rendergl.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/rendergl.rs b/src/rendergl.rs index a13949c..2cc846f 100755 --- a/src/rendergl.rs +++ b/src/rendergl.rs @@ -229,6 +229,7 @@ struct SolidLineProgram { modelview_uniform: c_int, projection_uniform: c_int, color_uniform: c_int, + texture_space_transform_uniform: c_int, } impl SolidLineProgram { @@ -240,6 +241,7 @@ impl SolidLineProgram { modelview_uniform: program.get_uniform_location("uMVMatrix"), projection_uniform: program.get_uniform_location("uPMatrix"), color_uniform: program.get_uniform_location("uColor"), + texture_space_transform_uniform: program.get_uniform_location("uTextureSpaceTransform"), } } @@ -258,6 +260,11 @@ impl SolidLineProgram { bind_buffer(ARRAY_BUFFER, buffers.line_quad_vertex_buffer); vertex_attrib_pointer_f32(self.vertex_position_attr as GLuint, 3, false, 0, 0); + + let texture_transform: Matrix4 = identity(); + uniform_matrix_4fv(self.texture_space_transform_uniform, + false, + texture_transform.to_array()); } fn enable_attribute_arrays(&self) { From 19ff34e39eaa69655d3b7696aa304dfece0e2d61 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Tue, 9 Sep 2014 14:54:53 -0700 Subject: [PATCH 4/5] Eliminate z-coordinate in vertex position attributes The z-coordinate is always 0, so we can just make it a constant in the shader. This should result in less data streaming to the GPU when the vertex coordinates change with clipping support. --- src/rendergl.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/rendergl.rs b/src/rendergl.rs index 2cc846f..2f33a78 100755 --- a/src/rendergl.rs +++ b/src/rendergl.rs @@ -59,7 +59,7 @@ static SOLID_COLOR_FRAGMENT_SHADER_SOURCE: &'static str = " "; static VERTEX_SHADER_SOURCE: &'static str = " - attribute vec3 aVertexPosition; + attribute vec2 aVertexPosition; attribute vec2 aTextureCoord; uniform mat4 uMVMatrix; @@ -69,16 +69,16 @@ static VERTEX_SHADER_SOURCE: &'static str = " varying vec2 vTextureCoord; void main(void) { - gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 0.0, 1.0); vTextureCoord = (uTextureSpaceTransform * vec4(aTextureCoord, 0., 1.)).xy; } "; -static TEXTURED_QUAD_VERTICES: [f32, ..12] = [ - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 1.0, 0.0, 0.0, - 1.0, 1.0, 0.0, +static TEXTURED_QUAD_VERTICES: [f32, ..8] = [ + 0.0, 0.0, + 0.0, 1.0, + 1.0, 0.0, + 1.0, 1.0, ]; static TEXTURE_COORDINATES: [f32, ..8] = [ @@ -88,12 +88,12 @@ static TEXTURE_COORDINATES: [f32, ..8] = [ 1.0, 1.0, ]; -static LINE_QUAD_VERTICES: [f32, ..15] = [ - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 1.0, 1.0, 0.0, - 1.0, 0.0, 0.0, - 0.0, 0.0, 0.0, +static LINE_QUAD_VERTICES: [f32, ..10] = [ + 0.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + 1.0, 0.0, + 0.0, 0.0, ]; static TILE_DEBUG_BORDER_COLOR: Color = Color { r: 0., g: 1., b: 1., a: 1.0 }; @@ -186,7 +186,7 @@ impl TextureProgram { uniform_matrix_4fv(self.projection_uniform, false, projection_matrix.to_array()); bind_buffer(ARRAY_BUFFER, buffers.textured_quad_vertex_buffer); - vertex_attrib_pointer_f32(self.vertex_position_attr as GLuint, 3, false, 0, 0); + vertex_attrib_pointer_f32(self.vertex_position_attr as GLuint, 2, false, 0, 0); bind_buffer(ARRAY_BUFFER, buffers.texture_coordinate_buffer); vertex_attrib_pointer_f32(self.texture_coord_attr as GLuint, 2, false, 0, 0); @@ -259,7 +259,7 @@ impl SolidLineProgram { color.a as GLfloat); bind_buffer(ARRAY_BUFFER, buffers.line_quad_vertex_buffer); - vertex_attrib_pointer_f32(self.vertex_position_attr as GLuint, 3, false, 0, 0); + vertex_attrib_pointer_f32(self.vertex_position_attr as GLuint, 2, false, 0, 0); let texture_transform: Matrix4 = identity(); uniform_matrix_4fv(self.texture_space_transform_uniform, From d14f4de3157aaa04da2174466e999e05f1f6e9e1 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 10 Sep 2014 08:06:00 -0700 Subject: [PATCH 5/5] Do not pass texture coordinates to shader This can always be inferred from the unit rectangle coordinates, so we simply omit them from the list of attributes passed to the shader. --- src/rendergl.rs | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/rendergl.rs b/src/rendergl.rs index 2f33a78..7ec053d 100755 --- a/src/rendergl.rs +++ b/src/rendergl.rs @@ -60,7 +60,6 @@ static SOLID_COLOR_FRAGMENT_SHADER_SOURCE: &'static str = " static VERTEX_SHADER_SOURCE: &'static str = " attribute vec2 aVertexPosition; - attribute vec2 aTextureCoord; uniform mat4 uMVMatrix; uniform mat4 uPMatrix; @@ -70,7 +69,7 @@ static VERTEX_SHADER_SOURCE: &'static str = " void main(void) { gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 0.0, 1.0); - vTextureCoord = (uTextureSpaceTransform * vec4(aTextureCoord, 0., 1.)).xy; + vTextureCoord = (uTextureSpaceTransform * vec4(aVertexPosition, 0., 1.)).xy; } "; @@ -81,13 +80,6 @@ static TEXTURED_QUAD_VERTICES: [f32, ..8] = [ 1.0, 1.0, ]; -static TEXTURE_COORDINATES: [f32, ..8] = [ - 0.0, 0.0, - 0.0, 1.0, - 1.0, 0.0, - 1.0, 1.0, -]; - static LINE_QUAD_VERTICES: [f32, ..10] = [ 0.0, 0.0, 0.0, 1.0, @@ -103,7 +95,6 @@ static LAYER_DEBUG_BORDER_THICKNESS: uint = 2; struct Buffers { textured_quad_vertex_buffer: GLuint, - texture_coordinate_buffer: GLuint, line_quad_vertex_buffer: GLuint, } @@ -149,7 +140,6 @@ impl ShaderProgram { struct TextureProgram { program: ShaderProgram, vertex_position_attr: c_int, - texture_coord_attr: c_int, modelview_uniform: c_int, projection_uniform: c_int, sampler_uniform: c_int, @@ -168,7 +158,6 @@ impl TextureProgram { TextureProgram { program: program, vertex_position_attr: program.get_attribute_location("aVertexPosition"), - texture_coord_attr: program.get_attribute_location("aTextureCoord"), modelview_uniform: program.get_uniform_location("uMVMatrix"), projection_uniform: program.get_uniform_location("uPMatrix"), sampler_uniform: program.get_uniform_location("uSampler"), @@ -188,9 +177,6 @@ impl TextureProgram { bind_buffer(ARRAY_BUFFER, buffers.textured_quad_vertex_buffer); vertex_attrib_pointer_f32(self.vertex_position_attr as GLuint, 2, false, 0, 0); - bind_buffer(ARRAY_BUFFER, buffers.texture_coordinate_buffer); - vertex_attrib_pointer_f32(self.texture_coord_attr as GLuint, 2, false, 0, 0); - uniform_matrix_4fv(self.texture_space_transform_uniform, false, texture_space_transform.to_array()); @@ -198,12 +184,10 @@ impl TextureProgram { fn enable_attribute_arrays(&self) { enable_vertex_attrib_array(self.vertex_position_attr as GLuint); - enable_vertex_attrib_array(self.texture_coord_attr as GLuint); } fn disable_attribute_arrays(&self) { disable_vertex_attrib_array(self.vertex_position_attr as GLuint); - disable_vertex_attrib_array(self.texture_coord_attr as GLuint); } fn create_2d_program() -> TextureProgram { @@ -319,13 +303,8 @@ impl RenderContext { bind_buffer(ARRAY_BUFFER, line_quad_vertex_buffer); buffer_data(ARRAY_BUFFER, LINE_QUAD_VERTICES, STATIC_DRAW); - let texture_coordinate_buffer = gen_buffers(1)[0]; - bind_buffer(ARRAY_BUFFER, texture_coordinate_buffer); - buffer_data(ARRAY_BUFFER, TEXTURE_COORDINATES, STATIC_DRAW); - Buffers { textured_quad_vertex_buffer: textured_quad_vertex_buffer, - texture_coordinate_buffer: texture_coordinate_buffer, line_quad_vertex_buffer: line_quad_vertex_buffer, } }