diff --git a/GNUmakefile b/GNUmakefile index d8eccf0..da50be3 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -64,12 +64,6 @@ EXAMPLES = examples/example$(EXEC) examples/rotate$(EXEC) examples/image$(EXEC) ifeq ($(OPENGL),1) L_OBJS += src/opengl.o EXAMPLES += examples/opengl$(EXEC) - -ifeq ($(UNIX),1) -L_LIBS += -lGL -else ifeq ($(WINDOWS),1) -L_LIBS += -lopengl32 -endif endif ifeq ($(VULKAN),1) diff --git a/include/Mw/MachDep.h b/include/Mw/MachDep.h index c42b984..314b2a7 100644 --- a/include/Mw/MachDep.h +++ b/include/Mw/MachDep.h @@ -19,6 +19,7 @@ #include #include #include +#include #endif #if defined(_MILSKO) && defined(_WIN32) diff --git a/src/gdi.c b/src/gdi.c index 7e695c7..fd85e45 100644 --- a/src/gdi.c +++ b/src/gdi.c @@ -28,11 +28,9 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { u->ll->hDC = hbdc; MwLLDispatch(u->ll, draw); - if(u->ll->copy_buffer) { - dc = BeginPaint(hWnd, &ps); - StretchBlt(dc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hbdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SRCCOPY); - EndPaint(hWnd, &ps); - } + dc = BeginPaint(hWnd, &ps); + StretchBlt(dc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hbdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SRCCOPY); + EndPaint(hWnd, &ps); DeleteDC(hbdc); DeleteObject(hbmp); diff --git a/src/opengl.c b/src/opengl.c index 1976bc8..018cdb4 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -10,14 +10,42 @@ #include #ifdef _WIN32 +typedef HGLRC(WINAPI* MWwglCreateContext)(HDC); +typedef BOOL(WINAPI* MWwglMakeCurrent)(HDC, HGLRC); +typedef PROC(WINAPI* MWwglGetProcAddress)(LPCSTR); +typedef BOOL(WINAPI* MWwglDeleteContext)(HGLRC); + typedef struct opengl { HDC dc; HGLRC gl; + + void* lib; + + MWwglCreateContext wglCreateContext; + MWwglMakeCurrent wglMakeCurrent; + MWwglDeleteContext wglDeleteContext; + MWwglGetProcAddress wglGetProcAddress; } opengl_t; #else +typedef XVisualInfo* (*MWglXChooseVisual)(Display* dpy, int screen, int* attribList); +typedef GLXContext (*MWglXCreateContext)(Display* dpy, XVisualInfo* vis, GLXContext shareList, Bool direct); +typedef void (*MWglXDestroyContext)(Display* dpy, GLXContext ctx); +typedef Bool (*MWglXMakeCurrent)(Display* dpy, GLXDrawable drawable, GLXContext ctx); +typedef void (*MWglXSwapBuffers)(Display* dpy, GLXDrawable drawable); +typedef void* (*MWglXGetProcAddress)(const GLubyte* procname); + typedef struct opengl { XVisualInfo* visual; GLXContext gl; + + void* lib; + + MWglXChooseVisual glXChooseVisual; + MWglXCreateContext glXCreateContext; + MWglXDestroyContext glXDestroyContext; + MWglXMakeCurrent glXMakeCurrent; + MWglXSwapBuffers glXSwapBuffers; + MWglXGetProcAddress glXGetProcAddress; } opengl_t; #endif @@ -39,9 +67,22 @@ static void create(MwWidget handle) { pf = ChoosePixelFormat(o->dc, &pfd); SetPixelFormat(o->dc, pf, &pfd); - o->gl = wglCreateContext(o->dc); + o->lib = LoadLibrary("opengl32.dll"); + + o->wglCreateContext = (MWwglCreateContext)(void*)GetProcAddress(o->lib, "wglCreateContext"); + o->wglMakeCurrent = (MWwglMakeCurrent)(void*)GetProcAddress(o->lib, "wglMakeCurrent"); + o->wglDeleteContext = (MWwglDeleteContext)(void*)GetProcAddress(o->lib, "wglDeleteContext"); + o->wglGetProcAddress = (MWwglGetProcAddress)(void*)GetProcAddress(o->lib, "wglGetProcAddress"); + + o->gl = o->wglCreateContext(o->dc); #else - int attribs[5]; + int attribs[5]; + const char* glpath[] = { + "libGL.so", + "/usr/local/lib/libGL.so", + "/usr/X11R7/lib/libGL.so", + "/usr/pkg/lib/libGL.so"}; + int glincr = 0; attribs[0] = GLX_RGBA; attribs[1] = GLX_DOUBLEBUFFER; @@ -49,9 +90,18 @@ static void create(MwWidget handle) { attribs[3] = 24; attribs[4] = None; + while(glpath[glincr] != NULL && (o->lib = dlopen(glpath[glincr++], RTLD_LAZY)) == NULL); + + o->glXChooseVisual = (MWglXChooseVisual)dlsym(o->lib, "glXChooseVisual"); + o->glXCreateContext = (MWglXCreateContext)dlsym(o->lib, "glXCreateContext"); + o->glXDestroyContext = (MWglXDestroyContext)dlsym(o->lib, "glXDestroyContext"); + o->glXMakeCurrent = (MWglXMakeCurrent)dlsym(o->lib, "glXMakeCurrent"); + o->glXSwapBuffers = (MWglXSwapBuffers)dlsym(o->lib, "glXSwapBuffers"); + o->glXGetProcAddress = (MWglXGetProcAddress)dlsym(o->lib, "glXGetProcAddress"); + /* XXX: fix this */ - o->visual = glXChooseVisual(handle->lowlevel->display, DefaultScreen(handle->lowlevel->display), attribs); - o->gl = glXCreateContext(handle->lowlevel->display, o->visual, NULL, GL_TRUE); + o->visual = o->glXChooseVisual(handle->lowlevel->display, DefaultScreen(handle->lowlevel->display), attribs); + o->gl = o->glXCreateContext(handle->lowlevel->display, o->visual, NULL, GL_TRUE); #endif handle->internal = o; handle->lowlevel->copy_buffer = 0; @@ -62,12 +112,16 @@ static void create(MwWidget handle) { static void destroy(MwWidget handle) { opengl_t* o = (opengl_t*)handle->internal; #ifdef _WIN32 - wglMakeCurrent(NULL, NULL); + o->wglMakeCurrent(NULL, NULL); DeleteDC(o->dc); - wglDeleteContext(o->gl); + o->wglDeleteContext(o->gl); + + FreeLibrary(o->lib); #else - glXMakeCurrent(handle->lowlevel->display, None, NULL); - glXDestroyContext(handle->lowlevel->display, o->gl); + o->glXMakeCurrent(handle->lowlevel->display, None, NULL); + o->glXDestroyContext(handle->lowlevel->display, o->gl); + + dlclose(o->lib); #endif free(o); } @@ -83,9 +137,9 @@ MwClass MwOpenGLClass = &MwOpenGLClassRec; void MwOpenGLMakeCurrent(MwWidget handle) { opengl_t* o = (opengl_t*)handle->internal; #ifdef _WIN32 - wglMakeCurrent(o->dc, o->gl); + o->wglMakeCurrent(o->dc, o->gl); #else - glXMakeCurrent(handle->lowlevel->display, handle->lowlevel->window, o->gl); + o->glXMakeCurrent(handle->lowlevel->display, handle->lowlevel->window, o->gl); #endif } @@ -96,18 +150,19 @@ void MwOpenGLSwapBuffer(MwWidget handle) { #else (void)o; - glXSwapBuffers(handle->lowlevel->display, handle->lowlevel->window); + o->glXSwapBuffers(handle->lowlevel->display, handle->lowlevel->window); #endif } void* MwOpenGLGetProcAddress(MwWidget handle, const char* name) { + opengl_t* o = (opengl_t*)handle->internal; #ifdef _WIN32 (void)handle; - return wglGetProcAddress(name); + return o->wglGetProcAddress(name); #else (void)handle; - return glXGetProcAddress((const GLubyte*)name); + return o->glXGetProcAddress((const GLubyte*)name); #endif } diff --git a/src/vulkan.c b/src/vulkan.c index 0410843..528ce23 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -19,9 +19,6 @@ #include #endif -#ifndef _WIN32 -#include -#endif #include #include "stb_ds.h"