123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- /* $Id: shape.c,v 1.3 2000/06/27 15:34:35 brianp Exp $ */
-
- /*
- * Example of using the X "shape" extension with OpenGL: render a spinning
- * cube inside of a non-rectangular window.
- *
- * Press ESC to exit. Press up/down to change window shape.
- *
- * To compile add "shape" to the PROGS list in Makefile.
- *
- * Brian Paul
- * June 16, 1997
- *
- * This program is in the public domain.
- */
-
-
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/keysym.h>
- #include <X11/extensions/shape.h>
- #include <GL/glx.h>
-
- #ifndef PI
- #define PI 3.1415926
- #endif
-
-
- static int Width=500, Height=500;
-
- static float Xangle = 0.0, Yangle = 0.0;
- static int Redraw = 0;
- static int Sides = 5;
- static int MinSides = 3;
- static int MaxSides = 20;
-
-
- /*
- * Draw the OpenGL stuff and do a SwapBuffers.
- */
- static void display(Display *dpy, Window win)
- {
- float scale = 1.7;
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glPushMatrix();
-
- glScalef(scale, scale, scale);
- glRotatef(Xangle, 1.0, 0.0, 0.0);
- glRotatef(Yangle, 0.0, 1.0, 0.0);
-
- /*
- * wireframe box
- */
- glColor3f(1.0, 1.0, 1.0);
- glBegin(GL_LINE_LOOP);
- glVertex3f(-1.0, -1.0, -1.0);
- glVertex3f( 1.0, -1.0, -1.0);
- glVertex3f( 1.0, 1.0, -1.0);
- glVertex3f(-1.0, 1.0, -1.0);
- glEnd();
-
- glBegin(GL_LINE_LOOP);
- glVertex3f(-1.0, -1.0, 1.0);
- glVertex3f( 1.0, -1.0, 1.0);
- glVertex3f( 1.0, 1.0, 1.0);
- glVertex3f(-1.0, 1.0, 1.0);
- glEnd();
-
- glBegin(GL_LINES);
- glVertex3f(-1.0, -1.0, -1.0); glVertex3f(-1.0, -1.0, 1.0);
- glVertex3f( 1.0, -1.0, -1.0); glVertex3f( 1.0, -1.0, 1.0);
- glVertex3f( 1.0, 1.0, -1.0); glVertex3f( 1.0, 1.0, 1.0);
- glVertex3f(-1.0, 1.0, -1.0); glVertex3f(-1.0, 1.0, 1.0);
- glEnd();
-
- /*
- * Solid box
- */
- glPushMatrix();
- glScalef(0.75, 0.75, 0.75);
-
- glColor3f(1, 0, 0);
- glBegin(GL_POLYGON);
- glVertex3f(1, -1, -1);
- glVertex3f(1, 1, -1);
- glVertex3f(1, 1, 1);
- glVertex3f(1, -1, 1);
- glEnd();
-
- glColor3f(0, 1, 1);
- glBegin(GL_POLYGON);
- glVertex3f(-1, -1, -1);
- glVertex3f(-1, 1, -1);
- glVertex3f(-1, 1, 1);
- glVertex3f(-1, -1, 1);
- glEnd();
-
- glColor3f(0, 1, 0);
- glBegin(GL_POLYGON);
- glVertex3f(-1, 1, -1);
- glVertex3f( 1, 1, -1);
- glVertex3f( 1, 1, 1);
- glVertex3f(-1, 1, 1);
- glEnd();
-
- glColor3f(1, 0, 1);
- glBegin(GL_POLYGON);
- glVertex3f(-1, -1, -1);
- glVertex3f( 1, -1, -1);
- glVertex3f( 1, -1, 1);
- glVertex3f(-1, -1, 1);
- glEnd();
-
- glColor3f(0, 0, 1);
- glBegin(GL_POLYGON);
- glVertex3f(-1, -1, 1);
- glVertex3f( 1, -1, 1);
- glVertex3f( 1, 1, 1);
- glVertex3f(-1, 1, 1);
- glEnd();
-
- glColor3f(1, 1, 0);
- glBegin(GL_POLYGON);
- glVertex3f(-1, -1, -1);
- glVertex3f( 1, -1, -1);
- glVertex3f( 1, 1, -1);
- glVertex3f(-1, 1, -1);
- glEnd();
- glPopMatrix();
-
-
- glPopMatrix();
-
- glXSwapBuffers(dpy, win);
- }
-
-
- /*
- * Called when no events are pending.
- */
- static void idle(void)
- {
- Xangle += 2.0;
- Yangle += 3.3;
- Redraw = 1;
- }
-
-
- /*
- * This is called when we have to recompute the window shape bitmask.
- * We just generate an n-sided regular polygon here but any other shape
- * would be possible.
- */
- static void make_shape_mask(Display *dpy, Window win, int width, int height,
- int sides)
- {
- Pixmap shapeMask;
- XGCValues xgcv;
- GC gc;
-
- /* allocate 1-bit deep pixmap and a GC */
- shapeMask = XCreatePixmap(dpy, win, width, height, 1);
- gc = XCreateGC(dpy, shapeMask, 0, &xgcv);
-
- /* clear shapeMask to zeros */
- XSetForeground(dpy, gc, 0);
- XFillRectangle(dpy, shapeMask, gc, 0, 0, width, height);
-
- /* draw mask */
- XSetForeground(dpy, gc, 1);
- {
- int cx = width / 2;
- int cy = height / 2;
- float angle = 0.0;
- float step = 2.0 * PI / sides;
- float radius = width / 2;
- int i;
- XPoint points[100];
- for (i=0;i<sides;i++) {
- int x = cx + radius * sin(angle);
- int y = cy - radius * cos(angle);
- points[i].x = x;
- points[i].y = y;
- angle += step;
- }
- XFillPolygon(dpy, shapeMask, gc, points, sides, Convex, CoordModeOrigin);
- }
-
- /* This is the only SHAPE extension call- simple! */
- XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, shapeMask, ShapeSet);
-
- XFreeGC(dpy, gc);
- XFreePixmap(dpy, shapeMask);
- }
-
-
- /*
- * Called when window is resized. Do OpenGL viewport and projection stuff.
- */
- static void reshape(int width, int height)
- {
- glViewport(0, 0, width, height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(-1.0, 1.0, -1.0, 1.0, 3.0, 20.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0, 0.0, -10.0);
-
- glEnable(GL_DEPTH_TEST);
- }
-
-
- /*
- * Process X events.
- */
- static void event_loop(Display *dpy, Window win)
- {
- while (1) {
- XEvent event;
- if (XPending(dpy)) {
- XNextEvent(dpy, &event);
- switch (event.type) {
- case Expose:
- display(dpy, event.xexpose.window);
- break;
- case ConfigureNotify:
- Width = event.xconfigure.width;
- Height = event.xconfigure.height,
- make_shape_mask(dpy, win, Width, Height, Sides);
- reshape(Width, Height);
- break;
- case KeyPress:
- {
- char buf[100];
- KeySym keySym;
- XComposeStatus stat;
- XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
- switch (keySym) {
- case XK_Escape:
- exit(0);
- break;
- case XK_Up:
- Sides++;
- if (Sides>MaxSides) Sides = MaxSides;
- make_shape_mask(dpy, win, Width, Height, Sides);
- break;
- case XK_Down:
- Sides--;
- if (Sides<MinSides) Sides = MinSides;
- make_shape_mask(dpy, win, Width, Height, Sides);
- break;
- }
- }
- break;
- default:
- ;;
- }
- }
- else {
- idle();
- if (Redraw) {
- display(dpy, win);
- Redraw = 0;
- }
- }
- }
- }
-
-
- /*
- * Allocate a "nice" colormap. This could be better (HP-CR support, etc).
- */
- static Colormap alloc_colormap(Display *dpy, Window parent, Visual *vis)
- {
- Screen *scr = DefaultScreenOfDisplay(dpy);
- int scrnum = DefaultScreen(dpy);
-
- if (MaxCmapsOfScreen(scr)==1 && vis==DefaultVisual(dpy, scrnum)) {
- /* The window and root are of the same visual type so */
- /* share the root colormap. */
- return DefaultColormap(dpy, scrnum);
- }
- else {
- return XCreateColormap(dpy, parent, vis, AllocNone);
- }
- }
-
-
- int main(int argc, char *argv[])
- {
- static int glAttribs[] = {
- GLX_DOUBLEBUFFER,
- GLX_RGBA,
- GLX_DEPTH_SIZE, 1,
- None
- };
- Display *dpy;
- XVisualInfo *visInfo;
- int scrn;
- Window root;
- Colormap cmap;
- Window win;
- XSetWindowAttributes winAttribs;
- unsigned long winAttribsMask;
- GLXContext glCtx;
- int ignore;
- const char *name = "OpenGL in a Shaped Window";
-
- dpy = XOpenDisplay(NULL);
- if (!dpy) {
- fprintf(stderr, "Couldn't open default display\n");
- return 1;
- }
-
- /* check that we can use the shape extension */
- if (!XQueryExtension(dpy, "SHAPE", &ignore, &ignore, &ignore )) {
- fprintf(stderr, "Display doesn't support shape extension\n");
- return 1;
- }
-
- scrn = DefaultScreen(dpy);
-
- root = RootWindow(dpy, scrn);
-
- visInfo = glXChooseVisual(dpy, scrn, glAttribs);
- if (!visInfo) {
- fprintf(stderr, "Couldn't get RGB, DB, Z visual\n");
- return 1;
- }
-
- glCtx = glXCreateContext(dpy, visInfo, 0, True);
- if (!glCtx) {
- fprintf(stderr, "Couldn't create GL context\n");
- return 1;
- }
-
- cmap = alloc_colormap(dpy, root, visInfo->visual);
- if (!cmap) {
- fprintf(stderr, "Couln't create colormap\n");
- return 1;
- }
-
- winAttribs.border_pixel = 0;
- winAttribs.colormap = cmap;
- winAttribs.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
- winAttribsMask = CWBorderPixel | CWColormap | CWEventMask;
- win = XCreateWindow(dpy, root, 0, 0, Width, Height, 0,
- visInfo->depth, InputOutput,
- visInfo->visual,
- winAttribsMask, &winAttribs);
-
- {
- XSizeHints sizehints;
- /*
- sizehints.x = xpos;
- sizehints.y = ypos;
- sizehints.width = width;
- sizehints.height = height;
- */
- sizehints.flags = 0;
- XSetNormalHints(dpy, win, &sizehints);
- XSetStandardProperties(dpy, win, name, name,
- None, (char **)NULL, 0, &sizehints);
- }
-
-
- XMapWindow(dpy, win);
-
- glXMakeCurrent(dpy, win, glCtx);
-
- printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
- printf("Press ESC to exit.\n");
- printf("Press up/down to change window shape.\n");
-
- event_loop(dpy, win);
-
- return 0;
- }
|