~ubuntu-branches/ubuntu/oneiric/mesa-demos/oneiric

« back to all changes in this revision

Viewing changes to src/xdemos/shape.c

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2010-09-27 16:18:27 UTC
  • Revision ID: james.westby@ubuntu.com-20100927161827-1yfgolc1oy9sjhi8
Tags: upstream-8.0.1
ImportĀ upstreamĀ versionĀ 8.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Example of using the X "shape" extension with OpenGL:  render a spinning
 
4
 * cube inside of a non-rectangular window.
 
5
 *
 
6
 * Press ESC to exit.  Press up/down to change window shape.
 
7
 *
 
8
 * To compile add "shape" to the PROGS list in Makefile.
 
9
 *
 
10
 * Brian Paul
 
11
 * June 16, 1997
 
12
 *
 
13
 * This program is in the public domain.
 
14
 */
 
15
 
 
16
 
 
17
#include <math.h>
 
18
#include <stdio.h>
 
19
#include <stdlib.h>
 
20
#include <sys/time.h>
 
21
#include <time.h>
 
22
#include <unistd.h>
 
23
#include <X11/Xlib.h>
 
24
#include <X11/Xutil.h>
 
25
#include <X11/keysym.h>
 
26
#include <X11/extensions/shape.h>
 
27
#include <GL/glx.h>
 
28
 
 
29
#ifndef PI
 
30
#define PI 3.1415926
 
31
#endif
 
32
 
 
33
 
 
34
static int Width=500, Height=500;
 
35
 
 
36
static float Xangle = 0.0, Yangle = 0.0;
 
37
static int Sides = 5;
 
38
static int MinSides = 3;
 
39
static int MaxSides = 20;
 
40
 
 
41
 
 
42
/* return current time (in seconds) */
 
43
static double
 
44
current_time(void)
 
45
{
 
46
   struct timeval tv;
 
47
#ifdef __VMS
 
48
   (void) gettimeofday(&tv, NULL );
 
49
#else
 
50
   struct timezone tz;
 
51
   (void) gettimeofday(&tv, &tz);
 
52
#endif
 
53
   return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
 
54
}
 
55
 
 
56
 
 
57
/*
 
58
 * Draw the OpenGL stuff and do a SwapBuffers.
 
59
 */
 
60
static void display(Display *dpy, Window win)
 
