transparent-cube

Minimal cross-platform native/wasm graphics example.
git clone git://git.amin.space/transparent-cube.git
Log | Files | Refs | README | LICENSE

commit 1b54f1a17a33c3dea23c5b6e33a6d00b251fb7e2
parent 36ebce33510b345490321342531677bba01f29ff
Author: amin <dev@aminmesbah.com>
Date:   Mon,  5 Feb 2024 07:41:40 +0000

Fix wasm builds

- Get rid of bare `inline`, which has a very esoteric purpose in C, and anyway
  was breaking nonoptimized builds.
- Get rid of `inline` altogether. Compilers do their own thing anyway.
- Invoke clang's public API, not the private one that breaks.
- Don't depend on math.h (how did that ever work!?)

FossilOrigin-Name: dbc8a3e3370f2feeadc8fe5920f5dfeab38423d521b4f285a14e5d1507698ab2
Diffstat:
MMakefile | 2+-
Mbuild_wasm.sh | 41+++++++++++++++--------------------------
Msrc/glmth.h | 28++++++++++++++--------------
Msrc/platform_linux.c | 1+
Msrc/webgl.h | 72++++++++++++++++++++++++++++++++++++------------------------------------
5 files changed, 67 insertions(+), 77 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ CC = clang -CFLAGS = -std=c11 -Ilib -Wall -Wextra -Wshadow -Wswitch-enum -Wno-unused-parameter -Wno-missing-braces +CFLAGS = -std=c11 -Ilib -Wall -Wextra -Wshadow -Wswitch-enum -Wno-unused-parameter -Wno-unused-function -Wno-missing-braces LDFLAGS = -ldl -lglfw -lGL SRC_FILES = platform_linux.c diff --git a/build_wasm.sh b/build_wasm.sh @@ -13,30 +13,19 @@ 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 \ - -o $wasm_dir/wasm.bc \ +clang \ + --no-standard-libraries \ + --target=wasm32 \ + -DGAME_WEBGL \ + -O3 \ + -Wall \ + -Wno-unused-function \ + -std=c11 \ + -Wl,--allow-undefined-file=src/platform_wasm_js_symbols.txt \ + -Wl,--export=init \ + -Wl,--export=render \ + -Wl,--export=window_resize \ + -Wl,--import-memory \ + -Wl,--no-entry \ + -o $wasm_dir/binary.wasm \ src/platform_wasm.c - -llvm-link -o $wasm_dir/wasm.bc $wasm_dir/wasm.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=init \ - --export=render \ - --export=window_resize \ - --import-memory - -rm $wasm_dir/*.o -rm $wasm_dir/*.bc diff --git a/src/glmth.h b/src/glmth.h @@ -21,7 +21,7 @@ typedef double f64; #define GLMTH_D_PI_2 1.57079632679489661923f #define GLMTH_D_4_SQ_PI 0.40528473456935108578f -static inline f32 glmth_floorf(f32 x) +static f32 glmth_floorf(f32 x) { f32 result = (f32)((i32)x - (x < 0.0f)); return result; @@ -32,7 +32,7 @@ static inline f32 glmth_floorf(f32 x) // forums: // // https://web.archive.org/web/20080228213915/http://www.devmaster.net/forums/showthread.php?t=5784 -static inline f32 glmth_sinf(f32 x) +static f32 glmth_sinf(f32 x) { // wrap to range [0, 2PI] @@ -73,7 +73,7 @@ static inline f32 glmth_sinf(f32 x) return f; } -static inline f32 glmth_cosf(f32 x) +static f32 glmth_cosf(f32 x) { // wrap to range [0, 2PI] f32 full_circles = glmth_floorf(x / GLMTH_M_2_PI); @@ -118,7 +118,7 @@ static inline f32 glmth_cosf(f32 x) return f; } -static inline f32 glmth_tanf(f32 x) +static f32 glmth_tanf(f32 x) { // TODO: make a proper approximation return glmth_sinf(x)/glmth_cosf(x); @@ -194,7 +194,7 @@ typedef struct f32 E[4][4]; // E[row][column] } m4; -static inline m4 glmth_m4_init_id(void) +static m4 glmth_m4_init_id(void) { m4 m = { 0 }; m.E[0][0] = 1.0f; @@ -204,7 +204,7 @@ static inline m4 glmth_m4_init_id(void) return m; } -static inline void glmth_m4_valueptr(m4 m, f32* out_valueptr) +static void glmth_m4_valueptr(m4 m, f32* out_valueptr) { for (u8 v = 0; v < 16; ++v) { @@ -214,7 +214,7 @@ static inline void glmth_m4_valueptr(m4 m, f32* out_valueptr) } } -static inline m4 glmth_m4m4_m(m4 mat1, m4 mat2) +static m4 glmth_m4m4_m(m4 mat1, m4 mat2) { m4 r = { .E[0][0] = (mat1.E[0][0] * mat2.E[0][0]) + (mat1.E[0][1] * mat2.E[1][0]) + (mat1.E[0][2] * mat2.E[2][0]) + (mat1.E[0][3] * mat2.E[3][0]), @@ -240,18 +240,18 @@ static inline m4 glmth_m4m4_m(m4 mat1, m4 mat2) return r; } -static inline v3 glmth_v3_init(f32 x, f32 y, f32 z) +static v3 glmth_v3_init(f32 x, f32 y, f32 z) { v3 v = { .x = x, .y = y, .z = z }; return v; } -static inline f32 glmth_rad(f32 deg) +static f32 glmth_rad(f32 deg) { return deg * (M_PI / 180.0f); } -static inline m4 glmth_rotate(m4 m, f32 rad, v3 axis) +static m4 glmth_rotate(m4 m, f32 rad, v3 axis) { f32 c = glmth_cosf(rad); f32 s = glmth_sinf(rad); @@ -273,7 +273,7 @@ static inline m4 glmth_rotate(m4 m, f32 rad, v3 axis) return glmth_m4m4_m(m, r); } -static inline m4 glmth_translate(m4 m, v3 v) +static m4 glmth_translate(m4 m, v3 v) { m4 r = glmth_m4_init_id(); r.E[0][3] = v.x; @@ -282,7 +282,7 @@ static inline m4 glmth_translate(m4 m, v3 v) return glmth_m4m4_m(m, r); } -static inline m4 glmth_projection_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far) +static m4 glmth_projection_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far) { // TODO: This assert fails when you minimise the window in Windows. assert(left != right); @@ -314,7 +314,7 @@ static inline m4 glmth_projection_ortho(f32 left, f32 right, f32 bottom, f32 top return r; } -static inline m4 glmth_projection_perspective(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far) +static m4 glmth_projection_perspective(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far) { assert(left != right); assert(bottom != top); @@ -345,7 +345,7 @@ static inline m4 glmth_projection_perspective(f32 left, f32 right, f32 bottom, f return r; } -static inline m4 glmth_projection_perspective_fov(f32 fovy, f32 aspect, f32 near, f32 far) +static m4 glmth_projection_perspective_fov(f32 fovy, f32 aspect, f32 near, f32 far) { f32 half_height = glmth_tanf(fovy / 2.0f) * near; f32 half_width = half_height * aspect; diff --git a/src/platform_linux.c b/src/platform_linux.c @@ -1,4 +1,5 @@ #include <inttypes.h> +#include <stdarg.h> #include <stdint.h> #include <stdio.h> #include <time.h> diff --git a/src/webgl.h b/src/webgl.h @@ -75,7 +75,7 @@ typedef long GLsizeiptr; // TODO: add a version with safety checks #define WEBGL_CAST_I32(x) (i32)(x) -static inline i32 _webgl_strlen(const char *str) +static i32 _webgl_strlen(const char *str) { i32 len = 0; while(str[len] != '\0') @@ -85,107 +85,107 @@ static inline i32 _webgl_strlen(const char *str) return len; } -inline void glAttachShader(GLuint program, GLuint shader) +static void glAttachShader(GLuint program, GLuint shader) { webglAttachShader(WEBGL_CAST_I32(program), WEBGL_CAST_I32(shader)); } -inline void glBindBuffer(GLenum target, GLuint buffer) +static void glBindBuffer(GLenum target, GLuint buffer) { webglBindBuffer(WEBGL_CAST_I32(target), WEBGL_CAST_I32(buffer)); } -inline void glBindVertexArray(GLuint array) +static void glBindVertexArray(GLuint array) { webglBindVertexArray(WEBGL_CAST_I32(array)); } -inline void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +static void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { webglBlendColor((f32)red, (f32)green, (f32)blue, (f32)alpha); } -inline void glBlendFunc(GLenum sfactor, GLenum dfactor) +static void glBlendFunc(GLenum sfactor, GLenum dfactor) { webglBlendFunc(WEBGL_CAST_I32(sfactor), WEBGL_CAST_I32(dfactor)); } -inline void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) +static void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) { webglBufferData(WEBGL_CAST_I32(target), WEBGL_CAST_I32(size), WEBGL_CAST_I32(data), WEBGL_CAST_I32(usage)); } -inline void glClear(GLbitfield mask) +static void glClear(GLbitfield mask) { webglClear(WEBGL_CAST_I32(mask)); } -inline void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +static void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { webglClearColor((f32)red, (f32)green, (f32)blue, (f32)alpha); } -inline void glCompileShader(GLuint shader) +static void glCompileShader(GLuint shader) { webglCompileShader(WEBGL_CAST_I32(shader)); } -inline GLuint glCreateProgram(void) +static GLuint glCreateProgram(void) { i32 program_id = webglCreateProgram(); return (GLuint)program_id; } -inline GLuint glCreateShader(GLenum type) +static GLuint glCreateShader(GLenum type) { return webglCreateShader(WEBGL_CAST_I32(type)); } -inline void glDeleteBuffers(GLsizei n, const GLuint *buffers) +static void glDeleteBuffers(GLsizei n, const GLuint *buffers) { assert(n == 1); i32 the_buffer = WEBGL_CAST_I32(buffers[0]); webglDeleteBuffer(the_buffer); } -inline void glDeleteShader(GLuint shader) +static void glDeleteShader(GLuint shader) { webglDeleteShader(WEBGL_CAST_I32(shader)); } -inline void glDeleteVertexArrays(GLsizei n, const GLuint *arrays) +static void glDeleteVertexArrays(GLsizei n, const GLuint *arrays) { assert(n == 1); i32 the_array = WEBGL_CAST_I32(arrays[0]); webglDeleteVertexArray(the_array); } -inline void glDepthMask(GLboolean flag) +static void glDepthMask(GLboolean flag) { webglDepthMask(WEBGL_CAST_I32(flag)); } -inline void glDisable(GLenum cap) +static void glDisable(GLenum cap) { webglDisable(WEBGL_CAST_I32(cap)); } -inline void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) +static void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) { webglDrawElements(WEBGL_CAST_I32(mode), WEBGL_CAST_I32(count), WEBGL_CAST_I32(type), WEBGL_CAST_I32(indices)); } -inline void glEnable(GLenum cap) +static void glEnable(GLenum cap) { webglEnable(WEBGL_CAST_I32(cap)); } -inline void glEnableVertexAttribArray(GLuint index) +static void glEnableVertexAttribArray(GLuint index) { webglEnableVertexAttribArray(WEBGL_CAST_I32(index)); } -inline void glGenBuffers(GLsizei n, GLuint *buffers) +static void glGenBuffers(GLsizei n, GLuint *buffers) { assert(n == 1); i32 buffer_id = webglCreateBuffer(); @@ -193,7 +193,7 @@ inline void glGenBuffers(GLsizei n, GLuint *buffers) *buffers = (GLuint)buffer_id; } -inline void glGenVertexArrays(GLsizei n, GLuint *arrays) +static void glGenVertexArrays(GLsizei n, GLuint *arrays) { assert(n == 1); i32 vao_id = webglCreateVertexArray(); @@ -201,76 +201,76 @@ inline void glGenVertexArrays(GLsizei n, GLuint *arrays) *arrays = (GLuint)vao_id; } -inline void glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) +static void glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { // TODO: implement //webglGetProgramInfoLog(WEBGL_CAST_I32(program), WEBGL_CAST_I32(bufsize), WEBGL_CAST_I32(*length), WEBGL_CAST_I32(*infoLog)); } -inline void glGetProgramiv(GLuint program, GLenum pname, GLint *params) +static void glGetProgramiv(GLuint program, GLenum pname, GLint *params) { *params = webglGetProgramParameter(WEBGL_CAST_I32(program), WEBGL_CAST_I32(pname)); } -inline void glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) +static void glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { webglGetShaderInfoLog(WEBGL_CAST_I32(shader), infoLog); } -inline void glGetShaderiv(GLuint shader, GLenum pname, GLint *params) +static void glGetShaderiv(GLuint shader, GLenum pname, GLint *params) { *params = webglGetShaderParameter(WEBGL_CAST_I32(shader), WEBGL_CAST_I32(pname)); } -inline GLint glGetUniformLocation(GLuint program, const GLchar *name) +static GLint glGetUniformLocation(GLuint program, const GLchar *name) { i32 name_len = _webgl_strlen(name); return webglGetUniformLocation(WEBGL_CAST_I32(program), name, name_len); } -inline void glLinkProgram(GLuint program) +static void glLinkProgram(GLuint program) { webglLinkProgram(WEBGL_CAST_I32(program)); } -inline void glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length) +static void glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length) { const GLchar *s = (void *)*string; i32 l = _webgl_strlen(s); webglShaderSource(WEBGL_CAST_I32(shader), s, l); } -inline void glUniform1f(GLint location, GLfloat v0) +static void glUniform1f(GLint location, GLfloat v0) { webglUniform1f(WEBGL_CAST_I32(location), (f32)v0); } -inline void glUniform1i(GLint location, GLint v0) +static void glUniform1i(GLint location, GLint v0) { webglUniform1i(WEBGL_CAST_I32(location), WEBGL_CAST_I32(v0)); } -inline void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +static void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { webglUniform3f(WEBGL_CAST_I32(location), (f32)v0, (f32)v1, (f32)v2); } -inline void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +static void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { webglUniformMatrix4fv(WEBGL_CAST_I32(location), WEBGL_CAST_I32(transpose), value); } -inline void glUseProgram(GLuint program) +static void glUseProgram(GLuint program) { webglUseProgram(WEBGL_CAST_I32(program)); } -inline void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) +static void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) { webglVertexAttribPointer(WEBGL_CAST_I32(index), WEBGL_CAST_I32(size), WEBGL_CAST_I32(type), WEBGL_CAST_I32(normalized), WEBGL_CAST_I32(stride), WEBGL_CAST_I32(pointer)); } -inline void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) +static void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { webglViewport(x, y, WEBGL_CAST_I32(width), WEBGL_CAST_I32(height)); }