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
47 { GLX_RGBA, R, 8, G, 8, B, 8, D, 8, GLX_DOUBLEBUFFER, 0 }, /* rgb double */
48 { GLX_RGBA, R, 4, G, 4, B, 4, D, 4, GLX_DOUBLEBUFFER, 0 },
49 { GLX_RGBA, R, 2, G, 2, B, 2, D, 2, GLX_DOUBLEBUFFER, 0 },
50 { GLX_RGBA, R, 8, G, 8, B, 8, D, 8, 0 }, /* rgb single */
51 { GLX_RGBA, R, 4, G, 4, B, 4, D, 4, 0 },
52 { GLX_RGBA, R, 2, G, 2, B, 2, D, 2, 0 },
53 { I, 8, D, 8, GLX_DOUBLEBUFFER, 0 }, /* cmap double */
54 { I, 4, D, 4, GLX_DOUBLEBUFFER, 0 },
55 { I, 8, D, 8, 0 }, /* cmap single */
57 { GLX_RGBA, R, 1, G, 1, B, 1, D, 1, 0 } /* monochrome */
61 for (i = 0; i < sizeof(attrs)/sizeof(*attrs); i++)
63 XVisualInfo *vi = glXChooseVisual (dpy, screen_num, attrs[i]);
66 Visual *v = vi->visual;
68 /* describe_gl_visual (stderr, screen, v, False); */
79 describe_gl_visual (FILE *f, Screen *screen, Visual *visual,
82 describe_visual (f, screen, visual, private_cmap_p);
89 Display *dpy = DisplayOfScreen (screen);
90 XVisualInfo vi_in, *vi_out;
93 vi_in.screen = screen_number (screen);
94 vi_in.visualid = XVisualIDFromVisual (visual);
95 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
97 if (! vi_out) abort ();
99 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
101 if (status == GLX_NO_EXTENSION)
102 /* dpy does not support the GLX extension. */
105 if (status == GLX_BAD_VISUAL || value == False)
106 /* this visual does not support GLX. */
109 if (!glXGetConfig (dpy, vi_out, GLX_LEVEL, &value) &&
111 printf (" GLX level: %d\n", value);
113 if (!glXGetConfig (dpy, vi_out, GLX_RGBA, &value) && value)
115 int r=0, g=0, b=0, a=0;
116 glXGetConfig (dpy, vi_out, GLX_RED_SIZE, &r);
117 glXGetConfig (dpy, vi_out, GLX_GREEN_SIZE, &g);
118 glXGetConfig (dpy, vi_out, GLX_BLUE_SIZE, &b);
119 glXGetConfig (dpy, vi_out, GLX_ALPHA_SIZE, &a);
120 printf (" GLX type: RGBA (%2d, %2d, %2d, %2d)\n",
124 glXGetConfig (dpy, vi_out, GLX_ACCUM_RED_SIZE, &r);
125 glXGetConfig (dpy, vi_out, GLX_ACCUM_GREEN_SIZE, &g);
126 glXGetConfig (dpy, vi_out, GLX_ACCUM_BLUE_SIZE, &b);
127 glXGetConfig (dpy, vi_out, GLX_ACCUM_ALPHA_SIZE, &a);
128 printf (" GLX accum: RGBA (%2d, %2d, %2d, %2d)\n",
134 glXGetConfig (dpy, vi_out, GLX_BUFFER_SIZE, &value);
135 printf (" GLX type: indexed (%d)\n", value);
138 # ifdef GLX_VISUAL_CAVEAT_EXT
139 if (!glXGetConfig (dpy, vi_out, GLX_VISUAL_CAVEAT_EXT, &value) &&
140 value != GLX_NONE_EXT)
141 printf (" GLX rating: %s\n",
142 (value == GLX_NONE_EXT ? "none" :
143 value == GLX_SLOW_VISUAL_EXT ? "slow" :
144 # ifdef GLX_NON_CONFORMANT_EXT
145 value == GLX_NON_CONFORMANT_EXT ? "non-conformant" :
146 # endif /* GLX_NON_CONFORMANT_EXT */
148 # endif /* GLX_VISUAL_CAVEAT_EXT */
150 if (!glXGetConfig (dpy, vi_out, GLX_DOUBLEBUFFER, &value))
151 printf (" GLX double-buffer: %s\n", (value ? "yes" : "no"));
153 if (!glXGetConfig (dpy, vi_out, GLX_STEREO, &value) &&
155 printf (" GLX stereo: %s\n", (value ? "yes" : "no"));
157 if (!glXGetConfig (dpy, vi_out, GLX_AUX_BUFFERS, &value) &&
159 printf (" GLX aux buffers: %d\n", value);
161 if (!glXGetConfig (dpy, vi_out, GLX_DEPTH_SIZE, &value))
162 printf (" GLX depth size: %d\n", value);
164 if (!glXGetConfig (dpy, vi_out, GLX_STENCIL_SIZE, &value) &&
166 printf (" GLX stencil size: %d\n", value);
168 # ifdef GLX_SAMPLE_BUFFERS_SGIS
169 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLE_BUFFERS_SGIS, &value) &&
173 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLES_SGIS, &value))
174 printf (" GLX multisamplers: %d (%d)\n", bufs, value);
176 # endif /* GLX_SAMPLE_BUFFERS_SGIS */
178 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_TYPE_EXT, &value) &&
179 value != GLX_NONE_EXT)
181 if (value == GLX_NONE_EXT)
182 printf (" GLX transparency: none\n");
183 else if (value == GLX_TRANSPARENT_INDEX_EXT)
185 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_INDEX_VALUE_EXT,
187 printf (" GLX transparency: indexed (%d)\n", value);
189 else if (value == GLX_TRANSPARENT_RGB_EXT)
191 int r=0, g=0, b=0, a=0;
192 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_RED_VALUE_EXT, &r);
193 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g);
194 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_BLUE_VALUE_EXT, &b);
195 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a);
196 printf (" GLX transparency: RGBA (%2d, %2d, %2d, %2d)\n",
206 validate_gl_visual (FILE *out, Screen *screen, const char *window_desc,
213 Display *dpy = DisplayOfScreen (screen);
214 XVisualInfo vi_in, *vi_out;
218 vi_in.screen = screen_number (screen);
219 vi_in.visualid = XVisualIDFromVisual (visual);
220 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
222 if (! vi_out) abort ();
224 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
226 id = (unsigned int) vi_out->visualid;
227 XFree ((char *) vi_out);
229 if (status == GLX_NO_EXTENSION)
231 fprintf (out, "%s: display \"%s\" does not support the GLX extension.\n",
232 progname, DisplayString (dpy));
235 else if (status == GLX_BAD_VISUAL || value == False)
238 "%s: %s's visual 0x%x does not support the GLX extension.\n",
239 progname, window_desc, id);
249 fprintf (out, "%s: GL support was not compiled in to this program.\n",
253 #endif /* !HAVE_GL */