summaryrefslogtreecommitdiff
path: root/base/opengl_loader.c
diff options
context:
space:
mode:
authorPeter Fors <peter.fors@mindkiller.com>2025-03-29 20:11:56 +0100
committerPeter Fors <peter.fors@mindkiller.com>2025-03-29 20:11:56 +0100
commitd5486a5af100fb37fac08b60d862ac14943853ce (patch)
treee2206f620745ba49c94f0f29d180587e03bc9fda /base/opengl_loader.c
parentee4f15400998ca704c6ad8fc537f0d924930fabd (diff)
add base code for windowing and opengl crt-shader.
Diffstat (limited to 'base/opengl_loader.c')
-rw-r--r--base/opengl_loader.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/base/opengl_loader.c b/base/opengl_loader.c
new file mode 100644
index 0000000..36d2444
--- /dev/null
+++ b/base/opengl_loader.c
@@ -0,0 +1,210 @@
+#ifdef _WIN32
+typedef __int64 GLintptr;
+#else
+typedef intptr_t GLintptr;
+#endif
+typedef void GLvoid;
+typedef unsigned char GLboolean;
+typedef unsigned char GLubyte;
+typedef char GLchar;
+
+typedef int GLint;
+typedef int GLsizei;
+
+typedef unsigned int GLenum;
+typedef unsigned int GLuint;
+typedef unsigned int GLbitfield;
+
+typedef float GLfloat;
+typedef double GLdouble;
+
+typedef unsigned long long GLsizeiptr;
+
+#define GL_NO_ERROR 0
+#define GL_INFO_LOG_LENGTH 0x8b84
+#define GL_ZERO 0x0000
+#define GL_ONE 0x0001
+#define GL_ALPHA 0x1906
+#define GL_BLEND 0x0be2
+#define GL_CLAMP_TO_EDGE 0x812f
+#define GL_COLOR_BUFFER_BIT 0x4000
+#define GL_COMPILE_STATUS 0x8b81
+#define GL_DEPTH_TEST 0x0b71
+#define GL_FRAMEBUFFER_SRGB 0x8db9
+#define GL_FRAGMENT_SHADER 0x8b30
+#define GL_LINK_STATUS 0x8b82
+#define GL_MODELVIEW 0x1700
+#define GL_NEAREST 0x2600
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_PROJECTION 0x1701
+#define GL_QUADS 0x0007
+#define GL_RGBA 0x1908
+#define GL_RGBA8 0x8058
+#define GL_SCISSOR_TEST 0x0c11
+#define GL_SRGB8_ALPHA8 0x8c43
+#define GL_SRC_ALPHA 0x0302
+#define GL_TEXTURE0 0x84c0
+#define GL_TEXTURE_2D 0x0de1
+#define GL_TEXTURE_COORD_ARRAY 0x8078
+#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_UNSIGNED_BYTE 0x1401
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_VERTEX_SHADER 0x8b31
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_STATIC_DRAW 0x88e4
+#define GL_FLOAT 0x1406
+#define GL_FALSE 0
+#define GL_TRUE 1
+#define GL_LINEAR 0x2601
+#define GL_FUNC_ADD 0x8006
+#define GL_CULL_FACE 0x0b44
+#define GL_STREAM_DRAW 0x88e0
+#define GL_WRITE_ONLY 0x88b9
+#define GL_TRIANGLES 0x0004
+#define GL_UNSIGNED_INT 0x1405
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_MULTISAMPLE 0x809d
+#define GL_DYNAMIC_DRAW 0x88e8
+#define GL_RED 0x1903
+#define GL_FRAMEBUFFER_WIDTH 0x9310
+#define GL_FRAMEBUFFER_HEIGHT 0x9311
+#define GL_VIEWPORT 0x0ba2
+#define GL_PIXEL_UNPACK_BUFFER 0x88ec
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88ef
+#define GL_VERTEX_ARRAY_BINDING 0x85b5
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_CURRENT_PROGRAM 0x8b8d
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_SRGB_ALPHA 0x8c43
+#define GL_UNPACK_ROW_LENGTH 0x0cf2
+#define GL_UNPACK_SKIP_PIXELS 0x0cf4
+#define GL_UNPACK_SKIP_ROWS 0x0cf3
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8646
+
+#define DECLARE_GL_FUNCTION(Name, ReturnType, ...) typedef ReturnType (*type_##Name)(__VA_ARGS__);
+#define DECLARE_GLOBAL_FUNCTION(Name, ...) type_##Name Name;
+
+#define GL_FUNCTIONS(X) \
+ X(glActiveTexture, void, GLenum texture) \
+ X(glAttachShader, void, GLuint program, GLuint shader) \
+ X(glBindBuffer, void, GLenum target, GLuint buffer) \
+ X(glBindTexture, void, GLenum target, GLuint texture) \
+ X(glBufferData, void, GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) \
+ X(glClear, void, GLbitfield mask) \
+ X(glClearColor, void, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) \
+ X(glCompileShader, void, GLuint shader) \
+ X(glCreateProgram, GLuint) \
+ X(glCreateShader, GLuint, GLenum type) \
+ X(glDeleteShader, void, GLuint shader) \
+ X(glDrawElements, void, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) \
+ X(glEnableVertexAttribArray, void, GLuint index) \
+ X(glGenBuffers, void, GLsizei n, GLuint *buffers) \
+ X(glGenTextures, void, GLsizei n, GLuint *textures) \
+ X(glGetShaderInfoLog, void, GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog) \
+ X(glGetShaderiv, void, GLuint shader, GLenum pname, GLint *params) \
+ X(glGetUniformLocation, GLint, GLuint program, const GLchar *name) \
+ X(glLinkProgram, void, GLuint program) \
+ X(glShaderSource, void, GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length) \
+ X(glTexImage2D, void, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) \
+ X(glTexParameteri, void, GLenum target, GLenum pname, GLint param) \
+ X(glTexSubImage2D, void, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) \
+ X(glUniform1f, void, GLint location, GLfloat v0) \
+ X(glUniform1i, void, GLint location, GLint v0) \
+ X(glUniform2f, void, GLint location, GLfloat v0, GLfloat v1) \
+ X(glUniform4f, void, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
+ X(glUseProgram, void, GLuint program) \
+ X(glVertexAttribPointer, void, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) \
+ X(glViewport, void, GLint x, GLint y, GLsizei width, GLsizei height) \
+ X(glDeleteProgram, void, GLuint program) \
+ X(glDeleteBuffers, void, GLsizei n, const GLuint *buffers) \
+ X(glDeleteTextures, void, GLsizei n, const GLuint *textures) \
+ X(glEnable, void, GLenum cap) \
+ X(glGenerateMipmap, void, GLenum target) \
+ X(glGetProgramiv, void, GLuint program, GLenum pname, GLint *params) \
+ X(glGetAttribLocation, GLint, GLuint program, const GLchar *name) \
+ X(glDetachShader, void, GLuint program, GLuint shader) \
+ X(glUniformMatrix4fv, void, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
+ X(glMapBuffer, void*, GLenum target, GLenum access) \
+ X(glUnmapBuffer, GLboolean, GLenum target) \
+ X(glBlendEquation, void, GLenum mode) \
+ X(glBlendFunc, void, GLenum sfactor, GLenum dfactor) \
+ X(glDisable, void, GLenum cap) \
+ X(glScissor, void, GLint x, GLint y, GLsizei width, GLsizei height) \
+ X(glTexCoord2f, void, GLfloat s, GLfloat t) \
+ X(glVertex2f, void, GLfloat x, GLfloat y) \
+ X(glGetError, GLenum) \
+ X(glGetProgramInfoLog, void, GLuint program, GLsizei maxLength, GLsizei *length, GLchar *infoLog) \
+ X(glGenVertexArrays, void, GLsizei n, GLuint *arrays) \
+ X(glBindVertexArray, void, GLuint array) \
+ X(glDeleteVertexArrays, void, GLsizei n, const GLuint *arrays) \
+ X(glDrawArrays, void, GLenum mode, GLint first, GLsizei count) \
+ X(glBufferSubData, void, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) \
+ X(glDisableVertexAttribArray, void, GLuint index) \
+ X(glGetIntegerv, void, GLenum pname, GLint *data) \
+ X(glBindAttribLocation, void, GLuint program, GLuint index, const GLchar *name) \
+ X(glGetUniformfv, void, GLuint program, GLint location, GLfloat *params) \
+ X(glPixelStorei, void, GLenum pname, GLint param) \
+ X(glGetVertexAttribiv, void, GLuint index, GLenum pname, GLint *params) \
+ X(glFinish, void)
+
+GL_FUNCTIONS(DECLARE_GL_FUNCTION)
+GL_FUNCTIONS(DECLARE_GLOBAL_FUNCTION)
+
+
+#if defined(_WIN32)
+static void *get_any_gl_address(const char *name) {
+ void *p = (void *)wglGetProcAddress(name);
+ if(!p) {
+ HMODULE module = LoadLibraryA("opengl32.dll");
+ if(module) {
+ p = (void *)GetProcAddress(module, name);
+ }
+ }
+ return p;
+}
+
+#define GetOpenGLFunction(Name, ...) \
+ *(void **)&Name = (void *)get_any_gl_address(#Name); \
+ if(!Name) { \
+ DEBUG_PRINT("Failed to load OpenGL function: %s\n", #Name); \
+ exit(EXIT_FAILURE); \
+ }
+
+#elif defined(__linux__)
+#include <dlfcn.h>
+static void *glXGetProcAddress(const GLubyte *procName) {
+ static void *(*glxGetProcAddress)(const GLubyte *);
+ if(!glxGetProcAddress) {
+ void *libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);
+ if(!libGL) {
+ DEBUG_PRINT("Error: Unable to load libGL.so.1\n");
+ exit(EXIT_FAILURE);
+ }
+ glxGetProcAddress = dlsym(libGL, "glXGetProcAddress");
+ if(!glxGetProcAddress) {
+ DEBUG_PRINT("Error: Unable to find glXGetProcAddress\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+ return glxGetProcAddress(procName);
+}
+
+#define GetOpenGLFunction(Name, ...) \
+ *(void **)&Name = (void *)glXGetProcAddress((const GLubyte *)#Name); \
+ if(!Name) { \
+ DEBUG_PRINT("Failed to load OpenGL function: %s\n", #Name); \
+ exit(EXIT_FAILURE); \
+ }
+#endif
+
+__attribute__((cold, noinline, section(".init_section")))
+static void gl_loader() {
+ GL_FUNCTIONS(GetOpenGLFunction);
+}; \ No newline at end of file