Brian Paul | 56e9efa | 2003-09-03 23:04:02 +0000 | [diff] [blame] | 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 © 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 <GL/miniglx.h><br> |
| 83 | </code></blockquote> |
| 84 | <code></code>Applications should link with libGL.so (i.e. <code>gcc |
| 85 | myprogram.o -lGL -o myprogram</code>). 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. The |
| 88 | environment variable <code>LIBGL_DRIVERS_PATH</code> should name the |
| 89 | directory where these modules are located.<br> |
| 90 | <br> |
Brian Paul | 56e9efa | 2003-09-03 23:04:02 +0000 | [diff] [blame] | 91 | The remainder of this section describes the MiniGLX API functions.<br> |
| 92 | <br> |
| 93 | <h2>3.1 Initialization</h2> |
| 94 | <p>The XOpenDisplay function is used to initialize the graphics system:</p> |
| 95 | <blockquote> |
| 96 | <pre>Display *XOpenDisplay(const char *displayname)<br></pre> |
| 97 | </blockquote> |
| 98 | <p>The <code>displayName</code> parameter is currently ignored in Mini |
| 99 | GLX. It is recommended that <code>NULL</code> be passed as the<code>displayName</code> |
| 100 | parameter.</p> |
| 101 | <p>If XOpenDisplay is able to initialize the graphics system a pointer |
| 102 | to a Display will be returned. Otherwise, NULL will be returned.</p> |
| 103 | <h2>3.2 Choosing a Visual</h2> |
| 104 | <p>A visual (i.e. pixel format) must be chosen before a drawing surface |
| 105 | or rendering context can be created. This is done with the |
| 106 | glXChooseVisual function:</p> |
| 107 | <blockquote> |
| 108 | <pre>XVisualInfo *glXChooseVisual(Display *dpy, int screen, const int *attribList)<br></pre> |
| 109 | </blockquote> |
| 110 | <p><code>dpy</code> is a pointer to the display returned by |
| 111 | XOpenDisplay. </p> |
| 112 | <p><code>screen</code> is currently ignored by Mini GLX and should be |
| 113 | zero. </p> |
| 114 | <p><code>attribList</code> is a list of GLX attributes which describe |
| 115 | the desired pixel format. It is terminated by the token <code>None</code>. |
| 116 | The attributes are as follows:</p> |
| 117 | <blockquote> |
| 118 | <dl> |
| 119 | <dt><code>GLX_USE_GL</code></dt> |
| 120 | <dd>This attribute should always be present in order to maintain |
| 121 | compatibility with GLX.</dd> |
| 122 | <dt><code>GLX_RGBA</code></dt> |
| 123 | <dd>If present, only RGBA pixel formats will be considered. |
| 124 | Otherwise, only color index formats are considered.</dd> |
| 125 | <dt><code>GLX_DOUBLEBUFFER</code></dt> |
| 126 | <dd>if present, only double-buffered pixel formats will be chosen.</dd> |
| 127 | <dt><code>GLX_RED_SIZE n</code></dt> |
| 128 | <dd>Must be followed by a non-negative integer indicating the |
| 129 | minimum number of bits per red pixel component that is acceptable.</dd> |
| 130 | <dt><code>GLX_GREEN_SIZE n</code></dt> |
| 131 | <dd>Must be followed by a non-negative integer indicating the |
| 132 | minimum number of bits per green pixel component that is acceptable.</dd> |
| 133 | <dt><code>GLX_BLUE_SIZE n</code></dt> |
| 134 | <dd>Must be followed by a non-negative integer indicating the |
| 135 | minimum number of bits per blue pixel component that is acceptable.</dd> |
| 136 | <dt><code>GLX_ALPHA_SIZE n</code></dt> |
| 137 | <dd>Must be followed by a non-negative integer indicating the |
| 138 | minimum number of bits per alpha pixel component that is acceptable.</dd> |
| 139 | <dt><code>GLX_STENCIL_SIZE n</code></dt> |
| 140 | <dd>Must be followed by a non-negative integer indicating the |
| 141 | minimum number of bits per stencil value that is acceptable.</dd> |
| 142 | <dt><code>None</code></dt> |
| 143 | <dd>This token is used to terminate the attribute list.</dd> |
| 144 | </dl> |
| 145 | </blockquote> |
| 146 | <p>glXChooseVisual will return a pointer to an XVisualInfo object which |
| 147 | most closely matches the requirements of the attribute list. If there |
| 148 | is no visual which matches the request, NULL will be returned.</p> |
| 149 | <p>Note that visuals with accumulation buffers and depth buffers are |
| 150 | not available.<br> |
| 151 | <br> |
| 152 | </p> |
| 153 | <h2>3.3 Creating a Drawing Surface</h2> |
| 154 | <p>Drawing surfaces are created as X windows. For Mini GLX, |
| 155 | windows are <i>full-screen</i>; they cover the entire frame buffer. |
| 156 | Also, Mini GLX imposes a limit of one window. A second window |
| 157 | cannot be created until the first one is destroyed.</p> |
| 158 | <h3>3.3.1 Window Creation</h3> |
| 159 | <p>The XCreateWindow function is used to create a drawing surface:</p> |
| 160 | <blockquote> |
| 161 | <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> |
| 162 | </blockquote> |
| 163 | <p>The parameters are as follows:</p> |
| 164 | <blockquote> |
| 165 | <dl> |
| 166 | <dt><code>display</code></dt> |
| 167 | <dd>A Display pointer, as returned by XOpenDisplay.</dd> |
| 168 | <dt><code>parent</code></dt> |
| 169 | <dd>The parent window for the new window. For Mini GLX, this |
| 170 | should be<code>RootWindow(dpy, 0)</code>.</dd> |
| 171 | <dt><code>x, y</code></dt> |
| 172 | <dd>The position of the window. For Mini GLX, both values should |
| 173 | be zero.</dd> |
| 174 | <dt><code>width, height</code></dt> |
| 175 | <dd>The size of the window. For Mini GLX, this specifies the |
| 176 | desired screen size such as 1024, 768 or 1280, 1024.</dd> |
| 177 | <dt><code>borderWidth</code></dt> |
| 178 | <dd>This parameter should be zero.</dd> |
| 179 | <dt><code>depth</code></dt> |
| 180 | <dd>The pixel depth for the window. For Mini GLX this should be |
| 181 | the depth found in the XVisualInfo object returned by <code>glxChooseVisual</code>.</dd> |
| 182 | <dt><code>class</code></dt> |
| 183 | <dd>The window class. For Mini GLX this value should be <code>InputOutput</code>.</dd> |
| 184 | <dt><code>visual</code></dt> |
| 185 | <dd>This parameter should be the <code>visual</code> field of the <code>XVisualInfo</code> |
| 186 | object returned by <code>glxChooseVisual</code>.</dd> |
| 187 | <dt><code>valuemask</code></dt> |
| 188 | <dd>This parameter indicates which fields of the <code>XSetWindowAttributes</code> |
| 189 | are to be used. For Mini GLX this is typically the bitmask<code>CWBackPixel |
| 190 | | CWBorderPixel | CWColormap</code>.</dd> |
| 191 | <dt><code>attributes</code></dt> |
| 192 | <dd>Initial window attributes. Of the fields in the <code>XSetWindowAttributes</code> |
| 193 | structure, the<code>background_pixel</code>, <code>border_pixel</code> |
| 194 | and <code>colormap</code> fields should be set. See the discussion |
| 195 | below regarding colormaps.</dd> |
| 196 | </dl> |
| 197 | </blockquote> |
| 198 | <p><code>XCreateWindow</code> will return a window handle if it succeeds |
| 199 | or zero if it fails.</p> |
| 200 | <h3>3.3.2 Window Mapping</h3> |
| 201 | <p>To display the window the XMapWindow function must be called:</p> |
| 202 | <blockquote> |
| 203 | <pre>void XMapWindow(Display *dpy, Window w)</pre> |
| 204 | </blockquote> |
| 205 | <p>This function does nothing in Mini GLX but is required for Xlib/GLX |
| 206 | compatibility</p> |
| 207 | <h3>3.3.3 Colormaps<br> |
| 208 | </h3> |
| 209 | <p>Xlib requires specification of a colormap when creating a window. |
| 210 | For purposes of interoperability, Mini GLX requires this as well, |
| 211 | though the colormap is not actually used. The XCreateColormap |
| 212 | function is used to create a colormap:</p> |
| 213 | <blockquote><code>Colormap XCreateColormap(Display *dpy, Window window, |
| 214 | Visual *visual, int alloc)</code><br> |
| 215 | <code></code></blockquote> |
| 216 | <p>The parameters are as follows:<br> |
| 217 | </p> |
| 218 | <blockquote> |
| 219 | <dl> |
| 220 | <dt><code>dpy</code></dt> |
| 221 | <dd>The display handle as returned by XOpenDisplay.</dd> |
| 222 | <dt><code>window</code></dt> |
| 223 | <dd> This parameter is ignored by Mini GLX but should be the value |
| 224 | returned by the <code>RootWindow(dpy, 0)</code> macro.<br> |
| 225 | </dd> |
| 226 | <dt><code>visual</code></dt> |
| 227 | <dd>This parameter is ignored by Mini GLX but should be the visual |
| 228 | field of the XVisualInfo object returned by glXChooseVisual. </dd> |
| 229 | <dt><code>alloc</code></dt> |
| 230 | <dd>This parameter is ignored by Mini GLX but should be set to <code>AllocNone</code>.</dd> |
| 231 | </dl> |
| 232 | </blockquote> |
| 233 | <br> |
| 234 | <h2>3.4 Creating a Rendering Context</h2> |
| 235 | <p>An OpenGL rendering context is created with the <code>glXCreateContext</code> |
| 236 | function:</p> |
| 237 | <blockquote> |
| 238 | <pre>GLXContext glXCreateContext(Display *dpy, XVisualInfo *visInfo, GLXContext shareList, Bool direct)<br></pre> |
| 239 | </blockquote> |
| 240 | <p>The parameters are as follows:</p> |
| 241 | <blockquote> |
| 242 | <dl> |
| 243 | <dt><code>dpy</code></dt> |
| 244 | <dd>The display handle as returned by XOpenDisplay.</dd> |
| 245 | <dt><code>visInfo</code></dt> |
| 246 | <dd>The visual as returned by glXChooseVisual.</dd> |
| 247 | <dt><code>shareList</code></dt> |
| 248 | <dd>If non-zero, texture objects and display lists are shared with |
| 249 | the named rendering context. If zero, texture objects and display lists |
| 250 | will (initially) be private to this context. They may be shared when a |
| 251 | subsequent context is created.</dd> |
| 252 | <dt><code>direct</code></dt> |
| 253 | <dd>Specifies whether direct or indirect rendering is desired. For |
| 254 | Mini GLX this value is ignored but it should be set to <code>True</code>.</dd> |
| 255 | </dl> |
| 256 | </blockquote> |
| 257 | <p><code>glXCreateContext</code> will return a GLXContext handle if it |
| 258 | succeeds or zero if it fails due to invalid parameter or insufficient |
| 259 | resources.<br> |
| 260 | <br> |
| 261 | </p> |
| 262 | <h2>3.5 Binding a Rendering Context</h2> |
| 263 | <p>The final step before beginning OpenGL rendering is to bind (i.e. |
| 264 | activate) a rendering context and drawing surface with the |
| 265 | glXMakeCurrent function:</p> |
| 266 | <blockquote> |
| 267 | <pre>Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)<br></pre> |
| 268 | </blockquote> |
| 269 | <p>The parameters are as follows:</p> |
| 270 | <blockquote> |
| 271 | <dl> |
| 272 | <dt><code>dpy</code></dt> |
| 273 | <dd>The display handle, as returned by XOpenDisplay.</dd> |
| 274 | <dt><code>drawable</code></dt> |
| 275 | <dd>The window or drawable to bind to the rendering context. This |
| 276 | should be the value returned by XCreateWindow.</dd> |
| 277 | <dt><code>ctx</code></dt> |
| 278 | <dd>The rendering context to bind, as returned by glXCreateContext.</dd> |
| 279 | </dl> |
| 280 | </blockquote> |
| 281 | <p>If glXMakeCurrent succeeds True is returned. Otherwise False is |
| 282 | returned to indicate an invalid display, window or context parameter.</p> |
| 283 | <p>After the rendering context has been bound to the drawing surface |
| 284 | OpenGL rendering can begin.</p> |
| 285 | <p>The current rendering context may be unbound by calling |
| 286 | glXMakeCurrent with the window and context parameters set to zero.</p> |
| 287 | <p>An application may create any number of rendering contexts and bind |
| 288 | them as needed. Note that binding a rendering context is generally not a |
| 289 | light-weight operation. Most simple OpenGL applications create |
| 290 | only one rendering context.<br> |
| 291 | <br> |
| 292 | </p> |
| 293 | <h2>3.6 Color Buffer Swapping</h2> |
| 294 | <p>A double buffered window has two color buffers: a front buffer and a |
| 295 | back buffer. Normally, rendering is directed to the back buffer while |
| 296 | the front buffer is displayed. When rendering of a frame is finished |
| 297 | the front and back buffers are swapped to provide the illusion of |
| 298 | instanteous screen updates.</p> |
| 299 | <p>The color buffers for a particular window (i.e. drawable) may be |
| 300 | swapped with the glXSwapBuffers command:</p> |
| 301 | <blockquote> |
| 302 | <pre>void glXSwapBuffers(Display *dpy, GLXDrawable drawable)<br></pre> |
| 303 | </blockquote> |
| 304 | Any pending rendering commands will be completed before the buffer swap |
| 305 | takes place.<br> |
| 306 | <br> |
| 307 | Calling glXSwapBuffers on a window which is single-buffered has no |
| 308 | effect.<br> |
| 309 | <br> |
| 310 | <h2>3.7 Releasing Resources</h2> |
| 311 | <h3>3.7.1 Releasing Rendering Contexts</h3> |
| 312 | <p>A rendering context may be destroyed by calling glXDestroyContext:</p> |
| 313 | <blockquote> |
| 314 | <pre>void glXDestroyContext(Display *dpy, GLXContext ctx)<br></pre> |
| 315 | </blockquote> |
| 316 | <h3>3.7.2 Releasing Windows</h3> |
| 317 | <p>A window may be destroyed by calling XDestroyWindow:</p> |
| 318 | <blockquote> |
| 319 | <pre>void XDestroyWindow(Display *dpy, Window window)<br></pre> |
| 320 | </blockquote> |
| 321 | <h3>3.7.3 Releasing Visuals</h3> |
| 322 | <p>An XVisualInfo object may be freed by calling XFree:</p> |
| 323 | <blockquote> |
| 324 | <pre>void XFree(void *data)<br></pre> |
| 325 | </blockquote> |
| 326 | <h3>3.7.4 Releasing Colormaps</h3> |
| 327 | <p>A colormap may be freed by calling XFreeColormap:</p> |
| 328 | <blockquote> |
| 329 | <pre>void XFreeColormap(Display *dpy, Colormap colormap)<br></pre> |
| 330 | </blockquote> |
| 331 | <h3>3.7.4 Releasing Display Resources</h3> |
| 332 | <p>When the application is about to exit, the resources associated with |
| 333 | the graphics system can be released by calling XCloseDisplay:</p> |
| 334 | <blockquote> |
| 335 | <pre>void XCloseDisplay(Display *dpy)<br></pre> |
| 336 | </blockquote> |
| 337 | <p>The display handle becomes invalid at this point.<br> |
| 338 | <br> |
| 339 | </p> |
| 340 | <h2>3.8 Query Functions</h2> |
| 341 | <h3>3.8.1 Querying Available Visuals</h3> |
| 342 | A list of all available visuals can be obtained with the XGetVisualInfo |
| 343 | function:<br> |
| 344 | <br> |
| 345 | <div style="margin-left: 40px;"><code>XVisualInfo |
| 346 | *XGetVisualInfo(Display *dpy, long vinfo_mask, XVisualInfo |
| 347 | *vinfo_template, int *nitems_return)<br> |
| 348 | </code></div> |
| 349 | <br> |
| 350 | The parameters are as follows:<br> |
| 351 | <blockquote> |
| 352 | <dl> |
| 353 | <dt><code>dpy</code></dt> |
| 354 | <dd>The display handle, as returned by XOpenDisplay.</dd> |
| 355 | <dt><code>vinfo_mask</code></dt> |
| 356 | <dd>A bitmask indicating which fields of the vinfo_template are to |
| 357 | be matched. The value must be VisualScreenMask.</dd> |
| 358 | <dt><code>vinfo_template</code></dt> |
| 359 | <dd>A template whose fields indicate which visual attributes must |
| 360 | be matched by the results. The screen field of this structure must |
| 361 | be zero.</dd> |
| 362 | <dt><code>nitems_return</code></dt> |
| 363 | <dd>Returns the number of visuals returned. </dd> |
| 364 | </dl> |
| 365 | </blockquote> |
| 366 | The return value is the address of an array of all available visuals.<br> |
| 367 | <br> |
| 368 | An example of using XGetVisualInfo to get all available visuals follows:<br> |
| 369 | <br> |
| 370 | <div style="margin-left: 40px;"><code>XVisualInfo visTemplate, *results;</code><br> |
| 371 | <code>int numVisuals;</code><br> |
| 372 | <code>Display *dpy = XOpenDisplay(NULL);</code><br> |
| 373 | <code>visTemplate.screen = 0;</code><br> |
| 374 | <code>results = XGetVisualInfo(dpy, VisualScreenMask, &visTemplate, |
| 375 | &numVisuals);</code><br> |
| 376 | <code></code></div> |
| 377 | <br> |
| 378 | <h3>3.8.2 Querying Visual Attributes</h3> |
| 379 | <p>The GLX attributes of an X visual may be queried with the |
| 380 | glXGetConfig function:</p> |
| 381 | <blockquote> |
| 382 | <pre>int glXGetConfig(Display *dpy, XVisualInfo *vis, int attribute, int *value)<br></pre> |
| 383 | </blockquote> |
| 384 | <p>The parameters are as follows:</p> |
| 385 | <blockquote> |
| 386 | <dl> |
| 387 | <dt><code>dpy</code></dt> |
| 388 | <dd>The display handle, as returned by XOpenDisplay.</dd> |
| 389 | <dt><code>vis</code></dt> |
| 390 | <dd>The visual, as returned by glXChooseVisual.</dd> |
| 391 | <dt><code>attribute</code></dt> |
| 392 | <dd>The attribute to query. The attributes are listed below.</dd> |
| 393 | <dt><code>value</code></dt> |
| 394 | <dd>Pointer to an integer in which the result of the query will be |
| 395 | stored. </dd> |
| 396 | </dl> |
| 397 | </blockquote> |
| 398 | <p>The return value will be zero if no error occurs.<code> |
| 399 | GLX_INVALID_ATTRIBUTE</code> will be returned if the attribute |
| 400 | parameter is invalid.<code> GLX_BAD_VISUAL</code> will be returned |
| 401 | if the XVisualInfo parameter is invalid.</p> |
| 402 | <p>The following attributes may be queried:</p> |
| 403 | <blockquote> |
| 404 | <dl> |
| 405 | <dt><code>GLX_USE_GL</code></dt> |
| 406 | <dd>The result will be <code>True</code> or <code>False</code> to |
| 407 | indicate if OpenGL rendering is supported with the visual. Mini GLX |
| 408 | always return <code>True</code>.</dd> |
| 409 | <dt><code>GLX_RGBA</code></dt> |
| 410 | <dd>The result will be <code>True</code> for RGBA visuals or <code>False</code> |
| 411 | for color index visuals.</dd> |
| 412 | <dt><code>GLX_DOUBLEBUFFER</code></dt> |
| 413 | <dd>The result will be <code>True</code> if the visual has two |
| 414 | color buffers or <code>False</code> if the visual has one color buffer.</dd> |
| 415 | <dt><code>GLX_RED_SIZE</code></dt> |
| 416 | <dd>The result will be the number of red bits per pixel.</dd> |
| 417 | <dt><code>GLX_GREEN_SIZE</code></dt> |
| 418 | <dd>The result will be the number of green bits per pixel.</dd> |
| 419 | <dt><code>GLX_BLUE_SIZE</code></dt> |
| 420 | <dd>The result will be the number of blue bits per pixel.</dd> |
| 421 | <dt><code>GLX_ALPHA_SIZE</code></dt> |
| 422 | <dd>The result will be the number of alpha bits per pixel.</dd> |
| 423 | <dt><code>GLX_DEPTH_SIZE</code></dt> |
| 424 | <dd>The result will be the number of bits per Z value.</dd> |
| 425 | <dt><code>GLX_STENCIL_SIZE</code></dt> |
| 426 | <dd>The result will be the number of bits per stencil value.<br> |
| 427 | <br> |
| 428 | </dd> |
| 429 | </dl> |
| 430 | </blockquote> |
| 431 | <h3>3.8.3 Querying the Current Rendering Context</h3> |
| 432 | <p>The current rendering context can be queried with |
| 433 | glXGetCurrentContext: </p> |
| 434 | <blockquote> |
| 435 | <pre>GLXContext glXGetCurrentContext(void)<br></pre> |
| 436 | </blockquote> |
| 437 | <p>Zero will be returned if no context is currently bound.<br> |
| 438 | <br> |
| 439 | </p> |
| 440 | <h3>3.8.4 Querying the Current Drawable</h3> |
| 441 | <p>The current drawable (i.e. window or drawing surface) can be queried |
| 442 | with glXGetCurrentDrawable:</p> |
| 443 | <blockquote> |
| 444 | <pre>GLXDrawable glXGetCurrentDrawable(void)<br></pre> |
| 445 | </blockquote> |
| 446 | <p>Zero will be returned if no drawable is currently bound.<br> |
| 447 | <br> |
| 448 | </p> |
| 449 | <h3>3.8.5 Function Address Queries</h3> |
| 450 | <p>The glXGetProcAddress function will return the address of any |
| 451 | available OpenGL or Mini GLX function:</p> |
| 452 | <blockquote> |
| 453 | <pre>void *glXGetProcAddress(const GLubyte *procName)<br></pre> |
| 454 | </blockquote> |
| 455 | <p>If <code>procName</code> is a valid function name, a pointer to that |
| 456 | function will be returned. Otherwise, NULL will be returned.</p> |
| 457 | <p>The purpose of glXGetProcAddress is to facilitate using future |
| 458 | extensions to OpenGL or Mini GLX. If a future version of the library |
| 459 | adds new extension functions they'll be accessible via |
| 460 | glXGetProcAddress. The alternative is to hard-code calls to the new |
| 461 | functions in the application but doing so will prevent linking the |
| 462 | application with older versions of the library.<br> |
| 463 | <br> |
| 464 | </p> |
| 465 | <h2>3.9 Versioning</h2> |
| 466 | The Mini GLX version can be queried at run time with glXQueryVersion: |
| 467 | <blockquote> |
| 468 | <pre>Bool glXQueryVersion(Display *dpy, int *major, int *minor)<br></pre> |
| 469 | </blockquote> |
| 470 | <p><code>major</code> will be set to the major version number and<code>minor</code> |
| 471 | will be set to the minor version number.<code>True</code> will be |
| 472 | returned if the function succeeds. <code>False</code> will be returned |
| 473 | if the function fails due to invalid parameters. The <code>dpy</code> |
| 474 | argument is currently ignored, but should be the value returned by |
| 475 | XOpenDisplay.</p> |
| 476 | <p>At compile time, the Mini GLX interface version can be tested with |
| 477 | the MINI_GLX_VERSION_1_<i>x</i> preprocessor tokens. For example, if |
| 478 | version 1.0 of Mini GLX is supported, then<code> MINI_GLX_VERSION_1_0</code> |
| 479 | will be defined. If version 1.1 of Mini GLX is supported, then<code> |
| 480 | MINI_GLX_VERSION_1_1</code> will be defined.</p> |
| 481 | <p>At the time of writing the current Mini GLX version is 1.0.<br> |
| 482 | <br> |
| 483 | </p> |
| 484 | <h1>4.0 Interoperability with GLX and Xlib</h1> |
| 485 | While Mini GLX strives to be compatible with GLX and Xlib there are |
| 486 | some unavoidable differences which must be taken into consideration.<br> |
| 487 | <h2>4.1 Public vs Private Structures</h2> |
| 488 | The structure of many X data types is public. For example, the <code>Display</code> |
| 489 | data type is defined as a structure in /usr/include/X11/Xlib.h and |
| 490 | programmers may access any fields of that structure at will. Mini |
| 491 | GLX also defines a Display data type but its fields are hidden and not |
| 492 | visiblein <code>miniglx.h</code>. Duplicating the Xlib |
| 493 | declaration for the <code>Display</code> data type in minigl.h would |
| 494 | require defining a large number of other superfluous Xlib datatypes.<br> |
| 495 | <br> |
| 496 | Mini GLX users are discouraged from directly accessing the fields of |
| 497 | Xlib data types to maximize portability - though this is unavoidable to |
| 498 | some extent. For example, the <code>XVisualInfo</code> and <code>XSetWindowAtttributes</code> |
| 499 | data types must be completely public. |
| 500 | <h2>4.2 Macros</h2> |
| 501 | In some cases, Xlib defines macros which are meant to be used instead |
| 502 | of direct structure accesses. For example, the <code>RootWindow(dpy, |
| 503 | screen)</code> macro returns the root window for a given screen on a |
| 504 | given display. Unfortunately, macros do nothing to aid in ABI |
| 505 | compatibility since they are resolved at compile time instead of at |
| 506 | link/run time.<br> |
| 507 | <br> |
| 508 | Mini GLX also defines a <code>RootWindow</code> macro since it's |
| 509 | essential for creating windows. But the implementation of this |
| 510 | macro by Xlib and Mini GLX is completely different.<br> |
| 511 | <h2>4.3 Summary</h2> |
| 512 | Because Xlib and Mini GLX define data types and macros differently, |
| 513 | Mini GLX applications must be recompiled when retargeting Mini GLX or |
| 514 | native Xlib/GLX. That is, applications can't simply be re-linked |
| 515 | because of ABI incompatibilities.<br> |
| 516 | <br> |
| 517 | Nevertheless, the fact that Mini GLX programs can be recompiled for |
| 518 | Xlib and GLX increases portability and flexibility for testing and |
| 519 | prototyping.<br> |
| 520 | <br> |
| 521 | <h1>5.0 Example Program</h1> |
| 522 | <p>This section shows an example program which uses the Mini GLX |
| 523 | interface. The program simply draws several frames of a rotating square.<br> |
| 524 | </p> |
| 525 | <p>The program may be compiled for use with Xlib/GLX or Mini GLX by |
| 526 | setting the <code>USE_MINIGLX</code> token to 0 or 1, respectively. |
| 527 | Note that the only difference is the header files which are |
| 528 | included.<br> |
| 529 | </p> |
| 530 | <p> </p> |
| 531 | <pre><code><br></code>#define USE_MINIGLX 1 /* 1 = use Mini GLX, 0 = use Xlib/GLX */<br><br>#include <stdio.h><br>#include <stdlib.h><br>#include <GL/gl.h><br><br>#if USE_MINIGLX<br>#include <GL/miniglx.h><br>#else<br>#include <GL/glx.h><br>#include <X11/Xlib.h><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->visual, AllocNone);<br> attrMask = CWBackPixel | CWBorderPixel | CWColormap;<br> win = XCreateWindow(dpy, root, 0, 0, width, height,<br> 0, visinfo->depth, InputOutput,<br> visinfo->visual, attrMask, &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 < 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> |
| 532 | <br> |
| 533 | </body> |
| 534 | </html> |