diff --git a/inox2d-opengl/src/gl_buffer.rs b/inox2d-opengl/src/gl_buffer.rs index a21d346..6b7ba8d 100644 --- a/inox2d-opengl/src/gl_buffer.rs +++ b/inox2d-opengl/src/gl_buffer.rs @@ -4,11 +4,12 @@ use inox2d::render::RenderCtx; use super::OpenglRendererError; -unsafe fn upload_array_to_gl(gl: &glow::Context, array: &[T], target: u32, usage: u32) { +unsafe fn upload_array_to_gl(gl: &glow::Context, array: &[T], target: u32, usage: u32) -> glow::Buffer { let bytes: &[u8] = core::slice::from_raw_parts(array.as_ptr() as *const u8, std::mem::size_of_val(array)); let buffer = gl.create_buffer().unwrap(); gl.bind_buffer(target, Some(buffer)); gl.buffer_data_u8_slice(target, bytes, usage); + buffer } unsafe fn reupload_array_to_gl(gl: &glow::Context, array: &[T], target: u32, start_idx: usize, end_idx: usize) { @@ -22,8 +23,8 @@ pub trait RenderCtxOpenglExt { &self, gl: &glow::Context, vao: glow::VertexArray, - ) -> Result; - unsafe fn upload_deforms_to_gl(&self, gl: &glow::Context); + ) -> Result; + unsafe fn upload_deforms_to_gl(&self, gl: &glow::Context, buffer: glow::Buffer); } impl RenderCtxOpenglExt for RenderCtx { @@ -40,7 +41,7 @@ impl RenderCtxOpenglExt for RenderCtx { &self, gl: &glow::Context, vao: glow::VertexArray, - ) -> Result { + ) -> Result { gl.bind_vertex_array(Some(vao)); upload_array_to_gl(gl, &self.vertex_buffers.verts, glow::ARRAY_BUFFER, glow::STATIC_DRAW); @@ -51,7 +52,8 @@ impl RenderCtxOpenglExt for RenderCtx { gl.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, 0, 0); gl.enable_vertex_attrib_array(1); - upload_array_to_gl(gl, &self.vertex_buffers.deforms, glow::ARRAY_BUFFER, glow::DYNAMIC_DRAW); + let deform_buffer = + upload_array_to_gl(gl, &self.vertex_buffers.deforms, glow::ARRAY_BUFFER, glow::DYNAMIC_DRAW); gl.vertex_attrib_pointer_f32(2, 2, glow::FLOAT, false, 0, 0); gl.enable_vertex_attrib_array(2); @@ -62,14 +64,16 @@ impl RenderCtxOpenglExt for RenderCtx { glow::STATIC_DRAW, ); - Ok(vao) + Ok(deform_buffer) } /// # Safety /// /// unsafe as initiating GL calls. can be safely called for multiple times, /// but only needed once after deform update and before rendering. - unsafe fn upload_deforms_to_gl(&self, gl: &glow::Context) { + unsafe fn upload_deforms_to_gl(&self, gl: &glow::Context, buffer: glow::Buffer) { + gl.bind_buffer(glow::ARRAY_BUFFER, Some(buffer)); + reupload_array_to_gl( gl, &self.vertex_buffers.deforms, diff --git a/inox2d-opengl/src/lib.rs b/inox2d-opengl/src/lib.rs index f6e5f4f..fe504c5 100644 --- a/inox2d-opengl/src/lib.rs +++ b/inox2d-opengl/src/lib.rs @@ -129,6 +129,7 @@ pub struct OpenglRenderer { part_mask_shader: PartMaskShader, composite_shader: CompositeShader, composite_mask_shader: CompositeMaskShader, + deform_buffer: Option, textures: Vec, } @@ -183,6 +184,7 @@ impl OpenglRenderer { composite_mask_shader, textures: Vec::new(), + deform_buffer: None, }; // Set emission strength once (it doesn't change anywhere else) @@ -360,7 +362,7 @@ impl InoxRenderer for OpenglRenderer { type Error = OpenglRendererError; fn prepare(&mut self, model: &Model) -> Result<(), Self::Error> { - unsafe { model.puppet.render_ctx.setup_gl_buffers(&self.gl, self.vao)? }; + self.deform_buffer = Some(unsafe { model.puppet.render_ctx.setup_gl_buffers(&self.gl, self.vao)? }); match self.upload_model_textures(&model.textures) { Ok(_) => Ok(()), @@ -420,7 +422,10 @@ impl InoxRenderer for OpenglRenderer { fn render(&self, puppet: &Puppet) { let gl = &self.gl; unsafe { - puppet.render_ctx.upload_deforms_to_gl(gl); + if let Some(deform_buffer) = self.deform_buffer { + puppet.render_ctx.upload_deforms_to_gl(gl, deform_buffer); + } + gl.enable(glow::BLEND); gl.disable(glow::DEPTH_TEST); } diff --git a/inox2d-opengl/src/texture.rs b/inox2d-opengl/src/texture.rs index 090b186..ba286cd 100644 --- a/inox2d-opengl/src/texture.rs +++ b/inox2d-opengl/src/texture.rs @@ -28,7 +28,11 @@ impl Texture { gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::LINEAR as i32); gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::CLAMP_TO_BORDER as i32); gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::CLAMP_TO_BORDER as i32); + + // Texture parameters for f32 slices are not supported on WASM yet. + #[cfg(not(target_arch = "wasm32"))] gl.tex_parameter_f32_slice(glow::TEXTURE_2D, glow::TEXTURE_BORDER_COLOR, &[0.0; 4]); + gl.tex_image_2d( glow::TEXTURE_2D, 0,