xenocara/dist/Mesa/progs/xdemos/overlay.c
2006-11-25 18:56:37 +00:00

246 lines
5.5 KiB
C

/*
* 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;
}