source: trunk/third/xscreensaver/utils/visual-gl.c @ 20148

Revision 20148, 8.5 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20147, which included commits to RCS files with non-trunk default branches.
Line 
1/* xscreensaver, Copyright (c) 1999, 2000, 2003 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 on most
15   high end 3D cards (e.g., Silicon Graphics or nVidia.)
16
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
20   glXChooseVisual().
21 */
22
23#include "utils.h"
24#include "visual.h"
25
26#ifdef HAVE_GL
27# include <GL/gl.h>
28# include <GL/glx.h>
29#endif /* HAVE_GL */
30
31extern char *progname;
32
33Visual *
34get_gl_visual (Screen *screen)
35{
36#ifdef HAVE_GL
37  Display *dpy = DisplayOfScreen (screen);
38  int screen_num = screen_number (screen);
39
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
47
48  int attrs[][20] = {
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 */
61   { I, 4,                       D, 4,           0 },
62   { GLX_RGBA, R, 1, G, 1, B, 1, D, 1,           0 }  /* monochrome */
63  };
64
65  int i;
66  for (i = 0; i < sizeof(attrs)/sizeof(*attrs); i++)
67    {
68      XVisualInfo *vi = glXChooseVisual (dpy, screen_num, attrs[i]);
69      if (vi)
70        {
71          Visual *v = vi->visual;
72          XFree (vi);
73          /* describe_gl_visual (stderr, screen, v, False); */
74          return v;
75        }
76    }
77#endif /* !HAVE_GL */
78
79  return 0;
80}
81
82
83void
84describe_gl_visual (FILE *f, Screen *screen, Visual *visual,
85                    Bool private_cmap_p)
86{
87  describe_visual (f, screen, visual, private_cmap_p);
88
89#ifdef HAVE_GL
90  {
91    int status;
92    int value = False;
93
94    Display *dpy = DisplayOfScreen (screen);
95    XVisualInfo vi_in, *vi_out;
96    int out_count;
97
98    vi_in.screen = screen_number (screen);
99    vi_in.visualid = XVisualIDFromVisual (visual);
100    vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
101                             &vi_in, &out_count);
102    if (! vi_out) abort ();
103
104    status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
105
106    if (status == GLX_NO_EXTENSION)
107      /* dpy does not support the GLX extension. */
108      return;
109
110    if (status == GLX_BAD_VISUAL || value == False)
111      /* this visual does not support GLX. */
112      return;
113   
114    if (!glXGetConfig (dpy, vi_out, GLX_LEVEL, &value) &&
115        value != 0)
116      printf ("    GLX level:         %d\n", value);
117
118    if (!glXGetConfig (dpy, vi_out, GLX_RGBA, &value) && value)
119      {
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",
126                r, g, b, a);
127
128        r=0, g=0, b=0, a=0;
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",
134                r, g, b, a);
135      }
136    else
137      {
138        value = 0;
139        glXGetConfig (dpy, vi_out, GLX_BUFFER_SIZE, &value);
140        printf ("    GLX type:          indexed (%d)\n", value);
141      }
142
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" :
151               "???"));
152#   else     
153      printf ("    GLX rating:        %s\n",
154              (value == GLX_NONE_EXT ? "none" :
155               value == GLX_SLOW_VISUAL_EXT ? "slow" :
156               "???"));
157#   endif /* GLX_NON_CONFORMANT_EXT */
158# endif /* GLX_VISUAL_CAVEAT_EXT */
159
160    if (!glXGetConfig (dpy, vi_out, GLX_DOUBLEBUFFER, &value))
161      printf ("    GLX double-buffer: %s\n", (value ? "yes" : "no"));
162
163    if (!glXGetConfig (dpy, vi_out, GLX_STEREO, &value) &&
164        value)
165      printf ("    GLX stereo:        %s\n", (value ? "yes" : "no"));
166
167    if (!glXGetConfig (dpy, vi_out, GLX_AUX_BUFFERS, &value) &&
168        value != 0)
169      printf ("    GLX aux buffers:   %d\n", value);
170
171    if (!glXGetConfig (dpy, vi_out, GLX_DEPTH_SIZE, &value))
172      printf ("    GLX depth size:    %d\n", value);
173
174    if (!glXGetConfig (dpy, vi_out, GLX_STENCIL_SIZE, &value) &&
175        value != 0)
176      printf ("    GLX stencil size:  %d\n", value);
177
178# ifdef GLX_SAMPLE_BUFFERS_SGIS
179    if (!glXGetConfig (dpy, vi_out, GLX_SAMPLE_BUFFERS_SGIS, &value) &&
180        value != 0)
181      {
182        int bufs = value;
183        if (!glXGetConfig (dpy, vi_out, GLX_SAMPLES_SGIS, &value))
184          printf ("    GLX multisamplers: %d (%d)\n", bufs, value);
185      }
186# endif /* GLX_SAMPLE_BUFFERS_SGIS */
187
188    if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_TYPE_EXT, &value) &&
189        value != GLX_NONE_EXT)
190      {
191        if (value == GLX_NONE_EXT)
192          printf ("    GLX transparency:  none\n");
193        else if (value == GLX_TRANSPARENT_INDEX_EXT)
194          {
195            if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_INDEX_VALUE_EXT,
196                               &value))
197              printf ("    GLX transparency:  indexed (%d)\n", value);
198          }
199        else if (value == GLX_TRANSPARENT_RGB_EXT)
200          {
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",
207                    r, g, b, a);
208          }
209      }
210  }
211#endif  /* HAVE_GL */
212}
213
214
215Bool
216validate_gl_visual (FILE *out, Screen *screen, const char *window_desc,
217                    Visual *visual)
218{
219#ifdef HAVE_GL
220  int status;
221  int value = False;
222
223  Display *dpy = DisplayOfScreen (screen);
224  XVisualInfo vi_in, *vi_out;
225  int out_count;
226  unsigned int id;
227
228  vi_in.screen = screen_number (screen);
229  vi_in.visualid = XVisualIDFromVisual (visual);
230  vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
231                             &vi_in, &out_count);
232  if (! vi_out) abort ();
233
234  status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
235
236  id = (unsigned int) vi_out->visualid;
237  XFree ((char *) vi_out);
238
239  if (status == GLX_NO_EXTENSION)
240    {
241      fprintf (out, "%s: display \"%s\" does not support the GLX extension.\n",
242               progname, DisplayString (dpy));
243      return False;
244    }
245  else if (status == GLX_BAD_VISUAL || value == False)
246    {
247      fprintf (out,
248               "%s: %s's visual 0x%x does not support the GLX extension.\n",
249               progname, window_desc, id);
250      return False;
251    }
252  else
253    {
254      return True;
255    }
256
257#else  /* !HAVE_GL */
258
259  fprintf (out, "%s: GL support was not compiled in to this program.\n",
260           progname);
261  return False;
262
263#endif  /* !HAVE_GL */
264}
Note: See TracBrowser for help on using the repository browser.