a-game

2D platformer written from scratch.
git clone git://git.amin.space/a-game.git
Log | Files | Refs | README | LICENSE

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:
MMakefile | 17+++++++++++++----
Mbuild_wasm.sh | 1+
Asrc/am_gl.c | 31+++++++++++++++++++++++++++++++
Asrc/am_gl.h | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/game.c | 19++++++++++++-------
Msrc/game.h | 14++++++++++----
Asrc/platform_info.h | 8++++++++
Msrc/platform_linux.c | 24++++++++----------------
Msrc/platform_linux.h | 4----
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