commit 55ffcf3f544c934572873406d9e11a2ed0745318
parent 1c868ff4540e8ba7b8816753045c2360f2438bea
Author: amin <dev@aminmesbah.com>
Date: Sun, 9 Feb 2020 02:25:30 +0000
Load OpenGL functions manually
FossilOrigin-Name: 67d5c161ff59a4dcf6b1c3edd1c0eb220872dade3a8407f5fbdf413dba0b0777
Diffstat:
9 files changed, 218 insertions(+), 35 deletions(-)
diff --git a/Makefile b/Makefile
@@ -12,13 +12,15 @@ LIB_NAME = game.so
DBGDIR = out/debug
DBGEXE = $(DBGDIR)/$(EXE_FILE)
+DBGLIB = $(DBGDIR)/$(LIB_NAME)
+DBGLIBTMP = $(DBGLIB).tmp
DBGCFLAGS = -g -O0
RELDIR = out/release
RELEXE = $(RELDIR)/$(EXE_FILE)
RELLIB = $(RELDIR)/$(LIB_NAME)
RELLIBTMP = $(RELLIB).tmp
-RELCFLAGS = -DPLATFORM_HOTLOAD_GAME_CODE -O2 -Os
+RELCFLAGS = -O2 -Os -DPLATFORM_HOTLOAD_GAME_CODE
DEBUGGER = gdb -q
@@ -28,14 +30,18 @@ default: build_release
all: build_debug build_release
-build_debug: dir_debug
+build_debug: dir_debug build_lib_debug
$(CC) $(CFLAGS) $(DBGCFLAGS) $(SRC) -o $(DBGEXE) $(LDFLAGS)
-build_lib:
+build_lib_debug:
+ $(CC) $(CFLAGS) -fpic -shared $(DBGCFLAGS) $(LIB) -o $(DBGLIBTMP) $(LDFLAGS)
+ mv $(DBGLIBTMP) $(DBGLIB)
+
+build_lib_release:
$(CC) $(CFLAGS) -fpic -shared $(RELCFLAGS) $(LIB) -o $(RELLIBTMP) $(LDFLAGS)
mv $(RELLIBTMP) $(RELLIB)
-build_release: dir_release build_lib
+build_release: dir_release build_lib_release
$(CC) $(CFLAGS) $(RELCFLAGS) $(SRC) -o $(RELEXE) $(LDFLAGS)
clean:
@@ -50,6 +56,9 @@ dir_debug:
dir_release:
@mkdir -p $(RELDIR)
+dump:
+ $(CC) -E $(SRC)
+
memcheck: build_debug
valgrind --track-origins=yes ./$(DBGEXE)
diff --git a/build_wasm.sh b/build_wasm.sh
@@ -25,6 +25,7 @@ clang \
-std=c11 \
-internal-isystem /usr/lib/clang/$clang_version/include \
-internal-externc-isystem /usr/include \
+ -DPLATFORM_WASM \
-DGAME_WEBGL \
-o $wasm_dir/wasm.bc \
src/platform_wasm.c
diff --git a/src/am_gl.c b/src/am_gl.c
@@ -0,0 +1,31 @@
+#include "am_gl.h"
+
+#include <dlfcn.h>
+
+int am_gl_init()
+{
+ char *libgl_name = "libGL.so";
+ void *libgl = dlopen(libgl_name, RTLD_NOW | RTLD_GLOBAL);
+ if (libgl != NULL)
+ {
+
+#define AM_GLE(ret, name, ...) \
+ dlerror(); \
+ name = (name##Proc *) dlsym(libgl, #name); \
+ if (!name) { \
+ printf("Function gl" #name " couldn't be loaded.\n"); \
+ printf("dlerror(): %s\n", dlerror()); \
+ return 0; \
+ }
+ GL_LOAD_FUNCTION_LIST
+#undef AM_GLE
+
+ dlclose(libgl);
+ return 1;
+ }
+ else
+ {
+ printf("Failed to load libgl\n");
+ return 0;
+ }
+}
diff --git a/src/am_gl.h b/src/am_gl.h
@@ -0,0 +1,135 @@
+#if !defined(AM_GL_H)
+#define AM_GL_H
+
+// Thanks to Fabien Giesen [1] and Apoorva Joshi [2] for their succinct
+// examples of how to load OpenGL functions.
+// [1]: https://gist.github.com/rygorous/16796a0c876cf8a5f542caddb55bce8a
+// [2]: http://apoorvaj.io/loading-opengl-without-glew.html
+
+#if !defined(__gl_h_)
+#define __gl_h_
+#else
+#error <GL/gl.h> was already included. This conflicts with that.
+#endif
+
+// GL_VERSION_1_0
+typedef void GLvoid;
+typedef unsigned int GLenum;
+typedef float GLfloat;
+typedef int GLint;
+typedef int GLsizei;
+typedef unsigned int GLbitfield;
+typedef unsigned int GLuint;
+typedef unsigned char GLboolean;
+#define GL_BLEND 0x0BE2
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_FALSE 0
+#define GL_FILL 0x1B02
+#define GL_FLOAT 0x1406
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_LINEAR 0x2601
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_LINES 0x0001
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_RGBA 0x1908
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_SRC_ALPHA 0x0302
+#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_TRIANGLES 0x0004
+#define GL_TRUE 1
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_UNSIGNED_INT 0x1405
+// GL_VERSION_1_1
+#define GL_RGBA8 0x8058
+// GL_VERSION_1_2
+#define GL_CLAMP_TO_EDGE 0x812F
+// GL_VERSION_1_3
+#define GL_TEXTURE0 0x84C0
+// GL_VERSION_1_4
+// GL_VERSION_1_5
+typedef size_t GLsizeiptr;
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_STATIC_DRAW 0x88E4
+// GL_VERSION_2_0
+typedef char GLchar;
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_LINK_STATUS 0x8B82
+#define GL_VERTEX_SHADER 0x8B31
+// GL_VERSION_2_1
+// GL_VERSION_3_0
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+// GL_VERSION_3_1
+// GL_VERSION_3_2
+// GL_VERSION_3_3
+
+// https://www.khronos.org/registry/OpenGL/api/GL/glcorearb.h
+#define GL_LOAD_FUNCTION_LIST \
+ /* GL_VERSION_1_0 */ \
+ AM_GLE(void, glBlendFunc, GLenum sfactor, GLenum dfactor) \
+ AM_GLE(void, glClear, GLbitfield mask) \
+ AM_GLE(void, glClearColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) \
+ AM_GLE(void, glDisable, GLenum cap) \
+ AM_GLE(void, glEnable, GLenum cap) \
+ AM_GLE(void, glPolygonMode, GLenum face, GLenum mode) \
+ AM_GLE(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height) \
+ AM_GLE(void, glTexParameteri, GLenum target, GLenum pname, GLint param) \
+ AM_GLE(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height) \
+ /* GL_VERSION_1_1 */ \
+ AM_GLE(void, glBindTexture, GLenum target, GLuint texture) \
+ AM_GLE(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const void *indices) \
+ AM_GLE(void, glGenTextures, GLsizei n, GLuint *textures) \
+ /* GL_VERSION_1_2 */ \
+ AM_GLE(void, glTexImage3D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) \
+ AM_GLE(void, glTexSubImage3D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) \
+ /* GL_VERSION_1_3 */ \
+ AM_GLE(void, glActiveTexture, GLenum texture) \
+ /* GL_VERSION_1_4 */ \
+ /* GL_VERSION_1_5 */ \
+ AM_GLE(void, glBindBuffer, GLenum target, GLuint buffer) \
+ AM_GLE(void, glBufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) \
+ AM_GLE(void, glDeleteBuffers, GLsizei n, const GLuint *buffers) \
+ AM_GLE(void, glGenBuffers, GLsizei n, GLuint *buffers) \
+ /* GL_VERSION_2_0 */ \
+ AM_GLE(void, glAttachShader, GLuint program, GLuint shader) \
+ AM_GLE(void, glCompileShader, GLuint shader) \
+ AM_GLE(GLuint, glCreateProgram, void) \
+ AM_GLE(GLuint, glCreateShader, GLenum type) \
+ AM_GLE(void, glDeleteShader, GLuint shader) \
+ AM_GLE(void, glEnableVertexAttribArray, GLuint index) \
+ AM_GLE(void, glGetProgramiv, GLuint program, GLenum pname, GLint *params) \
+ AM_GLE(void, glGetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
+ AM_GLE(void, glGetShaderiv, GLuint shader, GLenum pname, GLint *params) \
+ AM_GLE(GLint, glGetUniformLocation, GLuint program, const GLchar *name) \
+ AM_GLE(void, glLinkProgram, GLuint program) \
+ AM_GLE(void, glShaderSource, GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length) \
+ AM_GLE(void, glUniform1f, GLint location, GLfloat v0) \
+ AM_GLE(void, glUniform1i, GLint location, GLint v0) \
+ AM_GLE(void, glUniform3f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
+ AM_GLE(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
+ AM_GLE(void, glUseProgram, GLuint program) \
+ AM_GLE(void, glVertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) \
+ /* GL_VERSION_2_1 */ \
+ /* GL_VERSION_3_0 */ \
+ AM_GLE(void, glBindVertexArray, GLuint array) \
+ AM_GLE(void, glDeleteVertexArrays, GLsizei n, const GLuint *arrays) \
+ AM_GLE(void, glGenerateMipmap, GLenum target) \
+ AM_GLE(void, glGenVertexArrays, GLsizei n, GLuint *arrays) \
+ /* GL_VERSION_3_1 */ \
+ /* GL_VERSION_3_2 */ \
+ /* GL_VERSION_3_3 */
+
+
+#define AM_GLE(ret, name, ...) \
+ typedef ret name##Proc(__VA_ARGS__); \
+ static name##Proc * name;
+ GL_LOAD_FUNCTION_LIST
+#undef AM_GLE
+
+int am_gl_init();
+
+#endif // AM_GL_H
diff --git a/src/game.c b/src/game.c
@@ -1,7 +1,9 @@
#include "game.h"
-#ifndef GAME_WEBGL
+#if defined(PLATFORM_WINDOWS)
#include "glad.c"
+#elif defined(PLATFORM_LINUX)
+#include "am_gl.c"
#endif
#include "shader.c"
@@ -219,6 +221,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
game_state->renderer.projection = math_projection_ortho(0.0f, framebuffer.width, 0.0f, framebuffer.height, -1.0f, 0.0f);
}
+
glEnable(GL_SCISSOR_TEST);
glScissor(
viewport.min.x,
@@ -394,7 +397,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
break;
}
- move_mode_print(player->move_mode);
+ //move_mode_print(player->move_mode);
// simulate movement mode
switch(player->move_mode)
@@ -484,10 +487,10 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
break;
}
- printf("v: ");
- math_print(player->velocity);
- printf("a: ");
- math_print(player->acceleration);
+ //printf("v: ");
+ //math_print(player->velocity);
+ //printf("a: ");
+ //math_print(player->acceleration);
// game_detect_collisions
{
@@ -714,6 +717,8 @@ internal void game_cleanup(struct GameMemory *game_memory)
#ifdef PLATFORM_HOTLOAD_GAME_CODE
void game_load_opengl_symbols(void)
{
- gladLoadGL();
+#if defined(PLATFORM_LINUX)
+ am_gl_init();
+#endif
}
#endif
diff --git a/src/game.h b/src/game.h
@@ -13,11 +13,14 @@
// TODO: only include this in the non-wasm builds
#include <math.h>
-#ifndef GAME_WEBGL
+#include "platform_info.h"
+
+#if !defined(PLATFORM_WASM)
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#else
// TODO: organize this stuff
@@ -65,12 +68,15 @@ void *memmove(void *dst, const void *src, size_t n)
{
return memcpy(dst, src, n);
}
-#endif // GAME_WEBGL
-#ifdef GAME_WEBGL
+#endif // PLATFORM_WASM
+
+#if defined(PLATFORM_WASM)
#include "webgl.h"
-#else
+#elif defined(PLATFORM_WINDOWS)
#include "glad/glad.h"
+#elif defined(PLATFORM_LINUX)
+#include "am_gl.h"
#endif
#include "types.h"
diff --git a/src/platform_info.h b/src/platform_info.h
@@ -0,0 +1,8 @@
+#if defined(__linux__)
+#define PLATFORM_LINUX
+#elif defined(__win32)
+#define PLATFORM_WINDOWS
+#elif defined(PLATFORM_WASM)
+#else
+#error "Unsupported platform"
+#endif
diff --git a/src/platform_linux.c b/src/platform_linux.c
@@ -3,7 +3,7 @@
#include <dlfcn.h>
#include <sys/stat.h>
-#include <glad/glad.h>
+#include "am_gl.h"
#include <GLFW/glfw3.h>
#include "game.c"
@@ -46,20 +46,19 @@ int main(void)
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetKeyCallback(window, key_callback);
- if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
- {
- fprintf(stderr, "glad initialization failed\n");
- glfwDestroyWindow(window);
- glfwTerminate();
- return -1;
- }
-
#ifdef USE_TEST_SEED
srand((uint32_t)0);
#else
srand((uint32_t)time(NULL));
#endif
+ if (!am_gl_init())
+ {
+ fprintf(stderr, "OpenGL function loading failed\n.");
+ glfwTerminate();
+ return -1;
+ }
+
struct GameMemory game_memory = {
.buffer_size = MEBIBYTES(64),
.platform = {
@@ -323,10 +322,3 @@ internal struct GameCode load_game_code(char *source_lib_path)
return game_code;
}
#endif // PLATFORM_HOTLOAD_GAME_CODE
-
-#ifdef GLAD_DEBUG
-internal void pre_gl_callback(const char *func_name, void *func_ptr, int len_args, ...)
-{
- printf("Calling: %s (%d arguments)\n", func_name, len_args);
-}
-#endif
diff --git a/src/platform_linux.h b/src/platform_linux.h
@@ -13,7 +13,3 @@ internal time_t file_get_modified_time(char *file_path);
internal void unload_game_code(struct GameCode *game_code);
internal struct GameCode load_game_code(char *source_lib_path);
#endif
-
-#ifdef GLAD_DEBUG
-internal void pre_gl_callback(const char *func_name, void *func_ptr, int len_args, ...);
-#endif