Files
milsko/src/opengl.c
NishiOwO cb46c5ba34 menu buttons
git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@106 b9cfdab3-6d41-4d17-bbe4-086880011989
2025-10-01 16:28:48 +00:00

170 lines
4.7 KiB
C

/* $Id$ */
#include <Mw/Milsko.h>
#include <Mw/OpenGL.h>
#ifdef _WIN32
/* nothing */
#else
#include <GL/glx.h>
#endif
#include <GL/gl.h>
#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
static void create(MwWidget handle) {
opengl_t* o = malloc(sizeof(*o));
#ifdef _WIN32
PIXELFORMATDESCRIPTOR pfd;
int pf;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.cDepthBits = 32;
pfd.cColorBits = 32;
o->dc = GetDC(handle->lowlevel->hWnd);
pf = ChoosePixelFormat(o->dc, &pfd);
SetPixelFormat(o->dc, pf, &pfd);
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];
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;
attribs[2] = GLX_DEPTH_SIZE;
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 = 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;
MwSetDefault(handle);
}
static void destroy(MwWidget handle) {
opengl_t* o = (opengl_t*)handle->internal;
#ifdef _WIN32
o->wglMakeCurrent(NULL, NULL);
DeleteDC(o->dc);
o->wglDeleteContext(o->gl);
FreeLibrary(o->lib);
#else
o->glXMakeCurrent(handle->lowlevel->display, None, NULL);
o->glXDestroyContext(handle->lowlevel->display, o->gl);
dlclose(o->lib);
#endif
free(o);
}
MwClassRec MwOpenGLClassRec = {
create, /* create */
destroy, /* destroy */
NULL, /* draw */
NULL, /* click */
NULL /* parent_resize */
};
MwClass MwOpenGLClass = &MwOpenGLClassRec;
void MwOpenGLMakeCurrent(MwWidget handle) {
opengl_t* o = (opengl_t*)handle->internal;
#ifdef _WIN32
o->wglMakeCurrent(o->dc, o->gl);
#else
o->glXMakeCurrent(handle->lowlevel->display, handle->lowlevel->window, o->gl);
#endif
}
void MwOpenGLSwapBuffer(MwWidget handle) {
opengl_t* o = (opengl_t*)handle->internal;
#ifdef _WIN32
SwapBuffers(o->dc);
#else
(void)o;
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 o->wglGetProcAddress(name);
#else
(void)handle;
return o->glXGetProcAddress((const GLubyte*)name);
#endif
}