commit e3e6a1a07cfe80b68f2e35f41dc86ab7c08af43b
parent 604c8c44f8d040b28e08dd9256000e3d007eae02
Author: amin <dev@aminmesbah.com>
Date: Mon, 17 Jun 2019 00:36:43 +0000
Narrow down missing deps to cosf and sinf
FossilOrigin-Name: eeba3f0329a5d12a2bf554281e5a699ae36997a97034768788d4c8a4e903e0e1
Diffstat:
8 files changed, 162 insertions(+), 68 deletions(-)
diff --git a/build_wasm.sh b/build_wasm.sh
@@ -3,5 +3,15 @@ clang -cc1 -Ofast -emit-llvm-bc -triple=wasm32-unknown-unknown-unknown-wasm -std
-DGAME_WEBGL \
src/game.c
llvm-link -o wasm.bc src/*.bc
-llc -O3 -filetype=obj wasm.bc -o wasm.o
+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 binary.wasm --strip-all -allow-undefined-file wasm_js_implemented_symbols.txt --import-memory
+
+#clang \
+# --target=wasm32 \
+# -emit-llvm \
+# -fno-builtin \
+# -c \
+# -S \
+# -DGAME_WEBGL \
+# src/game.c
diff --git a/src/game.c b/src/game.c
@@ -6,7 +6,7 @@
#include "shader.c"
-void game_init(struct GameState *game_state, uint32_t screen_width, uint32_t screen_height)
+void game_init(struct GameState *game_state, u32 screen_width, u32 screen_height)
{
// load cube vertex data
{
@@ -64,9 +64,12 @@ void game_init(struct GameState *game_state, uint32_t screen_width, uint32_t scr
struct PlatformApi platform = game_state->platform;
char *v_source = platform.platform_read_entire_file("shader/cube_v.glsl");
char *f_source = platform.platform_read_entire_file("shader/cube_f.glsl");
- struct Shader main_shader = shader_compile(v_source, f_source);
- free(v_source);
- free(f_source);
+ print = platform.platform_print;
+ struct Shader main_shader = {0};
+ // TODO: Check this result
+ shader_compile(v_source, f_source, &main_shader);
+ platform.platform_memory_free(v_source);
+ platform.platform_memory_free(f_source);
game_state->cube_shader = main_shader;
}
@@ -77,7 +80,7 @@ void game_init(struct GameState *game_state, uint32_t screen_width, uint32_t scr
#endif
}
-void game_update_and_render(struct GameState *game_state, float dt, uint32_t screen_width, uint32_t screen_height)
+void game_update_and_render(struct GameState *game_state, float dt, u32 screen_width, u32 screen_height)
{
glDepthMask(GL_TRUE);
glClearColor(0.2f, 0.2f, 0.3f, 1.0f);
diff --git a/src/game.h b/src/game.h
@@ -1,11 +1,33 @@
#pragma once
-#include <assert.h>
-#include <math.h>
-#include <stdbool.h>
+// TODO: Clean up
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#include <stddef.h>
#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
+#define static_assert _Static_assert
+
+static_assert(__has_builtin(__builtin_cosf), "cosf");
+static_assert(__has_builtin(__builtin_sinf), "sinf");
+static_assert(__has_builtin(__builtin_tanf), "tanf");
+static_assert(__has_builtin(__builtin_sqrtf), "sqrtf");
+static_assert(__has_builtin(__builtin_powf), "powf");
+#define cosf __builtin_cosf
+#define sinf __builtin_sinf
+#define tanf __builtin_tanf
+#define sqrtf __builtin_sqrtf
+#define powf __builtin_powf
+
+#define NULL ((void*)0)
+
+// TODO: fix this
+#define assert(x) (void)0
+
+typedef _Bool bool;
+#define true 1
+#define false 0
#ifdef GAME_WEBGL
#include "webgl.h"
@@ -17,5 +39,22 @@
#include "shader.h"
#include "platform.h"
+void *memcpy(void *dst, const void *src, size_t n)
+{
+ u8 *destination = (u8 *)dst;
+ u8 *source = (u8 *)src;
+
+ while (n--) {
+ *destination = *source;
+ destination++;
+ source++;
+ }
+
+ return dst;
+}
+
+// TODO: Consider finding a better way to make this func available
+static platform_print_func* print;
+
void game_init(struct GameState *game_state, u32 screen_width, u32 screen_height);
void game_cleanup(struct GameState *game_state);
diff --git a/src/platform.h b/src/platform.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#define PLATFORM_READ_ENTIRE_FILE(name) char *(name)(char *file_path)
+typedef PLATFORM_READ_ENTIRE_FILE(platform_read_entire_file_func);
+
+#define PLATFORM_PRINT(name) int (name)(const char *format, ...)
+typedef PLATFORM_PRINT(platform_print_func);
+
+#define PLATFORM_MEMORY_FREE(name) void (name)(void *ptr)
+typedef PLATFORM_MEMORY_FREE(platform_memory_free_func);
+
+struct PlatformApi
+{
+ platform_read_entire_file_func* platform_read_entire_file;
+ platform_print_func* platform_print;
+ platform_memory_free_func* platform_memory_free;
+};
+
+struct GameState
+{
+ u32 cube_vao;
+ u32 cube_vbo;
+ u32 cube_ebo;
+ struct Shader cube_shader;
+ struct PlatformApi platform;
+};
+
+#ifdef PLATFORM_HOTLOAD_GAME_CODE
+#include <time.h>
+// We need to call this from the platform layer in order for the game, when
+// built as a shared object library to have access to the OpenGL symbols.
+// https://github.com/Dav1dde/glad/issues/151
+typedef void (game_load_opengl_symbols_func)(void);
+
+typedef void (game_update_and_render_func)(struct GameState *game_state, float dt, u32 screen_width, u32 screen_height);
+
+struct GameCode
+{
+ bool is_valid;
+ void *game_code_library;
+ time_t last_write_time;
+ game_load_opengl_symbols_func *game_load_opengl_symbols;
+ game_update_and_render_func *game_update_and_render;
+};
+#endif // PLATFORM_HOTLOAD_GAME_CODE
diff --git a/src/platform_linux.c b/src/platform_linux.c
@@ -73,6 +73,8 @@ int main(void)
struct GameState game_state = {0};
game_state.platform.platform_read_entire_file = &linux_read_entire_file;
+ game_state.platform.platform_print = &linux_print;
+ game_state.platform.platform_memory_free = &linux_memory_free;
game_init(&game_state, PLATFORM_SCR_WIDTH, PLATFORM_SCR_HEIGHT);
@@ -154,6 +156,20 @@ time_t file_get_modified_time(char *file_path)
return mtime;
}
+PLATFORM_MEMORY_FREE(linux_memory_free)
+{
+ free(ptr);
+}
+
+PLATFORM_PRINT(linux_print)
+{
+ va_list args;
+ va_start(args, format);
+ int num_chars_printed = vprintf(format, args);
+ va_end(args);
+ return num_chars_printed;
+}
+
PLATFORM_READ_ENTIRE_FILE(linux_read_entire_file)
{
FILE *handle = fopen(file_path, "r");
diff --git a/src/platform_linux.h b/src/platform_linux.h
@@ -14,6 +14,8 @@
#define PLATFORM_MS_PER_UPDATE (PLATFORM_SECOND / PLATFORM_UPDATES_PER_SECOND)
PLATFORM_READ_ENTIRE_FILE(linux_read_entire_file);
+PLATFORM_PRINT(linux_print);
+PLATFORM_MEMORY_FREE(linux_memory_free);
#ifdef PLATFORM_HOTLOAD_GAME_CODE
#define PLATFORM_GAME_LIB_PATH "./out/release/game.so"
diff --git a/src/shader.c b/src/shader.c
@@ -1,12 +1,12 @@
-struct Shader shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source)
+bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source, struct Shader *compiled_shader)
{
GLint success;
GLchar info_log[512];
if (!(vertex_shader_source && fragment_shader_source))
{
- printf("Error: One or more shader source files weren't loaded.\n");
- exit(1);
+ print("Error: One or more shader source files weren't loaded.\n");
+ return false;
}
else
{
@@ -17,9 +17,9 @@ struct Shader shader_compile(const GLchar *vertex_shader_source, const GLchar *f
if (!success)
{
glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
- printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n", info_log);
+ print("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n", info_log);
// TODO: handle errors here in a better way
- exit(1);
+ return false;
}
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
@@ -29,134 +29,113 @@ struct Shader shader_compile(const GLchar *vertex_shader_source, const GLchar *f
if (!success)
{
glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
- printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s\n", info_log);
+ print("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s\n", info_log);
// TODO: handle errors here in a better way
- exit(1);
+ return false;
}
- struct Shader s;
- s.program = glCreateProgram();
- glAttachShader(s.program, vertex_shader);
- glAttachShader(s.program, fragment_shader);
- glLinkProgram(s.program);
- glGetProgramiv(s.program, GL_LINK_STATUS, &success);
+ compiled_shader->program = glCreateProgram();
+ glAttachShader(compiled_shader->program, vertex_shader);
+ glAttachShader(compiled_shader->program, fragment_shader);
+ glLinkProgram(compiled_shader->program);
+ glGetProgramiv(compiled_shader->program, GL_LINK_STATUS, &success);
if (!success)
{
- glGetShaderInfoLog(s.program, 512, NULL, info_log);
- printf("ERROR::SHADER::LINKING_FAILED\n %s\n", info_log);
+ glGetShaderInfoLog(compiled_shader->program, 512, NULL, info_log);
+ print("ERROR::SHADER::LINKING_FAILED\n %s\n", info_log);
// TODO: handle errors here in a better way
- exit(1);
+ return false;
}
glDeleteShader(fragment_shader);
glDeleteShader(vertex_shader);
- return s;
+ return true;
}
}
-
-void shader_use(struct Shader *s)
+bool shader_check_pointer(struct Shader *s)
{
if (s)
{
- glUseProgram(s->program);
+ return true;
}
else
{
- printf("Error: invalid Shader pointer\n");
+ print("Error: invalid Shader pointer\n");
+ return false;
+ }
+}
+
+void shader_use(struct Shader *s)
+{
+ if (shader_check_pointer(s))
+ {
+ glUseProgram(s->program);
}
}
void shader_setb(struct Shader *s, char *name, bool value)
{
- if (s)
+ if (shader_check_pointer(s))
{
glUniform1i(glGetUniformLocation(s->program, name), (int)value);
}
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
}
void shader_seti(struct Shader *s, char *name, int value)
{
- if (s)
+ if (shader_check_pointer(s))
{
glUniform1i(glGetUniformLocation(s->program, name), value);
}
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
}
void shader_setf(struct Shader *s, char *name, f32 value)
{
- if (s)
+ if (shader_check_pointer(s))
{
glUniform1f(glGetUniformLocation(s->program, name), value);
}
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
}
void shader_setm4(struct Shader *s, char *name, m4 *mat)
{
- if (s)
+ if (shader_check_pointer(s))
{
f32 valueptr[sizeof(m4)];
glmth_m4_valueptr(*mat, valueptr);
glUniformMatrix4fv(glGetUniformLocation(s->program, name), 1, GL_TRUE, valueptr);
}
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
}
void shader_setf3(struct Shader *s, char *name, f32 x, f32 y, f32 z)
{
- if (s)
+ if (shader_check_pointer(s))
{
glUniform3f(glGetUniformLocation(s->program, name), x, y, z);
}
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
}
void shader_setf3_1(struct Shader *s, char *name, f32 f)
{
- if (s)
+ if (shader_check_pointer(s))
{
shader_setf3(s, name, f, f, f);
}
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
}
void shader_setv3(struct Shader *s, char *name, v3 *v)
{
- if (s)
+ if (shader_check_pointer(s))
{
shader_setf3(s, name, v->x, v->y, v->z);
}
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
}
diff --git a/src/shader.h b/src/shader.h
@@ -3,7 +3,7 @@ struct Shader
u32 program;
};
-struct Shader shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source);
+bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source, struct Shader *compiled_shader);
void shader_use(struct Shader *s);
void shader_setb(struct Shader *s, char *name, bool value);
void shader_seti(struct Shader *s, char *name, int value);