summaryrefslogtreecommitdiff
path: root/webhogg/wasm/src/context/webgl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'webhogg/wasm/src/context/webgl.rs')
-rw-r--r--webhogg/wasm/src/context/webgl.rs134
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))
+ }
+}