#include "../include/mgl/gl.h" #include #include typedef struct { void **func; const char *name; } dlsym_assign; static void* dlsym_print_fail(void *handle, const char *name, int required) { dlerror(); void *sym = dlsym(handle, name); char *err_str = dlerror(); if(!sym) fprintf(stderr, "mgl %s: dlsym(handle, \"%s\") failed, error: %s\n", required ? "error" : "warning", name, err_str ? err_str : "(null)"); return sym; } int mgl_gl_load(mgl_gl *self) { const char *glx_path = "libGL.so.1"; self->handle = dlopen(glx_path, RTLD_LAZY); if(!self->handle) { fprintf(stderr, "mgl error:dlopen(\"%s\", RTLD_LAZY) failed\n", glx_path); return -1; } dlsym_assign required_dlsym[] = { { (void**)&self->glXCreateNewContext, "glXCreateNewContext" }, { (void**)&self->glXMakeContextCurrent, "glXMakeContextCurrent" }, { (void**)&self->glXDestroyContext, "glXDestroyContext" }, { (void**)&self->glXSwapBuffers, "glXSwapBuffers" }, { (void**)&self->glXChooseFBConfig, "glXChooseFBConfig" }, { (void**)&self->glXGetVisualFromFBConfig, "glXGetVisualFromFBConfig" }, { (void**)&self->glViewport, "glViewport" }, { (void**)&self->glScissor, "glScissor" }, { (void**)&self->glClearColor, "glClearColor" }, { (void**)&self->glClear, "glClear" }, { (void**)&self->glEnable, "glEnable" }, { (void**)&self->glBlendFunc, "glBlendFunc" }, { (void**)&self->glGenTextures, "glGenTextures" }, { (void**)&self->glDeleteTextures, "glDeleteTextures" }, { (void**)&self->glTexImage2D, "glTexImage2D" }, { (void**)&self->glTexSubImage2D, "glTexSubImage2D" }, { (void**)&self->glBindTexture, "glBindTexture" }, { (void**)&self->glTexParameteri, "glTexParameteri" }, { (void**)&self->glHint, "glHint" }, { (void**)&self->glBegin, "glBegin" }, { (void**)&self->glEnd, "glEnd" }, { (void**)&self->glVertex3f, "glVertex3f" }, { (void**)&self->glColor4ub, "glColor4ub" }, { (void**)&self->glTexCoord2f, "glTexCoord2f" }, { (void**)&self->glOrtho, "glOrtho" }, { (void**)&self->glMatrixMode, "glMatrixMode" }, { (void**)&self->glPushMatrix, "glPushMatrix" }, { (void**)&self->glPopMatrix, "glPopMatrix" }, { (void**)&self->glLoadIdentity, "glLoadIdentity" }, { (void**)&self->glLoadMatrixf, "glLoadMatrixf" }, { (void**)&self->glTranslatef, "glTranslatef" }, { (void**)&self->glRotatef, "glRotatef" }, { (void**)&self->glGenBuffers, "glGenBuffers" }, { (void**)&self->glBindBuffer, "glBindBuffer" }, { (void**)&self->glDeleteBuffers, "glDeleteBuffers" }, { (void**)&self->glBufferData, "glBufferData" }, { (void**)&self->glBufferSubData, "glBufferSubData" }, { (void**)&self->glDrawArrays, "glDrawArrays" }, { (void**)&self->glEnableClientState, "glEnableClientState" }, { (void**)&self->glVertexPointer, "glVertexPointer" }, { (void**)&self->glColorPointer, "glColorPointer" }, { (void**)&self->glTexCoordPointer, "glTexCoordPointer" }, { (void**)&self->glCompileShader, "glCompileShader" }, { (void**)&self->glCreateProgram, "glCreateProgram" }, { (void**)&self->glCreateShader, "glCreateShader" }, { (void**)&self->glDeleteProgram, "glDeleteProgram" }, { (void**)&self->glDeleteShader, "glDeleteShader" }, { (void**)&self->glGetShaderiv, "glGetShaderiv" }, { (void**)&self->glGetShaderInfoLog, "glGetShaderInfoLog" }, { (void**)&self->glGetProgramiv, "glGetProgramiv" }, { (void**)&self->glGetProgramInfoLog, "glGetProgramInfoLog" }, { (void**)&self->glLinkProgram, "glLinkProgram" }, { (void**)&self->glShaderSource, "glShaderSource" }, { (void**)&self->glUseProgram, "glUseProgram" }, { (void**)&self->glAttachShader, "glAttachShader" }, { (void**)&self->glGetUniformLocation, "glGetUniformLocation" }, { (void**)&self->glUniform1f, "glUniform1f" }, { (void**)&self->glUniform2f, "glUniform2f" }, { (void**)&self->glGetError, "glGetError" }, { (void**)&self->glGetString, "glGetString" }, { (void**)&self->glGetIntegerv, "glGetIntegerv" }, { (void**)&self->glPixelStorei, "glPixelStorei" }, { (void**)&self->glFlush, "glFlush" }, { (void**)&self->glFinish, "glFinish" }, { NULL, NULL } }; for(int i = 0; required_dlsym[i].func; ++i) { *required_dlsym[i].func = dlsym_print_fail(self->handle, required_dlsym[i].name, 1); if(!*required_dlsym[i].func) { mgl_gl_unload(self); return -1; } } const dlsym_assign optional_dlsym[] = { { (void**)&self->glXSwapIntervalEXT, "glXSwapIntervalEXT" }, { (void**)&self->glXSwapIntervalMESA, "glXGetSwapIntervalMESA" }, { (void**)&self->glXSwapIntervalSGI, "glXSwapIntervalSGI" }, { NULL, NULL } }; for(int i = 0; optional_dlsym[i].func; ++i) { *optional_dlsym[i].func = dlsym_print_fail(self->handle, optional_dlsym[i].name, 0); } return 0; } void mgl_gl_unload(mgl_gl *self) { if(self->handle) { dlclose(self->handle); self->handle = NULL; } }