/* * GLX overlay test/demo. * * Brian Paul * 18 July 2005 */ #include #include #include #include #include #include static int WinWidth = 300, WinHeight = 300; static Window NormalWindow = 0; static Window OverlayWindow = 0; static GLXContext NormalContext = 0; static GLXContext OverlayContext = 0; static GLboolean RGBOverlay = GL_FALSE; static GLfloat Angle = 0.0; static void RedrawNormal(Display *dpy) { glXMakeCurrent(dpy, NormalWindow, NormalContext); glViewport(0, 0, WinWidth, WinHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glClearColor(0.5, 0.5, 0.5, 1.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 0.0); glPushMatrix(); glRotatef(Angle, 0, 0, 1); glRectf(-0.8, -0.8, 0.8, 0.8); glPopMatrix(); glXSwapBuffers(dpy, NormalWindow); } static void RedrawOverlay(Display *dpy) { glXMakeCurrent(dpy, OverlayWindow, OverlayContext); glViewport(0, 0, WinWidth, WinHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glClear(GL_COLOR_BUFFER_BIT); if (RGBOverlay) { glColor3f(0.0, 1.0, 1.0); } else { glIndexi(2); } glBegin(GL_LINES); glVertex2f(-1, -1); glVertex2f(1, 1); glVertex2f(1, -1); glVertex2f(-1, 1); glEnd(); glXSwapBuffers(dpy, OverlayWindow); } static Window MakeWindow(Display *dpy, XVisualInfo *visinfo, Window parent, unsigned int width, unsigned int height) { int scrnum; XSetWindowAttributes attr; unsigned long mask; Window root; Window win; scrnum = DefaultScreen(dpy); root = RootWindow(dpy, scrnum); /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, parent, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); return win; } static void MakeNormalWindow(Display *dpy) { int attrib[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; int scrnum; Window root; XVisualInfo *visinfo; scrnum = DefaultScreen(dpy); root = RootWindow(dpy, scrnum); visinfo = glXChooseVisual(dpy, scrnum, attrib); if (!visinfo) { printf("Error: couldn't get an RGB, Double-buffered visual\n"); exit(1); } NormalWindow = MakeWindow(dpy, visinfo, root, WinWidth, WinHeight); assert(NormalWindow); NormalContext = glXCreateContext(dpy, visinfo, NULL, True); assert(NormalContext); } static void MakeOverlayWindow(Display *dpy) { int rgbAttribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_LEVEL, 1, None }; int indexAttribs[] = { /*GLX_RGBA, leave this out */ GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_LEVEL, 1, None }; int scrnum; Window root; XVisualInfo *visinfo; scrnum = DefaultScreen(dpy); root = RootWindow(dpy, scrnum); visinfo = glXChooseVisual(dpy, scrnum, rgbAttribs); if (visinfo) { printf("Found RGB overlay visual 0x%x\n", (int) visinfo->visualid); RGBOverlay = GL_TRUE; } else { visinfo = glXChooseVisual(dpy, scrnum, indexAttribs); if (visinfo) { printf("Found Color Index overlay visual 0x%x\n", (int) visinfo->visualid); /* XXX setup the colormap entries! */ } else { printf("Error: couldn't get an overlay visual!\n"); exit(1); } } OverlayWindow = MakeWindow(dpy, visinfo, NormalWindow, WinWidth, WinHeight); assert(OverlayWindow); OverlayContext = glXCreateContext(dpy, visinfo, NULL, True); assert(OverlayContext); } static void EventLoop(Display *dpy) { XEvent event; while (1) { XNextEvent(dpy, &event); switch (event.type) { case Expose: RedrawNormal(dpy); RedrawOverlay(dpy); break; case ConfigureNotify: WinWidth = event.xconfigure.width; WinHeight = event.xconfigure.height; if (event.xconfigure.window == NormalWindow) XResizeWindow(dpy, OverlayWindow, WinWidth, WinHeight); break; case KeyPress: { char buffer[10]; int r, code; code = XLookupKeysym(&event.xkey, 0); r = XLookupString(&event.xkey, buffer, sizeof(buffer), NULL, NULL); if (buffer[0] == 27) { /* escape */ return; } else if (buffer[0] == ' ') { Angle += 5.0; RedrawNormal(dpy); } } break; default: ; /* nothing */ } } } int main(int argc, char *argv[]) { Display *dpy = XOpenDisplay(NULL); assert(dpy); MakeNormalWindow(dpy); MakeOverlayWindow(dpy); XMapWindow(dpy, NormalWindow); XMapWindow(dpy, OverlayWindow); EventLoop(dpy); glXDestroyContext(dpy, OverlayContext); glXDestroyContext(dpy, NormalContext); XDestroyWindow(dpy, OverlayWindow); XDestroyWindow(dpy, NormalWindow); return 0; }