61
{
 
62
   float scale = 1.7;
 
63
 
 
64
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
65
 
 
66
   glPushMatrix();
 
67
 
 
68
   glScalef(scale, scale, scale);
 
69
   glRotatef(Xangle, 1.0, 0.0, 0.0);
 
70
   glRotatef(Yangle, 0.0, 1.0, 0.0);
 
71
 
 
72
   /*
 
73
    * wireframe box
 
74
    */
 
75
   glColor3f(1.0, 1.0, 1.0);
 
76
   glBegin(GL_LINE_LOOP);
 
77
   glVertex3f(-1.0, -1.0, -1.0);
 
78
   glVertex3f( 1.0, -1.0, -1.0);
 
79
   glVertex3f( 1.0,  1.0, -1.0);
 
80
   glVertex3f(-1.0,  1.0, -1.0);
 
81
   glEnd();
 
82
 
 
83
   glBegin(GL_LINE_LOOP);
 
84
   glVertex3f(-1.0, -1.0, 1.0);
 
85
   glVertex3f( 1.0, -1.0, 1.0);
 
86
   glVertex3f( 1.0,  1.0, 1.0);
 
87
   glVertex3f(-1.0,  1.0, 1.0);
 
88
   glEnd();
 
89
 
 
90
   glBegin(GL_LINES);
 
91
   glVertex3f(-1.0, -1.0, -1.0);   glVertex3f(-1.0, -1.0, 1.0);
 
92
   glVertex3f( 1.0, -1.0, -1.0);   glVertex3f( 1.0, -1.0, 1.0);
 
93
   glVertex3f( 1.0,  1.0, -1.0);   glVertex3f( 1.0,  1.0, 1.0);
 
94
   glVertex3f(-1.0,  1.0, -1.0);   glVertex3f(-1.0,  1.0, 1.0);
 
95
   glEnd();
 
96
 
 
97
   /*
 
98
    * Solid box
 
99
    */
 
100
   glPushMatrix();
 
101
   glScalef(0.75, 0.75, 0.75);
 
102
 
 
103
   glColor3f(1, 0, 0);
 
104
   glBegin(GL_POLYGON);
 
105
   glVertex3f(1, -1, -1);
 
106
   glVertex3f(1,  1, -1);
 
107
   glVertex3f(1,  1,  1);
 
108
   glVertex3f(1, -1,  1);
 
109
   glEnd();
 
110
 
 
111
   glColor3f(0, 1, 1);
 
112
   glBegin(GL_POLYGON);
 
113
   glVertex3f(-1, -1, -1);
 
114
   glVertex3f(-1,  1, -1);
 
115
   glVertex3f(-1,  1,  1);
 
116
   glVertex3f(-1, -1,  1);
 
117
   glEnd();
 
118
 
 
119
   glColor3f(0, 1, 0);
 
120
   glBegin(GL_POLYGON);
 
121
   glVertex3f(-1, 1, -1);
 
122
   glVertex3f( 1, 1, -1);
 
123
   glVertex3f( 1, 1,  1);
 
124
   glVertex3f(-1, 1,  1);
 
125
   glEnd();
 
126
 
 
127
   glColor3f(1, 0, 1);
 
128
   glBegin(GL_POLYGON);
 
129
   glVertex3f(-1, -1, -1);
 
130
   glVertex3f( 1, -1, -1);
 
131
   glVertex3f( 1, -1,  1);
 
132
   glVertex3f(-1, -1,  1);
 
133
   glEnd();
 
134
 
 
135
   glColor3f(0, 0, 1);
 
136
   glBegin(GL_POLYGON);
 
137
   glVertex3f(-1, -1, 1);
 
138
   glVertex3f( 1, -1, 1);
 
139
   glVertex3f( 1,  1, 1);
 
140
   glVertex3f(-1,  1, 1);
 
141
   glEnd();
 
142
 
 
143
   glColor3f(1, 1, 0);
 
144
   glBegin(GL_POLYGON);
 
145
   glVertex3f(-1, -1, -1);
 
146
   glVertex3f( 1, -1, -1);
 
147
   glVertex3f( 1,  1, -1);
 
148
   glVertex3f(-1,  1, -1);
 
149
   glEnd();
 
150
   glPopMatrix();
 
151
 
 
152
 
 
153
   glPopMatrix();
 
154
 
 
155
   glXSwapBuffers(dpy, win);
 
156
}
 
157
 
 
158
 
 
159
/*
 
160
 * This is called when we have to recompute the window shape bitmask.
 
161
 * We just generate an n-sided regular polygon here but any other shape
 
162
 * would be possible.
 
163
 */
 
164
static void make_shape_mask(Display *dpy, Window win, int width, int height,
 
165
                            int sides)
 
166
{
 
167
   Pixmap shapeMask;
 
168
   XGCValues xgcv;
 
169
   GC gc;
 
170
 
 
171
   /* allocate 1-bit deep pixmap and a GC */
 
172
   shapeMask = XCreatePixmap(dpy, win, width, height, 1);
 
173
   gc = XCreateGC(dpy, shapeMask, 0, &xgcv);
 
174
 
 
175
   /* clear shapeMask to zeros */
 
176
   XSetForeground(dpy, gc, 0);
 
177
   XFillRectangle(dpy, shapeMask, gc, 0, 0, width, height);
 
178
 
 
179
   /* draw mask */
 
180
   XSetForeground(dpy, gc, 1);
 
181
   {
 
182
      int cx = width / 2;
 
183
      int cy = height / 2;
 
184
      float angle = 0.0;
 
185
      float step = 2.0 * PI / sides;
 
186
      float radius = width / 2;
 
187
      int i;
 
188
      XPoint points[100];
 
189
      for (i=0;i<sides;i++) {
 
190
         int x = cx + radius * sin(angle);
 
191
         int y = cy - radius * cos(angle);
 
192
         points[i].x = x;
 
193
         points[i].y = y;
 
194
         angle += step;
 
195
      }
 
196
      XFillPolygon(dpy, shapeMask, gc, points, sides, Convex, CoordModeOrigin);
 
197
   }
 
198
 
 
199
   /* This is the only SHAPE extension call- simple! */
 
200
   XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, shapeMask, ShapeSet);
 
