summaryrefslogtreecommitdiff
path: root/WebInterface/wasm/asm-paint/src
diff options
context:
space:
mode:
Diffstat (limited to 'WebInterface/wasm/asm-paint/src')
-rw-r--r--WebInterface/wasm/asm-paint/src/app.rs19
-rw-r--r--WebInterface/wasm/asm-paint/src/canvas.rs39
-rw-r--r--WebInterface/wasm/asm-paint/src/client_logger.rs46
-rw-r--r--WebInterface/wasm/asm-paint/src/lib.rs31
-rw-r--r--WebInterface/wasm/asm-paint/src/shader.rs97
-rw-r--r--WebInterface/wasm/asm-paint/src/site.rs28
6 files changed, 241 insertions, 19 deletions
diff --git a/WebInterface/wasm/asm-paint/src/app.rs b/WebInterface/wasm/asm-paint/src/app.rs
new file mode 100644
index 0000000..005764d
--- /dev/null
+++ b/WebInterface/wasm/asm-paint/src/app.rs
@@ -0,0 +1,19 @@
+use crate::site::Site;
+
+pub struct App {
+ site: Site,
+}
+
+impl App {
+ pub fn new() -> Option<Self> {
+ Some(Self {
+ site: Site::from_current()?,
+ })
+ }
+
+ pub fn run(&mut self) {
+ let mut canvas = self.site.create_canvas().unwrap();
+ canvas.init().unwrap();
+ info!("canvas initialisation was succuessfull");
+ }
+}
diff --git a/WebInterface/wasm/asm-paint/src/canvas.rs b/WebInterface/wasm/asm-paint/src/canvas.rs
new file mode 100644
index 0000000..400e258
--- /dev/null
+++ b/WebInterface/wasm/asm-paint/src/canvas.rs
@@ -0,0 +1,39 @@
+use web_sys;
+use web_sys::{WebGl2RenderingContext};
+use wasm_bindgen::JsCast;
+use crate::shader::Shaders;
+
+pub struct Canvas {
+ element: web_sys::HtmlCanvasElement,
+ ctx: WebGl2RenderingContext,
+ shaders: Shaders,
+}
+
+impl Canvas {
+ pub fn new(element: web_sys::Element) -> Option<Self> {
+ let element: web_sys::HtmlCanvasElement =
+ element.dyn_into::<web_sys::HtmlCanvasElement>()
+ .ok()?;
+ debug!("create webgl2 context");
+ let ctx = element.get_context("webgl2").ok()??
+ .dyn_into::<WebGl2RenderingContext>().ok()?;
+ info!("created webgl2 context successfully");
+ Some(Self {
+ element, ctx,
+ shaders: Shaders::new(),
+ })
+ }
+
+ pub fn init(&mut self) -> Result<(), ()> {
+ self.shaders.init(&self.ctx).map_err(|_|())?;
+ self.ctx.clear_color(1.0, 0.2, 1.0, 1.0);
+ self.ctx.clear(WebGl2RenderingContext::COLOR_BUFFER_BIT);
+ Ok(())
+ }
+}
+
+impl Drop for Canvas {
+ fn drop(&mut self) {
+ self.shaders.remove(&self.ctx);
+ }
+}
diff --git a/WebInterface/wasm/asm-paint/src/client_logger.rs b/WebInterface/wasm/asm-paint/src/client_logger.rs
new file mode 100644
index 0000000..f71918f
--- /dev/null
+++ b/WebInterface/wasm/asm-paint/src/client_logger.rs
@@ -0,0 +1,46 @@
+use wasm_bindgen::prelude::*;
+
+#[wasm_bindgen]
+extern "C" {
+ #[wasm_bindgen(js_namespace=console, js_name=debug)]
+ fn __console_debug_colored2(f: &str, c1: &str, c2: &str);
+ #[wasm_bindgen(js_namespace=console, js_name=info)]
+ fn __console_info_colored2(f: &str, c1: &str, c2: &str);
+ #[wasm_bindgen(js_namespace=console, js_name=warn)]
+ fn __console_warn_colored2(f: &str, c1: &str, c2: &str);
+ #[wasm_bindgen(js_namespace=console, js_name=error)]
+ fn __console_error_colored2(f: &str, c1: &str, c2: &str);
+}
+
+fn log(rec: &log::Record) {
+ let log_fn = match rec.level() {
+ log::Level::Trace | log::Level::Debug => __console_debug_colored2,
+ log::Level::Info => __console_info_colored2,
+ log::Level::Warn => __console_warn_colored2,
+ log::Level::Error => __console_error_colored2,
+ };
+ log_fn(&format!("{}", rec.args()),
+ &format!("color: {}", match rec.level() {
+ log::Level::Trace => "violet",
+ log::Level::Debug => "blue",
+ log::Level::Info => "green",
+ log::Level::Warn => "orange",
+ log::Level::Error => "red"
+ }), "");
+}
+
+pub fn init_logger() {
+ fern::Dispatch::new().format(|out, message, record|{
+ out.finish(format_args!(
+ "%c{}%c {} > {}",
+ record.level(),
+ record.target(),
+ message
+ )
+ )
+ })
+ .level(log::LevelFilter::Debug)
+ .chain(fern::Output::call(log))
+ .apply().unwrap();
+}
+
diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs
index 462a89d..6c773c5 100644
--- a/WebInterface/wasm/asm-paint/src/lib.rs
+++ b/WebInterface/wasm/asm-paint/src/lib.rs
@@ -1,27 +1,20 @@
-use wasm_bindgen::prelude::*;
+mod client_logger;
+mod shader;
+mod canvas;
+mod site;
+mod app;
-macro_rules! console_log {
- ($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
-}
+use wasm_bindgen::prelude::*;
-#[wasm_bindgen]
-extern "C" {
- #[wasm_bindgen(js_namespace = console)]
- fn log(s: &str);
-}
+#[macro_use]
+extern crate log;
#[wasm_bindgen(start)]
pub fn entry() {
- use web_sys;
- console_log!("hello {} wasm", 42);
-
- let window = web_sys::window().unwrap();
-
- let document = window.document().unwrap();
-
- let body = document.body().unwrap();
+ client_logger::init_logger();
- //body.set_inner_html("<marquee><h1 style='font-size: 100px'>Hello from WASM</h1></marquee>");
+ info!("begin running wasm application");
- body.set_inner_html("oho");
+ let mut app = app::App::new().unwrap();
+ app.run();
}
diff --git a/WebInterface/wasm/asm-paint/src/shader.rs b/WebInterface/wasm/asm-paint/src/shader.rs
new file mode 100644
index 0000000..3352bcf
--- /dev/null
+++ b/WebInterface/wasm/asm-paint/src/shader.rs
@@ -0,0 +1,97 @@
+use web_sys::{WebGlProgram, WebGl2RenderingContext};
+
+const VERTEX_SHADER: &str =
+r#"#version 300 es
+in vec4 pos;
+void main() {
+ gl_Position = pos;
+}
+"#;
+
+const FRAGMENT_SHADER: &str =
+r#"#version 300 es
+precision mediump float;
+out vec4 color;
+
+void main() {
+ color = vec4(1, 0, 0, 1);
+}
+"#;
+
+pub struct Shaders {
+ program: Option<WebGlProgram>,
+ pos_loc: i32,
+}
+
+impl Shaders {
+ pub fn new() -> Self {
+ Self {
+ program: None,
+ pos_loc: -1
+ }
+ }
+
+ fn create_program(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> {
+ self.program = Some(ctx.create_program().ok_or("could not create program id")?);
+ Ok(())
+ }
+
+ fn create_shader(&mut self, ctx: &WebGl2RenderingContext,
+ shader_type: u32, source: &str) -> Result<(), String> {
+ let program = self.program.as_ref().ok_or("could not find created program")?;
+ let shader = ctx.create_shader(shader_type)
+ .ok_or("could not create shader")?;
+ ctx.shader_source(&shader, source);
+ ctx.compile_shader(&shader);
+ let status = ctx.get_shader_parameter(&shader, WebGl2RenderingContext::COMPILE_STATUS);
+ if status == wasm_bindgen::JsValue::TRUE {
+ ctx.attach_shader(program, &shader);
+ Ok(())
+ } else {
+ Err(format!("\n{}", ctx.get_shader_info_log(&shader).unwrap_or_default()))
+ }
+ }
+
+ fn create_vertex_shader(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> {
+ self.create_shader(ctx, WebGl2RenderingContext::VERTEX_SHADER, VERTEX_SHADER)
+ }
+
+ fn create_fragment_shader(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> {
+ self.create_shader(ctx, WebGl2RenderingContext::FRAGMENT_SHADER, FRAGMENT_SHADER)
+ }
+
+ fn compile(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> {
+ let program = self.program.as_ref().ok_or("could not find created program")?;
+ ctx.link_program(program);
+ let status = ctx.get_program_parameter(program, WebGl2RenderingContext::LINK_STATUS);
+ if status == wasm_bindgen::JsValue::TRUE {
+ Ok(())
+ } else {
+ Err(format!("\n{}", ctx.get_program_info_log(program).unwrap_or_default()))
+ }
+ }
+
+ pub fn init(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> {
+ debug!("create program");
+ self.create_program(ctx)
+ .map_err(|e| { error!("webgl2 create program: {}", e); e})?;
+ debug!("create vertex shader");
+ self.create_vertex_shader(ctx)
+ .map_err(|e| { error!("webgl2 create vertex shader: {}", e); e})?;
+ debug!("create fragment shader");
+ self.create_fragment_shader(ctx)
+ .map_err(|e| { error!("webgl2 create fragment shader: {}", e); e})?;
+ debug!("compile shader program");
+ self.compile(ctx)
+ .map_err(|e| { error!("webgl2 shader: {}", e); e})?;
+ let program = self.program.as_ref().ok_or("could not find created program")?;
+ self.pos_loc = ctx.get_attrib_location(program, "pos");
+ trace!("got attrib location 'pos'({})", self.pos_loc);
+ info!("initialised shader program");
+ Ok(())
+ }
+
+ pub fn remove(&mut self, ctx: &WebGl2RenderingContext) {
+ ctx.delete_program(self.program.as_ref())
+ }
+}
diff --git a/WebInterface/wasm/asm-paint/src/site.rs b/WebInterface/wasm/asm-paint/src/site.rs
new file mode 100644
index 0000000..4ae0237
--- /dev/null
+++ b/WebInterface/wasm/asm-paint/src/site.rs
@@ -0,0 +1,28 @@
+use web_sys;
+use crate::canvas::Canvas;
+
+pub struct Site {
+ window: web_sys::Window,
+ document: web_sys::Document,
+}
+
+impl Site {
+ pub fn from_current() -> Option<Self> {
+ let window = web_sys::window()
+ .or_else(|| {error!("unable to query window"); None})?;
+ let document = window.document()
+ .or_else(|| {error!("unable to query document"); None})?;
+ Some(Self {
+ window, document
+ })
+ }
+
+ pub fn create_canvas(&self) -> Option<Canvas> {
+ debug!("gain canvas element");
+ let element = self.document.get_element_by_id("canvas")
+ .or_else(|| {error!("could not gain canvas element"); None})?;
+ Canvas::new(element)
+ .or_else(|| {error!("could not create a webgl2 canvas.
+ Your browser doesn't seem to support webgl2"); None})
+ }
+}