Skip to content

Commit

Permalink
Work on GLX.
Browse files Browse the repository at this point in the history
  • Loading branch information
mackron committed Mar 14, 2019
1 parent 297a3ea commit 439371f
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 17 deletions.
69 changes: 67 additions & 2 deletions examples/01_Triangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,86 @@
#define GLBIND_IMPLEMENTATION
#include "../glbind.h"

void Render(GLBapi* pGL)
{
pGL->glClearColor(0.2f, 0.5f, 0.8f, 0);
pGL->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

pGL->glBegin(GL_TRIANGLES);
{
pGL->glColor3f(1, 0, 0);
pGL->glVertex2f( 0.0f, +0.5f);
pGL->glColor3f(0, 1, 0);
pGL->glVertex2f(-0.5f, -0.5f);
pGL->glColor3f(0, 0, 1);
pGL->glVertex2f(+0.5f, -0.5f);

}
pGL->glEnd();
}

int main(int argc, char** argv)
{
GLBapi gl;
GLenum result = glbInit(&gl);
GLenum result = glbInit(&gl, NULL);
if (result != GL_NO_ERROR) {
printf("Failed to initialize glbind.\n");
return result;
}

glbBindAPI(&gl); /* Bind the API to global scope. */

/* Create the window and show something on the screen. */
{
#if defined(GLBIND_GLX)
XSetWindowAttributes attr;
Display* pDisplay;
Window windowX11;
XVisualInfo* pVisualInfo = glbGetFBVisualInfo();
Atom g_WM_DELETE_WINDOW = 0;

pDisplay = glbGetDisplay();
pVisualInfo = glbGetFBVisualInfo();
g_WM_DELETE_WINDOW = XInternAtom(pDisplay, "WM_DELETE_WINDOW", False);

attr.colormap = glbGetColormap();
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask | VisibilityChangeMask;

windowX11 = XCreateWindow(pDisplay, XRootWindow(pDisplay, pVisualInfo->screen), 0, 0, 640, 480, 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual, CWColormap | CWEventMask, &attr);
if (windowX11 == 0) {
printf("Failed to create X11 window.\n");
return -1;
}

XSetWMProtocols(pDisplay, windowX11, &g_WM_DELETE_WINDOW, 1);
XStoreName(pDisplay, windowX11, "glbind 01_Triangle");
XMapRaised(pDisplay, windowX11); /* <-- Show the window. */

/* Do stuff. */
gl.glXMakeCurrent(pDisplay, windowX11, glbGetRC());

/* Loop. */
for (;;) {
if (XPending(pDisplay) > 0) {
XEvent x11Event;
XNextEvent(pDisplay, &x11Event);

if (x11Event.type == ClientMessage) {
if ((Atom)x11Event.xclient.data.l[0] == g_WM_DELETE_WINDOW) {
return 0; /* Received a quit message. */
}
};

/* Handle events here. */
} else {
Render(&gl);
gl.glXSwapBuffers(pDisplay, windowX11);
}
}

/* Shutdown. */
XDestroyWindow(pDisplay, windowX11);
#endif
}

glbUninit();

Expand Down
86 changes: 71 additions & 15 deletions source/glbind_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ some program wants to use them.
#define GLAPI extern
#endif



/*<<opengl_main>>*/

/*<<opengl_funcpointers_decl_global>>*/
Expand All @@ -125,6 +127,21 @@ typedef struct
/*<<opengl_funcpointers_decl_global:4>>*/
} GLBapi;

typedef struct
{
GLboolean singleBuffered;
#if defined(GLBIND_WGL)
#endif
#if defined(GLBIND_GLX)
Display* pDisplay;
#endif
} GLBconfig;

/*
Initializes a config object which can later be passed to glbInit() to configure the rendering context that's created by glbInit().
*/
GLBconfig glbConfigInit();

/*
Initializes glbind and attempts to load APIs statically.
Expand All @@ -140,8 +157,12 @@ time this is called it will bind the APIs to global scope.
The internal rendering context can be used like normal. It will be created in double-buffered mode. You can also create your own
context, but you may want to consider calling glbInitContextAPI() or glbInitCurrentContextAPI() after the fact to ensure function
pointers are valid for that context.
You can configure the internal rendering context by specifying a GLBconfig object. This can NULL in which case it will use
defaults. Initialize the config object with glbConfigInit(). The default config creates a context with 32-bit color, 24-bit depth,
8-bit stencil and double-buffered.
*/
GLenum glbInit(GLBapi* pAPI);
GLenum glbInit(GLBapi* pAPI, GLBconfig* pConfig);

