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 printf (" GLX rating: %s\n",
143 (value == GLX_NONE_EXT ? "none" :
144 value == GLX_SLOW_VISUAL_EXT ? "slow" :
145 # ifdef GLX_NON_CONFORMANT_EXT
146 value == GLX_NON_CONFORMANT_EXT ? "non-conformant" :
147 # endif /* GLX_NON_CONFORMANT_EXT */
149 # endif /* GLX_VISUAL_CAVEAT_EXT */
151 if (!glXGetConfig (dpy, vi_out, GLX_DOUBLEBUFFER, &value))
152 printf (" GLX double-buffer: %s\n", (value ? "yes" : "no"));
154 if (!glXGetConfig (dpy, vi_out, GLX_STEREO, &value) &&
156 printf (" GLX stereo: %s\n", (value ? "yes" : "no"));
158 if (!glXGetConfig (dpy, vi_out, GLX_AUX_BUFFERS, &value) &&
160 printf (" GLX aux buffers: %d\n", value);
162 if (!glXGetConfig (dpy, vi_out, GLX_DEPTH_SIZE, &value))
163 printf (" GLX depth size: %d\n", value);
165 if (!glXGetConfig (dpy, vi_out, GLX_STENCIL_SIZE, &value) &&
167 printf (" GLX stencil size: %d\n", value);
169 # ifdef GLX_SAMPLE_BUFFERS_SGIS
170 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLE_BUFFERS_SGIS, &value) &&
174 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLES_SGIS, &value))
175 printf (" GLX multisamplers: %d (%d)\n", bufs, value);
177 # endif /* GLX_SAMPLE_BUFFERS_SGIS */
179 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_TYPE_EXT, &value) &&
180 value != GLX_NONE_EXT)
182 if (value == GLX_NONE_EXT)
183 printf (" GLX transparency: none\n");
184 else if (value == GLX_TRANSPARENT_INDEX_EXT)
186 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_INDEX_VALUE_EXT,
188 printf (" GLX transparency: indexed (%d)\n", value);
190 else if (value == GLX_TRANSPARENT_RGB_EXT)
192 int r=0, g=0, b=0, a=0;
193 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_RED_VALUE_EXT, &r);
194 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g);
195 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_BLUE_VALUE_EXT, &b);
196 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a);
197 printf (" GLX transparency: RGBA (%2d, %2d, %2d, %2d)\n",
207 validate_gl_visual (FILE *out, Screen *screen, const char *window_desc,
214 Display *dpy = DisplayOfScreen (screen);
215 XVisualInfo vi_in, *vi_out;
219 vi_in.screen = screen_number (screen);
220 vi_in.visualid = XVisualIDFromVisual (visual);
221 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
223 if (! vi_out) abort ();
225 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
227 id = (unsigned int) vi_out->visualid;
228 XFree ((char *) vi_out);
230 if (status == GLX_NO_EXTENSION)
232 fprintf (out, "%s: display \"%s\" does not support the GLX extension.\n",
233 progname, DisplayString (dpy));
236 else if (status == GLX_BAD_VISUAL || value == False)
239 "%s: %s's visual 0x%x does not support the GLX extension.\n",
240 progname, window_desc, id);
250 fprintf (out, "%s: GL support was not compiled in to this program.\n",
254 #endif /* !HAVE_GL */