commit 45d442fea9b43b5915264741259f95482c903d7a
parent 8246212e7d5347ce89650b53576cdbdd4a120aff
Author: amin <dev@aminmesbah.com>
Date: Sun, 7 Jul 2019 01:59:12 +0000
Mostly fix wasm platform layer
It just expects the texture image to be RGBA, not BGRA.
FossilOrigin-Name: 8a0eb6e17015af74537f89f648facd72eb43f54d3c7e68503ea24c1c4036249c
Diffstat:
6 files changed, 111 insertions(+), 8 deletions(-)
diff --git a/build_wasm.sh b/build_wasm.sh
@@ -12,6 +12,7 @@ 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
+cp -r assets/ $wasm_dir
clang \
-cc1 \
diff --git a/src/platform_wasm.c b/src/platform_wasm.c
@@ -30,7 +30,8 @@ global_variable struct GameInput game_input = {0};
global_variable i32 g_width = PLATFORM_SCR_WIDTH;
global_variable i32 g_height = PLATFORM_SCR_HEIGHT;
// TODO: replace with allocator
-global_variable char g_mem_buffer[1000] = {0};
+// NOTE: If this buffer is too small, the browser will freeze up
+global_variable u8 g_mem_buffer[10000] = {0};
global_variable i32 g_mem_buffer_i = 0;
global_variable u32 previous_time = 0;
@@ -120,9 +121,10 @@ PLATFORM_READ_ENTIRE_FILE(wasm_read_entire_file)
{
g_mem_buffer_i++;
u8 *buf = &g_mem_buffer[g_mem_buffer_i];
- if(js_read_entire_file((i32)file_path, str_length(file_path), buf))
+ i32 file_data_length = js_read_entire_file((i32)file_path, str_length(file_path), buf);
+ if(file_data_length)
{
- i32 file_data_length = str_length(buf);
+ *out_num_bytes = file_data_length;
g_mem_buffer_i += file_data_length;
g_mem_buffer[g_mem_buffer_i] = '\0';
wasm_print("Succeeded in reading file.");
diff --git a/src/platform_wasm.h b/src/platform_wasm.h
@@ -5,5 +5,5 @@ PLATFORM_READ_ENTIRE_FILE(wasm_read_entire_file);
PLATFORM_MEMORY_FREE(wasm_memory_free);
// Functions implemented in the JS loader
-char *js_read_entire_file(i32 file_path, i32 name_len, char *file_data);
-int js_print(i32 string, i32 len);
+i32 js_read_entire_file(i32 file_path, i32 name_len, u8 *file_data);
+i32 js_print(i32 string, i32 len);
diff --git a/src/platform_wasm_js_symbols.txt b/src/platform_wasm_js_symbols.txt
@@ -1,6 +1,8 @@
+webglActiveTexture
webglAttachShader
webglBindBuffer
webglBindVertexArray
+webglBindTexture
webglBlendColor
webglBlendFunc
webglBufferData
@@ -10,6 +12,7 @@ webglCompileShader
webglCreateBuffer
webglCreateProgram
webglCreateShader
+webglCreateTexture
webglCreateVertexArray
webglDeleteBuffer
webglDeleteShader
@@ -19,6 +22,7 @@ webglDisable
webglDrawElements
webglEnable
webglEnableVertexAttribArray
+webglGenerateMipmap
webglGetProgramInfoLog
webglGetProgramParameter
webglGetShaderInfoLog
@@ -26,6 +30,8 @@ webglGetShaderParameter
webglGetUniformLocation
webglLinkProgram
webglShaderSource
+webglTexImage2D
+webglTexParameteri
webglUniform1f
webglUniform1i
webglUniform3f
diff --git a/src/platform_wasm_loader.js b/src/platform_wasm_loader.js
@@ -1,3 +1,4 @@
+'use strict';
let utf8decoder = new TextDecoder("utf-8");
let memory = null;
let exports = {};
@@ -20,6 +21,9 @@ const key_numeric_codes = {
KeyS: 4,
F11: 5,
};
+imports["webglActiveTexture"] = function(texture) {
+ gl.activeTexture(texture);
+}
imports["webglAttachShader"] = function(program_id, shader_id) {
let program = gl_id_map[program_id];
let shader = gl_id_map[shader_id];
@@ -29,6 +33,10 @@ imports["webglBindBuffer"] = function(target, buffer_id) {
let buffer = gl_id_map[buffer_id];
gl.bindBuffer(target, buffer);
}
+imports["webglBindTexture"] = function(target, texture_id) {
+ let texture = gl_id_map[texture_id];
+ gl.bindTexture(target, texture);
+}
imports["webglBindVertexArray"] = function(vao_id) {
let vao = gl_id_map[vao_id];
gl.bindVertexArray(vao);
@@ -68,6 +76,11 @@ imports["webglCreateShader"] = function(type) {
let shader_id = webgl_id_new(shader);
return shader_id;
}
+imports["webglCreateTexture"] = function(type) {
+ let texture = gl.createTexture();
+ let texture_id = webgl_id_new(texture);
+ return texture_id;
+}
imports["webglCreateVertexArray"] = function() {
let vao = gl.createVertexArray()
let vao_id = webgl_id_new(vao);
@@ -103,6 +116,9 @@ imports["webglEnable"] = function(cap) {
imports["webglEnableVertexAttribArray"] = function(index) {
gl.enableVertexAttribArray(index);
}
+imports["webglGenerateMipmap"] = function(target) {
+ gl.generateMipmap(target);
+}
imports["webglGetProgramInfoLog"] = function() {
}
imports["webglGetProgramParameter"] = function(program_id, param) {
@@ -142,6 +158,14 @@ imports["webglShaderSource"] = function(shader_id, source_ptr, source_len) {
let s = utf8decoder.decode(arr);
gl.shaderSource(shader, s);
}
+imports["webglTexImage2D"] = function(target, level, internalformat, width, height, border, format, type, pixels) {
+ const bytes_per_pixel = 4;
+ let dataslice = memory.subarray(pixels, pixels + (width * height * bytes_per_pixel));
+ gl.texImage2D(target, level, internalformat, width, height, border, format, type, dataslice);
+}
+imports["webglTexParameteri"] = function(target, pname, param) {
+ gl.texParameteri(target, pname, param);
+}
imports["webglUniform1f"] = function(location_id, value) {
let loc = gl_id_map[location_id];
gl['uniform1f'](loc, value);
@@ -169,19 +193,23 @@ imports["webglVertexAttribPointer"] = function(index, size, type, normalized, st
imports["webglViewport"] = function(x, y, width, height) {
gl.viewport(x, y, width, height);
}
-imports["js_read_entire_file"] = function(name, name_len, out_buf) {
+imports["js_read_entire_file"] = function(name, name_len, out_buf, out_len) {
let file_name = utf8decoder.decode(memory.subarray(name, name + name_len))
+ let file_size = 0;
if (file_name == "shader/main_f.glsl") {
var file = files[1];
} else if (file_name == "shader/main_v.glsl") {
var file = files[2];
+ } else if (file_name == "assets/tile0.tga") {
+ var file = files[3];
} else {
- return false;
+ return 0;
}
let arr = memory.subarray(out_buf, out_buf + file.byteLength);
+ file_size = arr.length * arr.BYTES_PER_ELEMENT;
let s = String.fromCharCode.apply(null, arr);
arr.set(new Uint8Array(file));
- return true;
+ return file_size;
}
imports["js_print"] = function(s, len) {
let arr = memory.subarray(s, s + len);
@@ -251,6 +279,7 @@ window.onload = async function() {
files[0] = file_load("binary.wasm");
files[1] = file_load("shader/main_f.glsl");
files[2] = file_load("shader/main_v.glsl");
+ files[3] = file_load("assets/tile0.tga");
for(var i = 0; i < files.length; i++) {
files[i] = await files[i];
}
diff --git a/src/webgl.h b/src/webgl.h
@@ -6,8 +6,10 @@ typedef double f64;
// NOTE(amin): Since these functions will be implemented in javascript, we can
// only use i32, f32, and f64 params.
+void webglActiveTexture(i32 texture);
void webglAttachShader(i32 program, i32 shader);
void webglBindBuffer(i32 target, i32 buffer);
+void webglBindTexture(i32 target, i32 texture);
void webglBindVertexArray(i32 vao);
void webglBlendColor(f32 r, f32 g, f32 b, f32 a);
void webglBlendFunc(i32 sfactor, i32 dfactor);
@@ -18,6 +20,7 @@ void webglCompileShader(i32 shader);
i32 webglCreateBuffer(void);
i32 webglCreateProgram(void);
i32 webglCreateShader(i32 type);
+i32 webglCreateTexture(void);
i32 webglCreateVertexArray(void);
void webglDeleteBuffer(i32 bo);
void webglDeleteShader(i32 shader);
@@ -27,6 +30,7 @@ void webglDisable(i32 cap);
void webglDrawElements(i32 mode, i32 count, i32 type, i32 offset);
void webglEnable(i32 cap);
void webglEnableVertexAttribArray(i32 index);
+void webglGenerateMipmap(i32 target);
void webglGetProgramInfoLog(void);
int webglGetProgramParameter(i32 program, i32 param);
void webglGetShaderInfoLog(i32 shader, char *out_buf);
@@ -34,6 +38,8 @@ int webglGetShaderParameter(i32 shader, i32 param);
i32 webglGetUniformLocation(i32 program, const char name[static 1], i32 name_len);
void webglLinkProgram(i32 program);
void webglShaderSource(i32 shader, const char source[static 1], i32 source_len);
+void webglTexImage2D(i32 target, i32 level, i32 internalformat, i32 width, i32 height, i32 border, i32 format, i32 type, i32 pixels);
+void webglTexParameteri(i32 target, i32 pname, i32 param);
void webglUniform1f(i32 location, f32 value);
void webglUniform1i(i32 location, i32 value);
void webglUniform3f(i32 location, f32 x, f32 y, f32 z);
@@ -49,13 +55,31 @@ void webglViewport(i32 x, i32 y, i32 width, i32 height);
#define GL_LINES 0x0001
#define GL_TRIANGLES 0x0004
#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_FRONT_AND_BACK 0x0408
#define GL_DEPTH_TEST 0x0B71
#define GL_BLEND 0x0BE2
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_UNSIGNED_BYTE 0x1401
#define GL_UNSIGNED_INT 0x1405
#define GL_FLOAT 0x1406
+#define GL_RGBA 0x1908
#define GL_FILL 0x1B02
+#define GL_LINEAR 0x2601
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
#define GL_CONSTANT_ALPHA 0x8003
+// NOTE(amin): this should normally be: `#define GL_BGRA 0x80E1`, however
+// OpenGL ES 3.0, and consequently WebGL 2.0, doesn't support GL_BGRA, so we
+// resort to this hideous hack just to get things working, along with a texture
+// swizzle in the shader.
+// TODO(amin): fix this in a better way
+#define GL_BGRA GL_RGBA
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_TEXTURE0 0x84C0
#define GL_ARRAY_BUFFER 0x8892
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_STATIC_DRAW 0x88E4
@@ -88,6 +112,11 @@ static inline i32 _webgl_strlen(const char *str)
return len;
}
+void glActiveTexture(GLenum texture)
+{
+ webglActiveTexture(WEBGL_CAST_I32(texture));
+}
+
inline void glAttachShader(GLuint program, GLuint shader)
{
webglAttachShader(WEBGL_CAST_I32(program), WEBGL_CAST_I32(shader));
@@ -98,6 +127,11 @@ inline void glBindBuffer(GLenum target, GLuint buffer)
webglBindBuffer(WEBGL_CAST_I32(target), WEBGL_CAST_I32(buffer));
}
+void glBindTexture(GLenum target, GLuint texture)
+{
+ webglBindTexture(WEBGL_CAST_I32(target), WEBGL_CAST_I32(texture));
+}
+
inline void glBindVertexArray(GLuint array)
{
webglBindVertexArray(WEBGL_CAST_I32(array));
@@ -196,6 +230,18 @@ inline void glGenBuffers(GLsizei n, GLuint *buffers)
*buffers = (GLuint)buffer_id;
}
+void glGenerateMipmap(GLenum target)
+{
+ webglGenerateMipmap(WEBGL_CAST_I32(target));
+}
+
+void glGenTextures(GLsizei n, GLuint *textures)
+{
+ assert(n == 1);
+ i32 texture_id = webglCreateTexture();
+ *textures = (GLuint)texture_id;
+}
+
inline void glGenVertexArrays(GLsizei n, GLuint *arrays)
{
assert(n == 1);
@@ -248,6 +294,25 @@ inline void glShaderSource(GLuint shader, GLsizei count, const GLchar *const *st
webglShaderSource(WEBGL_CAST_I32(shader), s, l);
}
+void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)
+{
+ webglTexImage2D(
+ WEBGL_CAST_I32(target),
+ WEBGL_CAST_I32(level),
+ WEBGL_CAST_I32(internalformat),
+ WEBGL_CAST_I32(width),
+ WEBGL_CAST_I32(height),
+ WEBGL_CAST_I32(border),
+ WEBGL_CAST_I32(format),
+ WEBGL_CAST_I32(type),
+ WEBGL_CAST_I32(pixels));
+}
+
+void glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ webglTexParameteri(WEBGL_CAST_I32(target), WEBGL_CAST_I32(pname), WEBGL_CAST_I32(param));
+}
+
inline void glUniform1f(GLint location, GLfloat v0)
{
webglUniform1f(WEBGL_CAST_I32(location), (f32)v0);