diff options
Diffstat (limited to 'webhogg/wasm/src/context/webgl.rs')
-rw-r--r-- | webhogg/wasm/src/context/webgl.rs | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/webhogg/wasm/src/context/webgl.rs b/webhogg/wasm/src/context/webgl.rs new file mode 100644 index 0000000..8883835 --- /dev/null +++ b/webhogg/wasm/src/context/webgl.rs @@ -0,0 +1,134 @@ +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, +} + +impl WebGl2 { + pub fn from_context(context: GlContext) -> Self { + WebGl2 { + gl: context, + } + } + + 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)) + } +} |