diff options
author | Dennis Kobert <d-kobert@web.de> | 2019-06-21 23:52:07 +0200 |
---|---|---|
committer | Dennis Kobert <d-kobert@web.de> | 2019-06-21 23:52:07 +0200 |
commit | 4e0037169db5d0c7d824debedb5513b69676506a (patch) | |
tree | 82c56547fa70b499627236efa66c3bf7e5411ead /webhogg/wasm/src/context/graphics.rs | |
parent | 36c89240a87ecb826cf09bc7b3069aa636c9f2f1 (diff) | |
parent | 031f63755aada2f1b51eb945fda2a18ad0d24aad (diff) |
Merge branch 'wasm' into game_server_refactor
Diffstat (limited to 'webhogg/wasm/src/context/graphics.rs')
-rw-r--r-- | webhogg/wasm/src/context/graphics.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/webhogg/wasm/src/context/graphics.rs b/webhogg/wasm/src/context/graphics.rs new file mode 100644 index 0000000..6af35a2 --- /dev/null +++ b/webhogg/wasm/src/context/graphics.rs @@ -0,0 +1,81 @@ +use crate::error::WasmError; +use wasm_bindgen::JsCast; +use web_sys::WebGl2RenderingContext as GlContext; + +use super::webgl; +use super::webgl::{Color4, ShaderType, WebGl2}; +use super::shader::{MAIN_VERTEX_SHADER, MAIN_FRAGMENT_SHADER}; +use super::shader::ShaderProgram; + +pub struct GraphicsContext { + gl: WebGl2, + frame_nr: u64, + shader: ShaderProgram, + vao: webgl::WebGlVertexArrayObject, + buffer: webgl::WebGlBuffer, +} + +impl GraphicsContext { + pub fn from_canvas(canvas: web_sys::OffscreenCanvas) -> Result<Self, WasmError> { + let context = canvas.get_context("webgl2") + .map_err(|_| WasmError::WebGl2ContextCreation( + format!("context cration failed: getContext returned an exception")))? + .ok_or_else(|| WasmError::WebGl2ContextCreation( + format!("context cration failed: getContext returned nothing")))?; + let context = context + .dyn_into::<GlContext>() + .map_err(|_| WasmError::WebGl2ContextCreation( + format!("context object is not a context")))?; + + let gl = WebGl2::from_context(context); + let shader = ShaderProgram::from_sources(&gl, &[ + (ShaderType::Vertex, MAIN_VERTEX_SHADER.to_string()), + (ShaderType::Fragment, MAIN_FRAGMENT_SHADER.to_string()), + ])?; + + let vao = gl.create_vertex_array() + .map_err(|_| WasmError::WebGlBuffer( + format!("glGenVertexArrays failed")))?; + gl.bind_vertex_array(&vao); + + let buffer = gl.create_buffer() + .map_err(|_| WasmError::WebGlBuffer( + format!("glCreateBuffer failed")))?; + gl.bind_array_buffer(&buffer); + gl.array_buffer_data_f32(&[ + 0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + 0.0, 1.0, + 1.0, 0.0, + ]); + gl.enable_vertex_attrib_array(0); + + Ok(Self { + gl, frame_nr: 0, + shader, vao, buffer + }) + } + + pub fn update(&mut self) -> Result<(), WasmError> { + let light = 0.5; + let speed = 60.0; + + let a = (self.frame_nr as f32) / speed; + let a = f32::abs(f32::sin(a)); + let b = f32::abs(f32::cos(a)); + let (a, b) = (a * light, b * light); + + self.gl.set_viewport(); + self.gl.clear(&Color4::new(a, light - a, b, 1.0)); + + self.shader.run(&self.gl); + self.gl.vertex_attrib_f32_pointer(0, 2); + self.gl.draw_triangle_arrays(6); + + self.frame_nr += 1; + + Ok(()) + } +} |