246 lines
5.5 KiB
C
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;
|
|
}
|