Among other things, I needed to create two windows and make the main window the parent of the overlay window.
Here’s a sample that was sent to me:
#include <stdio.h>
#include <GL/glx.h>
#include <X11/keysym.h>
#define SIZE 300
Display* display;
GLXContext mainContext, overlayContext;
Window mainWindow, overlayWindow;
static int mainAttrs[] = {GLX_RGBA, GLX_DOUBLEBUFFER, None};
static int overlayAttrs[] = {GLX_RGBA,GLX_DOUBLEBUFFER, GLX_LEVEL,1,None};
static int resizeWindow = 0;
static int curWidth;
static int curHeight;
void FatalError(char* msg)
{
fprintf(stderr,"Error: %s
",msg);
exit(1);
}
void InitOpenGL()
{
glClearColor(0.0,0.0,0.0,0.0);
glClearColor(0.0,0.0,0.0,0.0);
glViewport(0,0,SIZE,SIZE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0,1.0,-1.0,1.0,1.0,10.0);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0,0.0,-3.0);
curWidth = SIZE;
curHeight = SIZE;
}
void DrawMain()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(0.1f,0.0f,0.0f,1.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0,0.0,0.0);
glVertex2i( 0, 1);
glVertex2i(-1,-1);
glVertex2i( 1,-1);
glEnd();
}
void DrawOverlay()
{
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(-0.2f,0.0f,0.0f,1.0f);
glBegin(GL_QUADS);
glColor3f(0.0,1.0,0.0);
glVertex2f( 0.75, 0.75);
glVertex2f(-0.75, 0.75);
glVertex2f(-0.75,-0.75);
glVertex2f( 0.75,-0.75);
glEnd();
}
int main(int argc, char** argv)
{
XVisualInfo *mainVisual, *overlayVisual;
XSetWindowAttributes mainWindowAttrs,overlayWindowAttrs;
int dummy;
XEvent event;
int redrawMain = 0;
int redrawOverlay = 0;
int animate = 0;
char charBuf[100];
KeySym keySym;
float aspect;
/* Open connection to server */
display = XOpenDisplay(NULL);
if (display == NULL)
FatalError(“Could not open display”);
/* Make sure GLX extension is supported */
if (!glXQueryExtension(display,&dummy,&dummy))
FatalError(“X Server has no OpenGL GLX extension”);
/********* Setup for main window *******/
/ Find a visual for the main window */
mainVisual = glXChooseVisual(display,DefaultScreen(display),mainAttrs);
if (mainVisual == NULL)
FatalError("Could not find suitable RGB visual
");
/* Create a GLX context for main window */
mainContext = glXCreateContext(display,mainVisual,0,GL_TRUE);
if (mainContext == NULL)
FatalError(“Could not create GL context for main window”);
/* Create a color map for main window */
mainWindowAttrs.colormap = XCreateColormap(display,RootWindow(display,mainVisual->screen),
mainVisual->visual,AllocNone);
mainWindowAttrs.border_pixel = 0;
/* Want to handle Expose, resize and key press events in main window */
mainWindowAttrs.event_mask = ExposureMask | StructureNotifyMask;
mainWindow = XCreateWindow(display,RootWindow(display,mainVisual->screen),0,0,SIZE,SIZE,0,
mainVisual->depth, InputOutput, mainVisual->visual,
CWBorderPixel | CWColormap | CWEventMask,&mainWindowAttrs);
/******** Setup for overlay window ******/
/ Find a visual */
overlayVisual = glXChooseVisual(display,DefaultScreen(display),overlayAttrs);
if (overlayVisual == NULL)
FatalError(“Could not find suitable overlay visual”);
overlayContext = glXCreateContext(display,overlayVisual,0,GL_TRUE);
if (overlayContext == NULL)
FatalError(“Could not create GL context for overlay window”);
overlayWindowAttrs.colormap = XCreateColormap(display,RootWindow(display,overlayVisual->screen),
overlayVisual->visual,AllocNone);
overlayWindowAttrs.border_pixel = 0;
overlayWindowAttrs.event_mask = ExposureMask | KeyPressMask;
overlayWindow = XCreateWindow(display,mainWindow,0,0,SIZE,SIZE,0,overlayVisual->depth,
InputOutput,overlayVisual->visual,
CWBorderPixel | CWColormap | CWEventMask, &overlayWindowAttrs);
/******* Map windows to display ******/
XMapWindow(display,mainWindow);
XMapWindow(display,overlayWindow);
/******* OpenGL initialization for both windows ******/
glXMakeCurrent(display,mainWindow,mainContext);
InitOpenGL();
glXMakeCurrent(display,overlayWindow,overlayContext);
InitOpenGL();
glXMakeCurrent(display,mainWindow,mainContext);
/***** Main Event Loop *****/
while (1)
{
while(XPending(display))
{
XNextEvent(display,&event);
switch (event.type)
{
case Expose:
redrawMain = 1;
redrawOverlay = 1;
break;
case ConfigureNotify:
curWidth = event.xconfigure.width;
curHeight = event.xconfigure.height;
resizeWindow = 1;
break;
case KeyPress:
XLookupString(&event.xkey,charBuf,sizeof(charBuf),&keySym,NULL);
switch(keySym)
{
case XK_Escape:
exit(1);
break;
case XK_space:
animate = !animate;
break;
default:
break;
}
break;
default:
break;
}
}
if (redrawOverlay | | animate)
{
glXMakeCurrent(display,overlayWindow,overlayContext);
DrawOverlay();
redrawOverlay = 0;
glXSwapBuffers(display,overlayWindow);
}
if (redrawMain)
{
glXMakeCurrent(display,mainWindow,mainContext);
DrawMain();
redrawMain = 0;
glXSwapBuffers(display,mainWindow);
}
if (resizeWindow)
{
XResizeWindow(display,overlayWindow, curWidth, curHeight);
glXMakeCurrent(display,mainWindow,mainContext);
glViewport(0,0,curWidth,curHeight);
glXMakeCurrent(display,overlayWindow,overlayContext);
glViewport(0,0,curWidth,curHeight);
resizeWindow = 0;
}
}
}