diff options
-rw-r--r-- | progs/xdemos/Makefile | 1 | ||||
-rw-r--r-- | progs/xdemos/overlay.c | 245 |
2 files changed, 246 insertions, 0 deletions
diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile index bff6b71ca4..84122d3b20 100644 --- a/progs/xdemos/Makefile +++ b/progs/xdemos/Makefile @@ -20,6 +20,7 @@ PROGS = glthreads \ glxswapcontrol \ manywin \ offset \ + overlay \ pbinfo \ pbdemo \ wincopy \ diff --git a/progs/xdemos/overlay.c b/progs/xdemos/overlay.c new file mode 100644 index 0000000000..4c425b64d4 --- /dev/null +++ b/progs/xdemos/overlay.c @@ -0,0 +1,245 @@ +/* + * GLX overlay test/demo. + * + * Brian Paul + * 18 July 2005 + */ + +#include <GL/gl.h> +#include <GL/glx.h> +#include <X11/keysym.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +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; +} |