201
 
 
202
   XFreeGC(dpy, gc);
 
203
   XFreePixmap(dpy, shapeMask);
 
204
}
 
205
 
 
206
 
 
207
/*
 
208
 * Called when window is resized.  Do OpenGL viewport and projection stuff.
 
209
 */
 
210
static void reshape(int width, int height)
 
211
{
 
212
   glViewport(0, 0, width, height);
 
213
   glMatrixMode(GL_PROJECTION);
 
214
   glLoadIdentity();
 
215
   glFrustum(-1.0, 1.0, -1.0, 1.0, 3.0, 20.0);
 
216
   glMatrixMode(GL_MODELVIEW);
 
217
   glLoadIdentity();
 
218
   glTranslatef(0.0, 0.0, -10.0);
 
219
 
 
220
   glEnable(GL_DEPTH_TEST);
 
221
}
 
222
 
 
223
 
 
224
/*
 
225
 * Process X events.
 
226
 */
 
227
static void event_loop(Display *dpy, Window win)
 
228
{
 
229
   while (1) {
 
230
      XEvent event;
 
231
      if (XPending(dpy)) {
 
232
         XNextEvent(dpy, &event);
 
233
         switch (event.type) {
 
234
            case Expose:
 
235
               display(dpy, event.xexpose.window);
 
236
               break;
 
237
            case ConfigureNotify:
 
238
               Width = event.xconfigure.width;
 
239
               Height = event.xconfigure.height,
 
240
               make_shape_mask(dpy, win, Width, Height, Sides);
 
241
               reshape(Width, Height);
 
242
               break;
 
243
            case KeyPress:
 
244
               {
 
245
                  char buf[100];
 
246
                  KeySym keySym;
 
247
                  XComposeStatus stat;
 
248
                  XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
 
249
                  switch (keySym) {
 
250
                     case XK_Escape:
 
251
                        exit(0);
 
252
                        break;
 
253
                     case XK_Up:
 
254
                        Sides++;
 
255
                        if (Sides>MaxSides) Sides = MaxSides;
 
256
                        make_shape_mask(dpy, win, Width, Height, Sides);
 
257
                        break;
 
258
                     case XK_Down:
 
259
                        Sides--;
 
260
                        if (Sides<MinSides) Sides = MinSides;
 
261
                        make_shape_mask(dpy, win, Width, Height, Sides);
 
262
                        break;
 
263
                  }
 
264
               }
 
265
               break;
 
266
            default:
 
267
               ;;
 
268
         }
 
269
      }
 
270
      else {
 
271
         static double t0 = -1.0;
 
272
         double dt, t = current_time();
 
273
         if (t0 < 0.0)
 
274
            t0 = t;
 
275
         dt = t - t0;
 
276
         Xangle += 90.0 * dt;  /* 90 degrees per second */
 
277
         Yangle += 70.0 * dt;
 
278
         t0 = t;
 
279
         display(dpy, win);
 
280
      }
 
281
   }
 
282
}
 
283
 
 
284
 
 
285
/*
 
286
 * Allocate a "nice" colormap.  This could be better (HP-CR support, etc).
 
287
 */
 
288
static Colormap alloc_colormap(Display *dpy, Window parent, Visual *vis)
 
