1 /* xscreensaver, Copyright (c) 1999, 2000, 2003 by Jamie Zawinski <jwz@jwz.org>
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
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 on most
15 high end 3D cards (e.g., Silicon Graphics or nVidia.)
17 There exists information about visuals which is available to GL, but
18 which is not available via Xlib calls. So the only way to know
19 which visual to use (other than impirically) is to actually call
31 extern char *progname;
34 get_gl_visual (Screen *screen)
37 Display *dpy = DisplayOfScreen (screen);
38 int screen_num = screen_number (screen);
40 # define R GLX_RED_SIZE
41 # define G GLX_GREEN_SIZE
42 # define B GLX_BLUE_SIZE
43 # define D GLX_DEPTH_SIZE
44 # define I GLX_BUFFER_SIZE
45 # define DB GLX_DOUBLEBUFFER
46 # define ST GLX_STENCIL_SIZE
49 { GLX_RGBA, R, 8, G, 8, B, 8, D, 8, DB, ST,1, 0 }, /* rgb double, stencil */
50 { GLX_RGBA, R, 4, G, 4, B, 4, D, 4, DB, ST,1, 0 },
51 { GLX_RGBA, R, 2, G, 2, B, 2, D, 2, DB, ST,1, 0 },
52 { GLX_RGBA, R, 8, G, 8, B, 8, D, 8, DB, 0 }, /* rgb double */
53 { GLX_RGBA, R, 4, G, 4, B, 4, D, 4, DB, 0 },
54 { GLX_RGBA, R, 2, G, 2, B, 2, D, 2, DB, 0 },
55 { GLX_RGBA, R, 8, G, 8, B, 8, D, 8, 0 }, /* rgb single */
56 { GLX_RGBA, R, 4, G, 4, B, 4, D, 4, 0 },
57 { GLX_RGBA, R, 2, G, 2, B, 2, D, 2, 0 },
58 { I, 8, D, 8, DB, 0 }, /* cmap double */
59 { I, 4, D, 4, DB, 0 },
60 { I, 8, D, 8, 0 }, /* cmap single */
62 { GLX_RGBA, R, 1, G, 1, B, 1, D, 1, 0 } /* monochrome */
66 for (i = 0; i < sizeof(attrs)/sizeof(*attrs); i++)
68 XVisualInfo *vi = glXChooseVisual (dpy, screen_num, attrs[i]);
71 Visual *v = vi->visual;
73 /* describe_gl_visual (stderr, screen, v, False); */
84 describe_gl_visual (FILE *f, Screen *screen, Visual *visual,
87 describe_visual (f, screen, visual, private_cmap_p);
94 Display *dpy = DisplayOfScreen (screen);
95 XVisualInfo vi_in, *vi_out;
98 vi_in.screen = screen_number (screen);
99 vi_in.visualid = XVisualIDFromVisual (visual);
100 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
102 if (! vi_out) abort ();
104 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
106 if (status == GLX_NO_EXTENSION)
107 /* dpy does not support the GLX extension. */
110 if (status == GLX_BAD_VISUAL || value == False)
111 /* this visual does not support GLX. */
114 if (!glXGetConfig (dpy, vi_out, GLX_LEVEL, &value) &&
116 printf (" GLX level: %d\n", value);
118 if (!glXGetConfig (dpy, vi_out, GLX_RGBA, &value) && value)
120 int r=0, g=0, b=0, a=0;
121 glXGetConfig (dpy, vi_out, GLX_RED_SIZE, &r);
122 glXGetConfig (dpy, vi_out, GLX_GREEN_SIZE, &g);
123 glXGetConfig (dpy, vi_out, GLX_BLUE_SIZE, &b);
124 glXGetConfig (dpy, vi_out, GLX_ALPHA_SIZE, &a);
125 printf (" GLX type: RGBA (%2d, %2d, %2d, %2d)\n",
129 glXGetConfig (dpy, vi_out, GLX_ACCUM_RED_SIZE, &r);
130 glXGetConfig (dpy, vi_out, GLX_ACCUM_GREEN_SIZE, &g);
131 glXGetConfig (dpy, vi_out, GLX_ACCUM_BLUE_SIZE, &b);
132 glXGetConfig (dpy, vi_out, GLX_ACCUM_ALPHA_SIZE, &a);
133 printf (" GLX accum: RGBA (%2d, %2d, %2d, %2d)\n",
139 glXGetConfig (dpy, vi_out, GLX_BUFFER_SIZE, &value);
140 printf (" GLX type: indexed (%d)\n", value);
143 # ifdef GLX_VISUAL_CAVEAT_EXT
144 if (!glXGetConfig (dpy, vi_out, GLX_VISUAL_CAVEAT_EXT, &value) &&
145 value != GLX_NONE_EXT)
146 # ifdef GLX_NON_CONFORMANT_EXT
147 printf (" GLX rating: %s\n",
148 (value == GLX_NONE_EXT ? "none" :
149 value == GLX_SLOW_VISUAL_EXT ? "slow" :
150 value == GLX_NON_CONFORMANT_EXT ? "non-conformant" :
153 printf (" GLX rating: %s\n",
154 (value == GLX_NONE_EXT ? "none" :
155 value == GLX_SLOW_VISUAL_EXT ? "slow" :
157 # endif /* GLX_NON_CONFORMANT_EXT */
158 # endif /* GLX_VISUAL_CAVEAT_EXT */
160 if (!glXGetConfig (dpy, vi_out, GLX_DOUBLEBUFFER, &value))
161 printf (" GLX double-buffer: %s\n", (value ? "yes" : "no"));
163 if (!glXGetConfig (dpy, vi_out, GLX_STEREO, &value) &&
165 printf (" GLX stereo: %s\n", (value ? "yes" : "no"));
167 if (!glXGetConfig (dpy, vi_out, GLX_AUX_BUFFERS, &value) &&
169 printf (" GLX aux buffers: %d\n", value);
171 if (!glXGetConfig (dpy, vi_out, GLX_DEPTH_SIZE, &value))
172 printf (" GLX depth size: %d\n", value);
174 if (!glXGetConfig (dpy, vi_out, GLX_STENCIL_SIZE, &value) &&
176 printf (" GLX stencil size: %d\n", value);
178 # ifdef GLX_SAMPLE_BUFFERS_SGIS
179 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLE_BUFFERS_SGIS, &value) &&
183 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLES_SGIS, &value))
184 printf (" GLX multisamplers: %d (%d)\n", bufs, value);
186 # endif /* GLX_SAMPLE_BUFFERS_SGIS */
188 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_TYPE_EXT, &value) &&
189 value != GLX_NONE_EXT)
191 if (value == GLX_NONE_EXT)
192 printf (" GLX transparency: none\n");
193 else if (value == GLX_TRANSPARENT_INDEX_EXT)
195 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_INDEX_VALUE_EXT,
197 printf (" GLX transparency: indexed (%d)\n", value);
199 else if (value == GLX_TRANSPARENT_RGB_EXT)
201 int r=0, g=0, b=0, a=0;
202 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_RED_VALUE_EXT, &r);
203 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g);
204 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_BLUE_VALUE_EXT, &b);
205 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a);
206 printf (" GLX transparency: RGBA (%2d, %2d, %2d, %2d)\n",
216 validate_gl_visual (FILE *out, Screen *screen, const char *window_desc,
223 Display *dpy = DisplayOfScreen (screen);
224 XVisualInfo vi_in, *vi_out;
228 vi_in.screen = screen_number (screen);
229 vi_in.visualid = XVisualIDFromVisual (visual);
230 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
232 if (! vi_out) abort ();
234 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
236 id = (unsigned int) vi_out->visualid;
237 XFree ((char *) vi_out);
239 if (status == GLX_NO_EXTENSION)
241 fprintf (out, "%s: display \"%s\" does not support the GLX extension.\n",
242 progname, DisplayString (dpy));
245 else if (status == GLX_BAD_VISUAL || value == False)
248 "%s: %s's visual 0x%x does not support the GLX extension.\n",
249 progname, window_desc, id);
259 fprintf (out, "%s: GL support was not compiled in to this program.\n",
263 #endif /* !HAVE_GL */