platform_wasm_loader.js (8109B)
1 let utf8decoder = new TextDecoder("utf-8"); 2 let memory = null; 3 let exports = {}; 4 let imports = {}; 5 let files = []; 6 let gl = null; 7 let gl_id_freelist = []; 8 let gl_id_map = [null]; 9 imports["webglAttachShader"] = function(program_id, shader_id) { 10 let program = gl_id_map[program_id]; 11 let shader = gl_id_map[shader_id]; 12 gl.attachShader(program, shader); 13 } 14 imports["webglBindBuffer"] = function(target, buffer_id) { 15 let buffer = gl_id_map[buffer_id]; 16 gl.bindBuffer(target, buffer); 17 } 18 imports["webglBindVertexArray"] = function(vao_id) { 19 let vao = gl_id_map[vao_id]; 20 gl.bindVertexArray(vao); 21 } 22 imports["webglBlendColor"] = function(red, green, blue, alpha) { 23 gl.blendColor(red, green, blue, alpha); 24 } 25 imports["webglBlendFunc"] = function(sfactor, dfactor) { 26 gl.blendFunc(sfactor, dfactor); 27 } 28 imports["webglBufferData"] = function(target, size, data, usage) { 29 let dataslice = memory.subarray(data, data + size); 30 gl.bufferData(target, dataslice, usage); 31 } 32 imports["webglClear"] = function(mask) { 33 gl.clear(mask); 34 } 35 imports["webglClearColor"] = function(red, green, blue, alpha) { 36 gl.clearColor(red, green, blue, alpha); 37 } 38 imports["webglCompileShader"] = function(shader_id) { 39 let shader = gl_id_map[shader_id]; 40 gl.compileShader(shader); 41 } 42 imports["webglCreateBuffer"] = function() { 43 let buffer = gl.createBuffer(); 44 let buffer_id = webgl_id_new(buffer); 45 return buffer_id 46 } 47 imports["webglCreateProgram"] = function() { 48 let program = gl.createProgram(); 49 let program_id = webgl_id_new(program); 50 return program_id; 51 } 52 imports["webglCreateShader"] = function(type) { 53 let shader = gl.createShader(type); 54 let shader_id = webgl_id_new(shader); 55 return shader_id; 56 } 57 imports["webglCreateVertexArray"] = function() { 58 let vao = gl.createVertexArray() 59 let vao_id = webgl_id_new(vao); 60 return vao_id 61 } 62 imports["webglDeleteBuffer"] = function(buffer_id) { 63 let buffer = gl_id_map[buffer_id]; 64 gl.deleteBuffer(buffer); 65 webgl_id_remove(buffer_id); 66 } 67 imports["webglDeleteShader"] = function(shader_id) { 68 let shader = gl_id_map[shader_id]; 69 gl.deleteShader(shader); 70 webgl_id_remove(shader_id); 71 } 72 imports["webglDeleteVertexArray"] = function(vao_id) { 73 let vao = gl_id_map[vao_id]; 74 gl.deleteVertexArray(vao); 75 webgl_id_remove(vao_id); 76 } 77 imports["webglDepthMask"] = function(flag) { 78 gl.depthMask(flag); 79 } 80 imports["webglDisable"] = function(cap) { 81 gl.disable(cap); 82 } 83 imports["webglDrawElements"] = function(mode, count, type, offset) { 84 gl.drawElements(mode, count, type, offset); 85 } 86 imports["webglEnable"] = function(cap) { 87 gl.enable(cap); 88 } 89 imports["webglEnableVertexAttribArray"] = function(index) { 90 gl.enableVertexAttribArray(index); 91 } 92 imports["webglGetProgramInfoLog"] = function() { 93 } 94 imports["webglGetProgramParameter"] = function(program_id, param) { 95 let program = gl_id_map[program_id]; 96 return gl.getProgramParameter(program, param); 97 } 98 imports["webglGetShaderInfoLog"] = function(shader_id, out_buf) { 99 let shader = gl_id_map[shader_id]; 100 let info_log = gl.getShaderInfoLog(shader); 101 102 // TODO: remove this once we get sprintf workingk 103 console.log(info_log); 104 105 let arr = memory.subarray(info_log, out_buf + info_log.byteLength); 106 arr.set(new Uint8Array(info_log)); 107 return true; 108 } 109 imports["webglGetShaderParameter"] = function(shader_id, param) { 110 let shader = gl_id_map[shader_id]; 111 let result = gl.getShaderParameter(shader, param); 112 return result; 113 } 114 imports["webglGetUniformLocation"] = function(program_id, name_ptr, name_len) { 115 let program = gl_id_map[program_id]; 116 let name = utf8decoder.decode(memory.subarray(name_ptr, name_ptr+name_len)); 117 let loc = gl.getUniformLocation(program, name); 118 let location_id = webgl_id_new(loc); 119 return location_id; 120 } 121 imports["webglLinkProgram"] = function(program_id) { 122 let program = gl_id_map[program_id]; 123 gl.linkProgram(program); 124 } 125 imports["webglShaderSource"] = function(shader_id, source_ptr, source_len) { 126 let shader = gl_id_map[shader_id]; 127 let arr = memory.subarray(source_ptr, source_ptr + source_len); 128 let s = utf8decoder.decode(arr); 129 gl.shaderSource(shader, s); 130 } 131 imports["webglUniform1f"] = function(location_id, value) { 132 let loc = gl_id_map[location_id]; 133 gl['uniform1f'](loc, value); 134 } 135 imports["webglUniform1i"] = function(location_id, value) { 136 let loc = gl_id_map[location_id]; 137 gl['uniform1i'](loc, value); 138 } 139 imports["webglUniform3f"] = function(location_id, x, y, z) { 140 let loc = gl_id_map[location_id]; 141 gl['uniform3fv'](loc, [x, y, z]); 142 } 143 imports["webglUniformMatrix4fv"] = function(location_id, transpose, data) { 144 let loc = gl_id_map[location_id]; 145 let dataslice = memory.slice(data, data + 4 * 16); 146 gl.uniformMatrix4fv(loc, transpose, new Float32Array(dataslice.buffer)); 147 } 148 imports["webglUseProgram"] = function(program_id) { 149 let program = gl_id_map[program_id]; 150 gl.useProgram(program); 151 } 152 imports["webglVertexAttribPointer"] = function(index, size, type, normalized, stride, offset) { 153 gl.vertexAttribPointer(index, size, type, normalized, stride, offset); 154 } 155 imports["webglViewport"] = function(x, y, width, height) { 156 gl.viewport(x, y, width, height); 157 } 158 imports["js_read_entire_file"] = function(name, name_len, out_buf) { 159 let file_name = utf8decoder.decode(memory.subarray(name, name + name_len)) 160 if (file_name == "shader/cube_f.glsl") { 161 var file = files[1]; 162 } else if (file_name == "shader/cube_v.glsl") { 163 var file = files[2]; 164 } else { 165 return false; 166 } 167 let arr = memory.subarray(out_buf, out_buf + file.byteLength); 168 let s = String.fromCharCode.apply(null, arr); 169 arr.set(new Uint8Array(file)); 170 return true; 171 } 172 imports["js_print"] = function(s, len) { 173 let arr = memory.subarray(s, s + len); 174 console.log(utf8decoder.decode(arr)); 175 } 176 function error_fatal(message) { 177 console.log(message); 178 throw message; 179 } 180 function webgl_id_new(obj) { 181 if(gl_id_freelist.length == 0) { 182 gl_id_map.push(obj); 183 return gl_id_map.length - 1; 184 } else { 185 let id = gl_id_freelist.shift(); 186 gl_id_map[id] = obj; 187 return id; 188 } 189 } 190 function webgl_id_remove(id) { 191 delete gl_id_map[id]; 192 gl_id_freelist.push(id); 193 } 194 function canvas_resize() { 195 let pr = window.devicePixelRatio; 196 let w = window.innerWidth; 197 let h = window.innerHeight; 198 // Bitwise OR does float truncation 199 let w_pixels = (w * pr) | 0; 200 let h_pixels = (h * pr) | 0; 201 gl.canvas.width = w_pixels; 202 gl.canvas.height = h_pixels 203 exports['window_resize'](w_pixels, h_pixels); 204 console.log("resize: (" + w_pixels + ", " + h_pixels + ")"); 205 } 206 function canvas_render() { 207 exports['render'](); 208 window.requestAnimationFrame(canvas_render); 209 } 210 function file_load(name) { 211 let promise = new Promise((resolve, reject) => { 212 fetch(name).then(resp => { 213 resp.arrayBuffer().then(arr => resolve(arr)); 214 }); 215 }); 216 return promise; 217 } 218 window.onload = async function() { 219 let ctxopts = { 220 alpha: false, 221 depth: true, 222 stencil: false, 223 antialias: true, 224 preserveDrawingBuffer: false 225 }; 226 gl = document.getElementById("webglcanvas").getContext("webgl2", ctxopts); 227 if(!gl) { 228 error_fatal("Your browser does not support WebGL 2."); 229 } 230 files[0] = file_load("binary.wasm"); 231 files[1] = file_load("shader/cube_f.glsl"); 232 files[2] = file_load("shader/cube_v.glsl"); 233 for(var i=0; i<files.length; i++) { 234 files[i] = await files[i]; 235 } 236 let binary = files[0]; 237 imports['memory'] = new WebAssembly.Memory({'initial':32}); 238 memory = new Uint8Array(imports['memory']['buffer']); 239 let program = await WebAssembly.instantiate(binary, {"env":imports}); 240 let instance = program['instance']; 241 exports = instance['exports']; 242 canvas_resize(); 243 window.addEventListener("resize", canvas_resize); 244 if(!exports['init']()) { 245 error_fatal("Game initialization failed."); 246 } 247 canvas_render(); 248 }