/*
Loads context-specific APIs into the specified API object.
Expand Down Expand Up @@ -203,6 +224,16 @@ Display* glbGetDisplay();
Retrieves the rendering context that was created on the first call to glbInit().
*/
GLXContext glbGetRC();

/*
Retrieves the color map that was created on the first call to glbInit().
*/
Colormap glbGetColormap();

/*
Retrieves the framebuffer visual info that was created on the first call to glbInit().
*/
XVisualInfo* glbGetFBVisualInfo();
#endif

#ifdef __cplusplus
Expand All @@ -229,6 +260,16 @@ GLXContext glbGetRC();
typedef void* GLBhandle;
typedef void (* GLBproc)(void);

void glbZeroMemory(void* p, size_t sz)
{
size_t i;
for (i = 0; i < sz; ++i) {
((GLbyte*)p)[i] = 0;
}
}

#define glbZeroObject(p) glbZeroMemory((p), sizeof(*(p)));

GLBhandle glb_dlopen(const char* filename)
{
#ifdef _WIN32
Expand Down Expand Up @@ -357,7 +398,15 @@ GLenum glbLoadOpenGLSO()
return GL_INVALID_OPERATION;
}

GLenum glbInit(GLBapi* pAPI)
GLBconfig glbConfigInit()
{
GLBconfig config;
glbZeroObject(&config);

return config;
}

GLenum glbInit(GLBapi* pAPI, GLBconfig* pConfig)
{
GLenum result;

Expand Down Expand Up @@ -441,7 +490,7 @@ GLenum glbInit(GLBapi* pAPI)
memset(&glbind_PFD, 0, sizeof(glbind_PFD));
glbind_PFD.nSize = sizeof(glbind_PFD);
glbind_PFD.nVersion = 1;
glbind_PFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
glbind_PFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | ((pConfig == NULL || pConfig->singleBuffered == GL_FALSE) ? PFD_DOUBLEBUFFER : 0);
glbind_PFD.iPixelType = PFD_TYPE_RGBA;
glbind_PFD.cStencilBits = 8;
glbind_PFD.cDepthBits = 24;
Expand Down Expand Up @@ -481,16 +530,16 @@ GLenum glbInit(GLBapi* pAPI)
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_STENCIL_SIZE, 8,
None, /* Reserved for GLX_DOUBLEBUFFER */
GLX_DOUBLEBUFFER,
None, None
};

/* TODO: Add support for single buffered context's. */
/*if (!isSingleBuffered) {*/
attribs[13] = GLX_DOUBLEBUFFER;
/*}*/

/* TODO: Add support for an application-defined display. */
if (pConfig != NULL) {
if (!pConfig->singleBuffered) {
attribs[13] = None;
}
}

glbind_OwnsDisplay = GL_TRUE;
glbind_pDisplay = XOpenDisplay(NULL);
if (glbind_pDisplay == NULL) {
Expand Down Expand Up @@ -651,10 +700,7 @@ GLenum glbInitCurrentContextAPI(GLBapi* pAPI)
return GL_INVALID_OPERATION;
}

/* Just to avoid a memset() dependency. I wonder if a good compiler will optimize this... */
for (size_t i = 0; i < sizeof(*pAPI); ++i) {
((GLbyte*)pAPI)[i] = 0;
}
glbZeroObject(pAPI);

/*<<init_current_context_api>>*/

Expand Down Expand Up @@ -745,13 +791,23 @@ PIXELFORMATDESCRIPTOR* glbGetPFD()
#if defined(GLBIND_GLX)
Display* glbGetDisplay()
{
return glbind_Display;
return glbind_pDisplay;
}

GLXContext glbGetRC()
{
return glbind_RC;
}

Colormap glbGetColormap()
{
return glbind_Colormap;
}

XVisualInfo* glbGetFBVisualInfo()
{
return glbind_pFBVisualInfo;
}
#endif

#endif /* GLBIND_IMPLEMENTATION */
Expand Down

0 comments on commit 439371f

Please sign in to comment.