From 99aa994b5f7b9d3db0e97968fd68ec5fe76af999 Mon Sep 17 00:00:00 2001 From: Samson <16504129+sagudev@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:09:12 +0100 Subject: [PATCH] Add more gl functions (#317) * Add hint(target, mode) Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add sample_coverage Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add is_transform_feedback Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_frag_data_location Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add validate_program Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add vertex_attrib_4_{i32, u32} Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_sync_parameter_i32 Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_program_validate_status Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_program_parameter_i32 Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_sampler_parameter_{i32, f32} Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add invalidate_sub_framebuffer Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_tex_parameter_f32 Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_internal_format_i32_slice Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_vertex_attrib_parameter_f32_slice Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_uniform_u32 Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Fix two clippy warnings Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_uniform_indices Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_renderbuffer_parameter_i32 Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Add get_active_uniforms_parameter Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- src/lib.rs | 75 +++++++++++++ src/native.rs | 205 +++++++++++++++++++++++++++++++++-- src/web_sys.rs | 286 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 556 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 50f1c37..b3760ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -177,10 +177,16 @@ pub trait HasContext: __private::Sealed { unsafe fn link_program(&self, program: Self::Program); + unsafe fn validate_program(&self, program: Self::Program); + unsafe fn get_program_completion_status(&self, program: Self::Program) -> bool; + unsafe fn get_program_validate_status(&self, program: Self::Program) -> bool; + unsafe fn get_program_link_status(&self, program: Self::Program) -> bool; + unsafe fn get_program_parameter_i32(&self, program: Self::Program, parameter: u32) -> i32; + unsafe fn get_program_info_log(&self, program: Self::Program) -> String; unsafe fn get_program_resource_i32( @@ -457,6 +463,14 @@ pub trait HasContext: __private::Sealed { unsafe fn get_active_uniforms(&self, program: Self::Program) -> u32; + #[doc(alias = "GetActiveUniformsiv")] + unsafe fn get_active_uniforms_parameter( + &self, + program: Self::Program, + uniforms: &[u32], + pname: u32, + ) -> Vec; + unsafe fn get_active_uniform( &self, program: Self::Program, @@ -554,6 +568,8 @@ pub trait HasContext: __private::Sealed { unsafe fn pixel_store_bool(&self, parameter: u32, value: bool); + unsafe fn get_frag_data_location(&self, program: Self::Program, name: &str) -> i32; + unsafe fn bind_frag_data_location(&self, program: Self::Program, color_number: u32, name: &str); unsafe fn buffer_data_size(&self, target: u32, size: i32, usage: u32); @@ -633,6 +649,9 @@ pub trait HasContext: __private::Sealed { ); unsafe fn client_wait_sync(&self, fence: Self::Fence, flags: u32, timeout: i32) -> u32; + + unsafe fn get_sync_parameter_i32(&self, fence: Self::Fence, parameter: u32) -> i32; + unsafe fn wait_sync(&self, fence: Self::Fence, flags: u32, timeout: u64); unsafe fn copy_buffer_sub_data( @@ -885,6 +904,8 @@ pub trait HasContext: __private::Sealed { unsafe fn get_tex_parameter_i32(&self, target: u32, parameter: u32) -> i32; + unsafe fn get_tex_parameter_f32(&self, target: u32, parameter: u32) -> f32; + unsafe fn get_buffer_parameter_i32(&self, target: u32, parameter: u32) -> i32; #[doc(alias = "glGetBooleanv")] @@ -942,6 +963,8 @@ pub trait HasContext: __private::Sealed { unsafe fn get_parameter_vertex_array(&self, parameter: u32) -> Option; + unsafe fn get_renderbuffer_parameter_i32(&self, target: u32, parameter: u32) -> i32; + unsafe fn get_framebuffer_parameter_i32(&self, target: u32, parameter: u32) -> i32; unsafe fn get_named_framebuffer_parameter_i32( @@ -1030,6 +1053,10 @@ pub trait HasContext: __private::Sealed { unsafe fn sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32, value: i32); + unsafe fn get_sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32) -> i32; + + unsafe fn get_sampler_parameter_f32(&self, sampler: Self::Sampler, name: u32) -> f32; + unsafe fn generate_mipmap(&self, target: u32); unsafe fn generate_texture_mipmap(&self, texture: Self::Texture); @@ -1176,6 +1203,13 @@ pub trait HasContext: __private::Sealed { v: &mut [i32], ); + unsafe fn get_uniform_u32( + &self, + program: Self::Program, + location: &Self::UniformLocation, + v: &mut [u32], + ); + unsafe fn get_uniform_f32( &self, program: Self::Program, @@ -1368,6 +1402,16 @@ pub trait HasContext: __private::Sealed { unsafe fn invalidate_framebuffer(&self, target: u32, attachments: &[u32]); + unsafe fn invalidate_sub_framebuffer( + &self, + target: u32, + attachments: &[u32], + x: i32, + y: i32, + width: i32, + height: i32, + ); + unsafe fn polygon_offset(&self, factor: f32, units: f32); unsafe fn polygon_mode(&self, face: u32, mode: u32); @@ -1542,6 +1586,13 @@ pub trait HasContext: __private::Sealed { unsafe fn vertex_attrib_divisor(&self, index: u32, divisor: u32); + unsafe fn get_vertex_attrib_parameter_f32_slice( + &self, + index: u32, + pname: u32, + result: &mut [f32], + ); + unsafe fn vertex_attrib_pointer_f32( &self, index: u32, @@ -1603,6 +1654,10 @@ pub trait HasContext: __private::Sealed { unsafe fn vertex_attrib_4_f32(&self, index: u32, x: f32, y: f32, z: f32, w: f32); + unsafe fn vertex_attrib_4_i32(&self, index: u32, x: i32, y: i32, z: i32, w: i32); + + unsafe fn vertex_attrib_4_u32(&self, index: u32, x: u32, y: u32, z: u32, w: u32); + unsafe fn vertex_attrib_1_f32_slice(&self, index: u32, v: &[f32]); unsafe fn vertex_attrib_2_f32_slice(&self, index: u32, v: &[f32]); @@ -1710,6 +1765,12 @@ pub trait HasContext: __private::Sealed { unsafe fn get_uniform_block_index(&self, program: Self::Program, name: &str) -> Option; + unsafe fn get_uniform_indices( + &self, + program: Self::Program, + names: &[&str], + ) -> Vec>; + unsafe fn uniform_block_binding(&self, program: Self::Program, index: u32, binding: u32); unsafe fn get_shader_storage_block_index( @@ -1756,6 +1817,8 @@ pub trait HasContext: __private::Sealed { unsafe fn delete_transform_feedback(&self, transform_feedback: Self::TransformFeedback); + unsafe fn is_transform_feedback(&self, transform_feedback: Self::TransformFeedback) -> bool; + unsafe fn create_transform_feedback(&self) -> Result; unsafe fn bind_transform_feedback( @@ -1801,6 +1864,18 @@ pub trait HasContext: __private::Sealed { ); unsafe fn max_shader_compiler_threads(&self, count: u32); + + unsafe fn hint(&self, target: u32, mode: u32); + + unsafe fn sample_coverage(&self, value: f32, invert: bool); + + unsafe fn get_internal_format_i32_slice( + &self, + target: u32, + internal_format: u32, + pname: u32, + result: &mut [i32], + ); } pub const ACTIVE_ATOMIC_COUNTER_BUFFERS: u32 = 0x92D9; diff --git a/src/native.rs b/src/native.rs index 2505d5b..967e311 100644 --- a/src/native.rs +++ b/src/native.rs @@ -419,6 +419,11 @@ impl HasContext for Context { gl.LinkProgram(program.0.get()); } + unsafe fn validate_program(&self, program: Self::Program) { + let gl = &self.raw; + gl.ValidateProgram(program.0.get()); + } + unsafe fn get_program_completion_status(&self, program: Self::Program) -> bool { let gl = &self.raw; let mut status = 0; @@ -433,6 +438,20 @@ impl HasContext for Context { 1 == status } + unsafe fn get_program_validate_status(&self, program: Self::Program) -> bool { + let gl = &self.raw; + let mut status = 0; + gl.GetProgramiv(program.0.get(), VALIDATE_STATUS, &mut status); + status == 1 + } + + unsafe fn get_program_parameter_i32(&self, program: Self::Program, parameter: u32) -> i32 { + let gl = &self.raw; + let mut value = 0; + gl.GetProgramiv(program.0.get(), parameter, &mut value); + value + } + unsafe fn get_program_info_log(&self, program: Self::Program) -> String { let gl = &self.raw; let mut length = 0; @@ -1062,6 +1081,24 @@ impl HasContext for Context { count as u32 } + unsafe fn get_active_uniforms_parameter( + &self, + program: Self::Program, + uniforms: &[u32], + pname: u32, + ) -> Vec { + let gl = &self.raw; + let mut results = vec![0; uniforms.len()]; + gl.GetActiveUniformsiv( + program.0.get(), + uniforms.len() as _, + uniforms.as_ptr(), + pname, + results.as_mut_ptr(), + ); + results + } + unsafe fn get_active_uniform( &self, program: Self::Program, @@ -1307,6 +1344,12 @@ impl HasContext for Context { gl.PixelStorei(parameter, value as i32); } + unsafe fn get_frag_data_location(&self, program: Self::Program, name: &str) -> i32 { + let gl = &self.raw; + let name = CString::new(name).unwrap(); + gl.GetFragDataLocation(program.0.get(), name.as_ptr() as *const native_gl::GLchar) + } + unsafe fn bind_frag_data_location( &self, program: Self::Program, @@ -1509,6 +1552,13 @@ impl HasContext for Context { gl.ClientWaitSync(fence.0, flags, timeout as u64) } + unsafe fn get_sync_parameter_i32(&self, fence: Self::Fence, parameter: u32) -> i32 { + let gl = &self.raw; + let mut v = 0; + gl.GetSynciv(fence.0, parameter, 1, ptr::null_mut(), &mut v); + v + } + unsafe fn wait_sync(&self, fence: Self::Fence, flags: u32, timeout: u64) { let gl = &self.raw; gl.WaitSync(fence.0, flags, timeout) @@ -2021,6 +2071,13 @@ impl HasContext for Context { value } + unsafe fn get_tex_parameter_f32(&self, target: u32, parameter: u32) -> f32 { + let gl = &self.raw; + let mut value = 0.; + gl.GetTexParameterfv(target, parameter, &mut value); + value + } + unsafe fn get_buffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 { let gl = &self.raw; let mut value = 0; @@ -2153,6 +2210,13 @@ impl HasContext for Context { self.get_parameter_gl_name(parameter).map(NativeVertexArray) } + unsafe fn get_renderbuffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 { + let gl = &self.raw; + let mut value = 0; + gl.GetRenderbufferParameteriv(target, parameter, &mut value); + value + } + unsafe fn get_framebuffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 { let gl = &self.raw; let mut value = 0; @@ -2338,6 +2402,20 @@ impl HasContext for Context { gl.SamplerParameteri(sampler.0.get(), name, value); } + unsafe fn get_sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32) -> i32 { + let gl = &self.raw; + let mut value = 0; + gl.GetSamplerParameteriv(sampler.0.get(), name, &mut value); + value + } + + unsafe fn get_sampler_parameter_f32(&self, sampler: Self::Sampler, name: u32) -> f32 { + let gl = &self.raw; + let mut value = 0.; + gl.GetSamplerParameterfv(sampler.0.get(), name, &mut value); + value + } + unsafe fn generate_mipmap(&self, target: u32) { let gl = &self.raw; gl.GenerateMipmap(target); @@ -2607,11 +2685,17 @@ impl HasContext for Context { v: &mut [i32], ) { let gl = &self.raw; - gl.GetUniformiv( - program.0.get() as u32, - location.0 as i32, - v.as_mut_ptr() as *mut i32, - ) + gl.GetUniformiv(program.0.get(), location.0 as i32, v.as_mut_ptr()) + } + + unsafe fn get_uniform_u32( + &self, + program: Self::Program, + location: &Self::UniformLocation, + v: &mut [u32], + ) { + let gl = &self.raw; + gl.GetUniformuiv(program.0.get(), location.0 as i32, v.as_mut_ptr()) } unsafe fn get_uniform_f32( @@ -2621,11 +2705,7 @@ impl HasContext for Context { v: &mut [f32], ) { let gl = &self.raw; - gl.GetUniformfv( - program.0.get() as u32, - location.0 as i32, - v.as_mut_ptr() as *mut f32, - ) + gl.GetUniformfv(program.0.get(), location.0 as i32, v.as_mut_ptr()) } unsafe fn uniform_1_i32(&self, location: Option<&Self::UniformLocation>, x: i32) { @@ -3056,6 +3136,27 @@ impl HasContext for Context { gl.InvalidateFramebuffer(target, attachments.len() as i32, attachments.as_ptr()); } + unsafe fn invalidate_sub_framebuffer( + &self, + target: u32, + attachments: &[u32], + x: i32, + y: i32, + width: i32, + height: i32, + ) { + let gl = &self.raw; + gl.InvalidateSubFramebuffer( + target, + attachments.len() as i32, + attachments.as_ptr(), + x, + y, + width, + height, + ); + } + unsafe fn polygon_offset(&self, factor: f32, units: f32) { let gl = &self.raw; gl.PolygonOffset(factor, units); @@ -3426,6 +3527,16 @@ impl HasContext for Context { gl.VertexAttribDivisor(index, divisor); } + unsafe fn get_vertex_attrib_parameter_f32_slice( + &self, + index: u32, + pname: u32, + result: &mut [f32], + ) { + let gl = &self.raw; + gl.GetVertexAttribfv(index, pname, result.as_mut_ptr()); + } + unsafe fn vertex_attrib_pointer_f32( &self, index: u32, @@ -3536,6 +3647,16 @@ impl HasContext for Context { gl.VertexAttrib4f(index, x, y, z, w); } + unsafe fn vertex_attrib_4_i32(&self, index: u32, x: i32, y: i32, z: i32, w: i32) { + let gl = &self.raw; + gl.VertexAttribI4i(index, x, y, z, w); + } + + unsafe fn vertex_attrib_4_u32(&self, index: u32, x: u32, y: u32, z: u32, w: u32) { + let gl = &self.raw; + gl.VertexAttribI4ui(index, x, y, z, w); + } + unsafe fn vertex_attrib_1_f32_slice(&self, index: u32, v: &[f32]) { let gl = &self.raw; gl.VertexAttrib1fv(index, v.as_ptr()); @@ -3905,6 +4026,38 @@ impl HasContext for Context { } } + unsafe fn get_uniform_indices( + &self, + program: Self::Program, + names: &[&str], + ) -> Vec> { + let gl = &self.raw; + let c_names = names + .iter() + .map(|&name| CString::new(name).unwrap()) + .collect::>(); + let c_name_ptrs = c_names.iter().map(|name| name.as_ptr()).collect::>(); + + let count = names.len(); + let mut indices = vec![0; count]; + gl.GetUniformIndices( + program.0.get(), + count as _, + c_name_ptrs.as_ptr(), + indices.as_mut_ptr(), + ); + indices + .iter() + .map(|&index| { + if index == INVALID_INDEX { + None + } else { + Some(index) + } + }) + .collect() + } + unsafe fn uniform_block_binding(&self, program: Self::Program, index: u32, binding: u32) { let gl = &self.raw; gl.UniformBlockBinding(program.0.get(), index, binding); @@ -4016,6 +4169,11 @@ impl HasContext for Context { .ok_or_else(|| String::from("Unable to create TransformFeedback object")) } + unsafe fn is_transform_feedback(&self, transform_feedback: Self::TransformFeedback) -> bool { + let gl = &self.raw; + gl.IsTransformFeedback(transform_feedback.0.get()) != 0 + } + unsafe fn delete_transform_feedback(&self, transform_feedback: Self::TransformFeedback) { let gl = &self.raw; gl.DeleteTransformFeedbacks(1, &transform_feedback.0.get()); @@ -4232,6 +4390,33 @@ impl HasContext for Context { gl.MaxShaderCompilerThreadsARB(count); } } + + unsafe fn hint(&self, target: u32, mode: u32) { + let gl = &self.raw; + gl.Hint(target, mode); + } + + unsafe fn sample_coverage(&self, value: f32, invert: bool) { + let gl = &self.raw; + gl.SampleCoverage(value, invert as u8); + } + + unsafe fn get_internal_format_i32_slice( + &self, + target: u32, + internal_format: u32, + pname: u32, + result: &mut [i32], + ) { + let gl = &self.raw; + gl.GetInternalformativ( + target, + internal_format, + pname, + result.len() as _, + result.as_mut_ptr(), + ) + } } impl Drop for Context { diff --git a/src/web_sys.rs b/src/web_sys.rs index 1922995..42c9cdf 100644 --- a/src/web_sys.rs +++ b/src/web_sys.rs @@ -1904,6 +1904,15 @@ impl HasContext for Context { } } + unsafe fn validate_program(&self, program: Self::Program) { + let programs = self.programs.borrow(); + let raw_program = programs.get_unchecked(program); + match self.raw { + RawRenderingContext::WebGl1(ref gl) => gl.validate_program(raw_program), + RawRenderingContext::WebGl2(ref gl) => gl.validate_program(raw_program), + } + } + unsafe fn get_program_completion_status(&self, program: Self::Program) -> bool { let programs = self.programs.borrow(); let raw_program = programs.get_unchecked(program); @@ -1937,6 +1946,35 @@ impl HasContext for Context { .unwrap_or(false) } + unsafe fn get_program_validate_status(&self, program: Self::Program) -> bool { + let programs = self.programs.borrow(); + let raw_program = programs.get_unchecked(program); + match self.raw { + RawRenderingContext::WebGl1(ref gl) => { + gl.get_program_parameter(raw_program, VALIDATE_STATUS) + } + RawRenderingContext::WebGl2(ref gl) => { + gl.get_program_parameter(raw_program, VALIDATE_STATUS) + } + } + .as_bool() + .unwrap_or(false) + } + + unsafe fn get_program_parameter_i32(&self, program: Self::Program, parameter: u32) -> i32 { + let programs = self.programs.borrow(); + let raw_program = programs.get_unchecked(program); + match self.raw { + RawRenderingContext::WebGl1(ref gl) => gl.get_program_parameter(raw_program, parameter), + RawRenderingContext::WebGl2(ref gl) => gl.get_program_parameter(raw_program, parameter), + } + .as_f64() + .map(|v| v as i32) + // Errors will be caught by the browser or through `get_error` + // so return a default instead + .unwrap_or(0) + } + unsafe fn get_program_info_log(&self, program: Self::Program) -> String { let programs = self.programs.borrow(); let raw_program = programs.get_unchecked(program); @@ -2309,6 +2347,15 @@ impl HasContext for Context { .unwrap_or(0) } + unsafe fn get_active_uniforms_parameter( + &self, + _program: Self::Program, + _uniforms: &[u32], + _pname: u32, + ) -> Vec { + panic!("GetActiveUniformsiv is not supported") + } + unsafe fn get_active_uniform( &self, program: Self::Program, @@ -2597,6 +2644,17 @@ impl HasContext for Context { } } + unsafe fn get_frag_data_location(&self, program: Self::Program, name: &str) -> i32 { + let programs = self.programs.borrow(); + let raw_program = programs.get_unchecked(program); + match self.raw { + RawRenderingContext::WebGl1(ref _gl) => { + panic!("Get frag data location is not supported") + } + RawRenderingContext::WebGl2(ref gl) => gl.get_frag_data_location(raw_program, name), + } + } + unsafe fn bind_frag_data_location( &self, _program: Self::Program, @@ -2787,6 +2845,20 @@ impl HasContext for Context { } } + unsafe fn get_sync_parameter_i32(&self, fence: Self::Fence, parameter: u32) -> i32 { + let fences = self.fences.borrow(); + let raw_fence = fences.get_unchecked(fence); + match self.raw { + RawRenderingContext::WebGl1(ref _gl) => panic!("get sync parameter is not supported"), + RawRenderingContext::WebGl2(ref gl) => gl.get_sync_parameter(raw_fence, parameter), + } + .as_f64() + .map(|v| v as i32) + // Errors will be caught by the browser or through `get_error` + // so return a default instead + .unwrap_or(0) + } + unsafe fn wait_sync(&self, fence: Self::Fence, flags: u32, timeout: u64) { let fences = self.fences.borrow(); let raw_fence = fences.get_unchecked(fence); @@ -3350,6 +3422,18 @@ impl HasContext for Context { .unwrap_or(0) } + unsafe fn get_tex_parameter_f32(&self, target: u32, parameter: u32) -> f32 { + match self.raw { + RawRenderingContext::WebGl1(ref gl) => gl.get_tex_parameter(target, parameter), + RawRenderingContext::WebGl2(ref gl) => gl.get_tex_parameter(target, parameter), + } + .as_f64() + .map(|v| v as f32) + // Errors will be caught by the browser or through `get_error` + // so return a default instead + .unwrap_or(0.) + } + unsafe fn get_buffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 { match self.raw { RawRenderingContext::WebGl1(ref gl) => gl.get_buffer_parameter(target, parameter), @@ -3568,6 +3652,18 @@ impl HasContext for Context { panic!("Get framebuffer parameter is not supported"); } + unsafe fn get_renderbuffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 { + match self.raw { + RawRenderingContext::WebGl1(ref gl) => gl.get_renderbuffer_parameter(target, parameter), + RawRenderingContext::WebGl2(ref gl) => gl.get_renderbuffer_parameter(target, parameter), + } + .as_f64() + .map(|v| v as i32) + // Errors will be caught by the browser or through `get_error` + // so return a default instead + .unwrap_or(0) + } + unsafe fn get_named_framebuffer_parameter_i32( &self, _framebuffer: Option, @@ -3788,6 +3884,38 @@ impl HasContext for Context { } } + unsafe fn get_sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32) -> i32 { + let samplers = self.samplers.borrow(); + let raw_sampler = samplers.get_unchecked(sampler); + match self.raw { + RawRenderingContext::WebGl1(ref _gl) => { + panic!("Samper parameter for `i32` is not supported") + } + RawRenderingContext::WebGl2(ref gl) => gl.get_sampler_parameter(raw_sampler, name), + } + .as_f64() + .map(|v| v as i32) + // Errors will be caught by the browser or through `get_error` + // so return a default instead + .unwrap_or(0) + } + + unsafe fn get_sampler_parameter_f32(&self, sampler: Self::Sampler, name: u32) -> f32 { + let samplers = self.samplers.borrow(); + let raw_sampler = samplers.get_unchecked(sampler); + match self.raw { + RawRenderingContext::WebGl1(ref _gl) => { + panic!("Samper parameter for `i32` is not supported") + } + RawRenderingContext::WebGl2(ref gl) => gl.get_sampler_parameter(raw_sampler, name), + } + .as_f64() + .map(|v| v as f32) + // Errors will be caught by the browser or through `get_error` + // so return a default instead + .unwrap_or(0.) + } + unsafe fn generate_mipmap(&self, target: u32) { match self.raw { RawRenderingContext::WebGl1(ref gl) => { @@ -4602,6 +4730,30 @@ impl HasContext for Context { } } + unsafe fn invalidate_sub_framebuffer( + &self, + target: u32, + attachments: &[u32], + x: i32, + y: i32, + width: i32, + height: i32, + ) { + match self.raw { + RawRenderingContext::WebGl1(ref _gl) => { + panic!("Invalidate sub framebuffer is not supported"); + } + RawRenderingContext::WebGl2(ref gl) => { + let js_attachments = Array::new(); + for &a in attachments { + js_attachments.push(&a.into()); + } + gl.invalidate_sub_framebuffer(target, &js_attachments, x, y, width, height) + .unwrap(); + } + } + } + unsafe fn polygon_offset(&self, factor: f32, units: f32) { match self.raw { RawRenderingContext::WebGl1(ref gl) => gl.polygon_offset(factor, units), @@ -5030,6 +5182,25 @@ impl HasContext for Context { } } + unsafe fn get_vertex_attrib_parameter_f32_slice( + &self, + index: u32, + pname: u32, + result: &mut [f32], + ) { + let value = match self.raw { + RawRenderingContext::WebGl1(ref gl) => gl.get_vertex_attrib(index, pname), + RawRenderingContext::WebGl2(ref gl) => gl.get_vertex_attrib(index, pname), + } + .unwrap(); + use wasm_bindgen::JsCast; + if let Some(value) = value.as_f64() { + result[0] = value as f32; + } else if let Some(values) = value.dyn_ref::() { + values.copy_to(result) + } + } + unsafe fn vertex_attrib_pointer_f32( &self, index: u32, @@ -5135,6 +5306,20 @@ impl HasContext for Context { } } + unsafe fn vertex_attrib_4_i32(&self, index: u32, x: i32, y: i32, z: i32, w: i32) { + match self.raw { + RawRenderingContext::WebGl1(ref _gl) => panic!("vertex_attrib_4_i32 not supported"), + RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib_i4i(index, x, y, z, w), + } + } + + unsafe fn vertex_attrib_4_u32(&self, index: u32, x: u32, y: u32, z: u32, w: u32) { + match self.raw { + RawRenderingContext::WebGl1(ref _gl) => panic!("vertex_attrib_4_u32 not supported"), + RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib_i4ui(index, x, y, z, w), + } + } + unsafe fn vertex_attrib_1_f32_slice(&self, index: u32, v: &[f32]) { match self.raw { RawRenderingContext::WebGl1(ref gl) => gl.vertex_attrib1fv_with_f32_array(index, v), @@ -5400,6 +5585,37 @@ impl HasContext for Context { } } + unsafe fn get_uniform_indices( + &self, + program: Self::Program, + names: &[&str], + ) -> Vec> { + let programs = self.programs.borrow(); + let raw_program = programs.get_unchecked(program); + let indices = match self.raw { + RawRenderingContext::WebGl1(ref _gl) => panic!("Uniform blocks are not supported"), + RawRenderingContext::WebGl2(ref gl) => { + let js_names = Array::new(); + for &v in names { + js_names.push(&v.into()); + } + gl.get_uniform_indices(raw_program, &js_names) + } + } + .unwrap(); + indices + .iter() + .map(|index| { + let index = index.as_f64().unwrap() as u32; + if index == INVALID_INDEX { + None + } else { + Some(index) + } + }) + .collect() + } + unsafe fn uniform_block_binding(&self, program: Self::Program, index: u32, binding: u32) { match self.raw { RawRenderingContext::WebGl1(ref _gl) => { @@ -5526,6 +5742,26 @@ impl HasContext for Context { } } + unsafe fn get_uniform_u32( + &self, + program: Self::Program, + location: &Self::UniformLocation, + v: &mut [u32], + ) { + let programs = self.programs.borrow(); + let raw_program = programs.get_unchecked(program); + let value = match self.raw { + RawRenderingContext::WebGl1(ref gl) => gl.get_uniform(&raw_program, location), + RawRenderingContext::WebGl2(ref gl) => gl.get_uniform(&raw_program, location), + }; + use wasm_bindgen::JsCast; + if let Some(value) = value.as_f64() { + v[0] = value as u32; + } else if let Some(values) = value.dyn_ref::() { + values.copy_to(v) + } + } + unsafe fn get_uniform_f32( &self, program: Self::Program, @@ -5612,6 +5848,18 @@ impl HasContext for Context { } } + unsafe fn is_transform_feedback(&self, transform_feedback: Self::TransformFeedback) -> bool { + let transform_feedbacks = self.transform_feedbacks.borrow_mut(); + if let Some(f) = transform_feedbacks.get(transform_feedback) { + match &self.raw { + RawRenderingContext::WebGl1(_gl) => panic!("TransformFeedback is not supported"), + RawRenderingContext::WebGl2(gl) => gl.is_transform_feedback(Some(f)), + } + } else { + false + } + } + unsafe fn delete_transform_feedback(&self, transform_feedback: Self::TransformFeedback) { let mut transform_feedbacks = self.transform_feedbacks.borrow_mut(); if let Some(ref t) = transform_feedbacks.remove(transform_feedback) { @@ -5816,6 +6064,44 @@ impl HasContext for Context { unsafe fn max_shader_compiler_threads(&self, _count: u32) { // WebGL doesn't use this } + + unsafe fn hint(&self, target: u32, mode: u32) { + match self.raw { + RawRenderingContext::WebGl1(ref gl) => gl.hint(target, mode), + RawRenderingContext::WebGl2(ref gl) => gl.hint(target, mode), + } + } + + unsafe fn sample_coverage(&self, value: f32, invert: bool) { + match self.raw { + RawRenderingContext::WebGl1(ref gl) => gl.sample_coverage(value, invert), + RawRenderingContext::WebGl2(ref gl) => gl.sample_coverage(value, invert), + } + } + + unsafe fn get_internal_format_i32_slice( + &self, + target: u32, + internal_format: u32, + pname: u32, + result: &mut [i32], + ) { + let value = match self.raw { + RawRenderingContext::WebGl1(ref gl) => { + panic!("get_internalformat_parameter not supported") + } + RawRenderingContext::WebGl2(ref gl) => { + gl.get_internalformat_parameter(target, internal_format, pname) + } + } + .unwrap(); + use wasm_bindgen::JsCast; + if let Some(value) = value.as_f64() { + result[0] = value as i32; + } else if let Some(values) = value.dyn_ref::() { + values.copy_to(result) + } + } } /// Sending texture data requires different data views for different data types.