289
{
 
290
   Screen *scr = DefaultScreenOfDisplay(dpy);
 
291
   int scrnum = DefaultScreen(dpy);
 
292
 
 
293
   if (MaxCmapsOfScreen(scr)==1 && vis==DefaultVisual(dpy, scrnum)) {
 
294
      /* The window and root are of the same visual type so */
 
295
      /* share the root colormap. */
 
296
      return DefaultColormap(dpy, scrnum);
 
297
   }
 
298
   else {
 
299
      return XCreateColormap(dpy, parent, vis, AllocNone);
 
300
   }
 
301
}
 
302
 
 
303
 
 
304
int main(int argc, char *argv[])
 
305
{
 
306
   static int glAttribs[] = {
 
307
      GLX_DOUBLEBUFFER,
 
308
      GLX_RGBA,
 
309
      GLX_DEPTH_SIZE, 1,
 
310
      None
 
311
   };
 
312
   Display *dpy;
 
313
   XVisualInfo *visInfo;
 
314
   int scrn;
 
315
   Window root;
 
316
   Colormap cmap;
 
317
   Window win;
 
318
   XSetWindowAttributes winAttribs;
 
319
   unsigned long winAttribsMask;
 
320
   GLXContext glCtx;
 
321
   int ignore;
 
322
   const char *name = "OpenGL in a Shaped Window";
 
323
 
 
324
   dpy = XOpenDisplay(NULL);
 
325
   if (!dpy) {
 
326
      fprintf(stderr, "Couldn't open default display\n");
 
327
      return 1;
 
328
   }
 
329
 
 
330
   /* check that we can use the shape extension */
 
331
   if (!XQueryExtension(dpy, "SHAPE", &ignore, &ignore, &ignore )) {
 
332
      fprintf(stderr, "Display doesn't support shape extension\n");
 
333
      return 1;
 
334
   }
 
335
 
 
336
   scrn = DefaultScreen(dpy);
 
337
 
 
338
   root = RootWindow(dpy, scrn);
 
339
 
 
340
   visInfo = glXChooseVisual(dpy, scrn, glAttribs);
 
341
   if (!visInfo) {
 
342
      fprintf(stderr, "Couldn't get RGB, DB, Z visual\n");
 
343
      return 1;
 
344
   }
 
345
 
 
346
   glCtx = glXCreateContext(dpy, visInfo, 0, True);
 
347
   if (!glCtx) {
 
348
      fprintf(stderr, "Couldn't create GL context\n");
 
349
      return 1;
 
350
   }
 
351
 
 
352
   cmap = alloc_colormap(dpy, root, visInfo->visual);
 
353
   if (!cmap) {
 
354
      fprintf(stderr, "Couln't create colormap\n");
 
355
      return 1;
 
356
   }
 
357
 
 
358
   winAttribs.border_pixel = 0;
 
359
   winAttribs.colormap = cmap;
 
360
   winAttribs.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
 
361
   winAttribsMask = CWBorderPixel | CWColormap | CWEventMask;
 
362
   win = XCreateWindow(dpy, root, 0, 0, Width, Height, 0,
 
363
                       visInfo->depth, InputOutput,
 
364
                       visInfo->visual,
 
365
                       winAttribsMask, &winAttribs);
 
366
 
 
367
   {
 
368
      XSizeHints sizehints;
 
369
      /*
 
370
      sizehints.x = xpos;
 
371
      sizehints.y = ypos;
 
372
      sizehints.width  = width;
 
373
      sizehints.height = height;
 
374
      */
 
375
      sizehints.flags = 0;
 
376
      XSetNormalHints(dpy, win, &sizehints);
 
377
      XSetStandardProperties(dpy, win, name, name,
 
378
                              None, (char **)NULL, 0, &sizehints);
 
379
   }
 
380
 
 
381
 
 
382
   XMapWindow(dpy, win);
 
383
 
 
384
   glXMakeCurrent(dpy, win, glCtx);
 
385
 
 
386
   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
 
387
   printf("Press ESC to exit.\n");
 
388
   printf("Press up/down to change window shape.\n");
 
389
 
 
390
   event_loop(dpy, win);
 
391
 
 
392
   return 0;
 
393
}