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
00034
00035
00043
00044
00045
00046
00047
00048
00049
00050
00051 #ifdef HAVE_CONFIG_H
00052 # include <simgear_config.h>
00053 #endif
00054
00055 #include <simgear/compiler.h>
00056 #include <simgear/debug/logstream.hxx>
00057 #include <simgear/screen/extensions.hxx>
00058 #include <simgear/screen/RenderTexture.h>
00059
00060 #include <stdio.h>
00061 #include <stdlib.h>
00062 #include <assert.h>
00063 #include <stdarg.h>
00064
00065 #include <cstring>
00066
00067 #ifdef _WIN32
00068 #pragma comment(lib, "gdi32.lib") // required for GetPixelFormat()
00069 #endif
00070
00071 using namespace std;
00072
00073
00074
00075
00076
00077
00078 #if defined (_DEBUG)
00079 const char * get_attr_name( int val, int * pdef );
00080 #define dbg_printf printf
00081 #else
00082 #if defined (__GNUC__)
00083 #define dbg_printf(format,args...) ((void)0)
00084 #else // defined (__GNUC__)
00085 #define dbg_printf
00086 #endif // defined (__GNUC__)
00087 #endif // defined (_DEBUG)
00088
00089
00090 #define ADD_QUERY_BUFFER
00091 #define ADD_GET_DRAWABLE
00092
00093
00094
00095 #ifdef _WIN32
00096 static bool fctPtrInited = false;
00097
00098 static wglChoosePixelFormatARBProc wglChoosePixelFormatARBPtr = 0;
00099 static wglGetPixelFormatAttribivARBProc wglGetPixelFormatAttribivARBPtr = 0;
00100
00101 static wglCreatePbufferARBProc wglCreatePbufferARBPtr = 0;
00102 static wglGetPbufferDCARBProc wglGetPbufferDCARBPtr = 0;
00103 static wglQueryPbufferARBProc wglQueryPbufferARBPtr = 0;
00104 static wglReleasePbufferDCARBProc wglReleasePbufferDCARBPtr = 0;
00105 static wglDestroyPbufferARBProc wglDestroyPbufferARBPtr = 0;
00106
00107 static wglBindTexImageARBProc wglBindTexImageARBPtr = 0;
00108 static wglReleaseTexImageARBProc wglReleaseTexImageARBPtr = 0;
00109
00110 #elif defined( __MACH__ )
00111 #else
00112 static bool glXVersion1_3Present = false;
00113 static glXChooseFBConfigProc glXChooseFBConfigPtr = 0;
00114 static glXCreatePbufferProc glXCreatePbufferPtr = 0;
00115 static glXCreateGLXPbufferProc glXCreateGLXPbufferPtr = 0;
00116 static glXGetVisualFromFBConfigProc glXGetVisualFromFBConfigPtr = 0;
00117 static glXCreateContextProc glXCreateContextPtr = 0;
00118 static glXCreateContextWithConfigProc glXCreateContextWithConfigPtr = 0;
00119 static glXDestroyPbufferProc glXDestroyPbufferPtr = 0;
00120 static glXQueryDrawableProc glXQueryDrawablePtr = 0;
00121 static glXQueryGLXPbufferSGIXProc glXQueryGLXPbufferSGIXPtr = 0;
00122 #endif
00123
00124
00125
00126
00127
00132 RenderTexture::RenderTexture(const char *strMode)
00133 : _iWidth(0),
00134 _iHeight(0),
00135 _bIsTexture(false),
00136 _bIsDepthTexture(false),
00137 _bHasARBDepthTexture(true),
00138 #if defined(_WIN32) || defined(__MACH__)
00139 _eUpdateMode(RT_RENDER_TO_TEXTURE),
00140 #else
00141 _eUpdateMode(RT_COPY_TO_TEXTURE),
00142 #endif
00143 _bInitialized(false),
00144 _iNumAuxBuffers(0),
00145 _bIsBufferBound(false),
00146 _iCurrentBoundBuffer(0),
00147 _iNumDepthBits(0),
00148 _iNumStencilBits(0),
00149 _bFloat(false),
00150 _bDoubleBuffered(false),
00151 _bPowerOf2(true),
00152 _bRectangle(false),
00153 _bMipmap(false),
00154 _bShareObjects(false),
00155 _bCopyContext(false),
00156 #ifdef _WIN32
00157 _hDC(NULL),
00158 _hGLContext(NULL),
00159 _hPBuffer(NULL),
00160 _hPreviousDC(0),
00161 _hPreviousContext(0),
00162 #elif defined( __MACH__ )
00163 _hGLContext(NULL),
00164 _hPBuffer(0),
00165 _hPreviousContext(NULL),
00166 #else
00167 _pDisplay(NULL),
00168 _hGLContext(NULL),
00169 _hPBuffer(0),
00170 _hPreviousDrawable(0),
00171 _hPreviousContext(0),
00172 #endif
00173 _iTextureTarget(GL_NONE),
00174 _iTextureID(0),
00175 _iDepthTextureID(0),
00176 _pPoorDepthTexture(0)
00177 {
00178 dbg_printf("RenderTexture::RenderTexture(%s) BGN instantiation.\n", strMode );
00179 _iNumColorBits[0] = _iNumColorBits[1] =
00180 _iNumColorBits[2] = _iNumColorBits[3] = 0;
00181
00182 #ifdef _WIN32
00183 dbg_printf("RenderTexture::RenderTexture in _WIN32.\n" );
00184 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
00185 _pixelFormatAttribs.push_back(true);
00186 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
00187 _pixelFormatAttribs.push_back(true);
00188
00189 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
00190 _pbufferAttribs.push_back(true);
00191 #elif defined( __MACH__ )
00192 dbg_printf("RenderTexture::RenderTexture in __MACH__.\n" );
00193
00194 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
00195 _pixelFormatAttribs.push_back(kCGLPFAWindow);
00196 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
00197 #else
00198 dbg_printf("RenderTexture::RenderTexture !_WIN32 and !__MACH__.\n" );
00199 _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
00200 _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
00201 _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
00202 _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
00203 #endif
00204
00205 _ParseModeString(strMode, _pixelFormatAttribs, _pbufferAttribs);
00206
00207 #ifdef _WIN32
00208 _pixelFormatAttribs.push_back(0);
00209 _pbufferAttribs.push_back(0);
00210 #elif defined(__MACH__)
00211 _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
00212 _pbufferAttribs.push_back((CGLPixelFormatAttribute)0);
00213 #else
00214 _pixelFormatAttribs.push_back(None);
00215 #endif
00216
00217 dbg_printf("RenderTexture::RenderTexture(%s) END instantiation. pf=%d pb=%d\n",
00218 strMode, (int)_pixelFormatAttribs.size(), (int)_pbufferAttribs.size() );
00219
00220 }
00221
00222
00223
00224
00225
00226
00231 RenderTexture::~RenderTexture()
00232 {
00233 dbg_printf("RenderTexture::~RenderTexture: destructor.\n" );
00234 _Invalidate();
00235 }
00236
00237
00238
00239
00240
00245 #ifdef __MACH__
00246 static void _cglCheckErrorHelper(CGLError err, char *sourceFile, int sourceLine)
00247 {
00248 # ifdef _DEBUG
00249 if (err)
00250 {
00251 fprintf(stderr, "RenderTexture CGL Error: %s at (%s,%d)",
00252 CGLErrorString(err), sourceFile, sourceLine);
00253 }
00254 # endif
00255 }
00256
00257 # define _cglCheckError(err) _cglCheckErrorHelper(err,__FILE__,__LINE__)
00258
00259 #endif
00260
00261
00262
00263
00264
00265
00270 #ifdef _WIN32
00271 void _wglGetLastError()
00272 {
00273 #ifdef _DEBUG
00274
00275 DWORD err = GetLastError();
00276 switch(err)
00277 {
00278 case ERROR_INVALID_PIXEL_FORMAT:
00279 SG_LOG(SG_GL, SG_ALERT,
00280 "RenderTexture Win32 Error: ERROR_INVALID_PIXEL_FORMAT");
00281 break;
00282 case ERROR_NO_SYSTEM_RESOURCES:
00283 SG_LOG(SG_GL, SG_ALERT,
00284 "RenderTexture Win32 Error: ERROR_NO_SYSTEM_RESOURCES");
00285 break;
00286 case ERROR_INVALID_DATA:
00287 SG_LOG(SG_GL, SG_ALERT,
00288 "RenderTexture Win32 Error: ERROR_INVALID_DATA");
00289 break;
00290 case ERROR_INVALID_WINDOW_HANDLE:
00291 SG_LOG(SG_GL, SG_ALERT,
00292 "RenderTexture Win32 Error: ERROR_INVALID_WINDOW_HANDLE");
00293 break;
00294 case ERROR_RESOURCE_TYPE_NOT_FOUND:
00295 SG_LOG(SG_GL, SG_ALERT,
00296 "RenderTexture Win32 Error: ERROR_RESOURCE_TYPE_NOT_FOUND");
00297 break;
00298 case ERROR_SUCCESS:
00299
00300 break;
00301 default:
00302 LPVOID lpMsgBuf;
00303 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
00304 FORMAT_MESSAGE_FROM_SYSTEM |
00305 FORMAT_MESSAGE_IGNORE_INSERTS,
00306 NULL,
00307 err,
00308 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00309 (LPTSTR) &lpMsgBuf,
00310 0,
00311 NULL);
00312
00313 SG_LOG(SG_GL, SG_ALERT, "RenderTexture Win32 Error " << err << ":" << lpMsgBuf);
00314 LocalFree( lpMsgBuf );
00315 break;
00316 }
00317 SetLastError(0);
00318
00319 #endif // _DEBUG
00320 }
00321 #endif
00322
00323
00324
00325
00326
00331 void PrintExtensionError( const char* strMsg, ... )
00332 {
00333 SG_LOG(SG_GL, SG_ALERT,
00334 "Error: RenderTexture requires the following unsupported "
00335 "OpenGL extensions: ");
00336 char strBuffer[512];
00337 va_list args;
00338 va_start(args, strMsg);
00339 vsnprintf( strBuffer, 512, strMsg, args );
00340 va_end(args);
00341
00342 SG_LOG(SG_GL, SG_ALERT, strMsg);
00343 dbg_printf("Error: RenderTexture requires the following unsupported OpenGL extensions: \n[%s]\n", strMsg);
00344 }
00345
00346
00347
00348
00349
00357 bool RenderTexture::Initialize(int width, int height,
00358 bool shareObjects ,
00359 bool copyContext )
00360 {
00361 assert(width > 0 && height > 0);
00362
00363 dbg_printf("RenderTexture::Initialize w=%d h=%d\n", width, height );
00364
00365 _iWidth = width; _iHeight = height;
00366 _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
00367
00368 _bShareObjects = shareObjects;
00369 _bCopyContext = copyContext;
00370
00371
00372 if (!_VerifyExtensions()) {
00373 dbg_printf("RenderTexture::Initialize: _VerifyExtensions() FAILED - returning false.\n" );
00374 return false;
00375 }
00376
00377 if (_bInitialized)
00378 _Invalidate();
00379
00380 #ifdef _WIN32
00381
00382 HDC hdc = wglGetCurrentDC();
00383 if (NULL == hdc)
00384 _wglGetLastError();
00385 HGLRC hglrc = wglGetCurrentContext();
00386 if (NULL == hglrc)
00387 _wglGetLastError();
00388
00389 int iFormat = 0;
00390 unsigned int iNumFormats;
00391
00392 if (_bCopyContext)
00393 {
00394
00395 iFormat = GetPixelFormat(hdc);
00396 if (iFormat == 0)
00397 {
00398 SG_LOG(SG_GL, SG_ALERT,
00399 "RenderTexture Error: GetPixelFormat() failed.");
00400 return false;
00401 }
00402 }
00403 else
00404 {
00405 if (!wglChoosePixelFormatARBPtr(hdc, &_pixelFormatAttribs[0], NULL,
00406 1, &iFormat, &iNumFormats))
00407 {
00408 SG_LOG(SG_GL, SG_ALERT,
00409 "RenderTexture Error: wglChoosePixelFormatARB() failed.");
00410 _wglGetLastError();
00411 return false;
00412 }
00413 if ( iNumFormats <= 0 )
00414 {
00415 SG_LOG(SG_GL, SG_ALERT,
00416 "RenderTexture Error: Couldn't find a suitable "
00417 "pixel format.");
00418 _wglGetLastError();
00419 return false;
00420 }
00421 }
00422
00423
00424 _hPBuffer = wglCreatePbufferARBPtr(hdc, iFormat, _iWidth, _iHeight,
00425 &_pbufferAttribs[0]);
00426 if (!_hPBuffer)
00427 {
00428 SG_LOG(SG_GL, SG_ALERT,
00429 "RenderTexture Error: wglCreatePbufferARB() failed.");
00430 _wglGetLastError();
00431 return false;
00432 }
00433
00434
00435 _hDC = wglGetPbufferDCARBPtr( _hPBuffer);
00436 if ( !_hDC )
00437 {
00438 SG_LOG(SG_GL, SG_ALERT,
00439 "RenderTexture Error: wglGetGetPbufferDCARB() failed.");
00440 _wglGetLastError();
00441 return false;
00442 }
00443
00444
00445 if (_bCopyContext)
00446 {
00447
00448
00449
00450 _hGLContext = hglrc;
00451 }
00452 else
00453 {
00454 _hGLContext = wglCreateContext( _hDC );
00455 if ( !_hGLContext )
00456 {
00457 SG_LOG(SG_GL, SG_ALERT,
00458 "RenderTexture Error: wglCreateContext() failed.");
00459 _wglGetLastError();
00460 return false;
00461 }
00462 }
00463
00464
00465 if( _bShareObjects )
00466 {
00467 if( !wglShareLists(hglrc, _hGLContext) )
00468 {
00469 SG_LOG(SG_GL, SG_ALERT,
00470 "RenderTexture Error: wglShareLists() failed.");
00471 _wglGetLastError();
00472 return false;
00473 }
00474 }
00475
00476
00477 wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
00478 wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
00479
00480 _bInitialized = true;
00481
00482
00483 int attrib = WGL_RED_BITS_ARB;
00484
00485 int value;
00486 _iNumColorBits[0] =
00487 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00488 ? value : 0;
00489 attrib = WGL_GREEN_BITS_ARB;
00490 _iNumColorBits[1] =
00491 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00492 ? value : 0;
00493 attrib = WGL_BLUE_BITS_ARB;
00494 _iNumColorBits[2] =
00495 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00496 ? value : 0;
00497 attrib = WGL_ALPHA_BITS_ARB;
00498 _iNumColorBits[3] =
00499 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00500 ? value : 0;
00501 attrib = WGL_DEPTH_BITS_ARB;
00502 _iNumDepthBits =
00503 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00504 ? value : 0;
00505 attrib = WGL_STENCIL_BITS_ARB;
00506 _iNumStencilBits =
00507 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00508 ? value : 0;
00509 attrib = WGL_DOUBLE_BUFFER_ARB;
00510 _bDoubleBuffered =
00511 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
00512 ? (value?true:false) : false;
00513
00514 #if defined(_DEBUG) | defined(DEBUG)
00515 SG_LOG(SG_GL, SG_ALERT, "Created a " << _iWidth << "x" << _iHeight <<
00516 " RenderTexture with BPP(" <<
00517 _iNumColorBits[0] << "," << _iNumColorBits[1] << "," <<
00518 _iNumColorBits[2] << "," << _iNumColorBits[3] << ")");
00519 if (_iNumDepthBits) SG_LOG(SG_GL, SG_ALERT, " depth=" << _iNumDepthBits);
00520 if (_iNumStencilBits) SG_LOG(SG_GL, SG_ALERT, " stencil=" << _iNumStencilBits);
00521 if (_bDoubleBuffered) SG_LOG(SG_GL, SG_ALERT, " double buffered");
00522 #endif
00523
00524 #elif defined( __MACH__ )
00525
00526 CGLContextObj hglrc = CGLGetCurrentContext();
00527 if (NULL == hglrc)
00528 fprintf(stderr, "Couldn't get current context!");
00529
00530 CGLPixelFormatObj pixFormat = NULL;
00531 GLint iNumFormats;
00532 CGLError error;
00533
00534
00535
00536 CGLPixelFormatAttribute *pixFormatAttribs =
00537 (CGLPixelFormatAttribute *)malloc(sizeof(CGLPixelFormatAttribute)
00538 * _pixelFormatAttribs.size());
00539
00540 for (unsigned int ii = 0; ii < _pixelFormatAttribs.size(); ii++)
00541 {
00542 pixFormatAttribs[ii] =
00543 (CGLPixelFormatAttribute)_pixelFormatAttribs[ii];
00544 }
00545
00546 if (error =
00547 CGLChoosePixelFormat(&pixFormatAttribs[0], &pixFormat, &iNumFormats))
00548 {
00549 fprintf(stderr,
00550 "RenderTexture Error: CGLChoosePixelFormat() failed.\n");
00551 _cglCheckError(error);
00552 return false;
00553 }
00554 if ( iNumFormats <= 0 )
00555 {
00556 SG_LOG(SG_GL, SG_ALERT,
00557 "RenderTexture Error: Couldn't find a suitable "
00558 "pixel format.");
00559 return false;
00560 }
00561
00562
00563 free(pixFormatAttribs);
00564
00565
00566 error = CGLCreateContext(pixFormat, (_bShareObjects)
00567 ? CGLGetCurrentContext() : NULL, &_hGLContext);
00568 if (error)
00569 {
00570 fprintf(stderr,
00571 "RenderTexture Error: CGLCreateContext() failed.\n");
00572 _cglCheckError(error);
00573 return false;
00574 }
00575 CGLDestroyPixelFormat(pixFormat);
00576
00577
00578 error = CGLCreatePBuffer(_iWidth, _iHeight, (_bRectangle)
00579 ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D, GL_RGBA, 0, &_hPBuffer);
00580 if (error)
00581 {
00582 fprintf(stderr,
00583 "RenderTexture Error: CGLCreatePBuffer() failed.\n");
00584 _cglCheckError(error);
00585 return false;
00586 }
00587
00588 GLint screen;
00589 if (error = CGLGetVirtualScreen(CGLGetCurrentContext(), &screen))
00590 {
00591 _cglCheckError(error);
00592 return false;
00593 }
00594 if (error = CGLSetPBuffer(_hGLContext, _hPBuffer, 0, 0, screen))
00595 {
00596 _cglCheckError(error);
00597 return false;
00598 }
00599
00600
00601
00602
00603
00604 _bInitialized = true;
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 #if defined(_DEBUG) | defined(DEBUG)
00641 fprintf(stderr, "Created a %dx%d RenderTexture with BPP(%d, %d, %d, %d)",
00642 _iWidth, _iHeight,
00643 _iNumColorBits[0], _iNumColorBits[1],
00644 _iNumColorBits[2], _iNumColorBits[3]);
00645 if (_iNumDepthBits) fprintf(stderr, " depth=%d", _iNumDepthBits);
00646 if (_iNumStencilBits) fprintf(stderr, " stencil=%d", _iNumStencilBits);
00647 if (_bDoubleBuffered) fprintf(stderr, " double buffered");
00648 fprintf(stderr, "\n");
00649 #endif
00650
00651 #else // !_WIN32, !__MACH_
00652
00653 _pDisplay = glXGetCurrentDisplay();
00654 if ( !_pDisplay ) {
00655 dbg_printf("RenderTexture::Initialize: ERROR: glXGetCurrentDisplay() returned NULL! return false\n");
00656 return false;
00657 }
00658 dbg_printf("RenderTexture::Initialize: got glXGetCurrentDisplay() _pDisplay=[%p]\n", _pDisplay);
00659
00660
00661 GLXContext context = glXGetCurrentContext();
00662 if ( !context ) {
00663 dbg_printf("RenderTexture::Initialize: ERROR: glXGetCurrentContext() returned NULL! return false\n");
00664 return false;
00665 }
00666 dbg_printf("RenderTexture::Initialize: got glXGetCurrentContext() context=[%p]\n", context);
00667 int screen = DefaultScreen(_pDisplay);
00668 dbg_printf("RenderTexture::Initialize: DefaultScreen(_pDisplay) screen=%d\n", screen);
00669
00670 XVisualInfo *visInfo = NULL;
00671
00672 GLXFBConfig *fbConfigs;
00673 int nConfigs;
00674 #ifdef _DEBUG
00675 dbg_printf("Using %d pixelFormatAttribs array\n", (int)_pixelFormatAttribs.size());
00676 size_t max = _pixelFormatAttribs.size() / 2;
00677 int dat = 0;
00678 size_t n;
00679 for (n = 0; n < max; n++) {
00680 const char * cp = get_attr_name(_pixelFormatAttribs[n*2], &dat);
00681 printf( "%s(%d) = %d (def=%d)\n",
00682 cp, _pixelFormatAttribs[n*2], _pixelFormatAttribs[(n*2)+1], dat );
00683 }
00684 n *= 2;
00685 if ( n < _pixelFormatAttribs.size() )
00686 printf( "Array ends with %d\n", _pixelFormatAttribs[n] );
00687 else
00688 printf( "WARNING: Array does not appear ODD! which is ODD\n" );
00689
00690 #endif
00691 fbConfigs = glXChooseFBConfigPtr(_pDisplay, screen,
00692 &_pixelFormatAttribs[0], &nConfigs);
00693
00694
00695
00696 if (nConfigs <= 0 || !fbConfigs)
00697 {
00698 SG_LOG(SG_GL, SG_ALERT,
00699 "RenderTexture Error: Couldn't find a suitable pixel format.");
00700 dbg_printf("RenderTexture Error: Couldn't find a suitable pixel format. return false\n");
00701 return false;
00702 }
00703
00704 dbg_printf("RenderTexture::Initialize: glXChooseFBConfigPtr() nConfigs = %d, fbConfigs=[%p]\n", nConfigs, fbConfigs);
00705
00706 int pbufAttrib[] = {
00707 GLX_PBUFFER_WIDTH, _iWidth,
00708 GLX_PBUFFER_HEIGHT, _iHeight,
00709 GLX_LARGEST_PBUFFER, False,
00710 None
00711 };
00712
00713
00714 if (glXCreatePbufferPtr && glXGetVisualFromFBConfigPtr && glXCreateContextPtr)
00715 {
00716 dbg_printf("RenderTexture::Initialize: glXVersion1_3Present = TRUE\n");
00717 for (int i=0;i<nConfigs;i++)
00718 {
00719 _hPBuffer = glXCreatePbufferPtr(_pDisplay, fbConfigs[i], pbufAttrib);
00720 if (_hPBuffer)
00721 {
00722 XVisualInfo *visInfo = glXGetVisualFromFBConfigPtr(_pDisplay, fbConfigs[i]);
00723
00724 _hGLContext = glXCreateContextPtr(_pDisplay, visInfo,
00725 _bShareObjects ? context : NULL,
00726 True);
00727 if (!_hGLContext)
00728 {
00729 dbg_printf("RenderTexture Error: glXCreateContextPtr(_pDisplay, visInfo,..) FAILED! return false\n");
00730 return false;
00731 }
00732 XFree( visInfo );
00733 break;
00734 }
00735 }
00736 }
00737 else
00738 {
00739 #ifdef WIN32
00740 int iFormat = 0;
00741 int iNumFormats;
00742 int attrib = 0;
00743 #endif
00744 dbg_printf("RenderTexture::Initialize: glXVersion1_3Present = FALSE w=%d h=%d\n", _iWidth, _iHeight);
00745 for (int i=0; i < nConfigs; i++)
00746 {
00747 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() get buffer ptr\n", (i + 1));
00748 _hPBuffer = glXCreateGLXPbufferPtr(_pDisplay, fbConfigs[i],
00749 _iWidth, _iHeight,
00750 &pbufAttrib[0] );
00751 if (_hPBuffer)
00752 {
00753 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() got buffer [%p]\n", (i + 1), (void*)_hPBuffer);
00754 _hGLContext = glXCreateContextWithConfigPtr(_pDisplay,
00755 fbConfigs[i],
00756 GLX_RGBA_TYPE,
00757 _bShareObjects ? context : NULL,
00758 True);
00759 dbg_printf("RenderTexture::Initialize: %d: glXCreateContextWithConfigPtr() _hGLContext=[%p]\n", (i + 1), _hGLContext);
00760 break;
00761 } else {
00762 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() NO buffer\n", (i + 1));
00763 }
00764 }
00765 }
00766
00767 dbg_printf("RenderTexture::Initialize: doing XFree( fbConfigs=[%p].\n", fbConfigs);
00768 XFree( fbConfigs );
00769
00770 if (!_hPBuffer)
00771 {
00772 SG_LOG(SG_GL, SG_ALERT,
00773 "RenderTexture Error: glXCreateGLXPbufferPtr() failed.");
00774 dbg_printf("RenderTexture Error: glXCreateGLXPbufferPtr() failed.\n");
00775 return false;
00776 }
00777
00778 if(!_hGLContext)
00779 {
00780
00781 _hGLContext = glXCreateContext(_pDisplay, visInfo,
00782 _bShareObjects ? context : NULL, False);
00783 if ( !_hGLContext )
00784 {
00785 SG_LOG(SG_GL, SG_ALERT,
00786 "RenderTexture Error: glXCreateContext() failed.");
00787 dbg_printf("RenderTexture Error: glXCreateContext() failed. return false\n");
00788 return false;
00789 }
00790 }
00791
00792
00793 if ((!glXCreatePbufferPtr || !glXGetVisualFromFBConfigPtr || !glXCreateContextPtr) &&
00794 (!glXVersion1_3Present))
00795 {
00796 #ifdef ADD_QUERY_BUFFER
00797 dbg_printf("RenderTexture::Initialize: Doing glXQueryGLXPbufferSGIXPtr with GLX_WIDTH_SGIX\n");
00798 glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_WIDTH_SGIX,
00799 (GLuint*)&_iWidth);
00800 dbg_printf("RenderTexture::Initialize: Doing glXQueryGLXPbufferSGIXPtr with GLX_HEIGHT_SGIX\n");
00801 glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_HEIGHT_SGIX,
00802 (GLuint*)&_iHeight);
00803 #else
00804 dbg_printf("RenderTexture::Initialize: SKIPPED doing glXQueryGLXPbufferSGIXPtr with GLX_WIDTH_SGIX and GLX_HEIGHT_SGIX\n");
00805 #endif // #ifdef ADD_QUERY_BUFFER
00806 }
00807
00808 _bInitialized = true;
00809 dbg_printf( "RenderTexture::Initialize: _bIniialized set TRUE\n" );
00810
00811
00812 #endif
00813
00814
00815
00816
00817
00818
00819 #ifdef _WIN32
00820 if (false == wglMakeCurrent( _hDC, _hGLContext))
00821 {
00822 _wglGetLastError();
00823 return false;
00824 }
00825 #elif defined( __MACH__ )
00826 CGLError err;
00827 if (err = CGLSetCurrentContext(_hGLContext))
00828 {
00829 _cglCheckError(err);
00830 return false;
00831 }
00832 #else
00833
00834 #ifdef ADD_GET_DRAWABLE
00835 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentContext()\n" );
00836 _hPreviousContext = glXGetCurrentContext();
00837 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentDrawable()\n" );
00838 _hPreviousDrawable = glXGetCurrentDrawable();
00839 #else
00840 _hPreviousContext = context;
00841 _hPreviousDrawable = 0;
00842 dbg_printf( "RenderTexture::Initialize: SKIPPED doing glXGetCurrentContext(2nd) AND glXGetCurrentDrawable()\n" );
00843 #endif // #ifdef ADD_GET_DRAWABLE
00844
00845 dbg_printf( "RenderTexture::Initialize: doing glXMakeCurrent(_pDisplay(%p), _hPBuffer(%p), _hGLContext(%p))\n",
00846 _pDisplay, (void*)_hPBuffer, _hGLContext );
00847 if (False == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
00848 {
00849 dbg_printf( "glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext) FAILED. return false\n" );
00850 return false;
00851 }
00852
00853 #endif
00854
00855 bool result = _InitializeTextures();
00856 #ifdef _WIN32
00857 BindBuffer(WGL_FRONT_LEFT_ARB);
00858 _BindDepthBuffer();
00859 #endif
00860
00861
00862 #ifdef _WIN32
00863
00864 if (false == wglMakeCurrent( hdc, hglrc))
00865 {
00866 _wglGetLastError();
00867 return false;
00868 }
00869 #elif defined( __MACH__ )
00870 if (err = CGLSetCurrentContext(_hPreviousContext))
00871 {
00872 _cglCheckError(err);
00873 return false;
00874 }
00875 #else
00876 if (False == glXMakeCurrent(_pDisplay,
00877 _hPreviousDrawable, _hPreviousContext))
00878 {
00879 dbg_printf("glXMakeCurrent(_pDisplay, _hPreviousDrawable, _hPreviousContext)) FAILED! return false\n" );
00880 return false;
00881 }
00882
00883 if (glXVersion1_3Present)
00884
00885
00886 {
00887 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentDrawable()\n" );
00888 GLXDrawable draw = glXGetCurrentDrawable();
00889 dbg_printf( "RenderTexture::Initialize: doing glXQueryDrawablePtr for GLX_WIDTH and GLX_HEIGHT\n" );
00890 glXQueryDrawablePtr(_pDisplay, draw, GLX_WIDTH, (unsigned int*)&_iWidth);
00891 glXQueryDrawablePtr(_pDisplay, draw, GLX_HEIGHT, (unsigned int*)&_iHeight);
00892 }
00893 #endif
00894
00895 dbg_printf( "RenderTexture::Initialize(w=%d,h=%d): returning %s\n", _iWidth, _iHeight, (result ? "TRUE" : "FALSE") );
00896 return result;
00897 }
00898
00899
00900
00901
00902
00903
00909 bool RenderTexture::_Invalidate()
00910 {
00911 dbg_printf( "RenderTexture::_Invalidate() called...\n" );
00912
00913 _iNumColorBits[0] = _iNumColorBits[1] =
00914 _iNumColorBits[2] = _iNumColorBits[3] = 0;
00915 _iNumDepthBits = 0;
00916 _iNumStencilBits = 0;
00917
00918 if (_bIsTexture)
00919 glDeleteTextures(1, &_iTextureID);
00920 if (_bIsDepthTexture)
00921 {
00922
00923 if (!_bHasARBDepthTexture) delete[] _pPoorDepthTexture;
00924
00925 glDeleteTextures(1, &_iDepthTextureID);
00926 }
00927
00928 #ifdef _WIN32
00929 if ( _hPBuffer )
00930 {
00931
00932 if (wglGetCurrentContext() == _hGLContext)
00933 wglMakeCurrent(0,0);
00934 if (!_bCopyContext)
00935 wglDeleteContext( _hGLContext);
00936 wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
00937 wglDestroyPbufferARBPtr( _hPBuffer );
00938 _hPBuffer = 0;
00939 return true;
00940 }
00941 #elif defined( __MACH__ )
00942 if ( _hPBuffer )
00943 {
00944 if (CGLGetCurrentContext() == _hGLContext)
00945 CGLSetCurrentContext(NULL);
00946 if (!_bCopyContext)
00947 CGLDestroyContext(_hGLContext);
00948 CGLDestroyPBuffer(_hPBuffer);
00949 _hPBuffer = NULL;
00950 return true;
00951 }
00952 #else
00953 if ( _hPBuffer )
00954 {
00955 if(glXGetCurrentContext() == _hGLContext)
00956
00957 glXMakeCurrent(_pDisplay, _hPBuffer, 0);
00958 glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
00959 _hPBuffer = 0;
00960 dbg_printf( "RenderTexture::_Invalidate: glXDestroyPbufferPtr(_pDisplay, _hPBuffer); return true\n" );
00961 return true;
00962 }
00963 #endif
00964
00965 dbg_printf( "RenderTexture::_Invalidate: return false\n" );
00966
00967 return false;
00968 }
00969
00970
00971
00972
00973
00974
00982 bool RenderTexture::Reset(const char *strMode, ...)
00983 {
00984 dbg_printf("RenderTexure:Reset(): with %s\n", strMode);
00985
00986 _iWidth = 0; _iHeight = 0;
00987 _bIsTexture = false; _bIsDepthTexture = false,
00988 _bHasARBDepthTexture = true;
00989 #if defined(_WIN32) || defined(__MACH__)
00990 _eUpdateMode = RT_RENDER_TO_TEXTURE;
00991 #else
00992 _eUpdateMode = RT_COPY_TO_TEXTURE;
00993 #endif
00994 _bInitialized = false;
00995 _iNumAuxBuffers = 0;
00996 _bIsBufferBound = false;
00997 _iCurrentBoundBuffer = 0;
00998 _iNumDepthBits = 0; _iNumStencilBits = 0;
00999 _bDoubleBuffered = false;
01000 _bFloat = false; _bPowerOf2 = true;
01001 _bRectangle = false; _bMipmap = false;
01002 _bShareObjects = false; _bCopyContext = false;
01003 _iTextureTarget = GL_NONE; _iTextureID = 0;
01004 _iDepthTextureID = 0;
01005 _pPoorDepthTexture = 0;
01006 _pixelFormatAttribs.clear();
01007 _pbufferAttribs.clear();
01008 if (IsInitialized())
01009 {
01010 if (!_Invalidate())
01011 {
01012 dbg_printf( "RenderTexture::Reset(): failed to invalidate. return false\n");
01013 return false;
01014 }
01015 else
01016 {
01017 dbg_printf( "RenderTexture::Reset(): was Initialized, and now _Invalidate() ok.");
01018 }
01019 }
01020 else
01021 {
01022 dbg_printf("RenderTexure:Reset(): previous NOT initialised!\n");
01023 }
01024
01025 _iNumColorBits[0] = _iNumColorBits[1] =
01026 _iNumColorBits[2] = _iNumColorBits[3] = 0;
01027
01028 #ifdef _WIN32
01029 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
01030 _pixelFormatAttribs.push_back(true);
01031 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
01032 _pixelFormatAttribs.push_back(true);
01033
01034 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
01035 _pbufferAttribs.push_back(true);
01036 #elif defined( __MACH__ )
01037
01038 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
01039 _pixelFormatAttribs.push_back(kCGLPFAWindow);
01040 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
01041 #else
01042 _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
01043 _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
01044 _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
01045 _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
01046 #endif
01047
01048 va_list args;
01049 char strBuffer[256];
01050 va_start(args,strMode);
01051 vsnprintf( strBuffer, 256, strMode, args );
01052 va_end(args);
01053
01054 _ParseModeString(strBuffer, _pixelFormatAttribs, _pbufferAttribs);
01055
01056 #ifdef _WIN32
01057 _pixelFormatAttribs.push_back(0);
01058 _pbufferAttribs.push_back(0);
01059 #elif defined(__MACH__)
01060 _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
01061 #else
01062 _pixelFormatAttribs.push_back(None);
01063 #endif
01064 dbg_printf("RenderTexure:Reset(): returning true.\n");
01065 return true;
01066 }
01067
01068
01069
01070
01071
01081 bool RenderTexture::Resize(int iWidth, int iHeight)
01082 {
01083 if (!_bInitialized) {
01084 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Resize(): must Initialize() first.");
01085 return false;
01086 }
01087 if (iWidth == _iWidth && iHeight == _iHeight) {
01088 return true;
01089 }
01090
01091
01092 if (_bIsTexture)
01093 glDeleteTextures(1, &_iTextureID);
01094 if (_bIsDepthTexture)
01095 glDeleteTextures(1, &_iDepthTextureID);
01096 #ifdef _WIN32
01097 if ( _hPBuffer )
01098 {
01099
01100 if (wglGetCurrentContext() == _hGLContext)
01101 wglMakeCurrent(0,0);
01102 if (!_bCopyContext)
01103 wglDeleteContext( _hGLContext);
01104 wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
01105 wglDestroyPbufferARBPtr( _hPBuffer );
01106 _hPBuffer = 0;
01107 return true;
01108 }
01109 #elif defined( __MACH__ )
01110 if ( _hPBuffer )
01111 {
01112 if (CGLGetCurrentContext() == _hGLContext)
01113 CGLSetCurrentContext(NULL);
01114 if (!_bCopyContext)
01115 CGLDestroyContext(_hGLContext);
01116 CGLDestroyPBuffer(_hPBuffer);
01117 _hPBuffer = NULL;
01118 return true;
01119 }
01120 #else
01121 if ( _hPBuffer )
01122 {
01123 if(glXGetCurrentContext() == _hGLContext)
01124
01125 glXMakeCurrent(_pDisplay, _hPBuffer, 0);
01126 glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
01127 _hPBuffer = 0;
01128 }
01129 #endif
01130 else {
01131 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Resize(): failed to resize.");
01132 return false;
01133 }
01134 _bInitialized = false;
01135 return Initialize(iWidth, iHeight, _bShareObjects, _bCopyContext);
01136 }
01137
01138
01139
01140
01141
01146 bool RenderTexture::BeginCapture()
01147 {
01148 if (!_bInitialized)
01149 {
01150 SG_LOG(SG_GL, SG_ALERT,
01151 "RenderTexture::BeginCapture(): Texture is not initialized!");
01152 return false;
01153 }
01154 #ifdef _WIN32
01155
01156 _hPreviousDC = wglGetCurrentDC();
01157 if (NULL == _hPreviousDC)
01158 _wglGetLastError();
01159 _hPreviousContext = wglGetCurrentContext();
01160 if (NULL == _hPreviousContext)
01161 _wglGetLastError();
01162 #elif defined( __MACH__ )
01163 _hPreviousContext = CGLGetCurrentContext();
01164 #else
01165 _hPreviousContext = glXGetCurrentContext();
01166 _hPreviousDrawable = glXGetCurrentDrawable();
01167 #endif
01168
01169 _ReleaseBoundBuffers();
01170
01171 return _MakeCurrent();
01172 }
01173
01174
01175
01176
01177
01178
01183 bool RenderTexture::EndCapture()
01184 {
01185 if (!_bInitialized)
01186 {
01187 SG_LOG(SG_GL, SG_ALERT,
01188 "RenderTexture::EndCapture() : Texture is not initialized!");
01189 return false;
01190 }
01191
01192 glFlush();
01193
01194 _MaybeCopyBuffer();
01195
01196 #ifdef _WIN32
01197
01198 if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
01199 {
01200 _wglGetLastError();
01201 return false;
01202 }
01203 #elif defined( __MACH__ )
01204 CGLError err;
01205 if (err = CGLSetCurrentContext(_hPreviousContext))
01206 {
01207 _cglCheckError(err);
01208 return false;
01209 }
01210 #else
01211 if (False == glXMakeCurrent(_pDisplay, _hPreviousDrawable,
01212 _hPreviousContext))
01213 {
01214 return false;
01215 }
01216 #endif
01217
01218
01219 BindBuffer(_iCurrentBoundBuffer);
01220 _BindDepthBuffer();
01221
01222 return true;
01223 }
01224
01225
01226
01227
01228
01243 bool RenderTexture::BeginCapture(RenderTexture* current)
01244 {
01245
01246
01247 if (current == this) {
01248 return true;
01249 }
01250 if (!current) {
01251
01252 return BeginCapture();
01253 }
01254 if (!_bInitialized)
01255 {
01256 SG_LOG(SG_GL, SG_ALERT,
01257 "RenderTexture::BeginCapture(RenderTexture*): Texture is not initialized!");
01258 return false;
01259 }
01260 if (!current->_bInitialized)
01261 {
01262 SG_LOG(SG_GL, SG_ALERT,
01263 "RenderTexture::BeginCapture(RenderTexture): 'current' texture is not initialized!");
01264 return false;
01265 }
01266
01267
01268 current->_MaybeCopyBuffer();
01269
01270
01271
01272 #ifdef _WIN32
01273 _hPreviousDC = current->_hPreviousDC;
01274 if (NULL == _hPreviousDC)
01275 _wglGetLastError();
01276 _hPreviousContext = current->_hPreviousContext;
01277 if (NULL == _hPreviousContext)
01278 _wglGetLastError();
01279 #elif defined( __MACH__ )
01280 _hPreviousContext = current->_hPreviousContext;
01281 #else
01282 _hPreviousContext = current->_hPreviousContext;
01283 _hPreviousDrawable = current->_hPreviousDrawable;
01284 #endif
01285
01286
01287 if (!_ReleaseBoundBuffers())
01288 return false;
01289
01290
01291 if (!_MakeCurrent())
01292 return false;
01293
01294
01295 current->BindBuffer(_iCurrentBoundBuffer);
01296 current->_BindDepthBuffer();
01297
01298 return true;
01299 }
01300
01301
01302
01303
01304
01305
01306
01311 void RenderTexture::Bind() const
01312 {
01313 if (_bInitialized && _bIsTexture)
01314 {
01315 glBindTexture(_iTextureTarget, _iTextureID);
01316 }
01317 }
01318
01319
01320
01321
01322
01323
01328 void RenderTexture::BindDepth() const
01329 {
01330 if (_bInitialized && _bIsDepthTexture)
01331 {
01332 glBindTexture(_iTextureTarget, _iDepthTextureID);
01333 }
01334 }
01335
01336
01337
01338
01339
01340
01345 bool RenderTexture::BindBuffer( int iBuffer )
01346 {
01347
01348 if (_bInitialized && _bIsTexture)
01349 {
01350 glBindTexture(_iTextureTarget, _iTextureID);
01351
01352 #ifdef _WIN32
01353 if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
01354 (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
01355 {
01356 if (FALSE == wglBindTexImageARBPtr(_hPBuffer, iBuffer))
01357 {
01358
01359
01360
01361
01362 SetLastError(0);
01363 }
01364 _bIsBufferBound = true;
01365 _iCurrentBoundBuffer = iBuffer;
01366 }
01367 #elif defined(__MACH__)
01368 if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
01369 (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
01370 {
01371 CGLError err;
01372 if (err=CGLTexImagePBuffer(CGLGetCurrentContext(), _hPBuffer, iBuffer))
01373 {
01374 _cglCheckError(err);
01375 }
01376 _bIsBufferBound = true;
01377 _iCurrentBoundBuffer = iBuffer;
01378 }
01379 #endif
01380 }
01381 return true;
01382 }
01383
01384
01385
01386
01387
01388
01393 bool RenderTexture::_BindDepthBuffer() const
01394 {
01395 #ifdef WIN32
01396 if (_bInitialized && _bIsDepthTexture &&
01397 RT_RENDER_TO_TEXTURE == _eUpdateMode)
01398 {
01399 glBindTexture(_iTextureTarget, _iDepthTextureID);
01400 if (FALSE == wglBindTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
01401 {
01402 _wglGetLastError();
01403 return false;
01404 }
01405 }
01406 #elif defined(__MACH__)
01407 if (_bInitialized && _bIsDepthTexture &&
01408 RT_RENDER_TO_TEXTURE == _eUpdateMode)
01409 {
01410 glBindTexture(_iTextureTarget, _iDepthTextureID);
01411
01412
01413
01414
01415
01416 }
01417 #endif
01418 return true;
01419 }
01420
01421
01422
01423
01424
01429 void RenderTexture::_ParseModeString(const char *modeString,
01430 vector<int> &pfAttribs,
01431 vector<int> &pbAttribs)
01432 {
01433 dbg_printf("RenderTexture::_ParseModeString(%s). BGN vf=%d vp=%d\n", modeString, (int)pfAttribs.size(), (int)pbAttribs.size() );
01434 if (!modeString || strcmp(modeString, "") == 0)
01435 return;
01436
01437 _iNumComponents = 0;
01438 #if defined(_WIN32) || defined(__MACH__)
01439 _eUpdateMode = RT_RENDER_TO_TEXTURE;
01440 #else
01441 _eUpdateMode = RT_COPY_TO_TEXTURE;
01442 #endif
01443
01444 int iDepthBits = 0;
01445 bool bHasStencil = false;
01446 bool bBind2D = false;
01447 bool bBindRECT = false;
01448 bool bBindCUBE = false;
01449
01450 char *mode = strdup(modeString);
01451
01452
01453 vector<string> tokens;
01454 char *buf = strtok(mode, " ");
01455 while (buf != NULL)
01456 {
01457 tokens.push_back(buf);
01458 buf = strtok(NULL, " ");
01459 }
01460 free(mode);
01461 for (unsigned int i = 0; i < tokens.size(); i++)
01462 {
01463 string token = tokens[i];
01464
01465 KeyVal kv = _GetKeyValuePair(token);
01466
01467
01468 if (kv.first == "rgb" && (_iNumComponents <= 1))
01469 {
01470 if (kv.second.find("f") != kv.second.npos)
01471 _bFloat = true;
01472
01473 vector<int> bitVec = _ParseBitVector(kv.second);
01474
01475 if (bitVec.size() < 3)
01476 {
01477 bitVec.push_back(bitVec[0]);
01478 bitVec.push_back(bitVec[0]);
01479 }
01480
01481 #ifdef _WIN32
01482 pfAttribs.push_back(WGL_RED_BITS_ARB);
01483 pfAttribs.push_back(bitVec[0]);
01484 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
01485 pfAttribs.push_back(bitVec[1]);
01486 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
01487 pfAttribs.push_back(bitVec[2]);
01488 #elif defined( __MACH__ )
01489 # if 0
01490 pfAttribs.push_back(AGL_RED_SIZE);
01491 pfAttribs.push_back(bitVec[0]);
01492 pfAttribs.push_back(AGL_GREEN_SIZE);
01493 pfAttribs.push_back(bitVec[1]);
01494 pfAttribs.push_back(AGL_BLUE_SIZE);
01495 pfAttribs.push_back(bitVec[2]);
01496 # else
01497 pfAttribs.push_back(kCGLPFAColorSize);
01498 pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2]);
01499 # endif
01500 #else
01501 pfAttribs.push_back(GLX_RED_SIZE);
01502 pfAttribs.push_back(bitVec[0]);
01503 pfAttribs.push_back(GLX_GREEN_SIZE);
01504 pfAttribs.push_back(bitVec[1]);
01505 pfAttribs.push_back(GLX_BLUE_SIZE);
01506 pfAttribs.push_back(bitVec[2]);
01507 #endif
01508 _iNumComponents += 3;
01509 continue;
01510 }
01511 else if (kv.first == "rgb")
01512 {
01513 SG_LOG(SG_GL, SG_ALERT,
01514 "RenderTexture Warning: mistake in components definition "
01515 "(rgb + " << _iNumComponents << ").");
01516 dbg_printf("RenderTexture Warning 1: mistake in components definition "
01517 "(rgb + %d).\n", _iNumComponents );
01518 }
01519
01520 if (kv.first == "rgba" && (_iNumComponents == 0))
01521 {
01522 if (kv.second.find("f") != kv.second.npos)
01523 _bFloat = true;
01524
01525 vector<int> bitVec = _ParseBitVector(kv.second);
01526
01527 if (bitVec.size() < 4)
01528 {
01529 bitVec.push_back(bitVec[0]);
01530 bitVec.push_back(bitVec[0]);
01531 bitVec.push_back(bitVec[0]);
01532 }
01533
01534 #ifdef _WIN32
01535 pfAttribs.push_back(WGL_RED_BITS_ARB);
01536 pfAttribs.push_back(bitVec[0]);
01537 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
01538 pfAttribs.push_back(bitVec[1]);
01539 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
01540 pfAttribs.push_back(bitVec[2]);
01541 pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
01542 pfAttribs.push_back(bitVec[3]);
01543 #elif defined( __MACH__ )
01544 # if 0
01545 pfAttribs.push_back(AGL_RED_SIZE);
01546 pfAttribs.push_back(bitVec[0]);
01547 pfAttribs.push_back(AGL_GREEN_SIZE);
01548 pfAttribs.push_back(bitVec[1]);
01549 pfAttribs.push_back(AGL_BLUE_SIZE);
01550 pfAttribs.push_back(bitVec[2]);
01551 pfAttribs.push_back(AGL_ALPHA_SIZE);
01552 pfAttribs.push_back(bitVec[3]);
01553 # else
01554 pfAttribs.push_back(kCGLPFAColorSize);
01555 pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2] + bitVec[3]);
01556
01557
01558
01559
01560 # endif
01561 #else
01562 pfAttribs.push_back(GLX_RED_SIZE);
01563 pfAttribs.push_back(bitVec[0]);
01564 pfAttribs.push_back(GLX_GREEN_SIZE);
01565 pfAttribs.push_back(bitVec[1]);
01566 pfAttribs.push_back(GLX_BLUE_SIZE);
01567 pfAttribs.push_back(bitVec[2]);
01568 pfAttribs.push_back(GLX_ALPHA_SIZE);
01569 pfAttribs.push_back(bitVec[3]);
01570 #endif
01571 _iNumComponents = 4;
01572 continue;
01573 }
01574 else if (kv.first == "rgba")
01575 {
01576 SG_LOG(SG_GL, SG_ALERT,
01577 "RenderTexture Warning: mistake in components definition "
01578 "(rgba + " << _iNumComponents << ").");
01579 dbg_printf("RenderTexture Warning 2: mistake in components definition "
01580 "(rgb + %d).\n", _iNumComponents );
01581 }
01582
01583 if (kv.first == "r" && (_iNumComponents <= 1))
01584 {
01585 if (kv.second.find("f") != kv.second.npos)
01586 _bFloat = true;
01587
01588 vector<int> bitVec = _ParseBitVector(kv.second);
01589
01590 #ifdef _WIN32
01591 pfAttribs.push_back(WGL_RED_BITS_ARB);
01592 pfAttribs.push_back(bitVec[0]);
01593 #elif defined( __MACH__ )
01594 # if 0
01595 pfAttribs.push_back(AGL_RED_SIZE);
01596 pfAttribs.push_back(bitVec[0]);
01597 # else
01598 pfAttribs.push_back(kCGLPFAColorSize);
01599 pfAttribs.push_back(bitVec[0]);
01600 # endif
01601 #else
01602 pfAttribs.push_back(GLX_RED_SIZE);
01603 pfAttribs.push_back(bitVec[0]);
01604 #endif
01605 _iNumComponents++;
01606 continue;
01607 }
01608 else if (kv.first == "r")
01609 {
01610 SG_LOG(SG_GL, SG_ALERT,
01611 "RenderTexture Warning: mistake in components definition "
01612 "(r + " << _iNumComponents << ").");
01613 dbg_printf("RenderTexture Warning 3: mistake in components definition "
01614 "(rgb + %d).\n", _iNumComponents );
01615 }
01616 if (kv.first == "rg" && (_iNumComponents <= 1))
01617 {
01618 if (kv.second.find("f") != kv.second.npos)
01619 _bFloat = true;
01620
01621 vector<int> bitVec = _ParseBitVector(kv.second);
01622
01623 if (bitVec.size() < 2)
01624 {
01625 bitVec.push_back(bitVec[0]);
01626 }
01627
01628 #ifdef _WIN32
01629 pfAttribs.push_back(WGL_RED_BITS_ARB);
01630 pfAttribs.push_back(bitVec[0]);
01631 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
01632 pfAttribs.push_back(bitVec[1]);
01633 #elif defined( __MACH__ )
01634 # if 0
01635 pfAttribs.push_back(AGL_RED_SIZE);
01636 pfAttribs.push_back(bitVec[0]);
01637 pfAttribs.push_back(AGL_GREEN_SIZE);
01638 pfAttribs.push_back(bitVec[1]);
01639 # else
01640 pfAttribs.push_back(kCGLPFAColorSize);
01641 pfAttribs.push_back(bitVec[0] + bitVec[1]);
01642 # endif
01643 #else
01644 pfAttribs.push_back(GLX_RED_SIZE);
01645 pfAttribs.push_back(bitVec[0]);
01646 pfAttribs.push_back(GLX_GREEN_SIZE);
01647 pfAttribs.push_back(bitVec[1]);
01648 #endif
01649 _iNumComponents += 2;
01650 continue;
01651 }
01652 else if (kv.first == "rg")
01653 {
01654 SG_LOG(SG_GL, SG_ALERT,
01655 "RenderTexture Warning: mistake in components definition "
01656 "(rg + " << _iNumComponents << ").");
01657 dbg_printf("RenderTexture Warning 4: mistake in components definition "
01658 "(rgb + %d).\n", _iNumComponents );
01659 }
01660
01661 if (kv.first == "depth")
01662 {
01663 if (kv.second == "")
01664 iDepthBits = 24;
01665 else
01666 iDepthBits = strtol(kv.second.c_str(), 0, 10);
01667 continue;
01668 }
01669
01670 if (kv.first == "stencil")
01671 {
01672 bHasStencil = true;
01673 #ifdef _WIN32
01674 pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
01675 #elif defined( __MACH__ )
01676 # if 0
01677 pfAttribs.push_back(AGL_STENCIL_SIZE);
01678 # else
01679 pfAttribs.push_back(kCGLPFAStencilSize);
01680 # endif
01681 #else
01682 pfAttribs.push_back(GLX_STENCIL_SIZE);
01683 #endif
01684 if (kv.second == "")
01685 pfAttribs.push_back(8);
01686 else
01687 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
01688 continue;
01689 }
01690
01691 if (kv.first == "samples")
01692 {
01693 #ifdef _WIN32
01694 pfAttribs.push_back(WGL_SAMPLE_BUFFERS_ARB);
01695 pfAttribs.push_back(1);
01696 pfAttribs.push_back(WGL_SAMPLES_ARB);
01697 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
01698 #elif defined( __MACH__ )
01699 # if 0
01700 pfAttribs.push_back(AGL_SAMPLE_BUFFERS_ARB);
01701 pfAttribs.push_back(1);
01702 pfAttribs.push_back(AGL_SAMPLES_ARB);
01703 # else
01704 pfAttribs.push_back(kCGLPFAMultisample);
01705 pfAttribs.push_back(kCGLPFASamples);
01706 # endif
01707 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
01708 #else
01709 pfAttribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
01710 pfAttribs.push_back(1);
01711 pfAttribs.push_back(GLX_SAMPLES_ARB);
01712 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
01713 #endif
01714 continue;
01715
01716 }
01717
01718 if (kv.first == "doublebuffer" || kv.first == "double")
01719 {
01720 #ifdef _WIN32
01721 pfAttribs.push_back(WGL_DOUBLE_BUFFER_ARB);
01722 pfAttribs.push_back(true);
01723 #elif defined( __MACH__ )
01724 # if 0
01725 pfAttribs.push_back(AGL_DOUBLEBUFFER);
01726 pfAttribs.push_back(True);
01727 # else
01728 pfAttribs.push_back(kCGLPFADoubleBuffer);
01729 # endif
01730 #else
01731 pfAttribs.push_back(GLX_DOUBLEBUFFER);
01732 pfAttribs.push_back(True);
01733 #endif
01734 continue;
01735 }
01736
01737 if (kv.first == "aux")
01738 {
01739 #ifdef _WIN32
01740 pfAttribs.push_back(WGL_AUX_BUFFERS_ARB);
01741 #elif defined( __MACH__ )
01742 # if 0
01743 pfAttribs.push_back(AGL_AUX_BUFFERS);
01744 # else
01745 pfAttribs.push_back(kCGLPFAAuxBuffers);
01746 # endif
01747 #else
01748 pfAttribs.push_back(GLX_AUX_BUFFERS);
01749 #endif
01750 if (kv.second == "")
01751 pfAttribs.push_back(0);
01752 else
01753 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
01754 continue;
01755 }
01756
01757 if (token.find("tex") == 0)
01758 {
01759 _bIsTexture = true;
01760
01761 if ((kv.first == "texRECT") && (GL_NV_texture_rectangle ||
01762 GL_EXT_texture_rectangle))
01763 {
01764 _bRectangle = true;
01765 bBindRECT = true;
01766 }
01767 else if (kv.first == "texCUBE")
01768 {
01769 bBindCUBE = true;
01770 }
01771 else
01772 {
01773 bBind2D = true;
01774 }
01775
01776 continue;
01777 }
01778
01779 if (token.find("depthTex") == 0)
01780 {
01781 _bIsDepthTexture = true;
01782
01783 if ((kv.first == "depthTexRECT") && (GL_NV_texture_rectangle ||
01784 GL_EXT_texture_rectangle))
01785 {
01786 _bRectangle = true;
01787 bBindRECT = true;
01788 }
01789 else if (kv.first == "depthTexCUBE")
01790 {
01791 bBindCUBE = true;
01792 }
01793 else
01794 {
01795 bBind2D = true;
01796 }
01797
01798 continue;
01799 }
01800
01801 if (kv.first == "mipmap")
01802 {
01803 _bMipmap = true;
01804 continue;
01805 }
01806
01807 if (kv.first == "rtt")
01808 {
01809 _eUpdateMode = RT_RENDER_TO_TEXTURE;
01810 continue;
01811 }
01812
01813 if (kv.first == "ctt")
01814 {
01815 _eUpdateMode = RT_COPY_TO_TEXTURE;
01816 continue;
01817 }
01818
01819 SG_LOG(SG_GL, SG_ALERT,
01820 "RenderTexture Error: Unknown pbuffer attribute: " <<
01821 token.c_str());
01822 dbg_printf("RenderTexture Error: Uknown pbuffer attribute: %s\n",
01823 token.c_str() );
01824 }
01825
01826
01827
01828
01829 if (_bIsTexture && _bIsDepthTexture && !(bBind2D ^ bBindRECT ^ bBindCUBE))
01830 {
01831 SG_LOG(SG_GL, SG_ALERT,
01832 "RenderTexture Warning: Depth and Color texture targets "
01833 "should match.");
01834 dbg_printf( "RenderTexture Warning: Depth and Color texture targets should match.\n");
01835 }
01836
01837
01838 #ifdef _WIN32
01839 if (0 == _iNumComponents)
01840 {
01841 pfAttribs.push_back(WGL_RED_BITS_ARB);
01842 pfAttribs.push_back(8);
01843 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
01844 pfAttribs.push_back(8);
01845 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
01846 pfAttribs.push_back(8);
01847 pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
01848 pfAttribs.push_back(8);
01849 _iNumComponents = 4;
01850 }
01851 #endif
01852
01853
01854 if (_bIsDepthTexture && !iDepthBits)
01855 iDepthBits = 24;
01856
01857 #ifdef _WIN32
01858 pfAttribs.push_back(WGL_DEPTH_BITS_ARB);
01859 #elif defined( __MACH__ )
01860 # if 0
01861 pfAttribs.push_back(AGL_DEPTH_SIZE);
01862 # else
01863 pfAttribs.push_back(kCGLPFADepthSize);
01864 # endif
01865 #else
01866 pfAttribs.push_back(GLX_DEPTH_SIZE);
01867 #endif
01868 pfAttribs.push_back(iDepthBits);
01869
01870 if (!bHasStencil)
01871 {
01872 #ifdef _WIN32
01873 pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
01874 pfAttribs.push_back(0);
01875 #elif defined( __MACH__ )
01876 # if 0
01877 pfAttribs.push_back(AGL_STENCIL_SIZE);
01878 # else
01879 pfAttribs.push_back(kCGLPFAStencilSize);
01880 # endif
01881 pfAttribs.push_back(0);
01882 #else
01883 pfAttribs.push_back(GLX_STENCIL_SIZE);
01884 pfAttribs.push_back(0);
01885 #endif
01886
01887 }
01888 if (_iNumComponents < 4)
01889 {
01890
01891
01892
01893
01894
01895
01896 }
01897
01898 #ifdef _WIN32
01899 if (!WGL_NV_render_depth_texture && _bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
01900 {
01901 #if defined(DEBUG) || defined(_DEBUG)
01902 SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: No support found for "
01903 "render to depth texture.");
01904 #endif
01905 dbg_printf("RenderTexture Warning: No support found for render to depth texture.\n");
01906 _bIsDepthTexture = false;
01907 }
01908 #endif
01909
01910 if ((_bIsTexture || _bIsDepthTexture) &&
01911 (RT_RENDER_TO_TEXTURE == _eUpdateMode))
01912 {
01913 #ifdef _WIN32
01914 if (bBindRECT)
01915 {
01916 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
01917 pbAttribs.push_back(WGL_TEXTURE_RECTANGLE_NV);
01918 }
01919 else if (bBindCUBE)
01920 {
01921 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
01922 pbAttribs.push_back(WGL_TEXTURE_CUBE_MAP_ARB);
01923 }
01924 else if (bBind2D)
01925 {
01926 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
01927 pbAttribs.push_back(WGL_TEXTURE_2D_ARB);
01928 }
01929
01930 if (_bMipmap)
01931 {
01932 pbAttribs.push_back(WGL_MIPMAP_TEXTURE_ARB);
01933 pbAttribs.push_back(true);
01934 }
01935 #elif defined(__MACH__)
01936 #elif defined(DEBUG) || defined(_DEBUG)
01937 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: Render to Texture not "
01938 "supported in Linux or MacOS");
01939 #endif
01940 }
01941
01942
01943 if (_bFloat)
01944 {
01945 #ifdef _WIN32
01946 if (WGL_NV_float_buffer)
01947 {
01948 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
01949 pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
01950
01951 pfAttribs.push_back(WGL_FLOAT_COMPONENTS_NV);
01952 pfAttribs.push_back(true);
01953 }
01954 else
01955 {
01956 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
01957 pfAttribs.push_back(WGL_TYPE_RGBA_FLOAT_ATI);
01958 }
01959 #elif defined( __MACH__ )
01960
01961 {
01962 pfAttribs.push_back(kCGLPFAColorFloat);
01963 }
01964 #else
01965 if (GLX_NV_float_buffer)
01966 {
01967 pfAttribs.push_back(GLX_FLOAT_COMPONENTS_NV);
01968 pfAttribs.push_back(1);
01969 }
01970 #endif
01971 }
01972 else
01973 {
01974 #ifdef _WIN32
01975 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
01976 pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
01977 #endif
01978 }
01979
01980
01981 if (_bIsTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
01982 {
01983
01984 #ifdef _WIN32
01985 if (_bFloat)
01986 {
01987 if (WGL_NV_float_buffer)
01988 {
01989 switch(_iNumComponents)
01990 {
01991 case 1:
01992 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
01993 pfAttribs.push_back(true);
01994
01995 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
01996 pbAttribs.push_back(WGL_TEXTURE_FLOAT_R_NV);
01997 break;
01998 case 2:
01999 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
02000 pfAttribs.push_back(true);
02001
02002 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
02003 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RG_NV);
02004 break;
02005 case 3:
02006 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
02007 pfAttribs.push_back(true);
02008
02009 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
02010 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGB_NV);
02011 break;
02012 case 4:
02013 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
02014 pfAttribs.push_back(true);
02015
02016 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
02017 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
02018 break;
02019 default:
02020 SG_LOG(SG_GL, SG_ALERT,
02021 "RenderTexture Warning: Bad number of components "
02022 "(r=1,rg=2,rgb=3,rgba=4): " <<
02023 _iNumComponents);
02024 dbg_printf("RenderTexture Warning 1: Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n",
02025 _iNumComponents);
02026 break;
02027 }
02028 }
02029 else
02030 {
02031 if (4 == _iNumComponents)
02032 {
02033 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
02034 pfAttribs.push_back(true);
02035
02036 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
02037 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
02038 }
02039 else
02040 {
02041
02042 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
02043 pfAttribs.push_back(true);
02044
02045 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
02046 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
02047 }
02048 }
02049
02050 }
02051 else
02052 {
02053 switch(_iNumComponents)
02054 {
02055 case 3:
02056 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
02057 pfAttribs.push_back(true);
02058
02059 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
02060 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
02061 break;
02062 case 4:
02063 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
02064 pfAttribs.push_back(true);
02065
02066 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
02067 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
02068 break;
02069 default:
02070 SG_LOG(SG_GL, SG_ALERT,
02071 "RenderTexture Warning: Bad number of components "
02072 "(r=1,rg=2,rgb=3,rgba=4): " << _iNumComponents);
02073 dbg_printf("RenderTexture Warning 2: Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n",
02074 _iNumComponents);
02075 break;
02076 }
02077 }
02078 #elif defined(__MACH__)
02079 if (_bFloat)
02080 {
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143 }
02144 else
02145 {
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170 }
02171 #elif defined(DEBUG) || defined(_DEBUG)
02172 SG_LOG(SG_GL, SG_ALERT,
02173 "RenderTexture Error: Render to Texture not supported in Linux or MacOS");
02174 #endif
02175 dbg_printf( "RenderTexture Error 1: Render to Texture not supported in Linux or MacOS\n");
02176 }
02177
02178 if (_bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
02179 {
02180 #ifdef _WIN32
02181 if (_bRectangle)
02182 {
02183 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV);
02184 pfAttribs.push_back(true);
02185
02186 pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
02187 pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
02188 }
02189 else
02190 {
02191 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_DEPTH_NV);
02192 pfAttribs.push_back(true);
02193
02194 pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
02195 pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
02196 }
02197 #elif defined(__MACH__)
02198 #elif defined(DEBUG) || defined(_DEBUG)
02199 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: Render to Texture not supported in "
02200 "Linux or MacOS");
02201 #endif
02202 dbg_printf( "RenderTexture Error 2: Render to Texture not supported in Linux or MacOS\n");
02203 }
02204 dbg_printf("RenderTexture::_ParseModeString(%s). END vf=%d vp=%d\n", modeString, (int)pfAttribs.size(), (int)pbAttribs.size() );
02205
02206 }
02207
02208
02209
02210
02211
02216 RenderTexture::KeyVal RenderTexture::_GetKeyValuePair(string token)
02217 {
02218 string::size_type pos = 0;
02219 if ((pos = token.find("=")) != token.npos)
02220 {
02221 string key = token.substr(0, pos);
02222 string value = token.substr(pos+1, token.length()-pos+1);
02223 return KeyVal(key, value);
02224 }
02225 else
02226 return KeyVal(token, "");
02227 }
02228
02229
02230
02231
02232
02237 vector<int> RenderTexture::_ParseBitVector(string bitVector)
02238 {
02239 vector<string> pieces;
02240 vector<int> bits;
02241
02242 if (bitVector == "")
02243 {
02244 bits.push_back(8);
02245 return bits;
02246 }
02247
02248 string::size_type pos = 0;
02249 string::size_type nextpos = 0;
02250 do
02251 {
02252 nextpos = bitVector.find_first_of(", ", pos);
02253 pieces.push_back(string(bitVector, pos, nextpos - pos));
02254 pos = nextpos+1;
02255 } while (nextpos != bitVector.npos );
02256
02257 for ( vector<string>::iterator it = pieces.begin(); it != pieces.end(); it++)
02258 {
02259 bits.push_back(strtol(it->c_str(), 0, 10));
02260 }
02261
02262 return bits;
02263 }
02264
02265
02266
02267
02268
02273 bool RenderTexture::_VerifyExtensions()
02274 {
02275 dbg_printf("RenderTexture::_VerifyExtensions() called...\n");
02276 #ifdef _WIN32
02277
02278
02279 if ( true || !fctPtrInited )
02280 {
02281 fctPtrInited = true;
02282 wglGetExtensionsStringARBProc wglGetExtensionsStringARBPtr = (wglGetExtensionsStringARBProc)wglGetProcAddress( "wglGetExtensionsStringARB" );
02283 if ( wglGetExtensionsStringARBPtr == 0 )
02284 {
02285 PrintExtensionError("WGL_ARB_extensions_string");
02286 return false;
02287 }
02288 string wglExtensionsString = wglGetExtensionsStringARBPtr( wglGetCurrentDC() );
02289 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pixel_format" ) )
02290 {
02291 wglChoosePixelFormatARBPtr = (wglChoosePixelFormatARBProc)SGLookupFunction("wglChoosePixelFormatARB");
02292 wglGetPixelFormatAttribivARBPtr = (wglGetPixelFormatAttribivARBProc)SGLookupFunction("wglGetPixelFormatAttribivARB");
02293 }
02294 else
02295 {
02296 PrintExtensionError("WGL_ARB_pixel_format");
02297 return false;
02298 }
02299 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pbuffer" ) )
02300 {
02301 wglCreatePbufferARBPtr = (wglCreatePbufferARBProc)SGLookupFunction("wglCreatePbufferARB");
02302 wglGetPbufferDCARBPtr = (wglGetPbufferDCARBProc)SGLookupFunction("wglGetPbufferDCARB");
02303 wglQueryPbufferARBPtr = (wglQueryPbufferARBProc)SGLookupFunction("wglQueryPbufferARB");
02304 wglReleasePbufferDCARBPtr = (wglReleasePbufferDCARBProc)SGLookupFunction("wglReleasePbufferDCARB");
02305 wglDestroyPbufferARBPtr = (wglDestroyPbufferARBProc)SGLookupFunction("wglDestroyPbufferARB");
02306 }
02307 else
02308 {
02309 PrintExtensionError("WGL_ARB_pbuffer");
02310 return false;
02311 }
02312 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_render_texture" ) )
02313 {
02314 wglBindTexImageARBPtr = (wglBindTexImageARBProc)SGLookupFunction("wglBindTexImageARB");
02315 wglReleaseTexImageARBPtr = (wglReleaseTexImageARBProc)SGLookupFunction("wglReleaseTexImageARB");
02316 }
02317 else if ( _bIsTexture )
02318 {
02319 PrintExtensionError("WGL_ARB_render_texture");
02320 return false;
02321 }
02322 if (_bRectangle && !SGIsOpenGLExtensionSupported( "GL_NV_texture_rectangle" ))
02323 {
02324 PrintExtensionError("GL_NV_texture_rectangle");
02325 return false;
02326 }
02327 if (_bFloat && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) ||
02328 SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ATI_pixel_format_float" )))
02329 {
02330 PrintExtensionError("GL_NV_float_buffer or GL_ATI_pixel_format_float");
02331 return false;
02332
02333 }
02334 if (_bFloat && _bIsTexture && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) || SGIsOpenGLExtensionSupported( "GL_ATI_texture_float" )))
02335 {
02336 PrintExtensionError("NV_float_buffer or ATI_texture_float");
02337 }
02338 if (_bIsDepthTexture && !SGIsOpenGLExtensionSupported( "GL_ARB_depth_texture" ))
02339 {
02340
02341 #if defined(_DEBUG) | defined(DEBUG)
02342 SG_LOG(SG_GL, SG_ALERT,
02343 "RenderTexture Warning: "
02344 "OpenGL extension GL_ARB_depth_texture not available."
02345 " Using glReadPixels() to emulate behavior.");
02346 #endif
02347 _bHasARBDepthTexture = false;
02348
02349
02350
02351 }
02352 SetLastError(0);
02353 }
02354 #elif defined( __MACH__ )
02355
02356 #else
02357 Display* dpy = glXGetCurrentDisplay();
02358 int minor = 0, major = 0;
02359 if (!dpy) {
02360 dbg_printf("_VerifyExtensions: glXGetCurrentDisplay() returned NULL! returning false\n");
02361 return false;
02362 }
02363 if (!glXQueryVersion(dpy, &major, &minor))
02364 {
02365 dbg_printf("_VerifyExtensions: glXQueryVersion(dpy, &major, &minor) FAILED! returning false\n");
02366 return false;
02367 }
02368 else
02369 {
02370 dbg_printf("_VerifyExtensions: glXQueryVersion(dpy, major=%d, minor=%d)\n", major, minor);
02371 }
02372
02373 int screen = DefaultScreen(dpy);
02374 const char* extString = glXQueryExtensionsString(dpy, screen);
02375 dbg_printf("_VerifyExtensions: glXQueryExtensionsString(dpy, screen) returned -\n[%s]\n",
02376 (extString ? extString : "<NULL>") );
02377 if (!SGSearchExtensionsString(extString, "GLX_SGIX_fbconfig") ||
02378 !SGSearchExtensionsString(extString, "GLX_SGIX_pbuffer"))
02379 {
02380 dbg_printf("_VerifyExtensions: glXQueryExtensionsString(dpy,screen) does NOT contain GLX_SGIX_fbconfig or GLX_SGIX_pbuffer!\n" );
02381 const char * extClient = glXGetClientString( dpy, GLX_EXTENSIONS );
02382 if (!extClient ||
02383 !SGSearchExtensionsString(extClient, "GLX_SGIX_fbconfig") ||
02384 !SGSearchExtensionsString(extClient, "GLX_SGIX_pbuffer"))
02385 {
02386 dbg_printf("_VerifyExtensions: AND glXGetClientString(dpy,GLX_EXTENSIONS) also! returning false\n" );
02387 return false;
02388 }
02389 else
02390 {
02391 dbg_printf("_VerifyExtensions: BUT glXGetClientString(dpy,GLX_EXTENSIONS) returned \n[%s]\n", extClient );
02392 dbg_printf("Since this DOES contain fbconfig and pbuffer, continuing...\n");
02393 }
02394 }
02395
02396 glXChooseFBConfigPtr = (glXChooseFBConfigProc)SGLookupFunction("glXChooseFBConfig");
02397 glXCreatePbufferPtr = (glXCreatePbufferProc)SGLookupFunction("glXCreatePbuffer");
02398 glXGetVisualFromFBConfigPtr = (glXGetVisualFromFBConfigProc)SGLookupFunction("glXGetVisualFromFBConfig");
02399 glXCreateContextPtr = (glXCreateContextProc)SGLookupFunction("glXCreateContext");
02400 glXDestroyPbufferPtr = (glXDestroyPbufferProc)SGLookupFunction("glXDestroyPbuffer");
02401 glXQueryDrawablePtr = (glXQueryDrawableProc)SGLookupFunction("glXQueryDrawable");
02402
02403 if (((1 <= major && 3 <= minor) || 2 <= major) &&
02404 glXChooseFBConfigPtr &&
02405 glXCreatePbufferPtr &&
02406 glXGetVisualFromFBConfigPtr &&
02407 glXCreateContextPtr &&
02408 glXDestroyPbufferPtr &&
02409 glXQueryDrawablePtr) {
02410 dbg_printf("_VerifyExtensions: setting glXVersion1_3Present TRUE\n" );
02411 glXVersion1_3Present = true;
02412 }
02413 else
02414 {
02415 dbg_printf("_VerifyExtensions: setting glXVersion1_3Present FALSE\n Reason: " );
02416 if ( !((1 <= major && 3 <= minor) || 2 <= major) ) { dbg_printf( "Version wrong %d.%d ", major, minor ); }
02417 if ( !glXChooseFBConfigPtr ) { dbg_printf( "missing glXChooseFBConfigPtr " ); }
02418 if ( !glXCreatePbufferPtr ) { dbg_printf( "missing glXCreatePbufferPtr " ); }
02419 if ( !glXGetVisualFromFBConfigPtr ) { dbg_printf( "missing glXGetVisualFromFBConfigPtr " ); }
02420 if ( !glXCreateContextPtr ) { dbg_printf( "missing glXCreateContextPtr " ); }
02421 if ( !glXDestroyPbufferPtr ) { dbg_printf( "missing glXDestroyPbufferPtr " ); }
02422 if ( !glXQueryDrawablePtr ) { dbg_printf( "missing glXQueryDrawablePtr " ); }
02423 dbg_printf("\n");
02424
02425 glXChooseFBConfigPtr = (glXChooseFBConfigProc)SGLookupFunction("glXChooseFBConfigSGIX");
02426 glXCreateGLXPbufferPtr = (glXCreateGLXPbufferProc)SGLookupFunction("glXCreateGLXPbufferSGIX");
02427 glXGetVisualFromFBConfigPtr = (glXGetVisualFromFBConfigProc)SGLookupFunction("glXGetVisualFromFBConfigSGIX");
02428 glXCreateContextWithConfigPtr = (glXCreateContextWithConfigProc)SGLookupFunction("glXCreateContextWithConfigSGIX");
02429 glXDestroyPbufferPtr = (glXDestroyPbufferProc)SGLookupFunction("glXDestroyGLXPbufferSGIX");
02430 glXQueryGLXPbufferSGIXPtr = (glXQueryGLXPbufferSGIXProc)SGLookupFunction("glXQueryGLXPbufferSGIX");
02431
02432 if (!glXChooseFBConfigPtr ||
02433 !glXCreateGLXPbufferPtr ||
02434 !glXGetVisualFromFBConfigPtr ||
02435 !glXCreateContextWithConfigPtr ||
02436 !glXDestroyPbufferPtr ||
02437 !glXQueryGLXPbufferSGIXPtr)
02438 {
02439 dbg_printf("_VerifyExtensions: some pointer is NULL! return false\n" );
02440 if ( !glXCreateGLXPbufferPtr ) {
02441 dbg_printf("RenderTexture::Initialize: ERROR glXCreateGLXPbufferPtr = NULL!\n");
02442 } else if ( !glXCreateContextWithConfigPtr ) {
02443 dbg_printf("RenderTexture::Initialize: ERROR glXCreateContextWithConfigPtr = NULL!\n");
02444 } else if ( !glXVersion1_3Present && !glXQueryGLXPbufferSGIXPtr ) {
02445 dbg_printf("RenderTexture::Initialize: ERROR glXQueryGLXPbufferSGIXPtr = NULL!\n");
02446 }
02447 return false;
02448 } else {
02449 dbg_printf("_VerifyExtensions: appear to have all 'procs' glXCreateGLXPbufferPtr=[%p]\n", glXCreateGLXPbufferPtr );
02450 }
02451 }
02452
02453 if (_bIsDepthTexture && !GL_ARB_depth_texture)
02454 {
02455 PrintExtensionError("GL_ARB_depth_texture");
02456 return false;
02457 }
02458 if (_bFloat && _bIsTexture && !GLX_NV_float_buffer)
02459 {
02460 PrintExtensionError("GLX_NV_float_buffer");
02461 return false;
02462 }
02463 if (_eUpdateMode == RT_RENDER_TO_TEXTURE)
02464 {
02465 PrintExtensionError("Some GLX render texture extension: Please implement me!");
02466 return false;
02467 }
02468 #endif
02469
02470 dbg_printf("RenderTexture::_VerifyExtensions: return true.\n");
02471 return true;
02472 }
02473
02474
02475
02476
02477
02482 bool RenderTexture::_InitializeTextures()
02483 {
02484 dbg_printf( "RenderTexture::_InitializeTextures() called\n" );
02485
02486
02487 if (_bIsTexture || _bIsDepthTexture)
02488 {
02489 if (_bRectangle && GL_NV_texture_rectangle)
02490 _iTextureTarget = GL_TEXTURE_RECTANGLE_NV;
02491 else if (_bRectangle && GL_EXT_texture_rectangle)
02492 _iTextureTarget = GL_TEXTURE_RECTANGLE_EXT;
02493 else
02494 _iTextureTarget = GL_TEXTURE_2D;
02495 }
02496
02497 if (_bIsTexture)
02498 {
02499 glGenTextures(1, (GLuint*)&_iTextureID);
02500 glBindTexture(_iTextureTarget, _iTextureID);
02501
02502
02503 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
02504 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
02505
02506 glTexParameteri(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
02507 glTexParameteri(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
02508
02509
02510 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
02511 {
02512 GLuint iInternalFormat;
02513 GLuint iFormat;
02514
02515 if (_bFloat)
02516 {
02517 if (_bMipmap)
02518 {
02519 SG_LOG(SG_GL, SG_ALERT,
02520 "RenderTexture Error: mipmapped float textures not "
02521 "supported.");
02522 dbg_printf( "RenderTexture Error: mipmapped float textures not supported. return false\n");
02523 return false;
02524 }
02525
02526 switch(_iNumComponents)
02527 {
02528 case 1:
02529 if (GL_NV_float_buffer)
02530 {
02531 iInternalFormat = (_iNumColorBits[0] > 16) ?
02532 GL_FLOAT_R32_NV : GL_FLOAT_R16_NV;
02533 }
02534 else if (GL_ATI_texture_float)
02535 {
02536 iInternalFormat = (_iNumColorBits[0] > 16) ?
02537 GL_LUMINANCE_FLOAT32_ATI :
02538 GL_LUMINANCE_FLOAT16_ATI;
02539 }
02540 iFormat = GL_LUMINANCE;
02541 break;
02542 case 2:
02543 if (GL_NV_float_buffer)
02544 {
02545 iInternalFormat = (_iNumColorBits[0] > 16) ?
02546 GL_FLOAT_RG32_NV : GL_FLOAT_RG16_NV;
02547 }
02548 else if (GL_ATI_texture_float)
02549 {
02550 iInternalFormat = (_iNumColorBits[0] > 16) ?
02551 GL_LUMINANCE_ALPHA_FLOAT32_ATI :
02552 GL_LUMINANCE_ALPHA_FLOAT16_ATI;
02553 }
02554 iFormat = GL_LUMINANCE_ALPHA;
02555 break;
02556 case 3:
02557 if (GL_NV_float_buffer)
02558 {
02559 iInternalFormat = (_iNumColorBits[0] > 16) ?
02560 GL_FLOAT_RGB32_NV : GL_FLOAT_RGB16_NV;
02561 }
02562 else if (GL_ATI_texture_float)
02563 {
02564 iInternalFormat = (_iNumColorBits[0] > 16) ?
02565 GL_RGB_FLOAT32_ATI : GL_RGB_FLOAT16_ATI;
02566 }
02567 iFormat = GL_RGB;
02568 break;
02569 case 4:
02570 if (GL_NV_float_buffer)
02571 {
02572 iInternalFormat = (_iNumColorBits[0] > 16) ?
02573 GL_FLOAT_RGBA32_NV : GL_FLOAT_RGBA16_NV;
02574 }
02575 else if (GL_ATI_texture_float)
02576 {
02577 iInternalFormat = (_iNumColorBits[0] > 16) ?
02578 GL_RGBA_FLOAT32_ATI : GL_RGBA_FLOAT16_ATI;
02579 }
02580 iFormat = GL_RGBA;
02581 break;
02582 default:
02583 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: "
02584 "Invalid number of components: " <<
02585 _iNumComponents);
02586 dbg_printf( "RenderTexture Error: Invalid number of components: %d - return false\n",
02587 _iNumComponents);
02588 return false;
02589 }
02590 }
02591 else
02592 {
02593 if (4 == _iNumComponents)
02594 {
02595 iInternalFormat = GL_RGBA8;
02596 iFormat = GL_RGBA;
02597 }
02598 else
02599 {
02600 iInternalFormat = GL_RGB8;
02601 iFormat = GL_RGB;
02602 }
02603 }
02604
02605
02606 glTexImage2D(_iTextureTarget, 0, iInternalFormat,
02607 _iWidth, _iHeight, 0, iFormat, GL_FLOAT, NULL);
02608 }
02609 }
02610
02611 if (_bIsDepthTexture)
02612 {
02613 glGenTextures(1, (GLuint*)&_iDepthTextureID);
02614 glBindTexture(_iTextureTarget, _iDepthTextureID);
02615
02616
02617 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
02618 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
02619
02620 glTexParameteri(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
02621 glTexParameteri(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
02622
02623 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
02624 {
02625
02626 if (_bHasARBDepthTexture)
02627 {
02628
02629 glTexImage2D(_iTextureTarget, 0, GL_DEPTH_COMPONENT,
02630 _iWidth, _iHeight, 0, GL_DEPTH_COMPONENT,
02631 GL_FLOAT, NULL);
02632 }
02633 else
02634 {
02635
02636
02637 _pPoorDepthTexture = new unsigned short[_iWidth * _iHeight];
02638 glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16,
02639 _iWidth, _iHeight, 0, GL_LUMINANCE,
02640 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
02641 }
02642
02643 }
02644 }
02645
02646 dbg_printf( "RenderTexture::_InitializeTextures() returning true\n" );
02647 return true;
02648 }
02649
02650
02651
02652
02653
02654
02659 void RenderTexture::_MaybeCopyBuffer()
02660 {
02661 #ifdef _WIN32
02662 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
02663 {
02664 if (_bIsTexture)
02665 {
02666 glBindTexture(_iTextureTarget, _iTextureID);
02667 glCopyTexSubImage2D(_iTextureTarget,
02668 0, 0, 0, 0, 0, _iWidth, _iHeight);
02669 }
02670 if (_bIsDepthTexture)
02671 {
02672 glBindTexture(_iTextureTarget, _iDepthTextureID);
02673
02674
02675 if (_bHasARBDepthTexture)
02676 {
02677 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0,
02678 _iWidth, _iHeight);
02679 }
02680 else
02681 {
02682
02683
02684 glReadPixels(0, 0, _iWidth, _iHeight, GL_DEPTH_COMPONENT,
02685 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
02686 glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16,
02687 _iWidth, _iHeight, 0, GL_LUMINANCE,
02688 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
02689 }
02690
02691 }
02692 }
02693
02694 #elif defined(__MACH__)
02695 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
02696 {
02697 if (_bIsTexture)
02698 {
02699 glBindTexture(_iTextureTarget, _iTextureID);
02700 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
02701 }
02702 if (_bIsDepthTexture)
02703 {
02704 glBindTexture(_iTextureTarget, _iDepthTextureID);
02705 assert(_bHasARBDepthTexture);
02706 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
02707 }
02708 }
02709 #else
02710 if (_bIsTexture)
02711 {
02712 glBindTexture(_iTextureTarget, _iTextureID);
02713 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
02714 }
02715 if (_bIsDepthTexture)
02716 {
02717 glBindTexture(_iTextureTarget, _iDepthTextureID);
02718 assert(_bHasARBDepthTexture);
02719 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
02720 }
02721 #endif
02722
02723 }
02724
02725
02726
02727
02728
02733 bool RenderTexture::_ReleaseBoundBuffers()
02734 {
02735 #ifdef _WIN32
02736 if (_bIsTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
02737 {
02738 glBindTexture(_iTextureTarget, _iTextureID);
02739
02740
02741 if (0 != _iCurrentBoundBuffer && _bIsBufferBound)
02742 {
02743 if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, _iCurrentBoundBuffer))
02744 {
02745 _wglGetLastError();
02746 return false;
02747 }
02748 _bIsBufferBound = false;
02749 }
02750 }
02751
02752 if (_bIsDepthTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
02753 {
02754 glBindTexture(_iTextureTarget, _iDepthTextureID);
02755
02756
02757 if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
02758 {
02759 _wglGetLastError();
02760 return false;
02761 }
02762 }
02763
02764 #else
02765
02766 #endif
02767 return true;
02768 }
02769
02770
02771
02772
02773
02778 bool RenderTexture::_MakeCurrent()
02779 {
02780 #ifdef _WIN32
02781
02782 if (FALSE == wglMakeCurrent( _hDC, _hGLContext))
02783 {
02784 _wglGetLastError();
02785 return false;
02786 }
02787 #elif defined( __MACH__ )
02788 CGLError err;
02789
02790 if (err = CGLSetCurrentContext(_hGLContext))
02791 {
02792 _cglCheckError(err);
02793 return false;
02794 }
02795 #else
02796 static GLXContext last_hGLContext = 0;
02797 if (false == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
02798 {
02799 dbg_printf( "_MakeCurrent: glXMakeCurrent FAILED! returning false\n");
02800 return false;
02801 }
02802
02803 if ( last_hGLContext != _hGLContext ) {
02804 last_hGLContext = _hGLContext;
02805 dbg_printf( "_MakeCurrent: glXMakeCurrent set to [%p] SUCCESS! returning true\n", _hGLContext );
02806 }
02807 #endif
02808 return true;
02809 }
02810
02812
02813
02814
02816
02817
02818
02819
02820
02825 RenderTexture::RenderTexture(int width, int height,
02826 bool bIsTexture ,
02827 bool bIsDepthTexture )
02828 : _iWidth(width),
02829 _iHeight(height),
02830 _bIsTexture(bIsTexture),
02831 _bIsDepthTexture(bIsDepthTexture),
02832 _bHasARBDepthTexture(true),
02833 _eUpdateMode(RT_RENDER_TO_TEXTURE),
02834 _bInitialized(false),
02835 _iNumAuxBuffers(0),
02836 _iCurrentBoundBuffer(0),
02837 _iNumDepthBits(0),
02838 _iNumStencilBits(0),
02839 _bFloat(false),
02840 _bDoubleBuffered(false),
02841 _bPowerOf2(true),
02842 _bRectangle(false),
02843 _bMipmap(false),
02844 _bShareObjects(false),
02845 _bCopyContext(false),
02846 #ifdef _WIN32
02847 _hDC(NULL),
02848 _hGLContext(NULL),
02849 _hPBuffer(NULL),
02850 _hPreviousDC(0),
02851 _hPreviousContext(0),
02852 #elif defined( __MACH__ )
02853 _hGLContext(NULL),
02854 _hPBuffer(NULL),
02855 _hPreviousContext(NULL),
02856 #else
02857 _pDisplay(NULL),
02858 _hGLContext(NULL),
02859 _hPBuffer(0),
02860 _hPreviousDrawable(0),
02861 _hPreviousContext(0),
02862 #endif
02863 _iTextureTarget(GL_NONE),
02864 _iTextureID(0),
02865 _iDepthTextureID(0),
02866 _pPoorDepthTexture(0)
02867 {
02868 assert(width > 0 && height > 0);
02869 #if defined DEBUG || defined _DEBUG
02870 SG_LOG(SG_GL, SG_ALERT,
02871 "RenderTexture Warning: Deprecated Contructor interface used.");
02872 #endif
02873 dbg_printf("RenderTexture Warning: Deprecated Contructor interface used.\n");
02874
02875 _iNumColorBits[0] = _iNumColorBits[1] =
02876 _iNumColorBits[2] = _iNumColorBits[3] = 0;
02877 _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
02878 }
02879
02880
02881
02882
02883
02893 bool RenderTexture::Initialize(bool bShare ,
02894 bool bDepth ,
02895 bool bStencil ,
02896 bool bMipmap ,
02897 bool bAnisoFilter ,
02898 unsigned int iRBits ,
02899 unsigned int iGBits ,
02900 unsigned int iBBits ,
02901 unsigned int iABits ,
02902 UpdateMode updateMode )
02903 {
02904 if (0 == _iWidth || 0 == _iHeight)
02905 return false;
02906
02907 #if defined DEBUG || defined _DEBUG
02908 SG_LOG(SG_GL, SG_ALERT,
02909 "RenderTexture Warning: Deprecated Initialize() interface used.");
02910 #endif
02911 dbg_printf("RenderTexture Warning: Deprecated Initialize() interface used.\n");
02912
02913
02914 string mode = "";
02915 if (bDepth)
02916 mode.append("depth ");
02917 if (bStencil)
02918 mode.append("stencil ");
02919 if (bMipmap)
02920 mode.append("mipmap ");
02921 if (iRBits + iGBits + iBBits + iABits > 0)
02922 {
02923 if (iRBits > 0)
02924 mode.append("r");
02925 if (iGBits > 0)
02926 mode.append("g");
02927 if (iBBits > 0)
02928 mode.append("b");
02929 if (iABits > 0)
02930 mode.append("a");
02931 mode.append("=");
02932 char bitVector[100];
02933 snprintf( bitVector, 100,
02934 "%d%s,%d%s,%d%s,%d%s",
02935 iRBits, (iRBits >= 16) ? "f" : "",
02936 iGBits, (iGBits >= 16) ? "f" : "",
02937 iBBits, (iBBits >= 16) ? "f" : "",
02938 iABits, (iABits >= 16) ? "f" : "");
02939 mode.append(bitVector);
02940 mode.append(" ");
02941 }
02942 if (_bIsTexture)
02943 {
02944 if ((GL_NV_texture_rectangle || GL_EXT_texture_rectangle) &&
02945 ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
02946 || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
02947 mode.append("texRECT ");
02948 else
02949 mode.append("tex2D ");
02950 }
02951 if (_bIsDepthTexture)
02952 {
02953 if ((GL_NV_texture_rectangle || GL_EXT_texture_rectangle) &&
02954 ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
02955 || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
02956 mode.append("texRECT ");
02957 else
02958 mode.append("tex2D ");
02959 }
02960 if (RT_COPY_TO_TEXTURE == updateMode)
02961 mode.append("ctt");
02962
02963 _pixelFormatAttribs.clear();
02964 _pbufferAttribs.clear();
02965
02966 #ifdef _WIN32
02967 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
02968 _pixelFormatAttribs.push_back(true);
02969 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
02970 _pixelFormatAttribs.push_back(true);
02971
02972 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
02973 _pbufferAttribs.push_back(true);
02974 #elif defined( __MACH__ )
02975
02976 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
02977 _pixelFormatAttribs.push_back(kCGLPFAWindow);
02978 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
02979 #else
02980 _pixelFormatAttribs.push_back(GLX_RENDER_TYPE_SGIX);
02981 _pixelFormatAttribs.push_back(GLX_RGBA_BIT_SGIX);
02982 _pixelFormatAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
02983 _pixelFormatAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
02984 #endif
02985
02986 _ParseModeString(mode.c_str(), _pixelFormatAttribs, _pbufferAttribs);
02987
02988 #ifdef _WIN32
02989 _pixelFormatAttribs.push_back(0);
02990 _pbufferAttribs.push_back(0);
02991 #elif defined(__MACH__)
02992 _pixelFormatAttribs.push_back(0);
02993 #else
02994 _pixelFormatAttribs.push_back(None);
02995 #endif
02996
02997 Initialize(_iWidth, _iHeight, bShare);
02998
02999 return true;
03000 }
03001
03002
03003
03004
03005
03006
03014 bool RenderTexture::Reset(int iWidth, int iHeight)
03015 {
03016 SG_LOG(SG_GL, SG_ALERT,
03017 "RenderTexture Warning: Deprecated Reset() interface used.");
03018
03019 dbg_printf("RenderTexture Warning: Deprecated Reset(x,y) interface used.\n");
03020
03021 if (!_Invalidate())
03022 {
03023 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Reset(): failed to invalidate.");
03024 dbg_printf( "RenderTexture::Reset(x,y): failed to invalidate. returning false\n");
03025 return false;
03026 }
03027 _iWidth = iWidth;
03028 _iHeight = iHeight;
03029
03030 dbg_printf( "RenderTexture::Reset(x,y): succeeded. returning true\n");
03031 return true;
03032 }
03033
03034 #if defined( _DEBUG ) && !defined( _WIN32 ) && !defined( __MACH__ )
03035
03036
03037 typedef struct tagPXATTS {
03038 int attr;
03039 const char * name;
03040 const char * desc;
03041 int def;
03042 }PXATTS, * PPXATTS;
03043
03044 static PXATTS pxAtts[] = {
03045 { GLX_FBCONFIG_ID, "GLX_FBCONFIG_ID",
03046 "followed by a valid XID that indicates the desired GLX frame buffer configuration. "
03047 "When a GLX_FBCONFIG_ID is specified, all attributes are ignored. The default value is GLX_DONT_CARE.",
03048 GLX_DONT_CARE },
03049 { GLX_BUFFER_SIZE, "GLX_BUFFER_SIZE",
03050 "Must be followed by a nonnegative integer that indicates the desired color index buffer size."
03051 "The smallest index buffer of at least the specified size is preferred. This attribute is ignored if GLX_COLOR_INDEX_BIT is not set "
03052 "in GLX_RENDER_TYPE. The default value is 0.",
03053 0 },
03054 { GLX_LEVEL, "GLX_LEVEL",
03055 "Must be followed by an integer buffer-level specification. This specification is honored exactly."
03056 "Buffer level 0 corresponds to the default frame buffer of the display. "
03057 "Buffer level 1 is the first overlay frame buffer, level two the second overlay frame buffer, and so on."
03058 "Negative buffer levels correspond to underlay frame buffers. The default value is 0.",
03059 0 },
03060 { GLX_DOUBLEBUFFER, "GLX_DOUBLEBUFFER",
03061 "Must be followed by True or False. If True is specified, then only double-buffered frame buffer configurations are considered;"
03062 "if False is specified, then only single-buffered frame buffer configurations are considered. The default value is GLX_DONT_CARE.",
03063 GLX_DONT_CARE },
03064 { GLX_STEREO, "GLX_STEREO",
03065 "Must be followed by True or False. If True is specified, then only stereo frame buffer configurations are considered;"
03066 " if False is specified, then only monoscopic frame buffer configurations are considered. The default value is False.",
03067 False },
03068 { GLX_AUX_BUFFERS, "GLX_AUX_BUFFERS",
03069 "Must be followed by a nonnegative integer that indicates the desired number of auxiliary buffers."
03070 " Configurations with the smallest number of auxiliary buffers that meet or exceed the specified number are preferred."
03071 " The default value is 0.",
03072 0 },
03073 { GLX_RED_SIZE, "GLX_RED_SIZE",
03074 "must be followed by a nonnegative minimum size",
03075 0 },
03076 { GLX_GREEN_SIZE, "GLX_GREEN_SIZE",
03077 "must be followed by a nonnegative minimum size",
03078 0 },
03079 { GLX_BLUE_SIZE, "GLX_BLUE_SIZE",
03080 "must be followed by a nonnegative minimum size",
03081 0 },
03082 { GLX_ALPHA_SIZE, "GLX_ALPHA_SIZE",
03083 "Each attribute, if present, must be followed by a nonnegative minimum size specification or GLX_DONT_CARE."
03084 " The largest available total RGBA color buffer size (sum of GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE) "
03085 " of at least the minimum size specified for each color component is preferred. If the requested number of bits for a color "
03086 " component is 0 or GLX_DONT_CARE, it is not considered. The default value for each color component is 0.",
03087 0 },
03088 { GLX_DEPTH_SIZE, "GLX_DEPTH_SIZE",
03089 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
03090 "frame buffer configurations with no depth buffer are preferred."
03091 "Otherwise, the largest available depth buffer of at least the minimum size is preferred. The default value is 0.",
03092 0 },
03093 { GLX_STENCIL_SIZE, "GLX_STENCIL_SIZE",
03094 "Must be followed by a nonnegative integer that indicates the desired number of stencil bitplanes."
03095 "The smallest stencil buffer of at least the specified size is preferred. If the desired value is zero,"
03096 " frame buffer configurations with no stencil buffer are preferred. The default value is 0.",
03097 0 },
03098 { GLX_ACCUM_RED_SIZE, "GLX_ACCUM_RED_SIZE",
03099 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
03100 " frame buffer configurations with no red accumulation buffer are preferred."
03101 " Otherwise, the largest possible red accumulation buffer of at least the minimum size is preferred. The default value is 0.",
03102 0 },
03103 { GLX_ACCUM_GREEN_SIZE, "GLX_ACCUM_GREEN_SIZE",
03104 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
03105 "frame buffer configurations with no green accumulation buffer are preferred. "
03106 "Otherwise, the largest possible green accumulation buffer of at least the minimum size is preferred. The default value is 0.",
03107 0 },
03108 { GLX_ACCUM_BLUE_SIZE, "GLX_ACCUM_BLUE_SIZE",
03109 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
03110 "frame buffer configurations with no blue accumulation buffer are preferred. "
03111 "Otherwise, the largest possible blue accumulation buffer of at least the minimum size is preferred. The default value is 0.",
03112 0 },
03113 { GLX_ACCUM_ALPHA_SIZE, "GLX_ACCUM_ALPHA_SIZE",
03114 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
03115 "frame buffer configurations with no alpha accumulation buffer are preferred. "
03116 "Otherwise, the largest possible alpha accumulation buffer of at least the minimum size is preferred. The default value is 0.",
03117 0 },
03118 { GLX_RENDER_TYPE, "GLX_RENDER_TYPE",
03119 "Must be followed by a mask indicating which OpenGL rendering modes the frame buffer configuration must support. "
03120 "Valid bits are GLX_RGBA_BIT and GLX_COLOR_INDEX_BIT. If the mask is set to GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT, "
03121 "then only frame buffer configurations that can be bound to both RGBA contexts and color index contexts will be considered. "
03122 "The default value is GLX_RGBA_BIT.",
03123 GLX_RGBA_BIT },
03124 { GLX_DRAWABLE_TYPE, "GLX_DRAWABLE_TYPE",
03125 "Must be followed by a mask indicating which GLX drawable types the frame buffer configuration must support. "
03126 "Valid bits are GLX_WINDOW_BIT, GLX_PIXMAP_BIT, and GLX_PBUFFER_BIT. For example, if mask is set to "
03127 "GLX_WINDOW_BIT | GLX_PIXMAP_BIT, only frame buffer configurations that support both windows and GLX pixmaps "
03128 "will be considered. The default value is GLX_WINDOW_BIT.",
03129 GLX_WINDOW_BIT },
03130 { GLX_X_RENDERABLE, "GLX_X_RENDERABLE",
03131 "Must be followed by True or False. If True is specified, then only frame buffer configurations that "
03132 "have associated X visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. "
03133 "The default value is GLX_DONT_CARE. ",
03134 GLX_DONT_CARE },
03135 { GLX_X_VISUAL_TYPE, "GLX_X_VISUAL_TYPE",
03136 "Must be followed by one of GLX_TRUE_COLOR, GLX_DIRECT_COLOR, GLX_PSEUDO_COLOR, GLX_STATIC_COLOR, "
03137 "GLX_GRAY_SCALE, or GLX_STATIC_GRAY, indicating the desired X visual type. "
03138 "Not all frame buffer configurations have an associated X visual. If GLX_DRAWABLE_TYPE is specified in attrib_list and the "
03139 "mask that follows does not have GLX_WINDOW_BIT set, then this value is ignored. It is also ignored if "
03140 "GLX_X_RENDERABLE is specified as False. RGBA rendering may be supported for visuals of type "
03141 "GLX_TRUE_COLOR, GLX_DIRECT_COLOR, GLX_PSEUDO_COLOR, or GLX_STATIC_COLOR, "
03142 "but color index rendering is only supported for visuals of type GLX_PSEUDO_COLOR or GLX_STATIC_COLOR "
03143 "(i.e., single-channel visuals). The tokens GLX_GRAY_SCALE and GLX_STATIC_GRAY will "
03144 "not match current OpenGL enabled visuals, but are included for future use."
03145 "The default value for GLX_X_VISUAL_TYPE is GLX_DONT_CARE.",
03146 GLX_DONT_CARE },
03147 { GLX_CONFIG_CAVEAT, "GLX_CONFIG_CAVEAT",
03148 "Must be followed by one of GLX_NONE, GLX_SLOW_CONFIG, GLX_NON_CONFORMANT_CONFIG. "
03149 "If GLX_NONE is specified, then only frame buffer configurations with "
03150 "no caveats will be considered; if GLX_SLOW_CONFIG is specified, then only slow frame buffer configurations will be considered; if "
03151 "GLX_NON_CONFORMANT_CONFIG is specified, then only nonconformant frame buffer configurations will be considered."
03152 "The default value is GLX_DONT_CARE.",
03153 GLX_DONT_CARE },
03154 { GLX_TRANSPARENT_TYPE, "GLX_TRANSPARENT_TYPE",
03155 "Must be followed by one of GLX_NONE, GLX_TRANSPARENT_RGB, GLX_TRANSPARENT_INDEX. "
03156 "If GLX_NONE is specified, then only opaque frame buffer configurations will be considered; "
03157 "if GLX_TRANSPARENT_RGB is specified, then only transparent frame buffer configurations that support RGBA rendering will be considered; "
03158 "if GLX_TRANSPARENT_INDEX is specified, then only transparent frame buffer configurations that support color index rendering will be considered."
03159 "The default value is GLX_NONE.",
03160 GLX_NONE },
03161 { GLX_TRANSPARENT_INDEX_VALUE, "GLX_TRANSPARENT_INDEX_VALUE",
03162 "Must be followed by an integer value indicating the transparent index value; the value must be between 0 and the maximum "
03163 "frame buffer value for indices. Only frame buffer configurations that use the "
03164 "specified transparent index value will be considered. The default value is GLX_DONT_CARE. "
03165 "This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in attrib_list and specified as GLX_TRANSPARENT_INDEX.",
03166 GLX_DONT_CARE },
03167 { GLX_TRANSPARENT_RED_VALUE, "GLX_TRANSPARENT_RED_VALUE",
03168 "Must be followed by an integer value indicating the transparent red value; the value must be between 0 and the maximum "
03169 "frame buffer value for red. Only frame buffer configurations that use the specified transparent red value will be considered. "
03170 "The default value is GLX_DONT_CARE. This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in "
03171 "attrib_list and specified as GLX_TRANSPARENT_RGB.",
03172 GLX_DONT_CARE },
03173 { GLX_TRANSPARENT_GREEN_VALUE, "GLX_TRANSPARENT_GREEN_VALUE",
03174 "Must be followed by an integer value indicating the transparent green value; the value must be between 0 and the maximum "
03175 "frame buffer value for green. Only frame buffer configurations that use the specified transparent green value will be considered."
03176 "The default value is GLX_DONT_CARE. This attribute is "
03177 "ignored unless GLX_TRANSPARENT_TYPE is included in attrib_list and specified as GLX_TRANSPARENT_RGB.",
03178 GLX_DONT_CARE },
03179 { GLX_TRANSPARENT_BLUE_VALUE, "GLX_TRANSPARENT_BLUE_VALUE",
03180 "Must be followed by an integer value indicating the transparent blue value; the value must be between 0 and the maximum "
03181 "frame buffer value for blue. Only frame buffer configurations that use the specified transparent blue value will be considered."
03182 "The default value is GLX_DONT_CARE. This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in "
03183 "attrib_list and specified as GLX_TRANSPARENT_RGB. ",
03184 GLX_DONT_CARE },
03185 { GLX_TRANSPARENT_ALPHA_VALUE, "GLX_TRANSPARENT_ALPHA_VALUE",
03186 "Must be followed by an integer value indicating the transparent alpha value; the value must be between 0 and the maximum "
03187 "frame buffer value for alpha. Only frame buffer configurations that use the "
03188 "specified transparent alpha value will be considered. The default value is GLX_DONT_CARE.",
03189 GLX_DONT_CARE },
03190 { 0, NULL, NULL, -1 }
03191 };
03192
03193 const char * get_attr_name( int val, int * pdef )
03194 {
03195 PPXATTS pat = &pxAtts[0];
03196 while( pat->name )
03197 {
03198 if ( pat->attr == val ) {
03199 *pdef = pat->def;
03200 return pat->name;
03201 }
03202 pat++;
03203 }
03204 *pdef = -1;
03205 return "VALUE NOT IN LIST";
03206 }
03207
03208 #endif
03209