fb83fe4f295f716e6718c24bb1ea0084de698fe2
[xscreensaver] / utils / visual-gl.c
1 /* xscreensaver, Copyright (c) 1999 by Jamie Zawinski <jwz@jwz.org>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  */
11
12 /* This file contains code for picking the best visual for GL programs by
13    actually asking the GL library to figure it out for us.  The code in
14    visual.c might do a good job of this on most systems, but not, in
15    particular, on SGIs.
16
17    Why?  Because with the SGI O2 X server is weird.
18
19    GL programs tend to work best on a visual that is *half* as deep as the
20    depth of the screen, since that way, they can do double-buffering.  So
21    generally, if the screen is 24 bits deep, but a 12-bit TrueColor visual
22    is available, then that's the visual you should use.
23
24    But on the server that runs on the O2 (a machine that has serious hardware
25    support for GL) the 12-bit PseudoColor visual looks awful (you get a black
26    and white, flickery image.)  On these machines, the visual you want turns
27    out to be 0x31 -- this is but one of the eight 15-bit TrueColor visuals
28    (yes, 8, and yes, 15) that O2s provide.  This is the only visual that works
29    properly -- as far as `xdpyinfo' is concerned, all of the 15-bit TrueColor
30    visuals are identical, but some flicker like mad, and some have deeply
31    weird artifacts (hidden surfaces show through!)  I suppose these other
32    visuals must be tied to some arcane hardware feature...
33
34    So the bottom line is, there exists information about visuals which is
35    available to GL, but which is not available via Xlib calls.  So the only
36    way to know which visual to use (other than impirically) is to actually
37    call GLX routines.
38  */
39
40 #include "utils.h"
41 #include "visual.h"
42
43 #ifdef HAVE_GL
44 # include <GL/gl.h>
45 # include <GL/glx.h>
46 #endif /* HAVE_GL */
47
48 Visual *
49 get_gl_visual (Screen *screen)
50 {
51 #ifdef HAVE_GL
52   XVisualInfo *vi = 0;
53   Display *dpy = DisplayOfScreen (screen);
54   int screen_num = screen_number (screen);
55   int attrs[20];
56   int i = 0;
57
58   attrs[i++] = GLX_RGBA;
59   attrs[i++] = GLX_RED_SIZE;     attrs[i++] = 1;
60   attrs[i++] = GLX_GREEN_SIZE;   attrs[i++] = 1;
61   attrs[i++] = GLX_BLUE_SIZE;    attrs[i++] = 1;
62   attrs[i++] = GLX_DEPTH_SIZE;   attrs[i++] = 1;
63   attrs[i++] = GLX_DOUBLEBUFFER;
64   attrs[i++] = 0;
65
66   vi = glXChooseVisual (dpy, screen_num, attrs);
67
68   if (!vi)                              /* Try without double-buffering. */
69     {
70       attrs[i-1] = 0;
71       vi = glXChooseVisual (dpy, screen_num, attrs);
72     }
73
74   if (!vi)                              /* Try mono. */
75     {
76       i = 0;
77       attrs[i++] = GLX_DOUBLEBUFFER;
78       attrs[i++] = 0;
79       vi = glXChooseVisual (dpy, screen_num, attrs);
80     }
81
82   if (!vi)                              /* Try mono without double-buffer. */
83     {
84       attrs[0] = 0;
85       vi = glXChooseVisual (dpy, screen_num, attrs);
86     }
87
88   if (!vi)
89     return 0;
90   else
91     {
92       Visual *v = vi->visual;
93       XFree (vi);
94       return v;
95     }
96 #else  /* !HAVE_GL */
97   return 0;
98 #endif /* !HAVE_GL */
99 }