diff options
Diffstat (limited to 'webhogg/wasm/src/context/webgl.rs')
-rw-r--r-- | webhogg/wasm/src/context/webgl.rs | 112 |
1 files changed, 110 insertions, 2 deletions
diff --git a/webhogg/wasm/src/context/webgl.rs b/webhogg/wasm/src/context/webgl.rs index abecc6e..8883835 100644 --- a/webhogg/wasm/src/context/webgl.rs +++ b/webhogg/wasm/src/context/webgl.rs @@ -1,13 +1,50 @@ -use web_sys::WebGl2RenderingContext as GlContext; +pub use web_sys::{ + WebGl2RenderingContext as GlContext, + WebGlProgram, WebGlShader, + WebGlBuffer, WebGlVertexArrayObject, +}; +use wasm_bindgen::prelude::*; +use std::fmt::Display; pub struct Color4(f32, f32, f32, f32); +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace=Float32Array, js_name=of, variadic)] + fn _create_f32_buffer(args: &[f32]) -> js_sys::Float32Array; +} + +#[derive(Debug)] +pub enum ShaderType { + Vertex, + Fragment, +} + +impl Display for ShaderType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl ShaderType { + pub fn to_id(&self) -> u32 { + match self { + ShaderType::Vertex => GlContext::VERTEX_SHADER, + ShaderType::Fragment => GlContext::FRAGMENT_SHADER, + } + } +} + impl Color4 { pub fn new(r: f32, g: f32, b: f32, a: f32) -> Color4 { Color4(r, g, b, a) } } +pub fn create_f32_buffer(buffer: &[f32]) -> js_sys::Float32Array { + _create_f32_buffer(buffer) +} + pub struct WebGl2 { gl: GlContext, } @@ -19,8 +56,79 @@ impl WebGl2 { } } - pub fn clear(&self, color: Color4) { + pub fn create_program(&self) -> Result<WebGlProgram, ()> { + self.gl.create_program().ok_or(()) + } + + pub fn create_shader(&self, shader_type: &ShaderType) -> Result<WebGlShader, ()> { + self.gl.create_shader(shader_type.to_id()).ok_or(()) + } + + pub fn get_error(&self) -> u32 { self.gl.get_error() } + pub fn shader_source(&self, id: &WebGlShader, source: &str) { self.gl.shader_source(id, source) } + pub fn compile_shader(&self, id: &WebGlShader) -> Result<(), String> { + self.gl.compile_shader(id); + if self.gl.get_shader_parameter(id, GlContext::COMPILE_STATUS) == JsValue::FALSE { + Err(self.gl.get_shader_info_log(id) + .unwrap_or("/could not retrieve program information/".to_string())) + } else { Ok(()) } + } + pub fn link_program(&self, id: &WebGlProgram) -> Result<(), String> { + self.gl.link_program(id); + if self.gl.get_program_parameter(id, GlContext::LINK_STATUS) == JsValue::FALSE { + Err(self.gl.get_program_info_log(id) + .unwrap_or("/could not retrieve program information/".to_string())) + } else { Ok(()) } + } + pub fn attach_shader(&self, program: &WebGlProgram, shader: &WebGlShader) { + self.gl.attach_shader(program, shader) + } + + pub fn clear(&self, color: &Color4) { self.gl.clear_color(color.0, color.1, color.2, color.3); self.gl.clear(GlContext::COLOR_BUFFER_BIT); } + + pub fn set_viewport(&self) { + self.gl.viewport(0, 0, self.gl.drawing_buffer_width(), self.gl.drawing_buffer_height()); + } + + pub fn create_buffer(&self) -> Result<WebGlBuffer, ()> { + self.gl.create_buffer().ok_or(()) + } + + pub fn bind_array_buffer(&self, buffer: &WebGlBuffer) { + self.gl.bind_buffer(GlContext::ARRAY_BUFFER, Some(buffer)) + } + pub fn unbind_array_buffer(&self) { self.gl.bind_buffer(GlContext::ARRAY_BUFFER, None) } + + pub fn array_buffer_data_f32(&self, data: &[f32]) { + self.gl.buffer_data_with_opt_array_buffer( + GlContext::ARRAY_BUFFER, + Some(&create_f32_buffer(data).buffer()), + GlContext::STATIC_DRAW) + } + + pub fn create_vertex_array(&self) -> Result<WebGlVertexArrayObject, ()> { + self.gl.create_vertex_array().ok_or(()) + } + pub fn bind_vertex_array(&self, array: &WebGlVertexArrayObject) { + self.gl.bind_vertex_array(Some(array)) + } + pub fn unbind_vertex_array(&self) { self.gl.bind_vertex_array(None) } + pub fn vertex_attrib_f32_pointer(&self, location: u32, dim: i32) { + self.gl.vertex_attrib_pointer_with_i32(location, dim, GlContext::FLOAT, false, 0, 0) + } + + pub fn draw_triangle_arrays(&self, count: i32) { + self.gl.draw_arrays(GlContext::TRIANGLES, 0, count) + } + + pub fn enable_vertex_attrib_array(&self, location: u32) { + self.gl.enable_vertex_attrib_array(location) + } + + pub fn use_program(&self, program: &WebGlProgram) { + self.gl.use_program(Some(program)) + } } |