1/* 2 * GLX overlay test/demo. 3 * 4 * Brian Paul 5 * 18 July 2005 6 */ 7 8#include <GL/gl.h> 9#include <GL/glx.h> 10#include <X11/keysym.h> 11#include <assert.h> 12#include <stdio.h> 13#include <stdlib.h> 14 15static int WinWidth = 300, WinHeight = 300; 16static Window NormalWindow = 0; 17static Window OverlayWindow = 0; 18static GLXContext NormalContext = 0; 19static GLXContext OverlayContext = 0; 20static GLboolean RGBOverlay = GL_FALSE; 21static GLfloat Angle = 0.0; 22 23 24static void 25RedrawNormal(Display *dpy) 26{ 27 glXMakeCurrent(dpy, NormalWindow, NormalContext); 28 glViewport(0, 0, WinWidth, WinHeight); 29 glMatrixMode(GL_PROJECTION); 30 glLoadIdentity(); 31 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); 32 glMatrixMode(GL_MODELVIEW); 33 glClearColor(0.5, 0.5, 0.5, 1.0); 34 glClear(GL_COLOR_BUFFER_BIT); 35 glColor3f(1.0, 1.0, 0.0); 36 glPushMatrix(); 37 glRotatef(Angle, 0, 0, 1); 38 glRectf(-0.8, -0.8, 0.8, 0.8); 39 glPopMatrix(); 40 glXSwapBuffers(dpy, NormalWindow); 41} 42 43 44static void 45RedrawOverlay(Display *dpy) 46{ 47 glXMakeCurrent(dpy, OverlayWindow, OverlayContext); 48 glViewport(0, 0, WinWidth, WinHeight); 49 glMatrixMode(GL_PROJECTION); 50 glLoadIdentity(); 51 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); 52 glMatrixMode(GL_MODELVIEW); 53 glClear(GL_COLOR_BUFFER_BIT); 54 if (RGBOverlay) { 55 glColor3f(0.0, 1.0, 1.0); 56 } 57 else { 58 glIndexi(2); 59 } 60 glBegin(GL_LINES); 61 glVertex2f(-1, -1); 62 glVertex2f(1, 1); 63 glVertex2f(1, -1); 64 glVertex2f(-1, 1); 65 glEnd(); 66 glXSwapBuffers(dpy, OverlayWindow); 67} 68 69 70static Window 71MakeWindow(Display *dpy, XVisualInfo *visinfo, Window parent, 72 unsigned int width, unsigned int height) 73{ 74 int scrnum; 75 XSetWindowAttributes attr; 76 unsigned long mask; 77 Window root; 78 Window win; 79 80 scrnum = DefaultScreen(dpy); 81 root = RootWindow(dpy, scrnum); 82 83 /* window attributes */ 84 attr.background_pixel = 0; 85 attr.border_pixel = 0; 86 attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); 87 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; 88 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; 89 90 win = XCreateWindow(dpy, parent, 0, 0, width, height, 91 0, visinfo->depth, InputOutput, 92 visinfo->visual, mask, &attr); 93 return win; 94} 95 96 97static void 98MakeNormalWindow(Display *dpy) 99{ 100 int attrib[] = { GLX_RGBA, 101 GLX_RED_SIZE, 1, 102 GLX_GREEN_SIZE, 1, 103 GLX_BLUE_SIZE, 1, 104 GLX_DOUBLEBUFFER, 105 None }; 106 int scrnum; 107 Window root; 108 XVisualInfo *visinfo; 109 110 scrnum = DefaultScreen(dpy); 111 root = RootWindow(dpy, scrnum); 112 113 visinfo = glXChooseVisual(dpy, scrnum, attrib); 114 if (!visinfo) { 115 printf("Error: couldn't get an RGB, Double-buffered visual\n"); 116 exit(1); 117 } 118 119 NormalWindow = MakeWindow(dpy, visinfo, root, WinWidth, WinHeight); 120 assert(NormalWindow); 121 122 NormalContext = glXCreateContext(dpy, visinfo, NULL, True); 123 assert(NormalContext); 124} 125 126 127static void 128MakeOverlayWindow(Display *dpy) 129{ 130 int rgbAttribs[] = { 131 GLX_RGBA, 132 GLX_RED_SIZE, 1, 133 GLX_GREEN_SIZE, 1, 134 GLX_BLUE_SIZE, 1, 135 GLX_DOUBLEBUFFER, 136 GLX_LEVEL, 1, 137 None 138 }; 139 int indexAttribs[] = { 140 /*GLX_RGBA, leave this out */ 141 GLX_RED_SIZE, 1, 142 GLX_GREEN_SIZE, 1, 143 GLX_BLUE_SIZE, 1, 144 GLX_DOUBLEBUFFER, 145 GLX_LEVEL, 1, 146 None 147 }; 148 int scrnum; 149 XVisualInfo *visinfo; 150 151 scrnum = DefaultScreen(dpy); 152 153 visinfo = glXChooseVisual(dpy, scrnum, rgbAttribs); 154 if (visinfo) { 155 printf("Found RGB overlay visual 0x%x\n", (int) visinfo->visualid); 156 RGBOverlay = GL_TRUE; 157 } 158 else { 159 visinfo = glXChooseVisual(dpy, scrnum, indexAttribs); 160 if (visinfo) { 161 printf("Found Color Index overlay visual 0x%x\n", 162 (int) visinfo->visualid); 163 /* XXX setup the colormap entries! */ 164 } 165 else { 166 printf("Couldn't get an overlay visual.\n"); 167 printf("Your hardware probably doesn't support framebuffer overlay planes.\n"); 168 exit(1); 169 } 170 } 171 172 OverlayWindow = MakeWindow(dpy, visinfo, NormalWindow, WinWidth, WinHeight); 173 assert(OverlayWindow); 174 175 OverlayContext = glXCreateContext(dpy, visinfo, NULL, True); 176 assert(OverlayContext); 177} 178 179 180static void 181EventLoop(Display *dpy) 182{ 183 XEvent event; 184 185 while (1) { 186 XNextEvent(dpy, &event); 187 188 switch (event.type) { 189 case Expose: 190 RedrawNormal(dpy); 191 RedrawOverlay(dpy); 192 break; 193 case ConfigureNotify: 194 WinWidth = event.xconfigure.width; 195 WinHeight = event.xconfigure.height; 196 if (event.xconfigure.window == NormalWindow) 197 XResizeWindow(dpy, OverlayWindow, WinWidth, WinHeight); 198 break; 199 case KeyPress: 200 { 201 char buffer[10]; 202 XLookupString(&event.xkey, buffer, sizeof(buffer), 203 NULL, NULL); 204 if (buffer[0] == 27) { 205 /* escape */ 206 return; 207 } 208 else if (buffer[0] == ' ') { 209 Angle += 5.0; 210 RedrawNormal(dpy); 211 } 212 } 213 break; 214 default: 215 ; /* nothing */ 216 } 217 } 218} 219 220 221int 222main(int argc, char *argv[]) 223{ 224 Display *dpy = XOpenDisplay(NULL); 225 226 assert(dpy); 227 228 MakeNormalWindow(dpy); 229 MakeOverlayWindow(dpy); 230 231 XMapWindow(dpy, NormalWindow); 232 XMapWindow(dpy, OverlayWindow); 233 234 EventLoop(dpy); 235 236 glXDestroyContext(dpy, OverlayContext); 237 glXDestroyContext(dpy, NormalContext); 238 XDestroyWindow(dpy, OverlayWindow); 239 XDestroyWindow(dpy, NormalWindow); 240 241 return 0; 242} 243