commit f2dbe36ae6172eccd92c798745967e06b5b2973d
parent 0a48c423fd3db9aaa717f07964f2652246f1db2b
Author: amin <dev@aminmesbah.com>
Date: Sun, 23 Jun 2019 21:48:29 +0000
Clean wasm stuff up
FossilOrigin-Name: e0ddeb4051ddf4c6f6c8385751a8ae6f24f225dc655f19508f9668ac1319f039
Diffstat:
9 files changed, 294 insertions(+), 297 deletions(-)
diff --git a/build_wasm.sh b/build_wasm.sh
@@ -1,20 +1,40 @@
+#!/usr/bin/env bash
-mkdir -p ./out/wasm
-cat js/globals.js js/utils.js js/imports.js js/loader.js > ./out/wasm/script.js
-cp index.html ./out/wasm/index.html
-cp -r shader/ ./out/wasm/
+set -e # fail if any command has a non-zero exit status
+set -u # fail if any undefined variable is referenced
+set -o pipefail # propagate failure exit status through a pipeline
+shopt -s globstar nullglob # enable recursive and null globbing
-clang -cc1 -Ofast -emit-llvm-bc -triple=wasm32-unknown-unknown-unknown-wasm -std=c11 \
+out_dir="./out"
+wasm_dir="${out_dir}/wasm"
+
+mkdir -p $wasm_dir
+cp src/platform_wasm_loader.js $wasm_dir/script.js
+cp src/platform_wasm_index.html $wasm_dir/index.html
+cp -r shader/ $wasm_dir
+
+clang \
+ -cc1 \
+ -Ofast \
+ -emit-llvm-bc \
+ -triple=wasm32-unknown-unknown-unknown-wasm \
-ffreestanding \
-fno-builtin \
+ -std=c11 \
-DGAME_WEBGL \
src/platform_wasm.c
-llvm-link -o wasm.bc src/*.bc
-opt -O3 -disable-simplify-libcalls wasm.bc -o wasm.bc
-llc -O3 -disable-simplify-libcalls -filetype=obj wasm.bc -o wasm.o
-wasm-ld --no-entry wasm.o \
- -o ./out/wasm/binary.wasm \
- -allow-undefined-file wasm_js_implemented_symbols.txt \
+llvm-link -o $wasm_dir/wasm.bc src/*.bc
+opt -O3 -disable-simplify-libcalls $wasm_dir/wasm.bc -o $wasm_dir/wasm.bc
+llc -O3 -disable-simplify-libcalls -filetype=obj $wasm_dir/wasm.bc -o $wasm_dir/wasm.o
+
+wasm-ld \
+ --no-entry $wasm_dir/wasm.o \
+ -o $wasm_dir/binary.wasm \
+ -allow-undefined-file src/platform_wasm_js_symbols.txt \
--export-all \
--import-memory
+
+rm $wasm_dir/*.o
+rm $wasm_dir/*.bc
+rm src/*.bc
diff --git a/index.html b/index.html
@@ -1,17 +0,0 @@
-<!DOCTYPE html>
-<title>WASM Demo</title>
-<meta name=viewport content='width=device-width,initial-scale=1' charset='utf-8'>
-
-<style>
-body{
- margin: 0;
- overflow: hidden;
-}
-#mcanvas{
- width: 100vw;
- height: 100vh;
-}
-</style>
-
-<canvas id=mcanvas></canvas>
-<script src='script.js' defer></script>
diff --git a/js/globals.js b/js/globals.js
@@ -1,8 +0,0 @@
-let utf8decoder = new TextDecoder("utf-8");
-let memory = null;
-let exports = {};
-let imports = {};
-let files = [];
-let gl = null;
-let gl_id_freelist = [];
-let gl_id_map = [null];
diff --git a/js/imports.js b/js/imports.js
@@ -1,168 +0,0 @@
-imports["webglAttachShader"] = function(program_id, shader_id) {
- let program = gl_id_map[program_id];
- let shader = gl_id_map[shader_id];
- gl.attachShader(program, shader);
-}
-imports["webglBindBuffer"] = function(target, buffer_id) {
- let buffer = gl_id_map[buffer_id];
- gl.bindBuffer(target, buffer);
-}
-imports["webglBindVertexArray"] = function(vao_id) {
- let vao = gl_id_map[vao_id];
- gl.bindVertexArray(vao);
-}
-imports["webglBlendColor"] = function(red, green, blue, alpha) {
- gl.blendColor(red, green, blue, alpha);
-}
-imports["webglBlendFunc"] = function(sfactor, dfactor) {
- gl.blendFunc(sfactor, dfactor);
-}
-imports["webglBufferData"] = function(target, size, data, usage) {
- let dataslice = memory.subarray(data, data + size);
- gl.bufferData(target, dataslice, usage);
-}
-imports["webglClear"] = function(mask) {
- gl.clear(mask);
-}
-imports["webglClearColor"] = function(red, green, blue, alpha) {
- gl.clearColor(red, green, blue, alpha);
-}
-imports["webglCompileShader"] = function(shader_id) {
- let shader = gl_id_map[shader_id];
- gl.compileShader(shader);
-}
-imports["webglCreateBuffer"] = function() {
- let buffer = gl.createBuffer();
- let buffer_id = webgl_id_new(buffer);
- return buffer_id
-}
-imports["webglCreateProgram"] = function() {
- let program = gl.createProgram();
- let program_id = webgl_id_new(program);
- return program_id;
-}
-imports["webglCreateShader"] = function(type) {
- let shader = gl.createShader(type);
- let shader_id = webgl_id_new(shader);
- return shader_id;
-}
-imports["webglCreateVertexArray"] = function() {
- let vao = gl.createVertexArray()
- let vao_id = webgl_id_new(vao);
- return vao_id
-}
-imports["webglDeleteBuffer"] = function(buffer_id) {
- let buffer = gl_id_map[buffer_id];
- gl.deleteBuffer(buffer);
- webgl_id_remove(buffer_id);
-}
-imports["webglDeleteShader"] = function(shader_id) {
- let shader = gl_id_map[shader_id];
- gl.deleteShader(shader);
- webgl_id_remove(shader_id);
-}
-imports["webglDeleteVertexArray"] = function(vao_id) {
- let vao = gl_id_map[vao_id];
- gl.deleteVertexArray(vao);
- webgl_id_remove(vao_id);
-}
-imports["webglDepthMask"] = function(flag) {
- gl.depthMask(flag);
-}
-imports["webglDisable"] = function(cap) {
- gl.disable(cap);
-}
-imports["webglDrawElements"] = function(mode, count, type, offset) {
- gl.drawElements(mode, count, type, offset);
-}
-imports["webglEnable"] = function(cap) {
- gl.enable(cap);
-}
-imports["webglEnableVertexAttribArray"] = function(index) {
- gl.enableVertexAttribArray(index);
-}
-imports["webglGetProgramInfoLog"] = function() {
-}
-imports["webglGetProgramParameter"] = function(program_id, param) {
- let program = gl_id_map[program_id];
- return gl.getProgramParameter(program, param);
-}
-imports["webglGetShaderInfoLog"] = function(shader_id, out_buf) {
- let shader = gl_id_map[shader_id];
- let info_log = gl.getShaderInfoLog(shader);
-
- // TODO: remove this once we get sprintf workingk
- console.log(info_log);
-
- let arr = memory.subarray(info_log, out_buf + info_log.byteLength);
- arr.set(new Uint8Array(info_log));
- return true;
-}
-imports["webglGetShaderParameter"] = function(shader_id, param) {
- let shader = gl_id_map[shader_id];
- let result = gl.getShaderParameter(shader, param);
- return result;
-}
-imports["webglGetUniformLocation"] = function(program_id, name_ptr, name_len) {
- let program = gl_id_map[program_id];
- let name = utf8decoder.decode(memory.subarray(name_ptr, name_ptr+name_len));
- let loc = gl.getUniformLocation(program, name);
- let location_id = webgl_id_new(loc);
- return location_id;
-}
-imports["webglLinkProgram"] = function(program_id) {
- let program = gl_id_map[program_id];
- gl.linkProgram(program);
-}
-imports["webglShaderSource"] = function(shader_id, source_ptr, src_len) {
- let shader = gl_id_map[shader_id];
- let s = buf2str(source_ptr, src_len);
- gl.shaderSource(shader, s);
-}
-imports["webglUniform1f"] = function(location_id, value) {
- let loc = gl_id_map[location_id];
- gl['uniform1f'](loc, value);
-}
-imports["webglUniform1i"] = function(location_id, value) {
- let loc = gl_id_map[location_id];
- gl['uniform1i'](loc, value);
-}
-imports["webglUniform3f"] = function(location_id, x, y, z) {
- let loc = gl_id_map[location_id];
- gl['uniform3fv'](loc, [x, y, z]);
-}
-imports["webglUniformMatrix4fv"] = function(location_id, transpose, data) {
- let loc = gl_id_map[location_id];
- let dataslice = memory.slice(data, data + 4 * 16);
- gl.uniformMatrix4fv(loc, transpose, new Float32Array(dataslice.buffer));
-}
-imports["webglUseProgram"] = function(program_id) {
- let program = gl_id_map[program_id];
- gl.useProgram(program);
-}
-imports["webglVertexAttribPointer"] = function(index, size, type, normalized, stride, offset) {
- gl.vertexAttribPointer(index, size, type, normalized, stride, offset);
-}
-imports["webglViewport"] = function(x, y, width, height) {
- gl.viewport(x, y, width, height);
-}
-
-imports["js_read_entire_file"] = function(name, name_len, out_buf) {
- let file_name = utf8decoder.decode(memory.subarray(name, name + name_len))
- if (file_name == "shader/cube_f.glsl") {
- var file = files[1];
- } else if (file_name == "shader/cube_v.glsl") {
- var file = files[2];
- } else {
- return false;
- }
- let arr = memory.subarray(out_buf, out_buf + file.byteLength);
- let s = String.fromCharCode.apply(null, arr);
- arr.set(new Uint8Array(file));
- return true;
-}
-
-imports["js_print"] = function(s, len) {
- let arr = memory.subarray(s, s + len);
- console.log(utf8decoder.decode(arr));
-}
diff --git a/js/loader.js b/js/loader.js
@@ -1,65 +0,0 @@
-function canvas_resize() {
- let pr = window.devicePixelRatio;
- let w = window.innerWidth;
- let h = window.innerHeight;
- // Bitwise OR does float truncation
- let w_pixels = (w * pr) | 0;
- let h_pixels = (h * pr) | 0;
- gl.canvas.width = w_pixels;
- gl.canvas.height = h_pixels
- exports['window_resize'](w_pixels, h_pixels);
- console.log("resize: (" + w_pixels + ", " + h_pixels + ")");
-}
-
-function canvas_render() {
- exports['render']();
- window.requestAnimationFrame(canvas_render);
-}
-
-function file_load(name) {
- let promise = new Promise((ok, nope) => {
- fetch(name).then(resp => {
- resp.arrayBuffer().then(arr => ok(arr));
- });
- });
- return promise;
-}
-
-window.onload = async function() {
- let ctxopts = {
- alpha: false,
- depth: true,
- stencil: false,
- antialias: true,
- preserveDrawingBuffer: false
- };
-
- gl = document.getElementById("mcanvas").getContext("webgl2", ctxopts);
- if(!gl) {
- error_fatal("Your browser does not support WebGL 2");
- }
-
- files[0] = file_load("binary.wasm");
- files[1] = file_load("shader/cube_f.glsl");
- files[2] = file_load("shader/cube_v.glsl");
- for(var i=0; i<files.length; i++) {
- files[i] = await files[i];
- }
-
- let binary = files[0];
- imports['memory'] = new WebAssembly.Memory({'initial':32});
- memory = new Uint8Array(imports['memory']['buffer']);
- let program = await WebAssembly.instantiate(binary, {"env":imports});
-
- let instance = program['instance'];
- exports = instance['exports'];
-
- canvas_resize();
- window.addEventListener("resize", canvas_resize);
-
- if(!exports['init']()) {
- error_fatal("Engine initialization failed");
- }
-
- canvas_render();
-}
diff --git a/js/utils.js b/js/utils.js
@@ -1,28 +0,0 @@
-function buf2str(ptr, len) {
- let arr = memory.subarray(ptr, ptr + len);
- return utf8decoder.decode(arr);
-}
-
-function error_fatal(message) {
- console.log(message);
- throw message;
-}
-
-function webgl_id_new(obj) {
- if(gl_id_freelist.length == 0)
- {
- gl_id_map.push(obj);
- return gl_id_map.length - 1;
- }
- else
- {
- let id = gl_id_freelist.shift();
- gl_id_map[id] = obj;
- return id;
- }
-}
-
-function webgl_id_remove(id){
- delete gl_id_map[id];
- gl_id_freelist.push(id);
-}
diff --git a/src/platform_wasm_index.html b/src/platform_wasm_index.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Transparent Cube</title>
+<meta name=viewport content='width=device-width,initial-scale=1' charset='utf-8'>
+<style>
+body {
+ margin: 0;
+ overflow: hidden;
+}
+#webglcanvas {
+ width: 100vw;
+ height: 100vh;
+}
+</style>
+<canvas id=webglcanvas></canvas>
+<script src='script.js' defer></script>
diff --git a/wasm_js_implemented_symbols.txt b/src/platform_wasm_js_symbols.txt
diff --git a/src/platform_wasm_loader.js b/src/platform_wasm_loader.js
@@ -0,0 +1,248 @@
+let utf8decoder = new TextDecoder("utf-8");
+let memory = null;
+let exports = {};
+let imports = {};
+let files = [];
+let gl = null;
+let gl_id_freelist = [];
+let gl_id_map = [null];
+imports["webglAttachShader"] = function(program_id, shader_id) {
+ let program = gl_id_map[program_id];
+ let shader = gl_id_map[shader_id];
+ gl.attachShader(program, shader);
+}
+imports["webglBindBuffer"] = function(target, buffer_id) {
+ let buffer = gl_id_map[buffer_id];
+ gl.bindBuffer(target, buffer);
+}
+imports["webglBindVertexArray"] = function(vao_id) {
+ let vao = gl_id_map[vao_id];
+ gl.bindVertexArray(vao);
+}
+imports["webglBlendColor"] = function(red, green, blue, alpha) {
+ gl.blendColor(red, green, blue, alpha);
+}
+imports["webglBlendFunc"] = function(sfactor, dfactor) {
+ gl.blendFunc(sfactor, dfactor);
+}
+imports["webglBufferData"] = function(target, size, data, usage) {
+ let dataslice = memory.subarray(data, data + size);
+ gl.bufferData(target, dataslice, usage);
+}
+imports["webglClear"] = function(mask) {
+ gl.clear(mask);
+}
+imports["webglClearColor"] = function(red, green, blue, alpha) {
+ gl.clearColor(red, green, blue, alpha);
+}
+imports["webglCompileShader"] = function(shader_id) {
+ let shader = gl_id_map[shader_id];
+ gl.compileShader(shader);
+}
+imports["webglCreateBuffer"] = function() {
+ let buffer = gl.createBuffer();
+ let buffer_id = webgl_id_new(buffer);
+ return buffer_id
+}
+imports["webglCreateProgram"] = function() {
+ let program = gl.createProgram();
+ let program_id = webgl_id_new(program);
+ return program_id;
+}
+imports["webglCreateShader"] = function(type) {
+ let shader = gl.createShader(type);
+ let shader_id = webgl_id_new(shader);
+ return shader_id;
+}
+imports["webglCreateVertexArray"] = function() {
+ let vao = gl.createVertexArray()
+ let vao_id = webgl_id_new(vao);
+ return vao_id
+}
+imports["webglDeleteBuffer"] = function(buffer_id) {
+ let buffer = gl_id_map[buffer_id];
+ gl.deleteBuffer(buffer);
+ webgl_id_remove(buffer_id);
+}
+imports["webglDeleteShader"] = function(shader_id) {
+ let shader = gl_id_map[shader_id];
+ gl.deleteShader(shader);
+ webgl_id_remove(shader_id);
+}
+imports["webglDeleteVertexArray"] = function(vao_id) {
+ let vao = gl_id_map[vao_id];
+ gl.deleteVertexArray(vao);
+ webgl_id_remove(vao_id);
+}
+imports["webglDepthMask"] = function(flag) {
+ gl.depthMask(flag);
+}
+imports["webglDisable"] = function(cap) {
+ gl.disable(cap);
+}
+imports["webglDrawElements"] = function(mode, count, type, offset) {
+ gl.drawElements(mode, count, type, offset);
+}
+imports["webglEnable"] = function(cap) {
+ gl.enable(cap);
+}
+imports["webglEnableVertexAttribArray"] = function(index) {
+ gl.enableVertexAttribArray(index);
+}
+imports["webglGetProgramInfoLog"] = function() {
+}
+imports["webglGetProgramParameter"] = function(program_id, param) {
+ let program = gl_id_map[program_id];
+ return gl.getProgramParameter(program, param);
+}
+imports["webglGetShaderInfoLog"] = function(shader_id, out_buf) {
+ let shader = gl_id_map[shader_id];
+ let info_log = gl.getShaderInfoLog(shader);
+
+ // TODO: remove this once we get sprintf workingk
+ console.log(info_log);
+
+ let arr = memory.subarray(info_log, out_buf + info_log.byteLength);
+ arr.set(new Uint8Array(info_log));
+ return true;
+}
+imports["webglGetShaderParameter"] = function(shader_id, param) {
+ let shader = gl_id_map[shader_id];
+ let result = gl.getShaderParameter(shader, param);
+ return result;
+}
+imports["webglGetUniformLocation"] = function(program_id, name_ptr, name_len) {
+ let program = gl_id_map[program_id];
+ let name = utf8decoder.decode(memory.subarray(name_ptr, name_ptr+name_len));
+ let loc = gl.getUniformLocation(program, name);
+ let location_id = webgl_id_new(loc);
+ return location_id;
+}
+imports["webglLinkProgram"] = function(program_id) {
+ let program = gl_id_map[program_id];
+ gl.linkProgram(program);
+}
+imports["webglShaderSource"] = function(shader_id, source_ptr, source_len) {
+ let shader = gl_id_map[shader_id];
+ let arr = memory.subarray(source_ptr, source_ptr + source_len);
+ let s = utf8decoder.decode(arr);
+ gl.shaderSource(shader, s);
+}
+imports["webglUniform1f"] = function(location_id, value) {
+ let loc = gl_id_map[location_id];
+ gl['uniform1f'](loc, value);
+}
+imports["webglUniform1i"] = function(location_id, value) {
+ let loc = gl_id_map[location_id];
+ gl['uniform1i'](loc, value);
+}
+imports["webglUniform3f"] = function(location_id, x, y, z) {
+ let loc = gl_id_map[location_id];
+ gl['uniform3fv'](loc, [x, y, z]);
+}
+imports["webglUniformMatrix4fv"] = function(location_id, transpose, data) {
+ let loc = gl_id_map[location_id];
+ let dataslice = memory.slice(data, data + 4 * 16);
+ gl.uniformMatrix4fv(loc, transpose, new Float32Array(dataslice.buffer));
+}
+imports["webglUseProgram"] = function(program_id) {
+ let program = gl_id_map[program_id];
+ gl.useProgram(program);
+}
+imports["webglVertexAttribPointer"] = function(index, size, type, normalized, stride, offset) {
+ gl.vertexAttribPointer(index, size, type, normalized, stride, offset);
+}
+imports["webglViewport"] = function(x, y, width, height) {
+ gl.viewport(x, y, width, height);
+}
+imports["js_read_entire_file"] = function(name, name_len, out_buf) {
+ let file_name = utf8decoder.decode(memory.subarray(name, name + name_len))
+ if (file_name == "shader/cube_f.glsl") {
+ var file = files[1];
+ } else if (file_name == "shader/cube_v.glsl") {
+ var file = files[2];
+ } else {
+ return false;
+ }
+ let arr = memory.subarray(out_buf, out_buf + file.byteLength);
+ let s = String.fromCharCode.apply(null, arr);
+ arr.set(new Uint8Array(file));
+ return true;
+}
+imports["js_print"] = function(s, len) {
+ let arr = memory.subarray(s, s + len);
+ console.log(utf8decoder.decode(arr));
+}
+function error_fatal(message) {
+ console.log(message);
+ throw message;
+}
+function webgl_id_new(obj) {
+ if(gl_id_freelist.length == 0) {
+ gl_id_map.push(obj);
+ return gl_id_map.length - 1;
+ } else {
+ let id = gl_id_freelist.shift();
+ gl_id_map[id] = obj;
+ return id;
+ }
+}
+function webgl_id_remove(id) {
+ delete gl_id_map[id];
+ gl_id_freelist.push(id);
+}
+function canvas_resize() {
+ let pr = window.devicePixelRatio;
+ let w = window.innerWidth;
+ let h = window.innerHeight;
+ // Bitwise OR does float truncation
+ let w_pixels = (w * pr) | 0;
+ let h_pixels = (h * pr) | 0;
+ gl.canvas.width = w_pixels;
+ gl.canvas.height = h_pixels
+ exports['window_resize'](w_pixels, h_pixels);
+ console.log("resize: (" + w_pixels + ", " + h_pixels + ")");
+}
+function canvas_render() {
+ exports['render']();
+ window.requestAnimationFrame(canvas_render);
+}
+function file_load(name) {
+ let promise = new Promise((resolve, reject) => {
+ fetch(name).then(resp => {
+ resp.arrayBuffer().then(arr => resolve(arr));
+ });
+ });
+ return promise;
+}
+window.onload = async function() {
+ let ctxopts = {
+ alpha: false,
+ depth: true,
+ stencil: false,
+ antialias: true,
+ preserveDrawingBuffer: false
+ };
+ gl = document.getElementById("webglcanvas").getContext("webgl2", ctxopts);
+ if(!gl) {
+ error_fatal("Your browser does not support WebGL 2.");
+ }
+ files[0] = file_load("binary.wasm");
+ files[1] = file_load("shader/cube_f.glsl");
+ files[2] = file_load("shader/cube_v.glsl");
+ for(var i=0; i<files.length; i++) {
+ files[i] = await files[i];
+ }
+ let binary = files[0];
+ imports['memory'] = new WebAssembly.Memory({'initial':32});
+ memory = new Uint8Array(imports['memory']['buffer']);
+ let program = await WebAssembly.instantiate(binary, {"env":imports});
+ let instance = program['instance'];
+ exports = instance['exports'];
+ canvas_resize();
+ window.addEventListener("resize", canvas_resize);
+ if(!exports['init']()) {
+ error_fatal("Game initialization failed.");
+ }
+ canvas_render();
+}