1 /* xscreensaver, Copyright (c) 1999, 2000 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
48 { GLX_RGBA, R, 8, G, 8, B, 8, D, 8, DB, 0 }, /* rgb double */
49 { GLX_RGBA, R, 4, G, 4, B, 4, D, 4, DB, 0 },
50 { GLX_RGBA, R, 2, G, 2, B, 2, D, 2, DB, 0 },
51 { GLX_RGBA, R, 8, G, 8, B, 8, D, 8, 0 }, /* rgb single */
52 { GLX_RGBA, R, 4, G, 4, B, 4, D, 4, 0 },
53 { GLX_RGBA, R, 2, G, 2, B, 2, D, 2, 0 },
54 { I, 8, D, 8, DB, 0 }, /* cmap double */
55 { I, 4, D, 4, DB, 0 },
56 { I, 8, D, 8, 0 }, /* cmap single */
58 { GLX_RGBA, R, 1, G, 1, B, 1, D, 1, 0 } /* monochrome */
62 for (i = 0; i < sizeof(attrs)/sizeof(*attrs); i++)
64 XVisualInfo *vi = glXChooseVisual (dpy, screen_num, attrs[i]);
67 Visual *v = vi->visual;
69 /* describe_gl_visual (stderr, screen, v, False); */
80 describe_gl_visual (FILE *f, Screen *screen, Visual *visual,
83 describe_visual (f, screen, visual, private_cmap_p);
90 Display *dpy = DisplayOfScreen (screen);
91 XVisualInfo vi_in, *vi_out;
94 vi_in.screen = screen_number (screen);
95 vi_in.visualid = XVisualIDFromVisual (visual);
96 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
98 if (! vi_out) abort ();
100 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
102 if (status == GLX_NO_EXTENSION)
103 /* dpy does not support the GLX extension. */
106 if (status == GLX_BAD_VISUAL || value == False)
107 /* this visual does not support GLX. */
110 if (!glXGetConfig (dpy, vi_out, GLX_LEVEL, &value) &&
112 printf (" GLX level: %d\n", value);
114 if (!glXGetConfig (dpy, vi_out, GLX_RGBA, &value) && value)
116 int r=0, g=0, b=0, a=0;
117 glXGetConfig (dpy, vi_out, GLX_RED_SIZE, &r);
118 glXGetConfig (dpy, vi_out, GLX_GREEN_SIZE, &g);
119 glXGetConfig (dpy, vi_out, GLX_BLUE_SIZE, &b);
120 glXGetConfig (dpy, vi_out, GLX_ALPHA_SIZE, &a);
121 printf (" GLX type: RGBA (%2d, %2d, %2d, %2d)\n",
125 glXGetConfig (dpy, vi_out, GLX_ACCUM_RED_SIZE, &r);
126 glXGetConfig (dpy, vi_out, GLX_ACCUM_GREEN_SIZE, &g);
127 glXGetConfig (dpy, vi_out, GLX_ACCUM_BLUE_SIZE, &b);
128 glXGetConfig (dpy, vi_out, GLX_ACCUM_ALPHA_SIZE, &a);
129 printf (" GLX accum: RGBA (%2d, %2d, %2d, %2d)\n",
135 glXGetConfig (dpy, vi_out, GLX_BUFFER_SIZE, &value);
136 printf (" GLX type: indexed (%d)\n", value);
139 # ifdef GLX_VISUAL_CAVEAT_EXT
140 if (!glXGetConfig (dpy, vi_out, GLX_VISUAL_CAVEAT_EXT, &value) &&
141 value != GLX_NONE_EXT)
142 # ifdef GLX_NON_CONFORMANT_EXT
143 printf (" GLX rating: %s\n",
144 (value == GLX_NONE_EXT ? "none" :
145 value == GLX_SLOW_VISUAL_EXT ? "slow" :
146 value == GLX_NON_CONFORMANT_EXT ? "non-conformant" :
149 printf (" GLX rating: %s\n",
150 (value == GLX_NONE_EXT ? "none" :
151 value == GLX_SLOW_VISUAL_EXT ? "slow" :
153 # endif /* GLX_NON_CONFORMANT_EXT */
154 # endif /* GLX_VISUAL_CAVEAT_EXT */
156 if (!glXGetConfig (dpy, vi_out, GLX_DOUBLEBUFFER, &value))
157 printf (" GLX double-buffer: %s\n", (value ? "yes" : "no"));
159 if (!glXGetConfig (dpy, vi_out, GLX_STEREO, &value) &&
161 printf (" GLX stereo: %s\n", (value ? "yes" : "no"));
163 if (!glXGetConfig (dpy, vi_out, GLX_AUX_BUFFERS, &value) &&
165 printf (" GLX aux buffers: %d\n", value);
167 if (!glXGetConfig (dpy, vi_out, GLX_DEPTH_SIZE, &value))
168 printf (" GLX depth size: %d\n", value);
170 if (!glXGetConfig (dpy, vi_out, GLX_STENCIL_SIZE, &value) &&
172 printf (" GLX stencil size: %d\n", value);
174 # ifdef GLX_SAMPLE_BUFFERS_SGIS
175 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLE_BUFFERS_SGIS, &value) &&
179 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLES_SGIS, &value))
180 printf (" GLX multisamplers: %d (%d)\n", bufs, value);
182 # endif /* GLX_SAMPLE_BUFFERS_SGIS */
184 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_TYPE_EXT, &value) &&
185 value != GLX_NONE_EXT)
187 if (value == GLX_NONE_EXT)
188 printf (" GLX transparency: none\n");
189 else if (value == GLX_TRANSPARENT_INDEX_EXT)
191 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_INDEX_VALUE_EXT,
193 printf (" GLX transparency: indexed (%d)\n", value);
195 else if (value == GLX_TRANSPARENT_RGB_EXT)
197 int r=0, g=0, b=0, a=0;
198 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_RED_VALUE_EXT, &r);
199 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g);
200 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_BLUE_VALUE_EXT, &b);
201 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a);
202 printf (" GLX transparency: RGBA (%2d, %2d, %2d, %2d)\n",
212 validate_gl_visual (FILE *out, Screen *screen, const char *window_desc,
219 Display *dpy = DisplayOfScreen (screen);
220 XVisualInfo vi_in, *vi_out;
224 vi_in.screen = screen_number (screen);
225 vi_in.visualid = XVisualIDFromVisual (visual);
226 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
228 if (! vi_out) abort ();
230 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
232 id = (unsigned int) vi_out->visualid;
233 XFree ((char *) vi_out);
235 if (status == GLX_NO_EXTENSION)
237 fprintf (out, "%s: display \"%s\" does not support the GLX extension.\n",
238 progname, DisplayString (dpy));
241 else if (status == GLX_BAD_VISUAL || value == False)
244 "%s: %s's visual 0x%x does not support the GLX extension.\n",
245 progname, window_desc, id);
255 fprintf (out, "%s: GL support was not compiled in to this program.\n",
259 #endif /* !HAVE_GL */