| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | #include <stdio.h> |
|---|
| 15 | #include <iostream> |
|---|
| 16 | |
|---|
| 17 | #include "VisualChooser.h" |
|---|
| 18 | #include <osg/Referenced> |
|---|
| 19 | |
|---|
| 20 | using namespace std; |
|---|
| 21 | using namespace osgProducer; |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | VisualChooser::VisualChooser( void ) |
|---|
| 25 | { |
|---|
| 26 | |
|---|
| 27 | |
|---|
| 28 | _strictAdherence = false; |
|---|
| 29 | } |
|---|
| 30 | |
|---|
| 31 | VisualChooser::~VisualChooser(void) |
|---|
| 32 | { |
|---|
| 33 | clear(); |
|---|
| 34 | } |
|---|
| 35 | |
|---|
| 36 | #if 0 |
|---|
| 37 | void VisualChooser::setVisual( VisualInfo *vinfo ) |
|---|
| 38 | { |
|---|
| 39 | clear(); |
|---|
| 40 | _vinfo = vinfo; |
|---|
| 41 | } |
|---|
| 42 | #endif |
|---|
| 43 | void 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 | |
|---|
| 54 | } |
|---|
| 55 | |
|---|
| 56 | void VisualChooser::addAttribute( AttributeName attribute ) |
|---|
| 57 | { |
|---|
| 58 | resetVisualInfo(); |
|---|
| 59 | _visual_attributes.push_back( VisualAttribute( attribute ) ); |
|---|
| 60 | } |
|---|
| 61 | |
|---|
| 62 | void VisualChooser::addAttribute( AttributeName attribute, int parameter ) |
|---|
| 63 | { |
|---|
| 64 | resetVisualInfo(); |
|---|
| 65 | _visual_attributes.push_back( VisualAttribute( attribute, parameter ) ); |
|---|
| 66 | } |
|---|
| 67 | |
|---|
| 68 | void VisualChooser::addExtendedAttribute( unsigned int attribute ) |
|---|
| 69 | { |
|---|
| 70 | resetVisualInfo(); |
|---|
| 71 | _visual_attributes.push_back( VisualAttribute( attribute ) ); |
|---|
| 72 | } |
|---|
| 73 | |
|---|
| 74 | void VisualChooser::addExtendedAttribute( unsigned int attribute, int parameter ) |
|---|
| 75 | { |
|---|
| 76 | resetVisualInfo(); |
|---|
| 77 | _visual_attributes.push_back( VisualAttribute( attribute, parameter ) ); |
|---|
| 78 | } |
|---|
| 79 | |
|---|
| 80 | void VisualChooser::setBufferSize( unsigned int size ) |
|---|
| 81 | { |
|---|
| 82 | addAttribute( BufferSize, size ); |
|---|
| 83 | } |
|---|
| 84 | |
|---|
| 85 | void VisualChooser::setLevel( int level ) |
|---|
| 86 | { |
|---|
| 87 | addAttribute( Level, level ); |
|---|
| 88 | |
|---|
| 89 | } |
|---|
| 90 | void VisualChooser::useRGBA() |
|---|
| 91 | { |
|---|
| 92 | addAttribute( RGBA ); |
|---|
| 93 | } |
|---|
| 94 | void VisualChooser::useDoubleBuffer() |
|---|
| 95 | { |
|---|
| 96 | addAttribute( DoubleBuffer ); |
|---|
| 97 | } |
|---|
| 98 | void VisualChooser::useStereo() |
|---|
| 99 | { |
|---|
| 100 | addAttribute( Stereo ); |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | void VisualChooser::setAuxBuffers( unsigned int num ) |
|---|
| 104 | { |
|---|
| 105 | addAttribute( AuxBuffers, num ); |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | void VisualChooser::setRedSize( unsigned int size ) |
|---|
| 109 | { |
|---|
| 110 | addAttribute( RedSize, size ); |
|---|
| 111 | } |
|---|
| 112 | |
|---|
| 113 | void VisualChooser::setGreenSize( unsigned int size ) |
|---|
| 114 | { |
|---|
| 115 | addAttribute( GreenSize, size ); |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | void VisualChooser::setBlueSize( unsigned int size ) |
|---|
| 119 | { |
|---|
| 120 | addAttribute( BlueSize, size ); |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | void VisualChooser::setAlphaSize( unsigned int size ) |
|---|
| 124 | { |
|---|
| 125 | addAttribute( AlphaSize, size ); |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | void VisualChooser::setDepthSize( unsigned int size ) |
|---|
| 129 | { |
|---|
| 130 | addAttribute( DepthSize, size ); |
|---|
| 131 | } |
|---|
| 132 | |
|---|
| 133 | void VisualChooser::setStencilSize( unsigned int size ) |
|---|
| 134 | { |
|---|
| 135 | addAttribute( StencilSize, size ); |
|---|
| 136 | } |
|---|
| 137 | |
|---|
| 138 | void VisualChooser::setAccumRedSize( unsigned int size ) |
|---|
| 139 | { |
|---|
| 140 | addAttribute( AccumRedSize, size ); |
|---|
| 141 | } |
|---|
| 142 | |
|---|
| 143 | void VisualChooser::setAccumGreenSize( unsigned int size ) |
|---|
| 144 | { |
|---|
| 145 | addAttribute( AccumGreenSize, size ); |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | void VisualChooser::setAccumBlueSize( unsigned int size ) |
|---|
| 149 | { |
|---|
| 150 | addAttribute( AccumBlueSize, size ); |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | void VisualChooser::setAccumAlphaSize( unsigned int size ) |
|---|
| 154 | { |
|---|
| 155 | addAttribute( AccumAlphaSize, size ); |
|---|
| 156 | } |
|---|
| 157 | |
|---|
| 158 | void VisualChooser::setSamples( unsigned int size ) |
|---|
| 159 | { |
|---|
| 160 | addAttribute( Samples, size ); |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | void VisualChooser::setSampleBuffers( unsigned int size ) |
|---|
| 164 | { |
|---|
| 165 | addAttribute( SampleBuffers, size ); |
|---|
| 166 | } |
|---|
| 167 | |
|---|
| 168 | void VisualChooser::setVisualID( unsigned int id ) |
|---|
| 169 | { |
|---|
| 170 | _visual_id = id; |
|---|
| 171 | } |
|---|
| 172 | |
|---|
| 173 | void VisualChooser::setSimpleConfiguration( bool doublebuffer ) |
|---|
| 174 | { |
|---|
| 175 | clear(); |
|---|
| 176 | addAttribute( RGBA ); |
|---|
| 177 | addAttribute( DepthSize, 24 ); |
|---|
| 178 | if (doublebuffer) |
|---|
| 179 | addAttribute( DoubleBuffer ); |
|---|
| 180 | } |
|---|
| 181 | |
|---|
| 182 | void VisualChooser::clear() |
|---|
| 183 | { |
|---|
| 184 | _visual_attributes.clear(); |
|---|
| 185 | resetVisualInfo(); |
|---|
| 186 | |
|---|
| 187 | |
|---|
| 188 | addAttribute( UseGL ); |
|---|
| 189 | } |
|---|
| 190 | |
|---|
| 191 | |
|---|
| 192 | #ifdef _OSX_AGL_IMPLEMENTATION |
|---|
| 193 | #include <AGL/agl.h> |
|---|
| 194 | |
|---|
| 195 | void 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 | |
|---|
| 236 | VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence) |
|---|
| 237 | { |
|---|
| 238 | if(_vinfo != NULL) |
|---|
| 239 | { |
|---|
| 240 | |
|---|
| 241 | GLint val; |
|---|
| 242 | if((*_vinfo) && (aglDescribePixelFormat(*_vinfo, AGL_NO_RECOVERY, &val))) return _vinfo; |
|---|
| 243 | } |
|---|
| 244 | else |
|---|
| 245 | { |
|---|
| 246 | |
|---|
| 247 | _vinfo = (VisualInfo*)malloc(sizeof(VisualInfo*)); |
|---|
| 248 | } |
|---|
| 249 | |
|---|
| 250 | if( _visual_attributes.size() == 0 ) setSimpleConfiguration(); |
|---|
| 251 | |
|---|
| 252 | bool fullscreen = (screen == 1); |
|---|
| 253 | std::vector<int> va; |
|---|
| 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); |
|---|
| 264 | |
|---|
| 265 | |
|---|
| 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 |
|---|
| 299 | void 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 | |
|---|
| 312 | |
|---|
| 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 | |
|---|
| 338 | VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence) |
|---|
| 339 | { |
|---|
| 340 | if(_vinfo != NULL) |
|---|
| 341 | { |
|---|
| 342 | |
|---|
| 343 | GLint val; |
|---|
| 344 | if(!CGLDescribePixelFormat(*_vinfo, 0L, kCGLPFANoRecovery, &val)) |
|---|
| 345 | return _vinfo; |
|---|
| 346 | } |
|---|
| 347 | |
|---|
| 348 | |
|---|
| 349 | if( _visual_attributes.size() == 0 ) setSimpleConfiguration(); |
|---|
| 350 | |
|---|
| 351 | u_int32_t display_id = CGDisplayIDToOpenGLDisplayMask(*dpy); |
|---|
| 352 | std::vector<int> va; |
|---|
| 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)); |
|---|
| 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 | |
|---|
| 390 | void 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 | |
|---|
| 433 | VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool strict_adherence) |
|---|
| 434 | { |
|---|
| 435 | |
|---|
| 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 | |
|---|
| 480 | |
|---|
| 481 | |
|---|
| 482 | va.pop_back(); |
|---|
| 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); |
|---|
| 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 | |
|---|
| 510 | void 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 | |
|---|
| 531 | |
|---|
| 532 | |
|---|
| 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 | |
|---|
| 564 | VisualInfo *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 | |
|---|
| 590 | |
|---|
| 591 | |
|---|
| 592 | for (std::vector<int>::iterator k=attribs.begin(); k!=attribs.end(); ++k) |
|---|
| 593 | { |
|---|
| 594 | if (*k == WGL_SWAP_METHOD_ARB) |
|---|
| 595 | { |
|---|
| 596 | |
|---|
| 597 | |
|---|
| 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 | |
|---|
| 658 | |
|---|
| 659 | |
|---|
| 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 | |
|---|
| 710 | |
|---|
| 711 | |
|---|
| 712 | _vinfo = new VisualInfo; |
|---|
| 713 | DescribePixelFormat(*dpy, _visual_id, sizeof(PIXELFORMATDESCRIPTOR), _vinfo); |
|---|
| 714 | |
|---|
| 715 | return _vinfo; |
|---|
| 716 | } |
|---|
| 717 | |
|---|
| 718 | #endif |
|---|
| 719 | |
|---|
| 720 | #if 0 |
|---|
| 721 | unsigned int VisualChooser::getVisualID() const |
|---|
| 722 | { |
|---|
| 723 | return 0; |
|---|
| 724 | } |
|---|
| 725 | |
|---|
| 726 | bool VisualChooser::getStrictAdherence() |
|---|
| 727 | { |
|---|
| 728 | return _strictAdherence; |
|---|
| 729 | } |
|---|
| 730 | |
|---|
| 731 | void VisualChooser::setStrictAdherence(bool strictAdherence) |
|---|
| 732 | { |
|---|
| 733 | _strictAdherence = strictAdherence; |
|---|
| 734 | } |
|---|
| 735 | #endif |
|---|
| 736 | |
|---|
| 737 | bool 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 | } |
|---|