root/OpenSceneGraph/trunk/src/osgPlugins/cfg/VisualChooser.cpp @ 13041

Revision 13041, 24.6 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- Producer - Copyright (C) 2001-2004  Don Burns
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12 */
13
14#include <stdio.h>
15#include <iostream>
16
17#include "VisualChooser.h"
18#include <osg/Referenced>
19
20using namespace std;
21using namespace osgProducer;
22
23
24VisualChooser::VisualChooser( void )
25{
26//     _visual_id = 0;
27//     _vinfo = 0L;
28    _strictAdherence = false;
29}
30
31VisualChooser::~VisualChooser(void)
32{
33   clear();
34}
35
36#if 0
37void VisualChooser::setVisual( VisualInfo *vinfo )
38{
39    clear();
40    _vinfo = vinfo;
41}
42#endif
43void VisualChooser::resetVisualInfo()
44{
45#ifdef _WIN32_IMPLEMENTATION
46    if (_vinfo != NULL) delete _vinfo;
47#endif
48
49#ifdef _OSX_AGL_IMPLEMENTATION
50    if(_vinfo != NULL) free(_vinfo);
51#endif
52
53    //    _vinfo = 0L;
54}
55
56void VisualChooser::addAttribute( AttributeName attribute )
57{
58    resetVisualInfo();
59    _visual_attributes.push_back( VisualAttribute( attribute ) );
60}
61
62void VisualChooser::addAttribute( AttributeName attribute, int parameter )
63{
64    resetVisualInfo();
65    _visual_attributes.push_back( VisualAttribute( attribute, parameter ) );
66}
67
68void VisualChooser::addExtendedAttribute( unsigned int attribute )
69{
70    resetVisualInfo();
71    _visual_attributes.push_back( VisualAttribute( attribute ) );
72}
73
74void VisualChooser::addExtendedAttribute( unsigned int attribute, int parameter )
75{
76    resetVisualInfo();
77    _visual_attributes.push_back( VisualAttribute( attribute, parameter ) );
78}
79
80void VisualChooser::setBufferSize( unsigned int size )
81{
82    addAttribute( BufferSize, size );
83}
84
85void VisualChooser::setLevel( int level )
86{
87    addAttribute( Level, level );
88
89}
90void VisualChooser::useRGBA()
91{
92    addAttribute( RGBA );
93}
94void VisualChooser::useDoubleBuffer()
95{
96    addAttribute( DoubleBuffer );
97}
98void VisualChooser::useStereo()
99{
100    addAttribute( Stereo );
101}
102
103void VisualChooser::setAuxBuffers( unsigned int num )
104{
105    addAttribute( AuxBuffers, num );
106}
107
108void VisualChooser::setRedSize( unsigned int size )
109{
110    addAttribute( RedSize, size );
111}
112
113void VisualChooser::setGreenSize( unsigned int size )
114{
115    addAttribute( GreenSize, size );
116}
117
118void VisualChooser::setBlueSize( unsigned int size )
119{
120    addAttribute( BlueSize, size );
121}
122
123void VisualChooser::setAlphaSize( unsigned int size )
124{
125    addAttribute( AlphaSize, size );
126}
127
128void VisualChooser::setDepthSize( unsigned int size )
129{
130    addAttribute( DepthSize, size );
131}
132
133void VisualChooser::setStencilSize( unsigned int size )
134{
135    addAttribute( StencilSize, size );
136}
137
138void VisualChooser::setAccumRedSize( unsigned int size )
139{
140    addAttribute( AccumRedSize, size );
141}
142
143void VisualChooser::setAccumGreenSize( unsigned int size )
144{
145    addAttribute( AccumGreenSize, size );
146}
147
148void VisualChooser::setAccumBlueSize( unsigned int size )
149{
150    addAttribute( AccumBlueSize, size );
151}
152
153void VisualChooser::setAccumAlphaSize( unsigned int size )
154{
155    addAttribute( AccumAlphaSize, size );
156}
157
158void VisualChooser::setSamples( unsigned int size )
159{
160    addAttribute( Samples, size );
161}
162
163void VisualChooser::setSampleBuffers( unsigned int size )
164{
165    addAttribute( SampleBuffers, size );
166}
167
168void VisualChooser::setVisualID( unsigned int id )
169{
170    _visual_id = id;
171}
172
173void VisualChooser::setSimpleConfiguration( bool doublebuffer )
174{
175    clear();
176    addAttribute( RGBA );
177    addAttribute( DepthSize, 24 );
178    if (doublebuffer)
179        addAttribute( DoubleBuffer );
180}
181
182void VisualChooser::clear()
183{
184    _visual_attributes.clear();
185    resetVisualInfo();
186
187    // Always use UseGL
188    addAttribute( UseGL );
189}
190
191
192#ifdef _OSX_AGL_IMPLEMENTATION
193#include <AGL/agl.h>
194
195void VisualChooser::applyAttribute(const VisualAttribute &va, std::vector<int> &attribs)
196{
197    if(va.isExtension())
198    {
199      attribs.push_back(static_cast<int>(va.attribute()));
200    }
201    else
202    {
203      switch(va.attribute())
204      {
205        case UseGL:          attribs.push_back(AGL_COMPLIANT); break;
206        case BufferSize:     attribs.push_back(AGL_BUFFER_SIZE); break;
207        case Level:          attribs.push_back(AGL_LEVEL); break;
208        case RGBA:           attribs.push_back(AGL_RGBA); break;
209        case DoubleBuffer:   attribs.push_back(AGL_DOUBLEBUFFER); break;
210        case Stereo:         attribs.push_back(AGL_STEREO); break;
211        case AuxBuffers:     attribs.push_back(AGL_AUX_BUFFERS); break;
212        case RedSize:        attribs.push_back(AGL_RED_SIZE); break;
213        case GreenSize:      attribs.push_back(AGL_GREEN_SIZE); break;
214        case BlueSize:       attribs.push_back(AGL_BLUE_SIZE); break;
215        case AlphaSize:      attribs.push_back(AGL_ALPHA_SIZE); break;
216        case DepthSize:      attribs.push_back(AGL_DEPTH_SIZE); break;
217        case StencilSize:    attribs.push_back(AGL_STENCIL_SIZE); break;
218        case AccumRedSize:   attribs.push_back(AGL_ACCUM_RED_SIZE); break;
219        case AccumGreenSize: attribs.push_back(AGL_ACCUM_GREEN_SIZE); break;
220        case AccumBlueSize:  attribs.push_back(AGL_ACCUM_BLUE_SIZE); break;
221        case AccumAlphaSize: attribs.push_back(AGL_ACCUM_ALPHA_SIZE); break;
222#if defined (AGL_SAMPLE_BUFFERS_ARB) && defined (AGL_SAMPLES_ARB)
223        case SampleBuffers:  attribs.push_back(AGL_SAMPLE_BUFFERS_ARB); break;
224        case Samples:        attribs.push_back(AGL_SAMPLES_ARB); break;
225#endif
226        default: attribs.push_back((int)va.attribute()); break;
227      }
228    }
229
230    if (va.hasParameter())
231    {
232      attribs.push_back(va.parameter());
233    }
234}
235
236VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence)
237{
238    if(_vinfo != NULL)
239    {
240      // If VisualInfo exists, then we may be able to reuse it
241      GLint val;
242      if((*_vinfo) && (aglDescribePixelFormat(*_vinfo, AGL_NO_RECOVERY, &val))) return _vinfo;
243    }
244    else
245    {
246      // Use malloc() since new() causes a bus error
247      _vinfo = (VisualInfo*)malloc(sizeof(VisualInfo*));
248    }
249    // Set up basic attributes if needed
250    if( _visual_attributes.size() == 0 ) setSimpleConfiguration();
251
252    bool fullscreen = (screen == 1); // Whether to fullscreen or not
253    std::vector<int> va; // Visual attributes
254
255    va.push_back(AGL_NO_RECOVERY);
256    if(fullscreen) va.push_back(AGL_FULLSCREEN);
257
258    vector<VisualAttribute>::const_iterator p;
259    for( p = _visual_attributes.begin(); p != _visual_attributes.end(); p++ )
260    {
261      applyAttribute(*p, va);
262    }
263    va.push_back(AGL_NONE); // Must be last element
264
265    // Copy to GLint vector, since this is what the agl functions require
266    std::vector<GLint> glva;
267    std::vector<int>::iterator i;
268    for(i = va.begin(); i != va.end(); i++)
269    {
270      glva.push_back(*i);
271    }
272
273    if(fullscreen)
274    {
275      GDHandle gdhDisplay;
276      DMGetGDeviceByDisplayID((DisplayIDType)*dpy, &gdhDisplay, false);
277      *_vinfo = aglChoosePixelFormat(&gdhDisplay, 1, &(glva.front()));
278    }
279    else
280    {
281      *_vinfo = aglChoosePixelFormat(NULL, 0, &(glva.front()));
282    }
283
284    if(*_vinfo == NULL)
285    {
286      std::cerr<< "aglChoosePixelFormat failed: " << aglGetError() << std::endl;
287      for(i=va.begin(); i!=va.end(); ++i)
288      {
289        std::cerr << (*i) << ", ";
290      }
291      std::cerr << std::endl;
292    }
293    return _vinfo;
294}
295
296#endif
297
298#ifdef _OSX_CGL_IMPLEMENTATION
299void VisualChooser::applyAttribute(const VisualAttribute &va, std::vector<int> &attribs)
300{
301    if(va.isExtension())
302    {
303      attribs.push_back(static_cast<int>(va.attribute()));
304    }
305    else
306    {
307      switch(va.attribute())
308      {
309        case UseGL:          attribs.push_back(kCGLPFACompliant); break;
310        case BufferSize:     attribs.push_back(kCGLPFAColorSize); break;
311        //case Level:          attribs.push_back(GLX_LEVEL); break;
312        //case RGBA:           attribs.push_back(GLX_RGBA); break;
313        case DoubleBuffer:   attribs.push_back(kCGLPFADoubleBuffer); break;
314        case Stereo:         attribs.push_back(kCGLPFAStereo); break;
315        case AuxBuffers:     attribs.push_back(kCGLPFAAuxBuffers); break;
316        case RedSize:        attribs.push_back(kCGLPFAColorSize); break;
317        case GreenSize:      attribs.push_back(kCGLPFAColorSize); break;
318        case BlueSize:       attribs.push_back(kCGLPFAColorSize); break;
319        case AlphaSize:      attribs.push_back(kCGLPFAAlphaSize); break;
320        case DepthSize:      attribs.push_back(kCGLPFADepthSize); break;
321        case StencilSize:    attribs.push_back(kCGLPFAStencilSize); break;
322        case AccumRedSize:   attribs.push_back(kCGLPFAAccumSize); break;
323        case AccumGreenSize: attribs.push_back(kCGLPFAAccumSize); break;
324        case AccumBlueSize:  attribs.push_back(kCGLPFAAccumSize); break;
325        case AccumAlphaSize: attribs.push_back(kCGLPFAAccumSize); break;
326        case SampleBuffers:  attribs.push_back(kCGLPFASampleBuffers); break;
327        case Samples:        attribs.push_back(kCGLPFASamples); break;
328        default: attribs.push_back(va.attribute()); break;
329      }
330    }
331
332    if (va.hasParameter())
333    {
334      attribs.push_back(va.parameter());
335    }
336}
337
338VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence)
339{
340    if(_vinfo != NULL)
341    {
342      // If VisualInfo exists, then we may be able to reuse it
343      GLint val;
344      if(!CGLDescribePixelFormat(*_vinfo, 0L, kCGLPFANoRecovery, &val))
345        return _vinfo;
346    }
347
348    // Set up basic attributes if needed
349    if( _visual_attributes.size() == 0 ) setSimpleConfiguration();
350
351    u_int32_t display_id = CGDisplayIDToOpenGLDisplayMask(*dpy);
352    std::vector<int> va; // Visual attributes
353
354    va.push_back(kCGLPFADisplayMask);
355    va.push_back((CGLPixelFormatAttribute)display_id);
356    va.push_back(kCGLPFANoRecovery);
357    va.push_back( kCGLPFAAccelerated );
358    va.push_back( kCGLPFAFullScreen );
359
360    vector<VisualAttribute>::const_iterator p;
361    for( p = _visual_attributes.begin(); p != _visual_attributes.end(); p++ )
362    {
363      applyAttribute(*p, va);
364    }
365    va.push_back(CGLPixelFormatAttribute(0)); // Must be last element
366
367    long nvirt;
368    CGLPixelFormatAttribute *array = new CGLPixelFormatAttribute[va.size()];
369    memcpy(array, &(va.front()), va.size()*sizeof(CGLPixelFormatAttribute));
370    CGLError err = CGLChoosePixelFormat(array, _vinfo, &nvirt);
371    if(err)
372    {
373      std::cerr<< "CGLChoosePixelFormat failed: " << CGLErrorString(err) << std::endl;
374      std::vector<int>::iterator i;
375      for(i=va.begin(); i!=va.end(); ++i)
376      {
377        std::cerr << (*i) << ", ";
378      }
379      std::cerr << std::endl;
380    }
381
382    return _vinfo;
383}
384
385#endif
386
387#ifdef _X11_IMPLEMENTATION
388#include <GL/glx.h>
389
390void VisualChooser::applyAttribute(const VisualAttribute &va, std::vector<int> &attribs)
391{
392    if (va.isExtension())
393    {
394        attribs.push_back(static_cast<int>(va.attribute()));
395    }
396    else
397    {
398        switch (va.attribute())
399        {
400            case UseGL:          attribs.push_back(GLX_USE_GL); break;
401            case BufferSize:     attribs.push_back(GLX_BUFFER_SIZE); break;
402            case Level:          attribs.push_back(GLX_LEVEL); break;
403            case RGBA:           attribs.push_back(GLX_RGBA); break;
404            case DoubleBuffer:   attribs.push_back(GLX_DOUBLEBUFFER); break;
405            case Stereo:         attribs.push_back(GLX_STEREO); break;
406            case AuxBuffers:     attribs.push_back(GLX_AUX_BUFFERS); break;
407            case RedSize:        attribs.push_back(GLX_RED_SIZE); break;
408            case GreenSize:      attribs.push_back(GLX_GREEN_SIZE); break;
409            case BlueSize:       attribs.push_back(GLX_BLUE_SIZE); break;
410            case AlphaSize:      attribs.push_back(GLX_ALPHA_SIZE); break;
411            case DepthSize:      attribs.push_back(GLX_DEPTH_SIZE); break;
412            case StencilSize:    attribs.push_back(GLX_STENCIL_SIZE); break;
413            case AccumRedSize:   attribs.push_back(GLX_ACCUM_RED_SIZE); break;
414            case AccumGreenSize: attribs.push_back(GLX_ACCUM_GREEN_SIZE); break;
415            case AccumBlueSize:  attribs.push_back(GLX_ACCUM_BLUE_SIZE); break;
416            case AccumAlphaSize: attribs.push_back(GLX_ACCUM_ALPHA_SIZE); break;
417#if defined(GLX_SAMPLE_BUFFERS) && defined (GLX_SAMPLES)
418            case SampleBuffers:  attribs.push_back(GLX_SAMPLE_BUFFERS); break;
419            case Samples:        attribs.push_back(GLX_SAMPLES); break;
420#endif
421            default:             attribs.push_back(static_cast<int>(va.attribute())); break;
422        }
423    }
424
425    if (va.hasParameter())
426    {
427        attribs.push_back(va.parameter());
428    }
429}
430
431
432                                                           // we now ignore this...
433VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence)
434{
435    // Visual info was previously forced.
436    if( _vinfo != NULL )
437        return _vinfo;
438
439    if( _visual_id != 0 )
440    {
441
442        VisualInfo temp;
443        long mask = VisualIDMask;
444        int n;
445        temp.visualid = _visual_id;
446        _vinfo = XGetVisualInfo( dpy, mask, &temp, &n );
447
448    if( _vinfo != NULL || _strictAdherence )
449        return _vinfo;
450
451    }
452
453    if( _visual_attributes.size() == 0 )
454        setSimpleConfiguration();
455
456    vector<VisualAttribute>::const_iterator p;
457    vector<int>va;
458
459    for( p = _visual_attributes.begin(); p != _visual_attributes.end(); p++ )
460    {
461        applyAttribute(*p, va);
462    }
463    va.push_back(0);
464
465    if( _strictAdherence )
466    {
467    _vinfo = glXChooseVisual( dpy, screen, &(va.front()) );
468    }
469    else
470    {
471        p = _visual_attributes.end() - 1;
472
473        while( _vinfo == NULL && va.size() > 0)
474        {
475            _vinfo = glXChooseVisual( dpy, screen, &(va.front()) );
476        if( _vinfo == NULL && va.size() > 0 )
477        {
478
479                // should we report an message that we're relaxing constraints here?
480                // std::cout << "Popping attributes"<<std::endl;
481
482            va.pop_back(); // Pop the NULL terminator
483            if( (*p).hasParameter() && va.size() >= 2 )
484            {
485            va.pop_back();
486            va.pop_back();
487            }
488            else
489            va.pop_back();
490            va.push_back(0); // Push a new NULL terminator
491        if( p == _visual_attributes.begin() )
492            break;
493            p --;
494        }
495        }
496    }
497
498    if( _vinfo != 0L )
499        _visual_id = _vinfo->visualid;
500    else
501        _visual_id = 0;
502
503    return  _vinfo;
504}
505#endif
506
507#ifdef _WIN32_IMPLEMENTATION
508#include "WGLExtensions.h"
509
510void VisualChooser::applyAttribute(const VisualAttribute &va, std::vector<int> &attribs)
511{
512    if (va.attribute() == UseGL)
513    {
514        attribs.push_back(WGL_SUPPORT_OPENGL_ARB);
515        attribs.push_back(1);
516        attribs.push_back(WGL_ACCELERATION_ARB);
517        attribs.push_back(WGL_FULL_ACCELERATION_ARB);
518        return;
519    }
520
521    if (va.attribute() == DoubleBuffer)
522    {
523        attribs.push_back(WGL_DOUBLE_BUFFER_ARB);
524        attribs.push_back(1);
525        attribs.push_back(WGL_SWAP_METHOD_ARB);
526        attribs.push_back(WGL_SWAP_EXCHANGE_ARB);
527        return;
528    }
529
530    // please note that *all* WGL attributes must have a parameter!
531    // to keep compatibility we'll explicitely set a boolean
532    // parameter value where needed.
533
534    std::pair<int, int> attr = std::make_pair(static_cast<int>(va.attribute()), va.parameter());
535
536    switch (va.attribute())
537    {
538        case Level:          return;
539        case BufferSize:     attr.first = WGL_COLOR_BITS_ARB; break;
540        case RGBA:           attr.first = WGL_PIXEL_TYPE_ARB; attr.second = WGL_TYPE_RGBA_ARB; break;
541        case Stereo:         attr.first = WGL_STEREO_ARB; attr.second = 1;  break;
542        case AuxBuffers:     attr.first = WGL_AUX_BUFFERS_ARB; break;
543        case RedSize:        attr.first = WGL_RED_BITS_ARB; break;
544        case GreenSize:      attr.first = WGL_GREEN_BITS_ARB; break;
545        case BlueSize:       attr.first = WGL_BLUE_BITS_ARB; break;
546        case AlphaSize:      attr.first = WGL_ALPHA_BITS_ARB; break;
547        case DepthSize:      attr.first = WGL_DEPTH_BITS_ARB; break;
548        case StencilSize:    attr.first = WGL_STENCIL_BITS_ARB; break;
549        case AccumRedSize:   attr.first = WGL_ACCUM_RED_BITS_ARB; break;
550        case AccumGreenSize: attr.first = WGL_ACCUM_GREEN_BITS_ARB; break;
551        case AccumBlueSize:  attr.first = WGL_ACCUM_BLUE_BITS_ARB; break;
552        case AccumAlphaSize: attr.first = WGL_ACCUM_ALPHA_BITS_ARB; break;
553#if defined(WGL_SAMPLE_BUFFERS_ARB) && defined (WGL_SAMPLES_ARB)
554        case SampleBuffers:  attr.first = WGL_SAMPLE_BUFFERS_ARB; break;
555        case Samples:        attr.first = WGL_SAMPLES_ARB; break;
556#endif
557        default: ;
558    }
559
560    attribs.push_back(attr.first);
561    attribs.push_back(attr.second);
562}
563
564VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence)
565{
566    if (_vinfo)
567        return _vinfo;
568
569    if (_visual_attributes.empty())
570        setSimpleConfiguration();
571
572    int vid;
573    bool failed = false;
574
575    WGLExtensions *ext = WGLExtensions::instance();
576    if (ext && ext->isSupported(WGLExtensions::ARB_pixel_format))
577    {
578        do
579        {
580            std::vector<int> attribs;
581            for (std::vector<VisualAttribute>::const_iterator i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
582                applyAttribute(*i, attribs);
583            attribs.push_back(0);
584
585            unsigned int num_formats;
586            failed = !ext->wglChoosePixelFormat(*dpy, &attribs.front(), 0, 1, &vid, &num_formats) || num_formats == 0;
587            if (failed)
588            {
589                // **** DRIVER BUG? It seems that some ATI cards don't support
590                // **** the WGL_SWAP_METHOD_ARB attribute. Now we try to remove
591                // **** it from the attribute list and choose a pixel format again.
592                for (std::vector<int>::iterator k=attribs.begin(); k!=attribs.end(); ++k)
593                {
594                    if (*k == WGL_SWAP_METHOD_ARB)
595                    {
596                        // attribute come in sequential attribute,parameter pairs
597                        // as WGL specifications so we need to delete two entries
598                        attribs.erase(k,k+2);
599                        break;
600                    }
601                }
602
603                failed = !ext->wglChoosePixelFormat(*dpy, &attribs.front(), 0, 1, &vid, &num_formats) || num_formats == 0;
604            }
605
606            if (failed)
607            {
608                if (strict_adherence || _visual_attributes.empty())
609                    break;
610
611                std::cerr << "Producer::VisualChooser: the requested visual is not available, trying to relax attributes..." << std::endl;
612                _visual_attributes.pop_back();
613            }
614
615        } while (failed);
616    }
617
618    if (failed || !ext || !ext->isSupported(WGLExtensions::ARB_pixel_format))
619    {
620        std::cerr << "Producer::VisualChooser: unable to setup a valid visual with WGL extensions, switching to compatibility mode" << std::endl;
621
622        failed = false;
623        do
624        {
625            PIXELFORMATDESCRIPTOR pfd;
626            ZeroMemory(&pfd, sizeof(pfd));
627            pfd.nSize = sizeof(pfd);
628            pfd.nVersion = 1;
629            pfd.dwFlags = PFD_DRAW_TO_WINDOW;
630            pfd.iLayerType = PFD_MAIN_PLANE;
631
632            for (std::vector<VisualAttribute>::const_iterator i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
633            {
634                if (i->attribute() == UseGL)             pfd.dwFlags |= PFD_SUPPORT_OPENGL;
635                if (i->attribute() == DoubleBuffer)      pfd.dwFlags |= PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE;
636                if (i->attribute() == Stereo)            pfd.dwFlags |= PFD_STEREO;
637                if (i->attribute() == RGBA)              pfd.iPixelType = PFD_TYPE_RGBA;
638                if (i->attribute() == BufferSize)        pfd.cColorBits = i->parameter();
639                if (i->attribute() == RedSize)           pfd.cRedBits = i->parameter();
640                if (i->attribute() == GreenSize)         pfd.cGreenBits = i->parameter();
641                if (i->attribute() == BlueSize)          pfd.cBlueBits = i->parameter();
642                if (i->attribute() == AlphaSize)         pfd.cAlphaBits = i->parameter();
643                if (i->attribute() == AccumRedSize)      pfd.cAccumRedBits = i->parameter();
644                if (i->attribute() == AccumGreenSize)    pfd.cAccumGreenBits = i->parameter();
645                if (i->attribute() == AccumBlueSize)     pfd.cAccumBlueBits = i->parameter();
646                if (i->attribute() == AccumAlphaSize)    pfd.cAccumAlphaBits = i->parameter();
647                if (i->attribute() == DepthSize)         pfd.cDepthBits = i->parameter();
648                if (i->attribute() == StencilSize)       pfd.cStencilBits = i->parameter();
649                if (i->attribute() == AuxBuffers)        pfd.cAuxBuffers = i->parameter();
650            }
651
652            pfd.cAccumBits = pfd.cAccumRedBits + pfd.cAccumGreenBits + pfd.cAccumBlueBits + pfd.cAccumAlphaBits;
653
654            vid = ChoosePixelFormat(*dpy, &pfd);
655            if ( vid != 0 )
656            {
657              // Is this additional check neccessary ?
658              // Did anyone encountered a situation where
659              // ChoosePixelFormat returned PXIELFORMAT worse than required ?
660              _visual_id = static_cast<unsigned int>(vid);
661              VisualInfo pfd;
662              DescribePixelFormat(*dpy, _visual_id, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
663              bool boolOK = true;
664              for (std::vector<VisualAttribute>::const_iterator i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
665              {
666                  if (i->attribute() == UseGL)             boolOK &= !!( pfd.dwFlags & PFD_SUPPORT_OPENGL );
667                  if (i->attribute() == DoubleBuffer)      boolOK &= !!( pfd.dwFlags & ( PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE ) );
668                  if (i->attribute() == Stereo)            boolOK &= !!( pfd.dwFlags & PFD_STEREO );
669                  if (i->attribute() == RGBA)              boolOK &= pfd.iPixelType == PFD_TYPE_RGBA;
670                  if (i->attribute() == BufferSize)        boolOK &= pfd.cColorBits >= i->parameter();
671                  if (i->attribute() == RedSize)           boolOK &= pfd.cRedBits >= i->parameter();
672                  if (i->attribute() == GreenSize)         boolOK &= pfd.cGreenBits >= i->parameter();
673                  if (i->attribute() == BlueSize)          boolOK &= pfd.cBlueBits >= i->parameter();
674                  if (i->attribute() == AlphaSize)         boolOK &= pfd.cAlphaBits >= i->parameter();
675                  if (i->attribute() == AccumRedSize)      boolOK &= pfd.cAccumRedBits >= i->parameter();
676                  if (i->attribute() == AccumGreenSize)    boolOK &= pfd.cAccumGreenBits >= i->parameter();
677                  if (i->attribute() == AccumBlueSize)     boolOK &= pfd.cAccumBlueBits >= i->parameter();
678                  if (i->attribute() == AccumAlphaSize)    boolOK &= pfd.cAccumAlphaBits >= i->parameter();
679                  if (i->attribute() == DepthSize)         boolOK &= pfd.cDepthBits >= i->parameter();
680                  if (i->attribute() == StencilSize)       boolOK &= pfd.cStencilBits >= i->parameter();
681                  if (i->attribute() == AuxBuffers)        boolOK &= pfd.cAuxBuffers >= i->parameter();
682              }
683              if ( !boolOK )
684                vid = 0;
685            }
686
687            if( vid == 0 )
688            {
689                failed = true;
690                if (strict_adherence || _visual_attributes.empty())
691                    break;
692
693                std::cerr << "Producer::VisualChooser: the requested visual is not available, trying to relax attributes..." << std::endl;
694                _visual_attributes.pop_back();
695            }
696
697        } while (failed);
698
699    }
700
701    if (failed)
702    {
703        std::cerr << "Producer::VisualChooser: could not choose the pixel format" << std::endl;
704        return 0;
705    }
706
707    _visual_id = static_cast<unsigned int>(vid);
708
709    // we set _vinfo for compatibility, but it's going to be unused
710    // because the pixel format is usually chosen by visual ID rather
711    // than by descriptor.
712    _vinfo = new VisualInfo;
713    DescribePixelFormat(*dpy, _visual_id, sizeof(PIXELFORMATDESCRIPTOR), _vinfo);
714
715    return _vinfo;
716}
717
718#endif
719
720#if 0
721unsigned int VisualChooser::getVisualID()  const
722{
723    return 0;
724}
725
726bool VisualChooser::getStrictAdherence()
727{
728    return _strictAdherence;
729}
730
731void VisualChooser::setStrictAdherence(bool strictAdherence)
732{
733    _strictAdherence = strictAdherence;
734}
735#endif
736
737bool VisualChooser::isDoubleBuffer() const
738{
739    for (std::vector<VisualAttribute>::const_iterator i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
740        if (i->attribute() == DoubleBuffer)
741            return true;
742
743    return false;
744}
Note: See TracBrowser for help on using the browser.