00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00040 #pragma warning(disable:4786)
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #ifdef HAVE_CONFIG_H
00051 # include <simgear_config.h>
00052 #endif
00053
00054 #include <simgear/compiler.h>
00055 #include <simgear/debug/logstream.hxx>
00056 #include <simgear/screen/extensions.hxx>
00057 #include <simgear/screen/RenderTexture.h>
00058
00059 #include <stdio.h>
00060 #include <stdlib.h>
00061 #include <assert.h>
00062 #include <stdarg.h>
00063
00064 #include <cstring>
00065
00066 #ifdef _WIN32
00067 #pragma comment(lib, "gdi32.lib") // required for GetPixelFormat()
00068 #endif
00069
00070 using namespace std;
00071
00072 #ifdef _WIN32
00073 static bool fctPtrInited = false;
00074
00075 static wglChoosePixelFormatARBProc wglChoosePixelFormatARBPtr = 0;
00076 static wglGetPixelFormatAttribivARBProc wglGetPixelFormatAttribivARBPtr = 0;
00077
00078 static wglCreatePbufferARBProc wglCreatePbufferARBPtr = 0;
00079 static wglGetPbufferDCARBProc wglGetPbufferDCARBPtr = 0;
00080 static wglQueryPbufferARBProc wglQueryPbufferARBPtr = 0;
00081 static wglReleasePbufferDCARBProc wglReleasePbufferDCARBPtr = 0;
00082 static wglDestroyPbufferARBProc wglDestroyPbufferARBPtr = 0;
00083
00084 static wglBindTexImageARBProc wglBindTexImageARBPtr = 0;
00085 static wglReleaseTexImageARBProc wglReleaseTexImageARBPtr = 0;
00086
00087 #elif defined( __MACH__ )
00088 #else
00089 static bool glXVersion1_3Present = false;
00090 static glXChooseFBConfigProc glXChooseFBConfigPtr = 0;
00091 static glXCreatePbufferProc glXCreatePbufferPtr = 0;
00092 static glXCreateGLXPbufferProc glXCreateGLXPbufferPtr = 0;
00093 static glXGetVisualFromFBConfigProc glXGetVisualFromFBConfigPtr = 0;
00094 static glXCreateContextProc glXCreateContextPtr = 0;
00095 static glXCreateContextWithConfigProc glXCreateContextWithConfigPtr = 0;
00096 static glXDestroyPbufferProc glXDestroyPbufferPtr = 0;
00097 static glXQueryDrawableProc glXQueryDrawablePtr = 0;
00098 static glXQueryGLXPbufferSGIXProc glXQueryGLXPbufferSGIXPtr = 0;
00099 #endif
00100
00101
00102
00103
00104
00109 RenderTexture::RenderTexture(const char *strMode)
00110 : _iWidth(0),
00111 _iHeight(0),
00112 _bIsTexture(false),
00113 _bIsDepthTexture(false),
00114 _bHasARBDepthTexture(true),
00115 #if defined(_WIN32) || defined(__MACH__)
00116 _eUpdateMode(RT_RENDER_TO_TEXTURE),
00117 #else
00118 _eUpdateMode(RT_COPY_TO_TEXTURE),
00119 #endif
00120 _bInitialized(false),
00121 _iNumAuxBuffers(0),
00122 _bIsBufferBound(false),
00123 _iCurrentBoundBuffer(0),
00124 _iNumDepthBits(0),
00125 _iNumStencilBits(0),
00126 _bFloat(false),
00127 _bDoubleBuffered(false),
00128 _bPowerOf2(true),
00129 _bRectangle(false),
00130 _bMipmap(false),
00131 _bShareObjects(false),
00132 _bCopyContext(false),
00133 #ifdef _WIN32
00134 _hDC(NULL),
00135 _hGLContext(NULL),
00136 _hPBuffer(NULL),
00137 _hPreviousDC(0),
00138 _hPreviousContext(0),
00139 #elif defined( __MACH__ )
00140 _hGLContext(NULL),
00141 _hPBuffer(0),
00142 _hPreviousContext(NULL),
00143 #else
00144 _pDisplay(NULL),
00145 _hGLContext(NULL),
00146 _hPBuffer(0),
00147 _hPreviousDrawable(0),
00148 _hPreviousContext(0),
00149 #endif
00150 _iTextureTarget(GL_NONE),
00151 _iTextureID(0),
00152 _iDepthTextureID(0),
00153 _pPoorDepthTexture(0)
00154 {
00155 _iNumColorBits[0] = _iNumColorBits[1] =
00156 _iNumColorBits[2] = _iNumColorBits[3] = 0;
00157
00158 #ifdef _WIN32
00159 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
00160 _pixelFormatAttribs.push_back(true);
00161 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
00162 _pixelFormatAttribs.push_back(true);
00163
00164 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
00165 _pbufferAttribs.push_back(true);
00166 #elif defined( __MACH__ )
00167
00168 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
00169 _pixelFormatAttribs.push_back(kCGLPFAWindow);
00170 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
00171 #else
00172 _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
00173 _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
00174 _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
00175 _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
00176 #endif
00177
00178 _ParseModeString(strMode, _pixelFormatAttribs, _pbufferAttribs);
00179
00180 #ifdef _WIN32
00181 _pixelFormatAttribs.push_back(0);
00182 _pbufferAttribs.push_back(0);
00183 #elif defined(__MACH__)
00184 _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
00185 _pbufferAttribs.push_back((CGLPixelFormatAttribute)0);
00186 #else
00187 _pixelFormatAttribs.push_back(None);
00188 #endif
00189 }
00190
00191
00192
00193
00194
00195
00200 RenderTexture::~RenderTexture()
00201 {
00202 _Invalidate();
00203 }
00204
00205
00206
00207
00208
00213 #ifdef __MACH__
00214 static void _cglCheckErrorHelper(CGLError err, char *sourceFile, int sourceLine)
00215 {
00216 # ifdef _DEBUG
00217 if (err)
00218 {
00219 fprintf(stderr, "RenderTexture CGL Error: %s at (%s,%d)",
00220 CGLErrorString(err), sourceFile, sourceLine);
00221 }
00222 # endif
00223 }
00224
00225 # define _cglCheckError(err) _cglCheckErrorHelper(err,__FILE__,__LINE__)
00226
00227 #endif
00228
00229
00230
00231
00232
00233
00238 #ifdef _WIN32
00239 void _wglGetLastError()
00240 {
00241 #ifdef _DEBUG
00242
00243 DWORD err = GetLastError();
00244 switch(err)
00245 {
00246 case ERROR_INVALID_PIXEL_FORMAT:
00247 SG_LOG(SG_GL, SG_ALERT,
00248 "RenderTexture Win32 Error: ERROR_INVALID_PIXEL_FORMAT");
00249 break;
00250 case ERROR_NO_SYSTEM_RESOURCES:
00251 SG_LOG(SG_GL, SG_ALERT,
00252 "RenderTexture Win32 Error: ERROR_NO_SYSTEM_RESOURCES");
00253 break;
00254 case ERROR_INVALID_DATA:
00255 SG_LOG(SG_GL, SG_ALERT,
00256 "RenderTexture Win32 Error: ERROR_INVALID_DATA");
00257 break;
00258 case ERROR_INVALID_WINDOW_HANDLE:
00259 SG_LOG(SG_GL, SG_ALERT,
00260 "RenderTexture Win32 Error: ERROR_INVALID_WINDOW_HANDLE");
00261 break;
00262 case ERROR_RESOURCE_TYPE_NOT_FOUND:
00263 SG_LOG(SG_GL, SG_ALERT,
00264 "RenderTexture Win32 Error: ERROR_RESOURCE_TYPE_NOT_FOUND");
00265 break;
00266 case ERROR_SUCCESS:
00267
00268 break;
00269 default:
00270 LPVOID lpMsgBuf;
00271 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
00272 FORMAT_MESSAGE_FROM_SYSTEM |
00273 FORMAT_MESSAGE_IGNORE_INSERTS,
00274 NULL,
00275 err,
00276 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00277 (LPTSTR) &lpMsgBuf,
00278 0,
00279 NULL);
00280
00281 SG_LOG(SG_GL, SG_ALERT, "RenderTexture Win32 Error " << err << ":" << lpMsgBuf);
00282 LocalFree( lpMsgBuf );
00283 break;
00284 }
00285 SetLastError(0);
00286
00287 #endif // _DEBUG
00288 }
00289 #endif
00290
00291
00292
00293
00294
00299 void PrintExtensionError( const char* strMsg, ... )
00300 {
00301 SG_LOG(SG_GL, SG_ALERT,
00302 "Error: RenderTexture requires the following unsupported "
00303 "OpenGL extensions: ");
00304 char strBuffer[512];
00305 va_list args;
00306 va_start(args, strMsg);
00307 #if defined _WIN32 && !defined __CYGWIN__
00308 _vsnprintf( strBuffer, 512, strMsg, args );
00309 #else
00310 vsnprintf( strBuffer, 512, strMsg, args );
00311 #endif
00312 va_end(args);
00313
00314 SG_LOG(SG_GL, SG_ALERT, strMsg);
00315 }
00316
00317
00318
00319
00320
00321
00329 bool RenderTexture::Initialize(int width, int height,
00330 bool shareObjects ,
00331 bool copyContext )
00332 {
00333 assert(width > 0 && height > 0);
00334
00335 _iWidth = width; _iHeight = height;
00336 _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
00337
00338 _bShareObjects = shareObjects;
00339 _bCopyContext = copyContext;
00340
00341
00342 if (!_VerifyExtensions())
00343 return false;
00344
00345 if (_bInitialized)
00346 _Invalidate();
00347
00348 #ifdef _WIN32
00349
00350 HDC hdc = wglGetCurrentDC();
00351 if (NULL == hdc)
00352 _wglGetLastError();
00353 HGLRC hglrc = wglGetCurrentContext();
00354 if (NULL == hglrc)
00355 _wglGetLastError();
00356
00357 int iFormat = 0;
00358 unsigned int iNumFormats;
00359
00360 if (_bCopyContext)
00361 {
00362
00363 iFormat = GetPixelFormat(hdc);
00364 if (iFormat == 0)
00365 {
00366 SG_LOG(SG_GL, SG_ALERT,
00367 "RenderTexture Error: GetPixelFormat() failed.");
00368 return false;
00369 }
00370 }
00371 else
00372 {
00373 if (!wglChoosePixelFormatARBPtr(hdc, &_pixelFormatAttribs[0], NULL,
00374 1, &iFormat, &iNumFormats))
00375 {
00376 SG_LOG(SG_GL, SG_ALERT,
00377 "RenderTexture Error: wglChoosePixelFormatARB() failed.");
00378 _wglGetLastError();
00379 return false;
00380 }
00381 if ( iNumFormats <= 0 )
00382 {
00383 SG_LOG(SG_GL, SG_ALERT,
00384 "RenderTexture Error: Couldn't find a suitable "
00385 "pixel format.");
00386 _wglGetLastError();
00387 return false;
00388 }
00389 }
00390
00391
00392 _hPBuffer = wglCreatePbufferARBPtr(hdc, iFormat, _iWidth, _iHeight,
00393 &_pbufferAttribs[0]);
00394 if (!_hPBuffer)
00395 {
00396 SG_LOG(SG_GL, SG_ALERT,
00397 "RenderTexture Error: wglCreatePbufferARB() failed.");
00398 _wglGetLastError();
00399 return false;
00400 }
00401
00402
00403 _hDC = wglGetPbufferDCARBPtr( _hPBuffer);
00404 if ( !_hDC )
00405 {
00406 SG_LOG(SG_GL, SG_ALERT,
00407 "RenderTexture Error: wglGetGetPbufferDCARB() failed.");
00408 _wglGetLastError();
00409 return false;
00410 }
00411
00412
00413 if (_bCopyContext)
00414 {
00415
00416
00417
00418 _hGLContext = hglrc;
00419 }
00420 else
00421 {
00422 _hGLContext = wglCreateContext( _hDC );
00423 if ( !_hGLContext )
00424 {
00425 SG_LOG(SG_GL, SG_ALERT,
00426 "RenderTexture Error: wglCreateContext() failed.");
00427 _wglGetLastError();
00428 return false;
00429 }
00430 }
00431
00432
00433 if( _bShareObjects )
00434 {
00435 if( !wglShareLists(hglrc, _hGLContext) )
00436 {
00437 SG_LOG(SG_GL, SG_ALERT,
00438 "RenderTexture Error: wglShareLists() failed.");
00439 _wglGetLastError();
00440 return false;
00441 }
00442 }
00443
00444
00445 wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
00446 wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
00447
00448 _bInitialized = true;
00449
00450
00451 int attrib = WGL_RED_BITS_ARB;
00452
00453 int value;
00454 _iNumColorBits[0] =
00455 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00456 ? value : 0;
00457 attrib = WGL_GREEN_BITS_ARB;
00458 _iNumColorBits[1] =
00459 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00460 ? value : 0;
00461 attrib = WGL_BLUE_BITS_ARB;
00462 _iNumColorBits[2] =
00463 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00464 ? value : 0;
00465 attrib = WGL_ALPHA_BITS_ARB;
00466 _iNumColorBits[3] =
00467 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00468 ? value : 0;
00469 attrib = WGL_DEPTH_BITS_ARB;
00470 _iNumDepthBits =
00471 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00472 ? value : 0;
00473 attrib = WGL_STENCIL_BITS_ARB;
00474 _iNumStencilBits =
00475 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00476 ? value : 0;
00477 attrib = WGL_DOUBLE_BUFFER_ARB;
00478 _bDoubleBuffered =
00479 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00480 ? (value?true:false) : false;
00481
00482 #if defined(_DEBUG) | defined(DEBUG)
00483 SG_LOG(SG_GL, SG_ALERT, "Created a " << _iWidth << "x" << _iHeight <<
00484 " RenderTexture with BPP(" <<
00485 _iNumColorBits[0] << "," << _iNumColorBits[1] << "," <<
00486 _iNumColorBits[2] << "," << _iNumColorBits[3] << ")");
00487 if (_iNumDepthBits) SG_LOG(SG_GL, SG_ALERT, " depth=" << _iNumDepthBits);
00488 if (_iNumStencilBits) SG_LOG(SG_GL, SG_ALERT, " stencil=" << _iNumStencilBits);
00489 if (_bDoubleBuffered) SG_LOG(SG_GL, SG_ALERT, " double buffered");
00490 #endif
00491
00492 #elif defined( __MACH__ )
00493
00494 CGLContextObj hglrc = CGLGetCurrentContext();
00495 if (NULL == hglrc)
00496 fprintf(stderr, "Couldn't get current context!");
00497
00498 CGLPixelFormatObj pixFormat = NULL;
00499 GLint iNumFormats;
00500 CGLError error;
00501
00502
00503
00504 CGLPixelFormatAttribute *pixFormatAttribs =
00505 (CGLPixelFormatAttribute *)malloc(sizeof(CGLPixelFormatAttribute)
00506 * _pixelFormatAttribs.size());
00507
00508 for (unsigned int ii = 0; ii < _pixelFormatAttribs.size(); ii++)
00509 {
00510 pixFormatAttribs[ii] =
00511 (CGLPixelFormatAttribute)_pixelFormatAttribs[ii];
00512 }
00513
00514 if (error =
00515 CGLChoosePixelFormat(&pixFormatAttribs[0], &pixFormat, &iNumFormats))
00516 {
00517 fprintf(stderr,
00518 "RenderTexture Error: CGLChoosePixelFormat() failed.\n");
00519 _cglCheckError(error);
00520 return false;
00521 }
00522 if ( iNumFormats <= 0 )
00523 {
00524 SG_LOG(SG_GL, SG_ALERT,
00525 "RenderTexture Error: Couldn't find a suitable "
00526 "pixel format.");
00527 return false;
00528 }
00529
00530
00531 free(pixFormatAttribs);
00532
00533
00534 error = CGLCreateContext(pixFormat, (_bShareObjects)
00535 ? CGLGetCurrentContext() : NULL, &_hGLContext);
00536 if (error)
00537 {
00538 fprintf(stderr,
00539 "RenderTexture Error: CGLCreateContext() failed.\n");
00540 _cglCheckError(error);
00541 return false;
00542 }
00543 CGLDestroyPixelFormat(pixFormat);
00544
00545
00546 error = CGLCreatePBuffer(_iWidth, _iHeight, (_bRectangle)
00547 ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D, GL_RGBA, 0, &_hPBuffer);
00548 if (error)
00549 {
00550 fprintf(stderr,
00551 "RenderTexture Error: CGLCreatePBuffer() failed.\n");
00552 _cglCheckError(error);
00553 return false;
00554 }
00555
00556 GLint screen;
00557 if (error = CGLGetVirtualScreen(CGLGetCurrentContext(), &screen))
00558 {
00559 _cglCheckError(error);
00560 return false;
00561 }
00562 if (error = CGLSetPBuffer(_hGLContext, _hPBuffer, 0, 0, screen))
00563 {
00564 _cglCheckError(error);
00565 return false;
00566 }
00567
00568
00569
00570
00571
00572 _bInitialized = true;
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 #if defined(_DEBUG) | defined(DEBUG)
00609 fprintf(stderr, "Created a %dx%d RenderTexture with BPP(%d, %d, %d, %d)",
00610 _iWidth, _iHeight,
00611 _iNumColorBits[0], _iNumColorBits[1],
00612 _iNumColorBits[2], _iNumColorBits[3]);
00613 if (_iNumDepthBits) fprintf(stderr, " depth=%d", _iNumDepthBits);
00614 if (_iNumStencilBits) fprintf(stderr, " stencil=%d", _iNumStencilBits);
00615 if (_bDoubleBuffered) fprintf(stderr, " double buffered");
00616 fprintf(stderr, "\n");
00617 #endif
00618
00619 #else // !_WIN32, !__MACH_
00620 _pDisplay = glXGetCurrentDisplay();
00621 GLXContext context = glXGetCurrentContext();
00622 int screen = DefaultScreen(_pDisplay);
00623 XVisualInfo *visInfo = NULL;
00624
00625 GLXFBConfig *fbConfigs;
00626 int nConfigs;
00627
00628 fbConfigs = glXChooseFBConfigPtr(_pDisplay, screen,
00629 &_pixelFormatAttribs[0], &nConfigs);
00630
00631 if (nConfigs == 0 || !fbConfigs)
00632 {
00633 SG_LOG(SG_GL, SG_ALERT,
00634 "RenderTexture Error: Couldn't find a suitable pixel format.");
00635 return false;
00636 }
00637
00638
00639 if (glXVersion1_3Present)
00640 {
00641 int pbufAttrib[] = {
00642 GLX_PBUFFER_WIDTH, _iWidth,
00643 GLX_PBUFFER_HEIGHT, _iHeight,
00644 GLX_LARGEST_PBUFFER, False,
00645 None
00646 };
00647 for (int i=0;i<nConfigs;i++)
00648 {
00649 _hPBuffer = glXCreatePbufferPtr(_pDisplay, fbConfigs[i], pbufAttrib);
00650 if (_hPBuffer)
00651 {
00652 XVisualInfo *visInfo = glXGetVisualFromFBConfigPtr(_pDisplay, fbConfigs[i]);
00653
00654 _hGLContext = glXCreateContextPtr(_pDisplay, visInfo,
00655 _bShareObjects ? context : NULL,
00656 True);
00657 if (!_hGLContext)
00658 {
00659 return false;
00660 }
00661 XFree( visInfo );
00662 break;
00663 }
00664 }
00665 }
00666 else
00667 {
00668 #ifdef WIN32
00669 int iFormat = 0;
00670 int iNumFormats;
00671 int attrib = 0;
00672 #endif
00673 for (int i=0;i<nConfigs;i++)
00674 {
00675 _hPBuffer = glXCreateGLXPbufferPtr(_pDisplay, fbConfigs[i],
00676 _iWidth, _iHeight, NULL);
00677 if (_hPBuffer)
00678 {
00679 _hGLContext = glXCreateContextWithConfigPtr(_pDisplay,
00680 fbConfigs[i],
00681 GLX_RGBA_TYPE,
00682 _bShareObjects ? context : NULL,
00683 True);
00684 break;
00685 }
00686 }
00687 }
00688 XFree( fbConfigs );
00689
00690 if (!_hPBuffer)
00691 {
00692 SG_LOG(SG_GL, SG_ALERT,
00693 "RenderTexture Error: glXCreateGLXPbufferPtr() failed.");
00694 return false;
00695 }
00696
00697 if(!_hGLContext)
00698 {
00699
00700 _hGLContext = glXCreateContext(_pDisplay, visInfo,
00701 _bShareObjects ? context : NULL, False);
00702 if ( !_hGLContext )
00703 {
00704 SG_LOG(SG_GL, SG_ALERT,
00705 "RenderTexture Error: glXCreateContext() failed.");
00706 return false;
00707 }
00708 }
00709
00710 if (!glXVersion1_3Present)
00711 {
00712 glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_WIDTH_SGIX,
00713 (GLuint*)&_iWidth);
00714 glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_HEIGHT_SGIX,
00715 (GLuint*)&_iHeight);
00716 }
00717
00718 _bInitialized = true;
00719
00720
00721
00722 #endif
00723
00724
00725
00726
00727
00728
00729 #ifdef _WIN32
00730 if (false == wglMakeCurrent( _hDC, _hGLContext))
00731 {
00732 _wglGetLastError();
00733 return false;
00734 }
00735 #elif defined( __MACH__ )
00736 CGLError err;
00737 if (err = CGLSetCurrentContext(_hGLContext))
00738 {
00739 _cglCheckError(err);
00740 return false;
00741 }
00742 #else
00743 _hPreviousContext = glXGetCurrentContext();
00744 _hPreviousDrawable = glXGetCurrentDrawable();
00745
00746 if (False == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
00747 {
00748 return false;
00749 }
00750 #endif
00751
00752 bool result = _InitializeTextures();
00753 #ifdef _WIN32
00754 BindBuffer(WGL_FRONT_LEFT_ARB);
00755 _BindDepthBuffer();
00756 #endif
00757
00758
00759 #ifdef _WIN32
00760
00761 if (false == wglMakeCurrent( hdc, hglrc))
00762 {
00763 _wglGetLastError();
00764 return false;
00765 }
00766 #elif defined( __MACH__ )
00767 if (err = CGLSetCurrentContext(_hPreviousContext))
00768 {
00769 _cglCheckError(err);
00770 return false;
00771 }
00772 #else
00773 if (False == glXMakeCurrent(_pDisplay,
00774 _hPreviousDrawable, _hPreviousContext))
00775 {
00776 return false;
00777 }
00778 if (glXVersion1_3Present)
00779 {
00780 GLXDrawable draw = glXGetCurrentDrawable();
00781 glXQueryDrawablePtr(_pDisplay, draw, GLX_WIDTH, (unsigned int*)&_iWidth);
00782 glXQueryDrawablePtr(_pDisplay, draw, GLX_HEIGHT, (unsigned int*)&_iHeight);
00783 }
00784 #endif
00785
00786 return result;
00787 }
00788
00789
00790
00791
00792
00793
00799 bool RenderTexture::_Invalidate()
00800 {
00801 _iNumColorBits[0] = _iNumColorBits[1] =
00802 _iNumColorBits[2] = _iNumColorBits[3] = 0;
00803 _iNumDepthBits = 0;
00804 _iNumStencilBits = 0;
00805
00806 if (_bIsTexture)
00807 glDeleteTextures(1, &_iTextureID);
00808 if (_bIsDepthTexture)
00809 {
00810
00811 if (!_bHasARBDepthTexture) delete[] _pPoorDepthTexture;
00812
00813 glDeleteTextures(1, &_iDepthTextureID);
00814 }
00815
00816 #ifdef _WIN32
00817 if ( _hPBuffer )
00818 {
00819
00820 if (wglGetCurrentContext() == _hGLContext)
00821 wglMakeCurrent(0,0);
00822 if (!_bCopyContext)
00823 wglDeleteContext( _hGLContext);
00824 wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
00825 wglDestroyPbufferARBPtr( _hPBuffer );
00826 _hPBuffer = 0;
00827 return true;
00828 }
00829 #elif defined( __MACH__ )
00830 if ( _hPBuffer )
00831 {
00832 if (CGLGetCurrentContext() == _hGLContext)
00833 CGLSetCurrentContext(NULL);
00834 if (!_bCopyContext)
00835 CGLDestroyContext(_hGLContext);
00836 CGLDestroyPBuffer(_hPBuffer);
00837 _hPBuffer = NULL;
00838 return true;
00839 }
00840 #else
00841 if ( _hPBuffer )
00842 {
00843 if(glXGetCurrentContext() == _hGLContext)
00844
00845 glXMakeCurrent(_pDisplay, _hPBuffer, 0);
00846 glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
00847 _hPBuffer = 0;
00848 return true;
00849 }
00850 #endif
00851
00852
00853 return false;
00854 }
00855
00856
00857
00858
00859
00860
00868 bool RenderTexture::Reset(const char *strMode, ...)
00869 {
00870 _iWidth = 0; _iHeight = 0;
00871 _bIsTexture = false; _bIsDepthTexture = false,
00872 _bHasARBDepthTexture = true;
00873 #if defined(_WIN32) || defined(__MACH__)
00874 _eUpdateMode = RT_RENDER_TO_TEXTURE;
00875 #else
00876 _eUpdateMode = RT_COPY_TO_TEXTURE;
00877 #endif
00878 _bInitialized = false;
00879 _iNumAuxBuffers = 0;
00880 _bIsBufferBound = false;
00881 _iCurrentBoundBuffer = 0;
00882 _iNumDepthBits = 0; _iNumStencilBits = 0;
00883 _bDoubleBuffered = false;
00884 _bFloat = false; _bPowerOf2 = true;
00885 _bRectangle = false; _bMipmap = false;
00886 _bShareObjects = false; _bCopyContext = false;
00887 _iTextureTarget = GL_NONE; _iTextureID = 0;
00888 _iDepthTextureID = 0;
00889 _pPoorDepthTexture = 0;
00890 _pixelFormatAttribs.clear();
00891 _pbufferAttribs.clear();
00892
00893 if (IsInitialized() && !_Invalidate())
00894 {
00895 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Reset(): failed to invalidate.");
00896 return false;
00897 }
00898
00899 _iNumColorBits[0] = _iNumColorBits[1] =
00900 _iNumColorBits[2] = _iNumColorBits[3] = 0;
00901
00902 #ifdef _WIN32
00903 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
00904 _pixelFormatAttribs.push_back(true);
00905 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
00906 _pixelFormatAttribs.push_back(true);
00907
00908 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
00909 _pbufferAttribs.push_back(true);
00910 #elif defined( __MACH__ )
00911
00912 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
00913 _pixelFormatAttribs.push_back(kCGLPFAWindow);
00914 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
00915 #else
00916 _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
00917 _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
00918 _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
00919 _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
00920 #endif
00921
00922 va_list args;
00923 char strBuffer[256];
00924 va_start(args,strMode);
00925 #if defined _WIN32 && !defined __CYGWIN__
00926 _vsnprintf( strBuffer, 256, strMode, args );
00927 #else
00928 vsnprintf( strBuffer, 256, strMode, args );
00929 #endif
00930 va_end(args);
00931
00932 _ParseModeString(strBuffer, _pixelFormatAttribs, _pbufferAttribs);
00933
00934 #ifdef _WIN32
00935 _pixelFormatAttribs.push_back(0);
00936 _pbufferAttribs.push_back(0);
00937 #elif defined(__MACH__)
00938 _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
00939 #else
00940 _pixelFormatAttribs.push_back(None);
00941 #endif
00942 return true;
00943 }
00944
00945
00946
00947
00948
00958 bool RenderTexture::Resize(int iWidth, int iHeight)
00959 {
00960 if (!_bInitialized) {
00961 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Resize(): must Initialize() first.");
00962 return false;
00963 }
00964 if (iWidth == _iWidth && iHeight == _iHeight) {
00965 return true;
00966 }
00967
00968
00969 if (_bIsTexture)
00970 glDeleteTextures(1, &_iTextureID);
00971 if (_bIsDepthTexture)
00972 glDeleteTextures(1, &_iDepthTextureID);
00973 #ifdef _WIN32
00974 if ( _hPBuffer )
00975 {
00976
00977 if (wglGetCurrentContext() == _hGLContext)
00978 wglMakeCurrent(0,0);
00979 if (!_bCopyContext)
00980 wglDeleteContext( _hGLContext);
00981 wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
00982 wglDestroyPbufferARBPtr( _hPBuffer );
00983 _hPBuffer = 0;
00984 return true;
00985 }
00986 #elif defined( __MACH__ )
00987 if ( _hPBuffer )
00988 {
00989 if (CGLGetCurrentContext() == _hGLContext)
00990 CGLSetCurrentContext(NULL);
00991 if (!_bCopyContext)
00992 CGLDestroyContext(_hGLContext);
00993 CGLDestroyPBuffer(_hPBuffer);
00994 _hPBuffer = NULL;
00995 return true;
00996 }
00997 #else
00998 if ( _hPBuffer )
00999 {
01000 if(glXGetCurrentContext() == _hGLContext)
01001
01002 glXMakeCurrent(_pDisplay, _hPBuffer, 0);
01003 glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
01004 _hPBuffer = 0;
01005 }
01006 #endif
01007 else {
01008 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Resize(): failed to resize.");
01009 return false;
01010 }
01011 _bInitialized = false;
01012 return Initialize(iWidth, iHeight, _bShareObjects, _bCopyContext);
01013 }
01014
01015
01016
01017
01018
01023 bool RenderTexture::BeginCapture()
01024 {
01025 if (!_bInitialized)
01026 {
01027 SG_LOG(SG_GL, SG_ALERT,
01028 "RenderTexture::BeginCapture(): Texture is not initialized!");
01029 return false;
01030 }
01031 #ifdef _WIN32
01032
01033 _hPreviousDC = wglGetCurrentDC();
01034 if (NULL == _hPreviousDC)
01035 _wglGetLastError();
01036 _hPreviousContext = wglGetCurrentContext();
01037 if (NULL == _hPreviousContext)
01038 _wglGetLastError();
01039 #elif defined( __MACH__ )
01040 _hPreviousContext = CGLGetCurrentContext();
01041 #else
01042 _hPreviousContext = glXGetCurrentContext();
01043 _hPreviousDrawable = glXGetCurrentDrawable();
01044 #endif
01045
01046 _ReleaseBoundBuffers();
01047
01048 return _MakeCurrent();
01049 }
01050
01051
01052
01053
01054
01055
01060 bool RenderTexture::EndCapture()
01061 {
01062 if (!_bInitialized)
01063 {
01064 SG_LOG(SG_GL, SG_ALERT,
01065 "RenderTexture::EndCapture() : Texture is not initialized!");
01066 return false;
01067 }
01068
01069 glFlush();
01070
01071 _MaybeCopyBuffer();
01072
01073 #ifdef _WIN32
01074
01075 if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
01076 {
01077 _wglGetLastError();
01078 return false;
01079 }
01080 #elif defined( __MACH__ )
01081 CGLError err;
01082 if (err = CGLSetCurrentContext(_hPreviousContext))
01083 {
01084 _cglCheckError(err);
01085 return false;
01086 }
01087 #else
01088 if (False == glXMakeCurrent(_pDisplay, _hPreviousDrawable,
01089 _hPreviousContext))
01090 {
01091 return false;
01092 }
01093 #endif
01094
01095
01096 BindBuffer(_iCurrentBoundBuffer);
01097 _BindDepthBuffer();
01098
01099 return true;
01100 }
01101
01102
01103
01104
01105
01120 bool RenderTexture::BeginCapture(RenderTexture* current)
01121 {
01122
01123
01124 if (current == this) {
01125 return true;
01126 }
01127 if (!current) {
01128
01129 return BeginCapture();
01130 }
01131 if (!_bInitialized)
01132 {
01133 SG_LOG(SG_GL, SG_ALERT,
01134 "RenderTexture::BeginCapture(RenderTexture*): Texture is not initialized!");
01135 return false;
01136 }
01137 if (!current->_bInitialized)
01138 {
01139 SG_LOG(SG_GL, SG_ALERT,
01140 "RenderTexture::BeginCapture(RenderTexture): 'current' texture is not initialized!");
01141 return false;
01142 }
01143
01144
01145 current->_MaybeCopyBuffer();
01146
01147
01148
01149 #ifdef _WIN32
01150 _hPreviousDC = current->_hPreviousDC;
01151 if (NULL == _hPreviousDC)
01152 _wglGetLastError();
01153 _hPreviousContext = current->_hPreviousContext;
01154 if (NULL == _hPreviousContext)
01155 _wglGetLastError();
01156 #elif defined( __MACH__ )
01157 _hPreviousContext = current->_hPreviousContext;
01158 #else
01159 _hPreviousContext = current->_hPreviousContext;
01160 _hPreviousDrawable = current->_hPreviousDrawable;
01161 #endif
01162
01163
01164 if (!_ReleaseBoundBuffers())
01165 return false;
01166
01167
01168 if (!_MakeCurrent())
01169 return false;
01170
01171
01172 current->BindBuffer(_iCurrentBoundBuffer);
01173 current->_BindDepthBuffer();
01174
01175 return true;
01176 }
01177
01178
01179
01180
01181
01182
01183
01188 void RenderTexture::Bind() const
01189 {
01190 if (_bInitialized && _bIsTexture)
01191 {
01192 glBindTexture(_iTextureTarget, _iTextureID);
01193 }
01194 }
01195
01196
01197
01198
01199
01200
01205 void RenderTexture::BindDepth() const
01206 {
01207 if (_bInitialized && _bIsDepthTexture)
01208 {
01209 glBindTexture(_iTextureTarget, _iDepthTextureID);
01210 }
01211 }
01212
01213
01214
01215
01216
01217
01222 bool RenderTexture::BindBuffer( int iBuffer )
01223 {
01224
01225 if (_bInitialized && _bIsTexture)
01226 {
01227 glBindTexture(_iTextureTarget, _iTextureID);
01228
01229 #ifdef _WIN32
01230 if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
01231 (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
01232 {
01233 if (FALSE == wglBindTexImageARBPtr(_hPBuffer, iBuffer))
01234 {
01235
01236
01237
01238
01239 SetLastError(0);
01240 }
01241 _bIsBufferBound = true;
01242 _iCurrentBoundBuffer = iBuffer;
01243 }
01244 #elif defined(__MACH__)
01245 if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
01246 (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
01247 {
01248 CGLError err;
01249 if (err=CGLTexImagePBuffer(CGLGetCurrentContext(), _hPBuffer, iBuffer))
01250 {
01251 _cglCheckError(err);
01252 }
01253 _bIsBufferBound = true;
01254 _iCurrentBoundBuffer = iBuffer;
01255 }
01256 #endif
01257 }
01258 return true;
01259 }
01260
01261
01262
01263
01264
01265
01270 bool RenderTexture::_BindDepthBuffer() const
01271 {
01272 #ifdef WIN32
01273 if (_bInitialized && _bIsDepthTexture &&
01274 RT_RENDER_TO_TEXTURE == _eUpdateMode)
01275 {
01276 glBindTexture(_iTextureTarget, _iDepthTextureID);
01277 if (FALSE == wglBindTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
01278 {
01279 _wglGetLastError();
01280 return false;
01281 }
01282 }
01283 #elif defined(__MACH__)
01284 if (_bInitialized && _bIsDepthTexture &&
01285 RT_RENDER_TO_TEXTURE == _eUpdateMode)
01286 {
01287 glBindTexture(_iTextureTarget, _iDepthTextureID);
01288
01289
01290
01291
01292
01293 }
01294 #endif
01295 return true;
01296 }
01297
01298
01299
01300
01301
01306 void RenderTexture::_ParseModeString(const char *modeString,
01307 vector<int> &pfAttribs,
01308 vector<int> &pbAttribs)
01309 {
01310 if (!modeString || strcmp(modeString, "") == 0)
01311 return;
01312
01313 _iNumComponents = 0;
01314 #if defined(_WIN32) || defined(__MACH__)
01315 _eUpdateMode = RT_RENDER_TO_TEXTURE;
01316 #else
01317 _eUpdateMode = RT_COPY_TO_TEXTURE;
01318 #endif
01319
01320 int iDepthBits = 0;
01321 bool bHasStencil = false;
01322 bool bBind2D = false;
01323 bool bBindRECT = false;
01324 bool bBindCUBE = false;
01325
01326 char *mode = strdup(modeString);
01327
01328
01329 vector<string> tokens;
01330 char *buf = strtok(mode, " ");
01331 while (buf != NULL)
01332 {
01333 tokens.push_back(buf);
01334 buf = strtok(NULL, " ");
01335 }
01336 free(mode);
01337 for (unsigned int i = 0; i < tokens.size(); i++)
01338 {
01339 string token = tokens[i];
01340
01341 KeyVal kv = _GetKeyValuePair(token);
01342
01343
01344 if (kv.first == "rgb" && (_iNumComponents <= 1))
01345 {
01346 if (kv.second.find("f") != kv.second.npos)
01347 _bFloat = true;
01348
01349 vector<int> bitVec = _ParseBitVector(kv.second);
01350
01351 if (bitVec.size() < 3)
01352 {
01353 bitVec.push_back(bitVec[0]);
01354 bitVec.push_back(bitVec[0]);
01355 }
01356
01357 #ifdef _WIN32
01358 pfAttribs.push_back(WGL_RED_BITS_ARB);
01359 pfAttribs.push_back(bitVec[0]);
01360 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
01361 pfAttribs.push_back(bitVec[1]);
01362 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
01363 pfAttribs.push_back(bitVec[2]);
01364 #elif defined( __MACH__ )
01365 # if 0
01366 pfAttribs.push_back(AGL_RED_SIZE);
01367 pfAttribs.push_back(bitVec[0]);
01368 pfAttribs.push_back(AGL_GREEN_SIZE);
01369 pfAttribs.push_back(bitVec[1]);
01370 pfAttribs.push_back(AGL_BLUE_SIZE);
01371 pfAttribs.push_back(bitVec[2]);
01372 # else
01373 pfAttribs.push_back(kCGLPFAColorSize);
01374 pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2]);
01375 # endif
01376 #else
01377 pfAttribs.push_back(GLX_RED_SIZE);
01378 pfAttribs.push_back(bitVec[0]);
01379 pfAttribs.push_back(GLX_GREEN_SIZE);
01380 pfAttribs.push_back(bitVec[1]);
01381 pfAttribs.push_back(GLX_BLUE_SIZE);
01382 pfAttribs.push_back(bitVec[2]);
01383 #endif
01384 _iNumComponents += 3;
01385 continue;
01386 }
01387 else if (kv.first == "rgb")
01388 SG_LOG(SG_GL, SG_ALERT,
01389 "RenderTexture Warning: mistake in components definition "
01390 "(rgb + " << _iNumComponents << ").");
01391
01392 if (kv.first == "rgba" && (_iNumComponents == 0))
01393 {
01394 if (kv.second.find("f") != kv.second.npos)
01395 _bFloat = true;
01396
01397 vector<int> bitVec = _ParseBitVector(kv.second);
01398
01399 if (bitVec.size() < 4)
01400 {
01401 bitVec.push_back(bitVec[0]);
01402 bitVec.push_back(bitVec[0]);
01403 bitVec.push_back(bitVec[0]);
01404 }
01405
01406 #ifdef _WIN32
01407 pfAttribs.push_back(WGL_RED_BITS_ARB);
01408 pfAttribs.push_back(bitVec[0]);
01409 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
01410 pfAttribs.push_back(bitVec[1]);
01411 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
01412 pfAttribs.push_back(bitVec[2]);
01413 pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
01414 pfAttribs.push_back(bitVec[3]);
01415 #elif defined( __MACH__ )
01416 # if 0
01417 pfAttribs.push_back(AGL_RED_SIZE);
01418 pfAttribs.push_back(bitVec[0]);
01419 pfAttribs.push_back(AGL_GREEN_SIZE);
01420 pfAttribs.push_back(bitVec[1]);
01421 pfAttribs.push_back(AGL_BLUE_SIZE);
01422 pfAttribs.push_back(bitVec[2]);
01423 pfAttribs.push_back(AGL_ALPHA_SIZE);
01424 pfAttribs.push_back(bitVec[3]);
01425 # else
01426 pfAttribs.push_back(kCGLPFAColorSize);
01427 pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2] + bitVec[3]);
01428
01429
01430
01431
01432 # endif
01433 #else
01434 pfAttribs.push_back(GLX_RED_SIZE);
01435 pfAttribs.push_back(bitVec[0]);
01436 pfAttribs.push_back(GLX_GREEN_SIZE);
01437 pfAttribs.push_back(bitVec[1]);
01438 pfAttribs.push_back(GLX_BLUE_SIZE);
01439 pfAttribs.push_back(bitVec[2]);
01440 pfAttribs.push_back(GLX_ALPHA_SIZE);
01441 pfAttribs.push_back(bitVec[3]);
01442 #endif
01443 _iNumComponents = 4;
01444 continue;
01445 }
01446 else if (kv.first == "rgba")
01447 SG_LOG(SG_GL, SG_ALERT,
01448 "RenderTexture Warning: mistake in components definition "
01449 "(rgba + " << _iNumComponents << ").");
01450
01451 if (kv.first == "r" && (_iNumComponents <= 1))
01452 {
01453 if (kv.second.find("f") != kv.second.npos)
01454 _bFloat = true;
01455
01456 vector<int> bitVec = _ParseBitVector(kv.second);
01457
01458 #ifdef _WIN32
01459 pfAttribs.push_back(WGL_RED_BITS_ARB);
01460 pfAttribs.push_back(bitVec[0]);
01461 #elif defined( __MACH__ )
01462 # if 0
01463 pfAttribs.push_back(AGL_RED_SIZE);
01464 pfAttribs.push_back(bitVec[0]);
01465 # else
01466 pfAttribs.push_back(kCGLPFAColorSize);
01467 pfAttribs.push_back(bitVec[0]);
01468 # endif
01469 #else
01470 pfAttribs.push_back(GLX_RED_SIZE);
01471 pfAttribs.push_back(bitVec[0]);
01472 #endif
01473 _iNumComponents++;
01474 continue;
01475 }
01476 else if (kv.first == "r")
01477 SG_LOG(SG_GL, SG_ALERT,
01478 "RenderTexture Warning: mistake in components definition "
01479 "(r + " << _iNumComponents << ").");
01480
01481 if (kv.first == "rg" && (_iNumComponents <= 1))
01482 {
01483 if (kv.second.find("f") != kv.second.npos)
01484 _bFloat = true;
01485
01486 vector<int> bitVec = _ParseBitVector(kv.second);
01487
01488 if (bitVec.size() < 2)
01489 {
01490 bitVec.push_back(bitVec[0]);
01491 }
01492
01493 #ifdef _WIN32
01494 pfAttribs.push_back(WGL_RED_BITS_ARB);
01495 pfAttribs.push_back(bitVec[0]);
01496 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
01497 pfAttribs.push_back(bitVec[1]);
01498 #elif defined( __MACH__ )
01499 # if 0
01500 pfAttribs.push_back(AGL_RED_SIZE);
01501 pfAttribs.push_back(bitVec[0]);
01502 pfAttribs.push_back(AGL_GREEN_SIZE);
01503 pfAttribs.push_back(bitVec[1]);
01504 # else
01505 pfAttribs.push_back(kCGLPFAColorSize);
01506 pfAttribs.push_back(bitVec[0] + bitVec[1]);
01507 # endif
01508 #else
01509 pfAttribs.push_back(GLX_RED_SIZE);
01510 pfAttribs.push_back(bitVec[0]);
01511 pfAttribs.push_back(GLX_GREEN_SIZE);
01512 pfAttribs.push_back(bitVec[1]);
01513 #endif
01514 _iNumComponents += 2;
01515 continue;
01516 }
01517 else if (kv.first == "rg")
01518 SG_LOG(SG_GL, SG_ALERT,
01519 "RenderTexture Warning: mistake in components definition "
01520 "(rg + " << _iNumComponents << ").");
01521
01522 if (kv.first == "depth")
01523 {
01524 if (kv.second == "")
01525 iDepthBits = 24;
01526 else
01527 iDepthBits = strtol(kv.second.c_str(), 0, 10);
01528 continue;
01529 }
01530
01531 if (kv.first == "stencil")
01532 {
01533 bHasStencil = true;
01534 #ifdef _WIN32
01535 pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
01536 #elif defined( __MACH__ )
01537 # if 0
01538 pfAttribs.push_back(AGL_STENCIL_SIZE);
01539 # else
01540 pfAttribs.push_back(kCGLPFAStencilSize);
01541 # endif
01542 #else
01543 pfAttribs.push_back(GLX_STENCIL_SIZE);
01544 #endif
01545 if (kv.second == "")
01546 pfAttribs.push_back(8);
01547 else
01548 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
01549 continue;
01550 }
01551
01552 if (kv.first == "samples")
01553 {
01554 #ifdef _WIN32
01555 pfAttribs.push_back(WGL_SAMPLE_BUFFERS_ARB);
01556 pfAttribs.push_back(1);
01557 pfAttribs.push_back(WGL_SAMPLES_ARB);
01558 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
01559 #elif defined( __MACH__ )
01560 # if 0
01561 pfAttribs.push_back(AGL_SAMPLE_BUFFERS_ARB);
01562 pfAttribs.push_back(1);
01563 pfAttribs.push_back(AGL_SAMPLES_ARB);
01564 # else
01565 pfAttribs.push_back(kCGLPFAMultisample);
01566 pfAttribs.push_back(kCGLPFASamples);
01567 # endif
01568 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
01569 #else
01570 pfAttribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
01571 pfAttribs.push_back(1);
01572 pfAttribs.push_back(GLX_SAMPLES_ARB);
01573 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
01574 #endif
01575 continue;
01576
01577 }
01578
01579 if (kv.first == "doublebuffer" || kv.first == "double")
01580 {
01581 #ifdef _WIN32
01582 pfAttribs.push_back(WGL_DOUBLE_BUFFER_ARB);
01583 pfAttribs.push_back(true);
01584 #elif defined( __MACH__ )
01585 # if 0
01586 pfAttribs.push_back(AGL_DOUBLEBUFFER);
01587 pfAttribs.push_back(True);
01588 # else
01589 pfAttribs.push_back(kCGLPFADoubleBuffer);
01590 # endif
01591 #else
01592 pfAttribs.push_back(GLX_DOUBLEBUFFER);
01593 pfAttribs.push_back(True);
01594 #endif
01595 continue;
01596 }
01597
01598 if (kv.first == "aux")
01599 {
01600 #ifdef _WIN32
01601 pfAttribs.push_back(WGL_AUX_BUFFERS_ARB);
01602 #elif defined( __MACH__ )
01603 # if 0
01604 pfAttribs.push_back(AGL_AUX_BUFFERS);
01605 # else
01606 pfAttribs.push_back(kCGLPFAAuxBuffers);
01607 # endif
01608 #else
01609 pfAttribs.push_back(GLX_AUX_BUFFERS);
01610 #endif
01611 if (kv.second == "")
01612 pfAttribs.push_back(0);
01613 else
01614 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
01615 continue;
01616 }
01617
01618 if (token.find("tex") == 0)
01619 {
01620 _bIsTexture = true;
01621
01622 if ((kv.first == "texRECT") && (GL_NV_texture_rectangle ||
01623 GL_EXT_texture_rectangle))
01624 {
01625 _bRectangle = true;
01626 bBindRECT = true;
01627 }
01628 else if (kv.first == "texCUBE")
01629 {
01630 bBindCUBE = true;
01631 }
01632 else
01633 {
01634 bBind2D = true;
01635 }
01636
01637 continue;
01638 }
01639
01640 if (token.find("depthTex") == 0)
01641 {
01642 _bIsDepthTexture = true;
01643
01644 if ((kv.first == "depthTexRECT") && (GL_NV_texture_rectangle ||
01645 GL_EXT_texture_rectangle))
01646 {
01647 _bRectangle = true;
01648 bBindRECT = true;
01649 }
01650 else if (kv.first == "depthTexCUBE")
01651 {
01652 bBindCUBE = true;
01653 }
01654 else