1
2/*
3 * Very simple demo of how to use the Mesa/X11 interface instead of the
4 * glx, tk or aux toolkits.  I highly recommend using the GLX interface
5 * instead of the X/Mesa interface, however.
6 *
7 * This program is in the public domain.
8 *
9 * Brian Paul
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <X11/Xlib.h>
16#include <X11/Xutil.h>
17#include "GL/xmesa.h"
18#include "GL/gl.h"
19
20
21
22static GLint Black, Red, Green, Blue;
23
24
25
26static void make_window( char *title, int color_flag )
27{
28   int x = 10, y = 10, width = 400, height = 300;
29   Display *dpy;
30   int scr;
31   Window root, win;
32   Colormap cmap;
33   XColor xcolor;
34   int attr_flags;
35   XVisualInfo *visinfo;
36   XSetWindowAttributes attr;
37   XTextProperty tp;
38   XSizeHints sh;
39   XEvent e;
40   XMesaContext context;
41   XMesaVisual visual;
42   XMesaBuffer buffer;
43
44
45   /*
46    * Do the usual X things to make a window.
47    */
48
49   dpy = XOpenDisplay(NULL);
50   if (!dpy) {
51      printf("Couldn't open default display!\n");
52      exit(1);
53   }
54
55   scr = DefaultScreen(dpy);
56   root = RootWindow(dpy, scr);
57
58   /* alloc visinfo struct */
59   visinfo = (XVisualInfo *) malloc( sizeof(XVisualInfo) );
60
61   /* Get a visual and colormap */
62   if (color_flag) {
63      /* Open TrueColor window */
64
65/*
66      if (!XMatchVisualInfo( dpy, scr, 24, TrueColor, visinfo )) {
67	 printf("Couldn't get 24-bit TrueColor visual!\n");
68	 exit(1);
69      }
70*/
71      if (!XMatchVisualInfo( dpy, scr, 8, PseudoColor, visinfo )) {
72	 printf("Couldn't get 8-bit PseudoColor visual!\n");
73	 exit(1);
74      }
75
76      cmap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
77      Black = Red = Green = Blue = 0;
78   }
79   else {
80      /* Open color index window */
81
82      if (!XMatchVisualInfo( dpy, scr, 8, PseudoColor, visinfo )) {
83	 printf("Couldn't get 8-bit PseudoColor visual\n");
84	 exit(1);
85      }
86
87      cmap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
88
89      /* Allocate colors */
90      xcolor.red   = 0x0;
91      xcolor.green = 0x0;
92      xcolor.blue  = 0x0;
93      xcolor.flags = DoRed | DoGreen | DoBlue;
94      if (!XAllocColor( dpy, cmap, &xcolor )) {
95	 printf("Couldn't allocate black!\n");
96	 exit(1);
97      }
98      Black = xcolor.pixel;
99
100      xcolor.red   = 0xffff;
101      xcolor.green = 0x0;
102      xcolor.blue  = 0x0;
103      xcolor.flags = DoRed | DoGreen | DoBlue;
104      if (!XAllocColor( dpy, cmap, &xcolor )) {
105	 printf("Couldn't allocate red!\n");
106	 exit(1);
107      }
108      Red = xcolor.pixel;
109
110      xcolor.red   = 0x0;
111      xcolor.green = 0xffff;
112      xcolor.blue  = 0x0;
113      xcolor.flags = DoRed | DoGreen | DoBlue;
114      if (!XAllocColor( dpy, cmap, &xcolor )) {
115	 printf("Couldn't allocate green!\n");
116	 exit(1);
117      }
118      Green = xcolor.pixel;
119
120      xcolor.red   = 0x0;
121      xcolor.green = 0x0;
122      xcolor.blue  = 0xffff;
123      xcolor.flags = DoRed | DoGreen | DoBlue;
124      if (!XAllocColor( dpy, cmap, &xcolor )) {
125	 printf("Couldn't allocate blue!\n");
126	 exit(1);
127      }
128      Blue = xcolor.pixel;
129   }
130
131   /* set window attributes */
132   attr.colormap = cmap;
133   attr.event_mask = ExposureMask | StructureNotifyMask;
134   attr.border_pixel = BlackPixel( dpy, scr );
135   attr.background_pixel = BlackPixel( dpy, scr );
136   attr_flags = CWColormap | CWEventMask | CWBorderPixel | CWBackPixel;
137
138   /* Create the window */
139   win = XCreateWindow( dpy, root, x,y, width, height, 0,
140			    visinfo->depth, InputOutput,
141			    visinfo->visual,
142			    attr_flags, &attr);
143   if (!win) {
144      printf("Couldn't open window!\n");
145      exit(1);
146   }
147
148   XStringListToTextProperty(&title, 1, &tp);
149   sh.flags = USPosition | USSize;
150   XSetWMProperties(dpy, win, &tp, &tp, 0, 0, &sh, 0, 0);
151   XMapWindow(dpy, win);
152   while (1) {
153      XNextEvent( dpy, &e );
154      if (e.type == MapNotify && e.xmap.window == win) {
155	 break;
156      }
157   }
158
159
160   /*
161    * Now do the special Mesa/Xlib stuff!
162    */
163
164   visual = XMesaCreateVisual( dpy, visinfo,
165                              (GLboolean) color_flag,
166                               GL_FALSE,  /* alpha_flag */
167                               GL_FALSE,  /* db_flag */
168                               GL_FALSE,  /* stereo flag */
169                               GL_FALSE,  /* ximage_flag */
170                               0,         /* depth size */
171                               0,         /* stencil size */
172                               0,0,0,0,   /* accum_size */
173                               0,         /* num samples */
174                               0,         /* level */
175                               0          /* caveat */
176                              );
177   if (!visual) {
178      printf("Couldn't create Mesa/X visual!\n");
179      exit(1);
180   }
181
182   /* Create a Mesa rendering context */
183   context = XMesaCreateContext( visual,
184                                 NULL       /* share_list */
185                               );
186   if (!context) {
187      printf("Couldn't create Mesa/X context!\n");
188      exit(1);
189   }
190
191   buffer = XMesaCreateWindowBuffer( visual, win );
192   if (!buffer) {
193      printf("Couldn't create Mesa/X buffer!\n");
194      exit(1);
195   }
196
197
198   XMesaMakeCurrent( context, buffer );
199
200   /* Ready to render! */
201}
202
203
204
205static void draw_cube( void )
206{
207   /* X faces */
208   glIndexi( Red );
209   glColor3f( 1.0, 0.0, 0.0 );
210   glBegin( GL_POLYGON );
211   glVertex3f( 1.0, 1.0, 1.0 );
212   glVertex3f( 1.0, -1.0, 1.0 );
213   glVertex3f( 1.0, -1.0, -1.0 );
214   glVertex3f( 1.0, 1.0, -1.0 );
215   glEnd();
216
217   glBegin( GL_POLYGON );
218   glVertex3f( -1.0, 1.0, 1.0 );
219   glVertex3f( -1.0, 1.0, -1.0 );
220   glVertex3f( -1.0, -1.0, -1.0 );
221   glVertex3f( -1.0, -1.0, 1.0 );
222   glEnd();
223
224   /* Y faces */
225   glIndexi( Green );
226   glColor3f( 0.0, 1.0, 0.0 );
227   glBegin( GL_POLYGON );
228   glVertex3f(  1.0, 1.0,  1.0 );
229   glVertex3f(  1.0, 1.0, -1.0 );
230   glVertex3f( -1.0, 1.0, -1.0 );
231   glVertex3f( -1.0, 1.0,  1.0 );
232   glEnd();
233
234   glBegin( GL_POLYGON );
235   glVertex3f(  1.0, -1.0,  1.0 );
236   glVertex3f( -1.0, -1.0,  1.0 );
237   glVertex3f( -1.0, -1.0, -1.0 );
238   glVertex3f(  1.0, -1.0, -1.0 );
239   glEnd();
240
241   /* Z faces */
242   glIndexi( Blue );
243   glColor3f( 0.0, 0.0, 1.0 );
244   glBegin( GL_POLYGON );
245   glVertex3f(  1.0,  1.0,  1.0 );
246   glVertex3f( -1.0,  1.0,  1.0 );
247   glVertex3f( -1.0, -1.0,  1.0 );
248   glVertex3f(  1.0, -1.0,  1.0 );
249   glEnd();
250
251   glBegin( GL_POLYGON );
252   glVertex3f(  1.0, 1.0, -1.0 );
253   glVertex3f(  1.0,-1.0, -1.0 );
254   glVertex3f( -1.0,-1.0, -1.0 );
255   glVertex3f( -1.0, 1.0, -1.0 );
256   glEnd();
257}
258
259
260
261
262static void display_loop( void )
263{
264   GLfloat xrot, yrot, zrot;
265
266   xrot = yrot = zrot = 0.0;
267
268   glClearColor( 0.0, 0.0, 0.0, 0.0 );
269   glClearIndex( Black );
270
271   glMatrixMode( GL_PROJECTION );
272   glLoadIdentity();
273   glFrustum( -1.0, 1.0,  -1.0, 1.0,  1.0, 10.0 );
274   glTranslatef( 0.0, 0.0, -5.0 );
275
276   glMatrixMode( GL_MODELVIEW );
277   glLoadIdentity();
278
279   glCullFace( GL_BACK );
280   glEnable( GL_CULL_FACE );
281
282   glShadeModel( GL_FLAT );
283
284   while (1) {
285      glClear( GL_COLOR_BUFFER_BIT );
286      glPushMatrix();
287      glRotatef( xrot, 1.0, 0.0, 0.0 );
288      glRotatef( yrot, 0.0, 1.0, 0.0 );
289      glRotatef( zrot, 0.0, 0.0, 1.0 );
290
291      draw_cube();
292
293      glPopMatrix();
294      glFinish();
295
296      xrot += 10.0;
297      yrot += 7.0;
298      zrot -= 3.0;
299   }
300
301}
302
303
304
305
306int main( int argc, char *argv[] )
307{
308   int mode = 0;
309
310   if (argc >= 2)
311   {
312        if (strcmp(argv[1],"-ci")==0)
313           mode = 0;
314        else if (strcmp(argv[1],"-rgb")==0)
315           mode = 1;
316        else
317        {
318           printf("Bad flag: %s\n", argv[1]);
319           printf("Specify -ci for 8-bit color index or -rgb for RGB mode\n");
320           exit(1);
321        }
322   }
323   else
324   {
325        printf("Specify -ci for 8-bit color index or -rgb for RGB mode\n");
326        printf("Defaulting to  8-bit color index\n");
327   }
328
329   make_window( argv[0], mode );
330
331   display_loop();
332   return 0;
333}
334
335