Merge branch 'nouveau-import'
[mesa.git] / docs / MiniGLX.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html>
3 <head>
4 <title>Mini GLX Specification</title>
5 </head>
6 <body>
7 <h1>
8 <center>Mini GLX Specification</center>
9 </h1>
10 <h2>
11 <center>Tungsten Graphics, Inc.<br>
12 <br>
13 January 20, 2003<br>
14 <br>
15 </center>
16 </h2>
17 <p> Copyright &copy; 2002-2003 by Tungsten Graphics, Inc., Cedar Park,
18 Texas. All Rights Reserved. <br>
19 <br>
20 Permission is granted to make and distribute verbatim copies of this
21 document provided the copyright notice and this permission notice are
22 preserved on all copies.<br>
23 <br>
24 </p>
25 <h1>1. Introduction</h1>
26 <p>The Mini GLX interface facilitates OpenGL rendering on embedded
27 devices. The interface is a subset of the GLX interface, plus a minimal
28 set of Xlib-like functions.</p>
29 <p>Programs written to the Mini GLX specification should run unchanged
30 on systems with the X Window System and the GLX extension. The intention
31 is to allow flexibility for prototyping and testing.</p>
32 <p>This document serves as both the reference guide and programming
33 guide for Mini GLX.<br>
34 <br>
35 </p>
36 <h1>2. Mini GLX Concepts</h1>
37 <p>The OpenGL specification does not describe how OpenGL rendering
38 contexts and drawing surfaces (i.e. the frame buffer) are created and
39 managed. Rather, this is handled by an OpenGL window system interface,
40 such as Mini GLX.</p>
41 <p>There are three main datatypes or resources managed by Mini GLX. The
42 resources and their corresponding GLX or Xlib data types are:</p>
43 <table cellspacing="10" align="center">
44 <tbody>
45 <tr>
46 <td><u>Resource</u></td>
47 <td><u>Data type</u></td>
48 </tr>
49 <tr>
50 <td>pixel formats</td>
51 <td>X Visual and XVisualInfo</td>
52 </tr>
53 <tr>
54 <td>drawing surfaces</td>
55 <td>X Window or GLXDrawable</td>
56 </tr>
57 <tr>
58 <td>rendering contexts</td>
59 <td>GLXContext</td>
60 </tr>
61 </tbody>
62 </table>
63 <p>Pixel formats or X Visuals describe the per-pixel attributes of the
64 frame buffer. For example, bits per color component, Z buffer size,
65 stencil size, TrueColor vs PseudoColor, etc.</p>
66 <p>Drawing surfaces or X Windows typically describe a spatial
67 allocation of the frame buffer (i.e. the position and size of a
68 rectangular region of pixels). Since MiniGLX doesn't really support a
69 window system, the window is effectively the entire frame buffer.</p>
70 <p>A rendering context represents the current OpenGL state such as
71 current drawing color, line width, blending mode, texture parameters,
72 etc. Several rendering contexts can be created but only one can be in
73 use at any given time.</p>
74 <p>The Mini GLX interface provides all the functions needed for
75 choosing pixel formats, create drawing surfaces, creating rendering
76 contexts and binding rendering contexts to drawing surfaces.<br>
77 <br>
78 </p>
79 <h1>3. Using Mini GLX</h1>
80 <p>To use the Mini GLX interface in your application, include the
81 GL/miniglx.h header file at compile time:</p>
82 <blockquote><code> #include &lt;GL/miniglx.h&gt;<br>
83 </code></blockquote>
84 <code></code>Applications should link with libGL.so (i.e. <code>gcc
85 myprogram.o -lGL -o myprogram</code>). &nbsp;libGL.so implements the
86 MiniGLX API functions and, in turn, loads a hardware-specific device
87 driver (such as <code>radeon_dri.so</code>) at runtime. &nbsp;The
88 environment variable <code>LIBGL_DRIVERS_PATH</code> should name the
89 directory where these modules are located.<br>
90 <br>
91 Prior to running a MiniGXL application, the following kernel modules
92 must be installed:<br>
93 <br>
94 <div style="margin-left: 40px;"> agpgart.o<br>
95 radeonfb.o &nbsp;(assuming Radeon hardware)<br>
96 radeon.o &nbsp;(assuming Radeon hardware)<br>
97 </div>
98 <code></code> <br>
99 Finally, MiniGLX reads a configuration file (by default,<code>
100 /etc/miniglx.conf</code>) to determine basic configuration information.
101 &nbsp;The configuration file may also be located in the directory
102 specified by the <code>MINIGLX_CONF</code> environment variable).<br>
103 <br>
104 The remainder of this section describes the MiniGLX API functions.<br>
105 <br>
106 <h2>3.1 Initialization</h2>
107 <p>The XOpenDisplay function is used to initialize the graphics system:</p>
108 <blockquote>
109 <pre>Display *XOpenDisplay(const char *displayname)<br></pre>
110 </blockquote>
111 <p>The <code>displayName</code> parameter is currently ignored in Mini
112 GLX. It is recommended that <code>NULL</code> be passed as the<code>displayName</code>
113 parameter.</p>
114 <p>If XOpenDisplay is able to initialize the graphics system a pointer
115 to a Display will be returned. Otherwise, NULL will be returned.</p>
116 <h2>3.2 Choosing a Visual</h2>
117 <p>A visual (i.e. pixel format) must be chosen before a drawing surface
118 or rendering context can be created. This is done with the
119 glXChooseVisual function:</p>
120 <blockquote>
121 <pre>XVisualInfo *glXChooseVisual(Display *dpy, int screen, const int *attribList)<br></pre>
122 </blockquote>
123 <p><code>dpy</code> is a pointer to the display returned by
124 XOpenDisplay. </p>
125 <p><code>screen</code> is currently ignored by Mini GLX and should be
126 zero. </p>
127 <p><code>attribList</code> is a list of GLX attributes which describe
128 the desired pixel format. It is terminated by the token <code>None</code>.
129 The attributes are as follows:</p>
130 <blockquote>
131 <dl>
132 <dt><code>GLX_USE_GL</code></dt>
133 <dd>This attribute should always be present in order to maintain
134 compatibility with GLX.</dd>
135 <dt><code>GLX_RGBA</code></dt>
136 <dd>If present, only RGBA pixel formats will be considered.
137 Otherwise, only color index formats are considered.</dd>
138 <dt><code>GLX_DOUBLEBUFFER</code></dt>
139 <dd>if present, only double-buffered pixel formats will be chosen.</dd>
140 <dt><code>GLX_RED_SIZE n</code></dt>
141 <dd>Must be followed by a non-negative integer indicating the
142 minimum number of bits per red pixel component that is acceptable.</dd>
143 <dt><code>GLX_GREEN_SIZE n</code></dt>
144 <dd>Must be followed by a non-negative integer indicating the
145 minimum number of bits per green pixel component that is acceptable.</dd>
146 <dt><code>GLX_BLUE_SIZE n</code></dt>
147 <dd>Must be followed by a non-negative integer indicating the
148 minimum number of bits per blue pixel component that is acceptable.</dd>
149 <dt><code>GLX_ALPHA_SIZE n</code></dt>
150 <dd>Must be followed by a non-negative integer indicating the
151 minimum number of bits per alpha pixel component that is acceptable.</dd>
152 <dt><code>GLX_STENCIL_SIZE n</code></dt>
153 <dd>Must be followed by a non-negative integer indicating the
154 minimum number of bits per stencil value that is acceptable.</dd>
155 <dt><code>None</code></dt>
156 <dd>This token is used to terminate the attribute list.</dd>
157 </dl>
158 </blockquote>
159 <p>glXChooseVisual will return a pointer to an XVisualInfo object which
160 most closely matches the requirements of the attribute list. If there
161 is no visual which matches the request, NULL will be returned.</p>
162 <p>Note that visuals with accumulation buffers and depth buffers are
163 not available.<br>
164 <br>
165 </p>
166 <h2>3.3 Creating a Drawing Surface</h2>
167 <p>Drawing surfaces are created as X windows. &nbsp;For Mini GLX,
168 windows are <i>full-screen</i>; they cover the entire frame buffer.
169 &nbsp;Also, Mini GLX imposes a limit of one window. A second window
170 cannot be created until the first one is destroyed.</p>
171 <h3>3.3.1 Window Creation</h3>
172 <p>The XCreateWindow function is used to create a drawing surface:</p>
173 <blockquote>
174 <pre>Window XCreateWindow( Display *display,<br> Window parent,<br> int x, int y,<br> unsigned int width, unsigned int height,<br> unsigned int borderWidth,<br> int depth,<br> unsigned int class,<br> Visual *visual,<br> unsigned long valuemask,<br> XSetWindowAttributes *attributes )<br></pre>
175 </blockquote>
176 <p>The parameters are as follows:</p>
177 <blockquote>
178 <dl>
179 <dt><code>display</code></dt>
180 <dd>A Display pointer, as returned by XOpenDisplay.</dd>
181 <dt><code>parent</code></dt>
182 <dd>The parent window for the new window. For Mini GLX, this
183 should be<code>RootWindow(dpy, 0)</code>.</dd>
184 <dt><code>x, y</code></dt>
185 <dd>The position of the window. For Mini GLX, both values should
186 be zero.</dd>
187 <dt><code>width, height</code></dt>
188 <dd>The size of the window. For Mini GLX, this specifies the
189 desired screen size such as 1024, 768 or 1280, 1024.</dd>
190 <dt><code>borderWidth</code></dt>
191 <dd>This parameter should be zero.</dd>
192 <dt><code>depth</code></dt>
193 <dd>The pixel depth for the window. For Mini GLX this should be
194 the depth found in the XVisualInfo object returned by <code>glxChooseVisual</code>.</dd>
195 <dt><code>class</code></dt>
196 <dd>The window class. For Mini GLX this value should be <code>InputOutput</code>.</dd>
197 <dt><code>visual</code></dt>
198 <dd>This parameter should be the <code>visual</code> field of the <code>XVisualInfo</code>
199 object returned by <code>glxChooseVisual</code>.</dd>
200 <dt><code>valuemask</code></dt>
201 <dd>This parameter indicates which fields of the <code>XSetWindowAttributes</code>
202 are to be used. For Mini GLX this is typically the bitmask<code>CWBackPixel
203 | CWBorderPixel | CWColormap</code>.</dd>
204 <dt><code>attributes</code></dt>
205 <dd>Initial window attributes. Of the fields in the <code>XSetWindowAttributes</code>
206 structure, the<code>background_pixel</code>, <code>border_pixel</code>
207 and <code>colormap</code> fields should be set. &nbsp;See the discussion
208 below regarding colormaps.</dd>
209 </dl>
210 </blockquote>
211 <p><code>XCreateWindow</code> will return a window handle if it succeeds
212 or zero if it fails.</p>
213 <h3>3.3.2 Window Mapping</h3>
214 <p>To display the window the XMapWindow function must be called:</p>
215 <blockquote>
216 <pre>void XMapWindow(Display *dpy, Window w)</pre>
217 </blockquote>
218 <p>This function does nothing in Mini GLX but is required for Xlib/GLX
219 compatibility</p>
220 <h3>3.3.3 Colormaps<br>
221 </h3>
222 <p>Xlib requires specification of a colormap when creating a window.
223 &nbsp;For purposes of interoperability, Mini GLX requires this as well,
224 though the colormap is not actually used. &nbsp;The XCreateColormap
225 function is used to create a colormap:</p>
226 <blockquote><code>Colormap XCreateColormap(Display *dpy, Window window,
227 Visual *visual, int alloc)</code><br>
228 <code></code></blockquote>
229 <p>The parameters are as follows:<br>
230 </p>
231 <blockquote>
232 <dl>
233 <dt><code>dpy</code></dt>
234 <dd>The display handle as returned by XOpenDisplay.</dd>
235 <dt><code>window</code></dt>
236 <dd> This parameter is ignored by Mini GLX but should be the value
237 returned by the <code>RootWindow(dpy, 0)</code> macro.<br>
238 </dd>
239 <dt><code>visual</code></dt>
240 <dd>This parameter is ignored by Mini GLX but should be the visual
241 field of the XVisualInfo object returned by glXChooseVisual. </dd>
242 <dt><code>alloc</code></dt>
243 <dd>This parameter is ignored by Mini GLX but should be set to <code>AllocNone</code>.</dd>
244 </dl>
245 </blockquote>
246 <br>
247 <h2>3.4 Creating a Rendering Context</h2>
248 <p>An OpenGL rendering context is created with the <code>glXCreateContext</code>
249 function:</p>
250 <blockquote>
251 <pre>GLXContext glXCreateContext(Display *dpy, XVisualInfo *visInfo, GLXContext shareList, Bool direct)<br></pre>
252 </blockquote>
253 <p>The parameters are as follows:</p>
254 <blockquote>
255 <dl>
256 <dt><code>dpy</code></dt>
257 <dd>The display handle as returned by XOpenDisplay.</dd>
258 <dt><code>visInfo</code></dt>
259 <dd>The visual as returned by glXChooseVisual.</dd>
260 <dt><code>shareList</code></dt>
261 <dd>If non-zero, texture objects and display lists are shared with
262 the named rendering context. If zero, texture objects and display lists
263 will (initially) be private to this context. They may be shared when a
264 subsequent context is created.</dd>
265 <dt><code>direct</code></dt>
266 <dd>Specifies whether direct or indirect rendering is desired. For
267 Mini GLX this value is ignored but it should be set to <code>True</code>.</dd>
268 </dl>
269 </blockquote>
270 <p><code>glXCreateContext</code> will return a GLXContext handle if it
271 succeeds or zero if it fails due to invalid parameter or insufficient
272 resources.<br>
273 <br>
274 </p>
275 <h2>3.5 Binding a Rendering Context</h2>
276 <p>The final step before beginning OpenGL rendering is to bind (i.e.
277 activate) a rendering context and drawing surface with the
278 glXMakeCurrent function:</p>
279 <blockquote>
280 <pre>Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)<br></pre>
281 </blockquote>
282 <p>The parameters are as follows:</p>
283 <blockquote>
284 <dl>
285 <dt><code>dpy</code></dt>
286 <dd>The display handle, as returned by XOpenDisplay.</dd>
287 <dt><code>drawable</code></dt>
288 <dd>The window or drawable to bind to the rendering context. This
289 should be the value returned by XCreateWindow.</dd>
290 <dt><code>ctx</code></dt>
291 <dd>The rendering context to bind, as returned by glXCreateContext.</dd>
292 </dl>
293 </blockquote>
294 <p>If glXMakeCurrent succeeds True is returned. Otherwise False is
295 returned to indicate an invalid display, window or context parameter.</p>
296 <p>After the rendering context has been bound to the drawing surface
297 OpenGL rendering can begin.</p>
298 <p>The current rendering context may be unbound by calling
299 glXMakeCurrent with the window and context parameters set to zero.</p>
300 <p>An application may create any number of rendering contexts and bind
301 them as needed. Note that binding a rendering context is generally not a
302 light-weight operation. &nbsp;Most simple OpenGL applications create
303 only one rendering context.<br>
304 <br>
305 </p>
306 <h2>3.6 Color Buffer Swapping</h2>
307 <p>A double buffered window has two color buffers: a front buffer and a
308 back buffer. Normally, rendering is directed to the back buffer while
309 the front buffer is displayed. When rendering of a frame is finished
310 the front and back buffers are swapped to provide the illusion of
311 instanteous screen updates.</p>
312 <p>The color buffers for a particular window (i.e. drawable) may be
313 swapped with the glXSwapBuffers command:</p>
314 <blockquote>
315 <pre>void glXSwapBuffers(Display *dpy, GLXDrawable drawable)<br></pre>
316 </blockquote>
317 Any pending rendering commands will be completed before the buffer swap
318 takes place.<br>
319 <br>
320 Calling glXSwapBuffers on a window which is single-buffered has no
321 effect.<br>
322 <br>
323 <h2>3.7 Releasing Resources</h2>
324 <h3>3.7.1 Releasing Rendering Contexts</h3>
325 <p>A rendering context may be destroyed by calling glXDestroyContext:</p>
326 <blockquote>
327 <pre>void glXDestroyContext(Display *dpy, GLXContext ctx)<br></pre>
328 </blockquote>
329 <h3>3.7.2 Releasing Windows</h3>
330 <p>A window may be destroyed by calling XDestroyWindow:</p>
331 <blockquote>
332 <pre>void XDestroyWindow(Display *dpy, Window window)<br></pre>
333 </blockquote>
334 <h3>3.7.3 Releasing Visuals</h3>
335 <p>An XVisualInfo object may be freed by calling XFree:</p>
336 <blockquote>
337 <pre>void XFree(void *data)<br></pre>
338 </blockquote>
339 <h3>3.7.4 Releasing Colormaps</h3>
340 <p>A colormap may be freed by calling XFreeColormap:</p>
341 <blockquote>
342 <pre>void XFreeColormap(Display *dpy, Colormap colormap)<br></pre>
343 </blockquote>
344 <h3>3.7.4 Releasing Display Resources</h3>
345 <p>When the application is about to exit, the resources associated with
346 the graphics system can be released by calling XCloseDisplay:</p>
347 <blockquote>
348 <pre>void XCloseDisplay(Display *dpy)<br></pre>
349 </blockquote>
350 <p>The display handle becomes invalid at this point.<br>
351 <br>
352 </p>
353 <h2>3.8 Query Functions</h2>
354 <h3>3.8.1 Querying Available Visuals</h3>
355 A list of all available visuals can be obtained with the XGetVisualInfo
356 function:<br>
357 <br>
358 <div style="margin-left: 40px;"><code>XVisualInfo
359 *XGetVisualInfo(Display *dpy, long vinfo_mask, XVisualInfo
360 *vinfo_template, int *nitems_return)<br>
361 </code></div>
362 <br>
363 The parameters are as follows:<br>
364 <blockquote>
365 <dl>
366 <dt><code>dpy</code></dt>
367 <dd>The display handle, as returned by XOpenDisplay.</dd>
368 <dt><code>vinfo_mask</code></dt>
369 <dd>A bitmask indicating which fields of the vinfo_template are to
370 be matched. &nbsp;The value must be VisualScreenMask.</dd>
371 <dt><code>vinfo_template</code></dt>
372 <dd>A template whose fields indicate which visual attributes must
373 be matched by the results. &nbsp;The screen field of this structure must
374 be zero.</dd>
375 <dt><code>nitems_return</code></dt>
376 <dd>Returns the number of visuals returned. </dd>
377 </dl>
378 </blockquote>
379 The return value is the address of an array of all available visuals.<br>
380 <br>
381 An example of using XGetVisualInfo to get all available visuals follows:<br>
382 <br>
383 <div style="margin-left: 40px;"><code>XVisualInfo visTemplate, *results;</code><br>
384 <code>int numVisuals;</code><br>
385 <code>Display *dpy = XOpenDisplay(NULL);</code><br>
386 <code>visTemplate.screen = 0;</code><br>
387 <code>results = XGetVisualInfo(dpy, VisualScreenMask, &amp;visTemplate,
388 &amp;numVisuals);</code><br>
389 <code></code></div>
390 <br>
391 <h3>3.8.2 Querying Visual Attributes</h3>
392 <p>The GLX attributes of an X visual may be queried with the
393 glXGetConfig function:</p>
394 <blockquote>
395 <pre>int glXGetConfig(Display *dpy, XVisualInfo *vis, int attribute, int *value)<br></pre>
396 </blockquote>
397 <p>The parameters are as follows:</p>
398 <blockquote>
399 <dl>
400 <dt><code>dpy</code></dt>
401 <dd>The display handle, as returned by XOpenDisplay.</dd>
402 <dt><code>vis</code></dt>
403 <dd>The visual, as returned by glXChooseVisual.</dd>
404 <dt><code>attribute</code></dt>
405 <dd>The attribute to query. The attributes are listed below.</dd>
406 <dt><code>value</code></dt>
407 <dd>Pointer to an integer in which the result of the query will be
408 stored. </dd>
409 </dl>
410 </blockquote>
411 <p>The return value will be zero if no error occurs.<code>
412 &nbsp;GLX_INVALID_ATTRIBUTE</code> will be returned if the attribute
413 parameter is invalid.<code> &nbsp;GLX_BAD_VISUAL</code> will be returned
414 if the XVisualInfo parameter is invalid.</p>
415 <p>The following attributes may be queried:</p>
416 <blockquote>
417 <dl>
418 <dt><code>GLX_USE_GL</code></dt>
419 <dd>The result will be <code>True</code> or <code>False</code> to
420 indicate if OpenGL rendering is supported with the visual. Mini GLX
421 always return <code>True</code>.</dd>
422 <dt><code>GLX_RGBA</code></dt>
423 <dd>The result will be <code>True</code> for RGBA visuals or <code>False</code>
424 for color index visuals.</dd>
425 <dt><code>GLX_DOUBLEBUFFER</code></dt>
426 <dd>The result will be <code>True</code> if the visual has two
427 color buffers or <code>False</code> if the visual has one color buffer.</dd>
428 <dt><code>GLX_RED_SIZE</code></dt>
429 <dd>The result will be the number of red bits per pixel.</dd>
430 <dt><code>GLX_GREEN_SIZE</code></dt>
431 <dd>The result will be the number of green bits per pixel.</dd>
432 <dt><code>GLX_BLUE_SIZE</code></dt>
433 <dd>The result will be the number of blue bits per pixel.</dd>
434 <dt><code>GLX_ALPHA_SIZE</code></dt>
435 <dd>The result will be the number of alpha bits per pixel.</dd>
436 <dt><code>GLX_DEPTH_SIZE</code></dt>
437 <dd>The result will be the number of bits per Z value.</dd>
438 <dt><code>GLX_STENCIL_SIZE</code></dt>
439 <dd>The result will be the number of bits per stencil value.<br>
440 <br>
441 </dd>
442 </dl>
443 </blockquote>
444 <h3>3.8.3 Querying the Current Rendering Context</h3>
445 <p>The current rendering context can be queried with
446 glXGetCurrentContext: </p>
447 <blockquote>
448 <pre>GLXContext glXGetCurrentContext(void)<br></pre>
449 </blockquote>
450 <p>Zero will be returned if no context is currently bound.<br>
451 <br>
452 </p>
453 <h3>3.8.4 Querying the Current Drawable</h3>
454 <p>The current drawable (i.e. window or drawing surface) can be queried
455 with glXGetCurrentDrawable:</p>
456 <blockquote>
457 <pre>GLXDrawable glXGetCurrentDrawable(void)<br></pre>
458 </blockquote>
459 <p>Zero will be returned if no drawable is currently bound.<br>
460 <br>
461 </p>
462 <h3>3.8.5 Function Address Queries</h3>
463 <p>The glXGetProcAddress function will return the address of any
464 available OpenGL or Mini GLX function:</p>
465 <blockquote>
466 <pre>void *glXGetProcAddress(const GLubyte *procName)<br></pre>
467 </blockquote>
468 <p>If <code>procName</code> is a valid function name, a pointer to that
469 function will be returned. &nbsp;Otherwise, NULL will be returned.</p>
470 <p>The purpose of glXGetProcAddress is to facilitate using future
471 extensions to OpenGL or Mini GLX. If a future version of the library
472 adds new extension functions they'll be accessible via
473 glXGetProcAddress. The alternative is to hard-code calls to the new
474 functions in the application but doing so will prevent linking the
475 application with older versions of the library.<br>
476 <br>
477 </p>
478 <h2>3.9 Versioning</h2>
479 The Mini GLX version can be queried at run time with glXQueryVersion:
480 <blockquote>
481 <pre>Bool glXQueryVersion(Display *dpy, int *major, int *minor)<br></pre>
482 </blockquote>
483 <p><code>major</code> will be set to the major version number and<code>minor</code>
484 will be set to the minor version number.<code>True</code> will be
485 returned if the function succeeds. <code>False</code> will be returned
486 if the function fails due to invalid parameters. The <code>dpy</code>
487 argument is currently ignored, but should be the value returned by
488 XOpenDisplay.</p>
489 <p>At compile time, the Mini GLX interface version can be tested with
490 the MINI_GLX_VERSION_1_<i>x</i> preprocessor tokens. For example, if
491 version 1.0 of Mini GLX is supported, then<code> MINI_GLX_VERSION_1_0</code>
492 will be defined. If version 1.1 of Mini GLX is supported, then<code>
493 MINI_GLX_VERSION_1_1</code> will be defined.</p>
494 <p>At the time of writing the current Mini GLX version is 1.0.<br>
495 <br>
496 </p>
497 <h1>4.0 Interoperability with GLX and Xlib</h1>
498 While Mini GLX strives to be compatible with GLX and Xlib there are
499 some unavoidable differences which must be taken into consideration.<br>
500 <h2>4.1 Public vs Private Structures</h2>
501 The structure of many X data types is public. &nbsp;For example, the <code>Display</code>
502 data type is defined as a structure in /usr/include/X11/Xlib.h and
503 programmers may access any fields of that structure at will. &nbsp;Mini
504 GLX also defines a Display data type but its fields are hidden and not
505 visiblein <code>miniglx.h</code>. &nbsp;Duplicating the Xlib
506 declaration for the <code>Display</code> data type in minigl.h would
507 require defining a large number of other superfluous Xlib datatypes.<br>
508 <br>
509 Mini GLX users are discouraged from directly accessing the fields of
510 Xlib data types to maximize portability - though this is unavoidable to
511 some extent. &nbsp;For example, the <code>XVisualInfo</code> and <code>XSetWindowAtttributes</code>
512 data types must be completely public.
513 <h2>4.2 Macros</h2>
514 In some cases, Xlib defines macros which are meant to be used instead
515 of direct structure accesses. &nbsp;For example, the <code>RootWindow(dpy,
516 screen)</code> macro returns the root window for a given screen on a
517 given display. &nbsp;Unfortunately, macros do nothing to aid in ABI
518 compatibility since they are resolved at compile time instead of at
519 link/run time.<br>
520 <br>
521 Mini GLX also defines a <code>RootWindow</code> macro since it's
522 essential for creating windows. &nbsp;But the implementation of this
523 macro by Xlib and Mini GLX is completely different.<br>
524 <h2>4.3 Summary</h2>
525 Because Xlib and Mini GLX define data types and macros differently,
526 Mini GLX applications must be recompiled when retargeting Mini GLX or
527 native Xlib/GLX. &nbsp;That is, applications can't simply be re-linked
528 because of ABI incompatibilities.<br>
529 <br>
530 Nevertheless, the fact that Mini GLX programs can be recompiled for
531 Xlib and GLX increases portability and flexibility for testing and
532 prototyping.<br>
533 <br>
534 <h1>5.0 Example Program</h1>
535 <p>This section shows an example program which uses the Mini GLX
536 interface. The program simply draws several frames of a rotating square.<br>
537 </p>
538 <p>The program may be compiled for use with Xlib/GLX or Mini GLX by
539 setting the <code>USE_MINIGLX</code> token to 0 or 1, respectively.
540 &nbsp;Note that the only difference is the header files which are
541 included.<br>
542 </p>
543 <p> </p>
544 <pre><code><br></code>#define USE_MINIGLX 1 /* 1 = use Mini GLX, 0 = use Xlib/GLX */<br><br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;GL/gl.h&gt;<br><br>#if USE_MINIGLX<br>#include &lt;GL/miniglx.h&gt;<br>#else<br>#include &lt;GL/glx.h&gt;<br>#include &lt;X11/Xlib.h&gt;<br>#endif<br><br><code>/*<br> * Create a simple double-buffered RGBA window.<br> */<br>static Window<br>MakeWindow(Display * dpy, unsigned int width, unsigned int height)<br>{<br> int visAttributes[] = {<br> GLX_RGBA,<br> GLX_RED_SIZE, 1,<br> GLX_GREEN_SIZE, 1,<br> GLX_BLUE_SIZE, 1,<br> GLX_DOUBLEBUFFER,<br> None<br> };<br> XSetWindowAttributes attr;<br> unsigned long attrMask;<br> Window root;<br> Window win;<br> GLXContext ctx;<br> XVisualInfo *visinfo;<br><br> root = RootWindow(dpy, 0);<br><br> /* Choose GLX visual / pixel format */<br> visinfo = glXChooseVisual(dpy, 0, visAttributes);<br> if (!visinfo) {<br> printf("Error: couldn't get an RGB, Double-buffered visual\n");<br> exit(1);<br> }<br><br> /* Create the window */<br> attr.background_pixel = 0;<br> attr.border_pixel = 0;<br> attr.colormap = XCreateColormap(dpy, root, visinfo-&gt;visual, AllocNone);<br> attrMask = CWBackPixel | CWBorderPixel | CWColormap;<br> win = XCreateWindow(dpy, root, 0, 0, width, height,<br> 0, visinfo-&gt;depth, InputOutput,<br> visinfo-&gt;visual, attrMask, &amp;attr);<br> if (!win) {<br> printf("Error: XCreateWindow failed\n");<br> exit(1);<br> }<br><br> /* Display the window */<br> XMapWindow(dpy, win);<br><br> /* Create GLX rendering context */<br> ctx = glXCreateContext(dpy, visinfo, NULL, True);<br> if (!ctx) {<br> printf("Error: glXCreateContext failed\n");<br> exit(1);<br> }<br><br> /* Bind the rendering context and window */<br> glXMakeCurrent(dpy, win, ctx);<br><br> return win;<br>}<br><br><br>/*<br> * Draw a few frames of a rotating square.<br> */<br>static void<br>DrawFrames(Display * dpy, Window win)<br>{<br> int angle;<br> glShadeModel(GL_FLAT);<br> glClearColor(0.5, 0.5, 0.5, 1.0);<br> for (angle = 0; angle &lt; 360; angle += 10) {<br> glClear(GL_COLOR_BUFFER_BIT);<br> glColor3f(1.0, 1.0, 0.0);<br> glPushMatrix();<br> glRotatef(angle, 0, 0, 1);<br> glRectf(-0.8, -0.8, 0.8, 0.8);<br> glPopMatrix();<br> glXSwapBuffers(dpy, win);<br> }<br>}<br><br><br>int<br>main(int argc, char *argv[])<br>{<br> Display *dpy;<br> Window win;<br><br> dpy = XOpenDisplay(NULL);<br> if (!dpy) {<br> printf("Error: XOpenDisplay failed\n");<br> return 1;<br> }<br><br> win = MakeWindow(dpy, 300, 300);<br><br> DrawFrames(dpy, win);<br><br> return 0;<br>}<br></code></pre>
545 <br>
546 </body>
547 </html>