1 // File : RenderTexture.cpp
2 //---------------------------------------------------------------------------
3 // Copyright (c) 2002-2004 Mark J. Harris
4 //---------------------------------------------------------------------------
5 // This software is provided 'as-is', without any express or implied
6 // warranty. In no event will the authors be held liable for any
7 // damages arising from the use of this software.
9 // Permission is granted to anyone to use this software for any
10 // purpose, including commercial applications, and to alter it and
11 // redistribute it freely, subject to the following restrictions:
13 // 1. The origin of this software must not be misrepresented; you
14 // must not claim that you wrote the original software. If you use
15 // this software in a product, an acknowledgment in the product
16 // documentation would be appreciated but is not required.
18 // 2. Altered source versions must be plainly marked as such, and
19 // must not be misrepresented as being the original software.
21 // 3. This notice may not be removed or altered from any source
24 // --------------------------------------------------------------------------
26 // Original RenderTexture class: Mark J. Harris
27 // Original Render to Depth Texture support: Thorsten Scheuermann
28 // Linux Copy-to-texture: Eric Werness
29 // OS X: Alexander Powell (someone please help)
30 // Various Bug Fixes: Daniel (Redge) Sperl
32 // Ubuntu 8.04 64bit: Geoff McLane - 2009-07-01
33 // to work even when version 1.2 is returned.
35 // --------------------------------------------------------------------------
37 * @file RenderTexture.cpp
39 * Implementation of class RenderTexture. A multi-format render to
42 #pragma warning(disable:4786)
47 * Jan. 2005, Removed GLEW dependencies, Erik Hofman, Fred Bouvier
48 * Nov. 2005, Use the simgear logging facility, Erik Hofman
49 * Mar. 2006, Add MAC OS X support, Alexander Powell
53 # include <simgear_config.h>
56 #include <simgear/compiler.h>
57 #include <simgear/debug/logstream.hxx>
58 #include <simgear/screen/extensions.hxx>
59 #include <simgear/screen/RenderTexture.h>
69 #pragma comment(lib, "gdi32.lib") // required for GetPixelFormat()
74 // DEBUG - add a lot of noise
80 #define dbg_printf printf
81 const char * get_attr_name( int val, int * pdef );
86 // CHOP/NOT CHOP SOME CODE TO GET SOMETHING WORKING!
87 #define ADD_QUERY_BUFFER
88 #define ADD_GET_DRAWABLE
89 // =======================================
93 static bool fctPtrInited = false;
94 /* WGL_ARB_pixel_format */
95 static wglChoosePixelFormatARBProc wglChoosePixelFormatARBPtr = 0;
96 static wglGetPixelFormatAttribivARBProc wglGetPixelFormatAttribivARBPtr = 0;
98 static wglCreatePbufferARBProc wglCreatePbufferARBPtr = 0;
99 static wglGetPbufferDCARBProc wglGetPbufferDCARBPtr = 0;
100 static wglQueryPbufferARBProc wglQueryPbufferARBPtr = 0;
101 static wglReleasePbufferDCARBProc wglReleasePbufferDCARBPtr = 0;
102 static wglDestroyPbufferARBProc wglDestroyPbufferARBPtr = 0;
103 /* WGL_ARB_render_texture */
104 static wglBindTexImageARBProc wglBindTexImageARBPtr = 0;
105 static wglReleaseTexImageARBProc wglReleaseTexImageARBPtr = 0;
107 #elif defined( __MACH__ )
109 static bool glXVersion1_3Present = false;
110 static glXChooseFBConfigProc glXChooseFBConfigPtr = 0;
111 static glXCreatePbufferProc glXCreatePbufferPtr = 0;
112 static glXCreateGLXPbufferProc glXCreateGLXPbufferPtr = 0;
113 static glXGetVisualFromFBConfigProc glXGetVisualFromFBConfigPtr = 0;
114 static glXCreateContextProc glXCreateContextPtr = 0;
115 static glXCreateContextWithConfigProc glXCreateContextWithConfigPtr = 0;
116 static glXDestroyPbufferProc glXDestroyPbufferPtr = 0;
117 static glXQueryDrawableProc glXQueryDrawablePtr = 0;
118 static glXQueryGLXPbufferSGIXProc glXQueryGLXPbufferSGIXPtr = 0;
121 //---------------------------------------------------------------------------
122 // Function : RenderTexture::RenderTexture
124 //---------------------------------------------------------------------------
126 * @fn RenderTexture::RenderTexture()
127 * @brief Mode-string-based Constructor.
129 RenderTexture::RenderTexture(const char *strMode)
133 _bIsDepthTexture(false),
134 _bHasARBDepthTexture(true), // [Redge]
135 #if defined(_WIN32) || defined(__MACH__)
136 _eUpdateMode(RT_RENDER_TO_TEXTURE),
138 _eUpdateMode(RT_COPY_TO_TEXTURE),
140 _bInitialized(false),
142 _bIsBufferBound(false),
143 _iCurrentBoundBuffer(0),
147 _bDoubleBuffered(false),
151 _bShareObjects(false),
152 _bCopyContext(false),
158 _hPreviousContext(0),
159 #elif defined( __MACH__ )
162 _hPreviousContext(NULL),
167 _hPreviousDrawable(0),
168 _hPreviousContext(0),
170 _iTextureTarget(GL_NONE),
173 _pPoorDepthTexture(0) // [Redge]
175 dbg_printf("RenderTexture::RenderTexture(%s) BGN instantiation.\n", strMode );
176 _iNumColorBits[0] = _iNumColorBits[1] =
177 _iNumColorBits[2] = _iNumColorBits[3] = 0;
180 dbg_printf("RenderTexture::RenderTexture in _WIN32.\n" );
181 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
182 _pixelFormatAttribs.push_back(true);
183 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
184 _pixelFormatAttribs.push_back(true);
186 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
187 _pbufferAttribs.push_back(true);
188 #elif defined( __MACH__ )
189 dbg_printf("RenderTexture::RenderTexture in __MACH__.\n" );
190 //_pixelFormatAttribs.push_back(kCGLPFANoRecovery);
191 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
192 _pixelFormatAttribs.push_back(kCGLPFAWindow);
193 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
195 dbg_printf("RenderTexture::RenderTexture !_WIN32 and !__MACH__.\n" );
196 _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
197 _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
198 _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
199 _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
202 _ParseModeString(strMode, _pixelFormatAttribs, _pbufferAttribs);
205 _pixelFormatAttribs.push_back(0);
206 _pbufferAttribs.push_back(0);
207 #elif defined(__MACH__)
208 _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
209 _pbufferAttribs.push_back((CGLPixelFormatAttribute)0);
211 _pixelFormatAttribs.push_back(None);
214 dbg_printf("RenderTexture::RenderTexture(%s) END instantiation. pf=%d pb=%d\n",
215 strMode, _pixelFormatAttribs.size(), _pbufferAttribs.size() );
220 //---------------------------------------------------------------------------
221 // Function : RenderTexture::~RenderTexture
223 //---------------------------------------------------------------------------
225 * @fn RenderTexture::~RenderTexture()
228 RenderTexture::~RenderTexture()
230 dbg_printf("RenderTexture::~RenderTexture: destructor.\n" );
234 //---------------------------------------------------------------------------
235 // Function : _cglcheckError
237 //---------------------------------------------------------------------------
239 * @fn _cglCheckError()
240 * @brief Prints to stderr a description when an OS X error is found.
243 static void _cglCheckErrorHelper(CGLError err, char *sourceFile, int sourceLine)
248 fprintf(stderr, "RenderTexture CGL Error: %s at (%s,%d)",
249 CGLErrorString(err), sourceFile, sourceLine);
254 # define _cglCheckError(err) _cglCheckErrorHelper(err,__FILE__,__LINE__)
259 //---------------------------------------------------------------------------
260 // Function : _wglGetLastError
262 //---------------------------------------------------------------------------
264 * @fn wglGetLastError()
265 * @brief Returns the last windows error generated.
268 void _wglGetLastError()
272 DWORD err = GetLastError();
275 case ERROR_INVALID_PIXEL_FORMAT:
276 SG_LOG(SG_GL, SG_ALERT,
277 "RenderTexture Win32 Error: ERROR_INVALID_PIXEL_FORMAT");
279 case ERROR_NO_SYSTEM_RESOURCES:
280 SG_LOG(SG_GL, SG_ALERT,
281 "RenderTexture Win32 Error: ERROR_NO_SYSTEM_RESOURCES");
283 case ERROR_INVALID_DATA:
284 SG_LOG(SG_GL, SG_ALERT,
285 "RenderTexture Win32 Error: ERROR_INVALID_DATA");
287 case ERROR_INVALID_WINDOW_HANDLE:
288 SG_LOG(SG_GL, SG_ALERT,
289 "RenderTexture Win32 Error: ERROR_INVALID_WINDOW_HANDLE");
291 case ERROR_RESOURCE_TYPE_NOT_FOUND:
292 SG_LOG(SG_GL, SG_ALERT,
293 "RenderTexture Win32 Error: ERROR_RESOURCE_TYPE_NOT_FOUND");
300 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
301 FORMAT_MESSAGE_FROM_SYSTEM |
302 FORMAT_MESSAGE_IGNORE_INSERTS,
305 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
310 SG_LOG(SG_GL, SG_ALERT, "RenderTexture Win32 Error " << err << ":" << lpMsgBuf);
311 LocalFree( lpMsgBuf );
320 //---------------------------------------------------------------------------
321 // Function : PrintExtensionError
323 //---------------------------------------------------------------------------
325 * @fn PrintExtensionError( char* strMsg, ... )
326 * @brief Prints an error about missing OpenGL extensions.
328 void PrintExtensionError( const char* strMsg, ... )
330 SG_LOG(SG_GL, SG_ALERT,
331 "Error: RenderTexture requires the following unsupported "
332 "OpenGL extensions: ");
335 va_start(args, strMsg);
336 #if defined _WIN32 && !defined __CYGWIN__
337 _vsnprintf( strBuffer, 512, strMsg, args );
339 vsnprintf( strBuffer, 512, strMsg, args );
343 SG_LOG(SG_GL, SG_ALERT, strMsg);
344 dbg_printf("Error: RenderTexture requires the following unsupported OpenGL extensions: \n[%s]\n", strMsg);
347 //---------------------------------------------------------------------------
348 // Function : RenderTexture::Initialize
350 //---------------------------------------------------------------------------
352 * @fn RenderTexture::Initialize(int width, int height, bool shareObjects, bool copyContext);
353 * @brief Initializes the RenderTexture, sharing display lists and textures if specified.
355 * This function creates of the p-buffer. It can only be called once a GL
356 * context has already been created.
358 bool RenderTexture::Initialize(int width, int height,
359 bool shareObjects /* = true */,
360 bool copyContext /* = false */)
362 assert(width > 0 && height > 0);
364 dbg_printf("RenderTexture::Initialize w=%d h=%d\n", width, height );
366 _iWidth = width; _iHeight = height;
367 _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
369 _bShareObjects = shareObjects;
370 _bCopyContext = copyContext;
372 // Check if this is an NVXX GPU and verify necessary extensions.
373 if (!_VerifyExtensions()) {
374 dbg_printf("RenderTexture::Initialize: _VerifyExtensions() FAILED - returning false.\n" );
382 // Get the current context.
383 HDC hdc = wglGetCurrentDC();
386 HGLRC hglrc = wglGetCurrentContext();
391 unsigned int iNumFormats;
395 // Get the pixel format for the on-screen window.
396 iFormat = GetPixelFormat(hdc);
399 SG_LOG(SG_GL, SG_ALERT,
400 "RenderTexture Error: GetPixelFormat() failed.");
406 if (!wglChoosePixelFormatARBPtr(hdc, &_pixelFormatAttribs[0], NULL,
407 1, &iFormat, &iNumFormats))
409 SG_LOG(SG_GL, SG_ALERT,
410 "RenderTexture Error: wglChoosePixelFormatARB() failed.");
414 if ( iNumFormats <= 0 )
416 SG_LOG(SG_GL, SG_ALERT,
417 "RenderTexture Error: Couldn't find a suitable "
424 // Create the p-buffer.
425 _hPBuffer = wglCreatePbufferARBPtr(hdc, iFormat, _iWidth, _iHeight,
426 &_pbufferAttribs[0]);
429 SG_LOG(SG_GL, SG_ALERT,
430 "RenderTexture Error: wglCreatePbufferARB() failed.");
435 // Get the device context.
436 _hDC = wglGetPbufferDCARBPtr( _hPBuffer);
439 SG_LOG(SG_GL, SG_ALERT,
440 "RenderTexture Error: wglGetGetPbufferDCARB() failed.");
445 // Create a gl context for the p-buffer.
448 // Let's use the same gl context..
449 // Since the device contexts are compatible (i.e. same pixelformat),
450 // we should be able to use the same gl rendering context.
455 _hGLContext = wglCreateContext( _hDC );
458 SG_LOG(SG_GL, SG_ALERT,
459 "RenderTexture Error: wglCreateContext() failed.");
465 // Share lists, texture objects, and program objects.
468 if( !wglShareLists(hglrc, _hGLContext) )
470 SG_LOG(SG_GL, SG_ALERT,
471 "RenderTexture Error: wglShareLists() failed.");
477 // Determine the actual width and height we were able to create.
478 wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
479 wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
481 _bInitialized = true;
483 // get the actual number of bits allocated:
484 int attrib = WGL_RED_BITS_ARB;
488 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
490 attrib = WGL_GREEN_BITS_ARB;
492 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
494 attrib = WGL_BLUE_BITS_ARB;
496 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
498 attrib = WGL_ALPHA_BITS_ARB;
500 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
502 attrib = WGL_DEPTH_BITS_ARB;
504 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
506 attrib = WGL_STENCIL_BITS_ARB;
508 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
510 attrib = WGL_DOUBLE_BUFFER_ARB;
512 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
513 ? (value?true:false) : false;
515 #if defined(_DEBUG) | defined(DEBUG)
516 SG_LOG(SG_GL, SG_ALERT, "Created a " << _iWidth << "x" << _iHeight <<
517 " RenderTexture with BPP(" <<
518 _iNumColorBits[0] << "," << _iNumColorBits[1] << "," <<
519 _iNumColorBits[2] << "," << _iNumColorBits[3] << ")");
520 if (_iNumDepthBits) SG_LOG(SG_GL, SG_ALERT, " depth=" << _iNumDepthBits);
521 if (_iNumStencilBits) SG_LOG(SG_GL, SG_ALERT, " stencil=" << _iNumStencilBits);
522 if (_bDoubleBuffered) SG_LOG(SG_GL, SG_ALERT, " double buffered");
525 #elif defined( __MACH__ )
526 // Get the current context.
527 CGLContextObj hglrc = CGLGetCurrentContext();
529 fprintf(stderr, "Couldn't get current context!");
531 CGLPixelFormatObj pixFormat = NULL;
535 // Copy the _pixelFormatAttribs into another array to fix
537 CGLPixelFormatAttribute *pixFormatAttribs =
538 (CGLPixelFormatAttribute *)malloc(sizeof(CGLPixelFormatAttribute)
539 * _pixelFormatAttribs.size());
541 for (unsigned int ii = 0; ii < _pixelFormatAttribs.size(); ii++)
543 pixFormatAttribs[ii] =
544 (CGLPixelFormatAttribute)_pixelFormatAttribs[ii];
548 CGLChoosePixelFormat(&pixFormatAttribs[0], &pixFormat, &iNumFormats))
551 "RenderTexture Error: CGLChoosePixelFormat() failed.\n");
552 _cglCheckError(error);
555 if ( iNumFormats <= 0 )
557 SG_LOG(SG_GL, SG_ALERT,
558 "RenderTexture Error: Couldn't find a suitable "
563 // Free the copy of the _pixelFormatAttribs array
564 free(pixFormatAttribs);
566 // Create the context.
567 error = CGLCreateContext(pixFormat, (_bShareObjects)
568 ? CGLGetCurrentContext() : NULL, &_hGLContext);
572 "RenderTexture Error: CGLCreateContext() failed.\n");
573 _cglCheckError(error);
576 CGLDestroyPixelFormat(pixFormat);
578 // Create the p-buffer.
579 error = CGLCreatePBuffer(_iWidth, _iHeight, (_bRectangle)
580 ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D, GL_RGBA, 0, &_hPBuffer);
584 "RenderTexture Error: CGLCreatePBuffer() failed.\n");
585 _cglCheckError(error);
590 if (error = CGLGetVirtualScreen(CGLGetCurrentContext(), &screen))
592 _cglCheckError(error);
595 if (error = CGLSetPBuffer(_hGLContext, _hPBuffer, 0, 0, screen))
597 _cglCheckError(error);
601 // Determine the actual width and height we were able to create.
602 //wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
603 //wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
605 _bInitialized = true;
608 // get the actual number of bits allocated:
609 int attrib = WGL_RED_BITS_ARB;
613 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
615 attrib = WGL_GREEN_BITS_ARB;
617 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
619 attrib = WGL_BLUE_BITS_ARB;
621 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
623 attrib = WGL_ALPHA_BITS_ARB;
625 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
627 attrib = WGL_DEPTH_BITS_ARB;
629 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
631 attrib = WGL_STENCIL_BITS_ARB;
633 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
635 attrib = WGL_DOUBLE_BUFFER_ARB;
637 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
638 ? (value?true:false) : false;
641 #if defined(_DEBUG) | defined(DEBUG)
642 fprintf(stderr, "Created a %dx%d RenderTexture with BPP(%d, %d, %d, %d)",
644 _iNumColorBits[0], _iNumColorBits[1],
645 _iNumColorBits[2], _iNumColorBits[3]);
646 if (_iNumDepthBits) fprintf(stderr, " depth=%d", _iNumDepthBits);
647 if (_iNumStencilBits) fprintf(stderr, " stencil=%d", _iNumStencilBits);
648 if (_bDoubleBuffered) fprintf(stderr, " double buffered");
649 fprintf(stderr, "\n");
652 #else // !_WIN32, !__MACH_
654 _pDisplay = glXGetCurrentDisplay();
656 dbg_printf("RenderTexture::Initialize: ERROR: glXGetCurrentDisplay() returned NULL! return false\n");
659 dbg_printf("RenderTexture::Initialize: got glXGetCurrentDisplay() _pDisplay=[%p]\n", _pDisplay);
660 // glXGetCurrentContext returns the current context, as specified by glXMakeCurrent.
661 // If there is no current context, NULL is returned.
662 GLXContext context = glXGetCurrentContext();
664 dbg_printf("RenderTexture::Initialize: ERROR: glXGetCurrentContext() returned NULL! return false\n");
667 dbg_printf("RenderTexture::Initialize: got glXGetCurrentContext() context=[%p]\n", context);
668 int screen = DefaultScreen(_pDisplay);
669 dbg_printf("RenderTexture::Initialize: DefaultScreen(_pDisplay) screen=%d\n", screen);
671 XVisualInfo *visInfo = NULL;
673 GLXFBConfig *fbConfigs;
676 dbg_printf("Using %d pixelFormatAttribs array\n", _pixelFormatAttribs.size());
677 size_t max = _pixelFormatAttribs.size() / 2;
680 for (n = 0; n < max; n++) {
681 const char * cp = get_attr_name(_pixelFormatAttribs[n*2], &dat);
682 printf( "%s(%d) = %d (def=%d)\n",
683 cp, _pixelFormatAttribs[n*2], _pixelFormatAttribs[(n*2)+1], dat );
686 if ( n < _pixelFormatAttribs.size() )
687 printf( "Array ends with %d\n", _pixelFormatAttribs[n] );
689 printf( "WARNING: Array does not appear ODD! which is ODD\n" );
692 fbConfigs = glXChooseFBConfigPtr(_pDisplay, screen,
693 &_pixelFormatAttribs[0], &nConfigs);
694 // NOTE: ref: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseFBConfig.xml says
695 // Next, call glXGetFBConfigAttrib to retrieve additional attributes for the frame buffer configurations and then select between them.
697 if (nConfigs <= 0 || !fbConfigs)
699 SG_LOG(SG_GL, SG_ALERT,
700 "RenderTexture Error: Couldn't find a suitable pixel format.");
701 dbg_printf("RenderTexture Error: Couldn't find a suitable pixel format. return false\n");
705 dbg_printf("RenderTexture::Initialize: glXChooseFBConfigPtr() nConfigs = %d, fbConfigs=[%p]\n", nConfigs, fbConfigs);
708 GLX_PBUFFER_WIDTH, _iWidth,
709 GLX_PBUFFER_HEIGHT, _iHeight,
710 GLX_LARGEST_PBUFFER, False,
713 // Pick the first returned format that will return a pbuffer
714 // if (glXVersion1_3Present)
715 if (glXCreatePbufferPtr && glXGetVisualFromFBConfigPtr && glXCreateContextPtr)
717 dbg_printf("RenderTexture::Initialize: glXVersion1_3Present = TRUE\n");
718 for (int i=0;i<nConfigs;i++)
720 _hPBuffer = glXCreatePbufferPtr(_pDisplay, fbConfigs[i], pbufAttrib);
723 XVisualInfo *visInfo = glXGetVisualFromFBConfigPtr(_pDisplay, fbConfigs[i]);
725 _hGLContext = glXCreateContextPtr(_pDisplay, visInfo,
726 _bShareObjects ? context : NULL,
730 dbg_printf("RenderTexture Error: glXCreateContextPtr(_pDisplay, visInfo,..) FAILED! return false\n");
745 dbg_printf("RenderTexture::Initialize: glXVersion1_3Present = FALSE w=%d h=%d\n", _iWidth, _iHeight);
746 for (int i=0; i < nConfigs; i++)
748 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() get buffer ptr\n", (i + 1));
749 _hPBuffer = glXCreateGLXPbufferPtr(_pDisplay, fbConfigs[i],
751 &pbufAttrib[0] ); //NULL);
754 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() got buffer [%p]\n", (i + 1), _hPBuffer);
755 _hGLContext = glXCreateContextWithConfigPtr(_pDisplay,
758 _bShareObjects ? context : NULL,
760 dbg_printf("RenderTexture::Initialize: %d: glXCreateContextWithConfigPtr() _hGLContext=[%p]\n", (i + 1), _hGLContext);
763 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() NO buffer\n", (i + 1));
768 dbg_printf("RenderTexture::Initialize: doing XFree( fbConfigs=[%p].\n", fbConfigs);
773 SG_LOG(SG_GL, SG_ALERT,
774 "RenderTexture Error: glXCreateGLXPbufferPtr() failed.");
775 dbg_printf("RenderTexture Error: glXCreateGLXPbufferPtr() failed.\n");
782 _hGLContext = glXCreateContext(_pDisplay, visInfo,
783 _bShareObjects ? context : NULL, False);
786 SG_LOG(SG_GL, SG_ALERT,
787 "RenderTexture Error: glXCreateContext() failed.");
788 dbg_printf("RenderTexture Error: glXCreateContext() failed. return false\n");
793 // if (!glXVersion1_3Present)
794 if ((!glXCreatePbufferPtr || !glXGetVisualFromFBConfigPtr || !glXCreateContextPtr) &&
795 (!glXVersion1_3Present))
797 #ifdef ADD_QUERY_BUFFER
798 dbg_printf("RenderTexture::Initialize: Doing glXQueryGLXPbufferSGIXPtr with GLX_WIDTH_SGIX\n");
799 glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_WIDTH_SGIX,
801 dbg_printf("RenderTexture::Initialize: Doing glXQueryGLXPbufferSGIXPtr with GLX_HEIGHT_SGIX\n");
802 glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_HEIGHT_SGIX,
805 dbg_printf("RenderTexture::Initialize: SKIPPED doing glXQueryGLXPbufferSGIXPtr with GLX_WIDTH_SGIX and GLX_HEIGHT_SGIX\n");
806 #endif // #ifdef ADD_QUERY_BUFFER
809 _bInitialized = true;
810 dbg_printf( "RenderTexture::Initialize: _bIniialized set TRUE\n" );
811 // XXX Query the color format
816 // Now that the pbuffer is created, allocate any texture objects needed,
817 // and initialize them (for CTT updates only). These must be allocated
818 // in the context of the pbuffer, though, or the RT won't work without
821 if (false == wglMakeCurrent( _hDC, _hGLContext))
826 #elif defined( __MACH__ )
828 if (err = CGLSetCurrentContext(_hGLContext))
835 #ifdef ADD_GET_DRAWABLE
836 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentContext()\n" );
837 _hPreviousContext = glXGetCurrentContext();
838 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentDrawable()\n" );
839 _hPreviousDrawable = glXGetCurrentDrawable();
841 _hPreviousContext = context;
842 _hPreviousDrawable = 0;
843 dbg_printf( "RenderTexture::Initialize: SKIPPED doing glXGetCurrentContext(2nd) AND glXGetCurrentDrawable()\n" );
844 #endif // #ifdef ADD_GET_DRAWABLE
846 dbg_printf( "RenderTexture::Initialize: doing glXMakeCurrent(_pDisplay(%p), _hPBuffer(%p), _hGLContext(%p))\n",
847 _pDisplay, _hPBuffer, _hGLContext );
848 if (False == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
850 dbg_printf( "glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext) FAILED. return false\n" );
856 bool result = _InitializeTextures();
858 BindBuffer(WGL_FRONT_LEFT_ARB);
864 // make the previous rendering context current
865 if (false == wglMakeCurrent( hdc, hglrc))
870 #elif defined( __MACH__ )
871 if (err = CGLSetCurrentContext(_hPreviousContext))
877 if (False == glXMakeCurrent(_pDisplay,
878 _hPreviousDrawable, _hPreviousContext))
880 dbg_printf("glXMakeCurrent(_pDisplay, _hPreviousDrawable, _hPreviousContext)) FAILED! return false\n" );
884 if (glXVersion1_3Present)
885 //if ((glXVersion1_3Present) ||
886 // (glXCreatePbufferPtr && glXGetVisualFromFBConfigPtr && glXCreateContextPtr && glXQueryDrawablePtr))
888 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentDrawable()\n" );
889 GLXDrawable draw = glXGetCurrentDrawable();
890 dbg_printf( "RenderTexture::Initialize: doing glXQueryDrawablePtr for GLX_WIDTH and GLX_HEIGHT\n" );
891 glXQueryDrawablePtr(_pDisplay, draw, GLX_WIDTH, (unsigned int*)&_iWidth);
892 glXQueryDrawablePtr(_pDisplay, draw, GLX_HEIGHT, (unsigned int*)&_iHeight);
896 dbg_printf( "RenderTexture::Initialize(w=%d,h=%d): returning %s\n", _iWidth, _iHeight, (result ? "TRUE" : "FALSE") );
901 //---------------------------------------------------------------------------
902 // Function : RenderTexture::_Invalidate
904 //---------------------------------------------------------------------------
906 * @fn RenderTexture::_Invalidate()
907 * @brief Returns the pbuffer memory to the graphics device.
910 bool RenderTexture::_Invalidate()
912 dbg_printf( "RenderTexture::_Invalidate() called...\n" );
914 _iNumColorBits[0] = _iNumColorBits[1] =
915 _iNumColorBits[2] = _iNumColorBits[3] = 0;
917 _iNumStencilBits = 0;
920 glDeleteTextures(1, &_iTextureID);
921 if (_bIsDepthTexture)
924 if (!_bHasARBDepthTexture) delete[] _pPoorDepthTexture;
926 glDeleteTextures(1, &_iDepthTextureID);
932 // Check if we are currently rendering in the pbuffer
933 if (wglGetCurrentContext() == _hGLContext)
936 wglDeleteContext( _hGLContext);
937 wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
938 wglDestroyPbufferARBPtr( _hPBuffer );
942 #elif defined( __MACH__ )
945 if (CGLGetCurrentContext() == _hGLContext)
946 CGLSetCurrentContext(NULL);
948 CGLDestroyContext(_hGLContext);
949 CGLDestroyPBuffer(_hPBuffer);
956 if(glXGetCurrentContext() == _hGLContext)
957 // XXX I don't know if this is right at all
958 glXMakeCurrent(_pDisplay, _hPBuffer, 0);
959 glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
961 dbg_printf( "RenderTexture::_Invalidate: glXDestroyPbufferPtr(_pDisplay, _hPBuffer); return true\n" );
966 dbg_printf( "RenderTexture::_Invalidate: return false\n" );
967 // [WVB] do we need to call _ReleaseBoundBuffers() too?
972 //---------------------------------------------------------------------------
973 // Function : RenderTexture::Reset
975 //---------------------------------------------------------------------------
977 * @fn RenderTexture::Reset()
978 * @brief Resets the resolution of the offscreen buffer.
980 * Causes the buffer to delete itself. User must call Initialize() again
983 bool RenderTexture::Reset(const char *strMode, ...)
985 dbg_printf("RenderTexure:Reset(): with %s\n", strMode);
987 _iWidth = 0; _iHeight = 0;
988 _bIsTexture = false; _bIsDepthTexture = false,
989 _bHasARBDepthTexture = true;
990 #if defined(_WIN32) || defined(__MACH__)
991 _eUpdateMode = RT_RENDER_TO_TEXTURE;
993 _eUpdateMode = RT_COPY_TO_TEXTURE;
995 _bInitialized = false;
997 _bIsBufferBound = false;
998 _iCurrentBoundBuffer = 0;
999 _iNumDepthBits = 0; _iNumStencilBits = 0;
1000 _bDoubleBuffered = false;
1001 _bFloat = false; _bPowerOf2 = true;
1002 _bRectangle = false; _bMipmap = false;
1003 _bShareObjects = false; _bCopyContext = false;
1004 _iTextureTarget = GL_NONE; _iTextureID = 0;
1005 _iDepthTextureID = 0;
1006 _pPoorDepthTexture = 0;
1007 _pixelFormatAttribs.clear();
1008 _pbufferAttribs.clear();
1009 if (IsInitialized())
1013 dbg_printf( "RenderTexture::Reset(): failed to invalidate. return false\n");
1018 dbg_printf( "RenderTexture::Reset(): was Initialized, and now _Invalidate() ok.");
1023 dbg_printf("RenderTexure:Reset(): previous NOT initialised!\n");
1026 _iNumColorBits[0] = _iNumColorBits[1] =
1027 _iNumColorBits[2] = _iNumColorBits[3] = 0;
1030 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
1031 _pixelFormatAttribs.push_back(true);
1032 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
1033 _pixelFormatAttribs.push_back(true);
1035 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
1036 _pbufferAttribs.push_back(true);
1037 #elif defined( __MACH__ )
1038 //_pixelFormatAttribs.push_back(kCGLPFANoRecovery);
1039 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
1040 _pixelFormatAttribs.push_back(kCGLPFAWindow);
1041 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
1043 _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
1044 _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
1045 _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
1046 _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
1050 char strBuffer[256];
1051 va_start(args,strMode);
1052 #if defined _WIN32 && !defined __CYGWIN__
1053 _vsnprintf( strBuffer, 256, strMode, args );
1055 vsnprintf( strBuffer, 256, strMode, args );
1059 _ParseModeString(strBuffer, _pixelFormatAttribs, _pbufferAttribs);
1062 _pixelFormatAttribs.push_back(0);
1063 _pbufferAttribs.push_back(0);
1064 #elif defined(__MACH__)
1065 _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
1067 _pixelFormatAttribs.push_back(None);
1069 dbg_printf("RenderTexure:Reset(): returning true.\n");
1073 //------------------------------------------------------------------------------
1074 // Function : RenderTexture::Resize
1076 //------------------------------------------------------------------------------
1078 * @fn RenderTexture::Resize(int iWidth, int iHeight)
1079 * @brief Changes the size of the offscreen buffer.
1081 * Like Reset() this causes the buffer to delete itself.
1082 * But unlike Reset(), this call re-initializes the RenderTexture.
1083 * Note that Resize() will not work after calling Reset(), or before
1084 * calling Initialize() the first time.
1086 bool RenderTexture::Resize(int iWidth, int iHeight)
1088 if (!_bInitialized) {
1089 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Resize(): must Initialize() first.");
1092 if (iWidth == _iWidth && iHeight == _iHeight) {
1096 // Do same basic work as _Invalidate, but don't reset all our flags
1098 glDeleteTextures(1, &_iTextureID);
1099 if (_bIsDepthTexture)
1100 glDeleteTextures(1, &_iDepthTextureID);
1104 // Check if we are currently rendering in the pbuffer
1105 if (wglGetCurrentContext() == _hGLContext)
1106 wglMakeCurrent(0,0);
1108 wglDeleteContext( _hGLContext);
1109 wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
1110 wglDestroyPbufferARBPtr( _hPBuffer );
1114 #elif defined( __MACH__ )
1117 if (CGLGetCurrentContext() == _hGLContext)
1118 CGLSetCurrentContext(NULL);
1120 CGLDestroyContext(_hGLContext);
1121 CGLDestroyPBuffer(_hPBuffer);
1128 if(glXGetCurrentContext() == _hGLContext)
1129 // XXX I don't know if this is right at all
1130 glXMakeCurrent(_pDisplay, _hPBuffer, 0);
1131 glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
1136 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Resize(): failed to resize.");
1139 _bInitialized = false;
1140 return Initialize(iWidth, iHeight, _bShareObjects, _bCopyContext);
1143 //---------------------------------------------------------------------------
1144 // Function : RenderTexture::BeginCapture
1146 //---------------------------------------------------------------------------
1148 * @fn RenderTexture::BeginCapture()
1149 * @brief Activates rendering to the RenderTexture.
1151 bool RenderTexture::BeginCapture()
1155 SG_LOG(SG_GL, SG_ALERT,
1156 "RenderTexture::BeginCapture(): Texture is not initialized!");
1160 // cache the current context so we can reset it when EndCapture() is called.
1161 _hPreviousDC = wglGetCurrentDC();
1162 if (NULL == _hPreviousDC)
1164 _hPreviousContext = wglGetCurrentContext();
1165 if (NULL == _hPreviousContext)
1167 #elif defined( __MACH__ )
1168 _hPreviousContext = CGLGetCurrentContext();
1170 _hPreviousContext = glXGetCurrentContext();
1171 _hPreviousDrawable = glXGetCurrentDrawable();
1174 _ReleaseBoundBuffers();
1176 return _MakeCurrent();
1180 //---------------------------------------------------------------------------
1181 // Function : RenderTexture::EndCapture
1183 //---------------------------------------------------------------------------
1185 * @fn RenderTexture::EndCapture()
1186 * @brief Ends rendering to the RenderTexture.
1188 bool RenderTexture::EndCapture()
1192 SG_LOG(SG_GL, SG_ALERT,
1193 "RenderTexture::EndCapture() : Texture is not initialized!");
1197 glFlush(); // Added by a-lex
1202 // make the previous rendering context current
1203 if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
1208 #elif defined( __MACH__ )
1210 if (err = CGLSetCurrentContext(_hPreviousContext))
1212 _cglCheckError(err);
1216 if (False == glXMakeCurrent(_pDisplay, _hPreviousDrawable,
1223 // rebind the textures to a buffers for RTT
1224 BindBuffer(_iCurrentBoundBuffer);
1230 //---------------------------------------------------------------------------
1231 // Function : RenderTexture::BeginCapture(RenderTexture*)
1233 //---------------------------------------------------------------------------
1235 * @fn RenderTexture::BeginCapture(RenderTexture* other)
1236 * @brief Ends capture of 'other', begins capture on 'this'
1238 * When performing a series of operations where you modify one texture after
1239 * another, it is more efficient to use this method instead of the equivalent
1240 * 'EndCapture'/'BeginCapture' pair. This method switches directly to the
1241 * new context rather than changing to the default context, and then to the
1244 * RenderTexture doesn't have any mechanism for determining if
1245 * 'current' really is currently active, so no error will be thrown
1248 bool RenderTexture::BeginCapture(RenderTexture* current)
1250 // bool bContextReset = false;
1252 if (current == this) {
1253 return true; // no switch necessary
1256 // treat as normal Begin if current is 0.
1257 return BeginCapture();
1261 SG_LOG(SG_GL, SG_ALERT,
1262 "RenderTexture::BeginCapture(RenderTexture*): Texture is not initialized!");
1265 if (!current->_bInitialized)
1267 SG_LOG(SG_GL, SG_ALERT,
1268 "RenderTexture::BeginCapture(RenderTexture): 'current' texture is not initialized!");
1272 // Sync current pbuffer with its CTT texture if necessary
1273 current->_MaybeCopyBuffer();
1275 // pass along the previous context so we can reset it when
1276 // EndCapture() is called.
1278 _hPreviousDC = current->_hPreviousDC;
1279 if (NULL == _hPreviousDC)
1281 _hPreviousContext = current->_hPreviousContext;
1282 if (NULL == _hPreviousContext)
1284 #elif defined( __MACH__ )
1285 _hPreviousContext = current->_hPreviousContext;
1287 _hPreviousContext = current->_hPreviousContext;
1288 _hPreviousDrawable = current->_hPreviousDrawable;
1291 // Unbind textures before making context current
1292 if (!_ReleaseBoundBuffers())
1295 // Make the pbuffer context current
1296 if (!_MakeCurrent())
1299 // Rebind buffers of initial RenderTexture
1300 current->BindBuffer(_iCurrentBoundBuffer);
1301 current->_BindDepthBuffer();
1308 //---------------------------------------------------------------------------
1309 // Function : RenderTexture::Bind
1311 //---------------------------------------------------------------------------
1313 * @fn RenderTexture::Bind()
1314 * @brief Binds RGB texture.
1316 void RenderTexture::Bind() const
1318 if (_bInitialized && _bIsTexture)
1320 glBindTexture(_iTextureTarget, _iTextureID);
1325 //---------------------------------------------------------------------------
1326 // Function : RenderTexture::BindDepth
1328 //---------------------------------------------------------------------------
1330 * @fn RenderTexture::BindDepth()
1331 * @brief Binds depth texture.
1333 void RenderTexture::BindDepth() const
1335 if (_bInitialized && _bIsDepthTexture)
1337 glBindTexture(_iTextureTarget, _iDepthTextureID);
1342 //---------------------------------------------------------------------------
1343 // Function : RenderTexture::BindBuffer
1345 //---------------------------------------------------------------------------
1347 * @fn RenderTexture::BindBuffer()
1348 * @brief Associate the RTT texture id with 'iBuffer' (e.g. WGL_FRONT_LEFT_ARB)
1350 bool RenderTexture::BindBuffer( int iBuffer )
1352 // Must bind the texture too
1353 if (_bInitialized && _bIsTexture)
1355 glBindTexture(_iTextureTarget, _iTextureID);
1358 if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
1359 (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
1361 if (FALSE == wglBindTexImageARBPtr(_hPBuffer, iBuffer))
1363 // WVB: WGL API considers binding twice to the same buffer
1364 // to be an error. But we don't want to
1365 //_wglGetLastError();
1369 _bIsBufferBound = true;
1370 _iCurrentBoundBuffer = iBuffer;
1372 #elif defined(__MACH__)
1373 if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
1374 (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
1377 if (err=CGLTexImagePBuffer(CGLGetCurrentContext(), _hPBuffer, iBuffer))
1379 _cglCheckError(err);
1381 _bIsBufferBound = true;
1382 _iCurrentBoundBuffer = iBuffer;
1390 //---------------------------------------------------------------------------
1391 // Function : RenderTexture::BindDepthBuffer
1393 //---------------------------------------------------------------------------
1395 * @fn RenderTexture::_BindDepthBuffer()
1396 * @brief Associate the RTT depth texture id with the depth buffer
1398 bool RenderTexture::_BindDepthBuffer() const
1401 if (_bInitialized && _bIsDepthTexture &&
1402 RT_RENDER_TO_TEXTURE == _eUpdateMode)
1404 glBindTexture(_iTextureTarget, _iDepthTextureID);
1405 if (FALSE == wglBindTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
1411 #elif defined(__MACH__)
1412 if (_bInitialized && _bIsDepthTexture &&
1413 RT_RENDER_TO_TEXTURE == _eUpdateMode)
1415 glBindTexture(_iTextureTarget, _iDepthTextureID);
1416 //if (FALSE == CGLTexImagePBuffer(<#CGLContextObj ctx#>,<#CGLPBufferObj pbuffer#>,<#unsigned long source#>)(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
1418 // _wglGetLastError();
1426 //---------------------------------------------------------------------------
1427 // Function : RenderTexture::_ParseModeString
1429 //---------------------------------------------------------------------------
1431 * @fn RenderTexture::_ParseModeString()
1432 * @brief Parses the user-specified mode string for RenderTexture parameters.
1434 void RenderTexture::_ParseModeString(const char *modeString,
1435 vector<int> &pfAttribs,
1436 vector<int> &pbAttribs)
1438 dbg_printf("RenderTexture::_ParseModeString(%s). BGN vf=%d vp=%d\n", modeString, pfAttribs.size(), pbAttribs.size() );
1439 if (!modeString || strcmp(modeString, "") == 0)
1442 _iNumComponents = 0;
1443 #if defined(_WIN32) || defined(__MACH__)
1444 _eUpdateMode = RT_RENDER_TO_TEXTURE;
1446 _eUpdateMode = RT_COPY_TO_TEXTURE;
1450 bool bHasStencil = false;
1451 bool bBind2D = false;
1452 bool bBindRECT = false;
1453 bool bBindCUBE = false;
1455 char *mode = strdup(modeString);
1458 vector<string> tokens;
1459 char *buf = strtok(mode, " ");
1462 tokens.push_back(buf);
1463 buf = strtok(NULL, " ");
1466 for (unsigned int i = 0; i < tokens.size(); i++)
1468 string token = tokens[i];
1470 KeyVal kv = _GetKeyValuePair(token);
1473 if (kv.first == "rgb" && (_iNumComponents <= 1))
1475 if (kv.second.find("f") != kv.second.npos)
1478 vector<int> bitVec = _ParseBitVector(kv.second);
1480 if (bitVec.size() < 3) // expand the scalar to a vector
1482 bitVec.push_back(bitVec[0]);
1483 bitVec.push_back(bitVec[0]);
1487 pfAttribs.push_back(WGL_RED_BITS_ARB);
1488 pfAttribs.push_back(bitVec[0]);
1489 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1490 pfAttribs.push_back(bitVec[1]);
1491 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
1492 pfAttribs.push_back(bitVec[2]);
1493 #elif defined( __MACH__ )
1495 pfAttribs.push_back(AGL_RED_SIZE);
1496 pfAttribs.push_back(bitVec[0]);
1497 pfAttribs.push_back(AGL_GREEN_SIZE);
1498 pfAttribs.push_back(bitVec[1]);
1499 pfAttribs.push_back(AGL_BLUE_SIZE);
1500 pfAttribs.push_back(bitVec[2]);
1502 pfAttribs.push_back(kCGLPFAColorSize);
1503 pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2]);
1506 pfAttribs.push_back(GLX_RED_SIZE);
1507 pfAttribs.push_back(bitVec[0]);
1508 pfAttribs.push_back(GLX_GREEN_SIZE);
1509 pfAttribs.push_back(bitVec[1]);
1510 pfAttribs.push_back(GLX_BLUE_SIZE);
1511 pfAttribs.push_back(bitVec[2]);
1513 _iNumComponents += 3;
1516 else if (kv.first == "rgb")
1518 SG_LOG(SG_GL, SG_ALERT,
1519 "RenderTexture Warning: mistake in components definition "
1520 "(rgb + " << _iNumComponents << ").");
1521 dbg_printf("RenderTexture Warning 1: mistake in components definition "
1522 "(rgb + %d).\n", _iNumComponents );
1525 if (kv.first == "rgba" && (_iNumComponents == 0))
1527 if (kv.second.find("f") != kv.second.npos)
1530 vector<int> bitVec = _ParseBitVector(kv.second);
1532 if (bitVec.size() < 4) // expand the scalar to a vector
1534 bitVec.push_back(bitVec[0]);
1535 bitVec.push_back(bitVec[0]);
1536 bitVec.push_back(bitVec[0]);
1540 pfAttribs.push_back(WGL_RED_BITS_ARB);
1541 pfAttribs.push_back(bitVec[0]);
1542 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1543 pfAttribs.push_back(bitVec[1]);
1544 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
1545 pfAttribs.push_back(bitVec[2]);
1546 pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
1547 pfAttribs.push_back(bitVec[3]);
1548 #elif defined( __MACH__ )
1550 pfAttribs.push_back(AGL_RED_SIZE);
1551 pfAttribs.push_back(bitVec[0]);
1552 pfAttribs.push_back(AGL_GREEN_SIZE);
1553 pfAttribs.push_back(bitVec[1]);
1554 pfAttribs.push_back(AGL_BLUE_SIZE);
1555 pfAttribs.push_back(bitVec[2]);
1556 pfAttribs.push_back(AGL_ALPHA_SIZE);
1557 pfAttribs.push_back(bitVec[3]);
1559 pfAttribs.push_back(kCGLPFAColorSize);
1560 pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2] + bitVec[3]);
1561 //pfAttribs.push_back(kCGLPFAAlphaSize);
1562 //pfAttribs.push_back(bitVec[3]);
1563 // printf("Color size: %d\n", bitVec[0] + bitVec[1] + bitVec[2] + bitVec[3]);
1567 pfAttribs.push_back(GLX_RED_SIZE);
1568 pfAttribs.push_back(bitVec[0]);
1569 pfAttribs.push_back(GLX_GREEN_SIZE);
1570 pfAttribs.push_back(bitVec[1]);
1571 pfAttribs.push_back(GLX_BLUE_SIZE);
1572 pfAttribs.push_back(bitVec[2]);
1573 pfAttribs.push_back(GLX_ALPHA_SIZE);
1574 pfAttribs.push_back(bitVec[3]);
1576 _iNumComponents = 4;
1579 else if (kv.first == "rgba")
1581 SG_LOG(SG_GL, SG_ALERT,
1582 "RenderTexture Warning: mistake in components definition "
1583 "(rgba + " << _iNumComponents << ").");
1584 dbg_printf("RenderTexture Warning 2: mistake in components definition "
1585 "(rgb + %d).\n", _iNumComponents );
1588 if (kv.first == "r" && (_iNumComponents <= 1))
1590 if (kv.second.find("f") != kv.second.npos)
1593 vector<int> bitVec = _ParseBitVector(kv.second);
1596 pfAttribs.push_back(WGL_RED_BITS_ARB);
1597 pfAttribs.push_back(bitVec[0]);
1598 #elif defined( __MACH__ )
1600 pfAttribs.push_back(AGL_RED_SIZE);
1601 pfAttribs.push_back(bitVec[0]);
1603 pfAttribs.push_back(kCGLPFAColorSize);
1604 pfAttribs.push_back(bitVec[0]);
1607 pfAttribs.push_back(GLX_RED_SIZE);
1608 pfAttribs.push_back(bitVec[0]);
1613 else if (kv.first == "r")
1615 SG_LOG(SG_GL, SG_ALERT,
1616 "RenderTexture Warning: mistake in components definition "
1617 "(r + " << _iNumComponents << ").");
1618 dbg_printf("RenderTexture Warning 3: mistake in components definition "
1619 "(rgb + %d).\n", _iNumComponents );
1621 if (kv.first == "rg" && (_iNumComponents <= 1))
1623 if (kv.second.find("f") != kv.second.npos)
1626 vector<int> bitVec = _ParseBitVector(kv.second);
1628 if (bitVec.size() < 2) // expand the scalar to a vector
1630 bitVec.push_back(bitVec[0]);
1634 pfAttribs.push_back(WGL_RED_BITS_ARB);
1635 pfAttribs.push_back(bitVec[0]);
1636 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1637 pfAttribs.push_back(bitVec[1]);
1638 #elif defined( __MACH__ )
1640 pfAttribs.push_back(AGL_RED_SIZE);
1641 pfAttribs.push_back(bitVec[0]);
1642 pfAttribs.push_back(AGL_GREEN_SIZE);
1643 pfAttribs.push_back(bitVec[1]);
1645 pfAttribs.push_back(kCGLPFAColorSize);
1646 pfAttribs.push_back(bitVec[0] + bitVec[1]);
1649 pfAttribs.push_back(GLX_RED_SIZE);
1650 pfAttribs.push_back(bitVec[0]);
1651 pfAttribs.push_back(GLX_GREEN_SIZE);
1652 pfAttribs.push_back(bitVec[1]);
1654 _iNumComponents += 2;
1657 else if (kv.first == "rg")
1659 SG_LOG(SG_GL, SG_ALERT,
1660 "RenderTexture Warning: mistake in components definition "
1661 "(rg + " << _iNumComponents << ").");
1662 dbg_printf("RenderTexture Warning 4: mistake in components definition "
1663 "(rgb + %d).\n", _iNumComponents );
1666 if (kv.first == "depth")
1668 if (kv.second == "")
1671 iDepthBits = strtol(kv.second.c_str(), 0, 10);
1675 if (kv.first == "stencil")
1679 pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
1680 #elif defined( __MACH__ )
1682 pfAttribs.push_back(AGL_STENCIL_SIZE);
1684 pfAttribs.push_back(kCGLPFAStencilSize);
1687 pfAttribs.push_back(GLX_STENCIL_SIZE);
1689 if (kv.second == "")
1690 pfAttribs.push_back(8);
1692 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1696 if (kv.first == "samples")
1699 pfAttribs.push_back(WGL_SAMPLE_BUFFERS_ARB);
1700 pfAttribs.push_back(1);
1701 pfAttribs.push_back(WGL_SAMPLES_ARB);
1702 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1703 #elif defined( __MACH__ )
1705 pfAttribs.push_back(AGL_SAMPLE_BUFFERS_ARB);
1706 pfAttribs.push_back(1);
1707 pfAttribs.push_back(AGL_SAMPLES_ARB);
1709 pfAttribs.push_back(kCGLPFAMultisample);
1710 pfAttribs.push_back(kCGLPFASamples);
1712 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1714 pfAttribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
1715 pfAttribs.push_back(1);
1716 pfAttribs.push_back(GLX_SAMPLES_ARB);
1717 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1723 if (kv.first == "doublebuffer" || kv.first == "double")
1726 pfAttribs.push_back(WGL_DOUBLE_BUFFER_ARB);
1727 pfAttribs.push_back(true);
1728 #elif defined( __MACH__ )
1730 pfAttribs.push_back(AGL_DOUBLEBUFFER);
1731 pfAttribs.push_back(True);
1733 pfAttribs.push_back(kCGLPFADoubleBuffer);
1736 pfAttribs.push_back(GLX_DOUBLEBUFFER);
1737 pfAttribs.push_back(True);
1742 if (kv.first == "aux")
1745 pfAttribs.push_back(WGL_AUX_BUFFERS_ARB);
1746 #elif defined( __MACH__ )
1748 pfAttribs.push_back(AGL_AUX_BUFFERS);
1750 pfAttribs.push_back(kCGLPFAAuxBuffers);
1753 pfAttribs.push_back(GLX_AUX_BUFFERS);
1755 if (kv.second == "")
1756 pfAttribs.push_back(0);
1758 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1762 if (token.find("tex") == 0)
1766 if ((kv.first == "texRECT") && (GL_NV_texture_rectangle ||
1767 GL_EXT_texture_rectangle))
1772 else if (kv.first == "texCUBE")
1784 if (token.find("depthTex") == 0)
1786 _bIsDepthTexture = true;
1788 if ((kv.first == "depthTexRECT") && (GL_NV_texture_rectangle ||
1789 GL_EXT_texture_rectangle))
1794 else if (kv.first == "depthTexCUBE")
1806 if (kv.first == "mipmap")
1812 if (kv.first == "rtt")
1814 _eUpdateMode = RT_RENDER_TO_TEXTURE;
1818 if (kv.first == "ctt")
1820 _eUpdateMode = RT_COPY_TO_TEXTURE;
1824 SG_LOG(SG_GL, SG_ALERT,
1825 "RenderTexture Error: Unknown pbuffer attribute: " <<
1827 dbg_printf("RenderTexture Error: Uknown pbuffer attribute: %s\n",
1831 // Processing of some options must be last because of interactions.
1833 // Check for inconsistent texture targets
1834 if (_bIsTexture && _bIsDepthTexture && !(bBind2D ^ bBindRECT ^ bBindCUBE))
1836 SG_LOG(SG_GL, SG_ALERT,
1837 "RenderTexture Warning: Depth and Color texture targets "
1839 dbg_printf( "RenderTexture Warning: Depth and Color texture targets should match.\n");
1842 // Apply default bit format if none specified
1844 if (0 == _iNumComponents)
1846 pfAttribs.push_back(WGL_RED_BITS_ARB);
1847 pfAttribs.push_back(8);
1848 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1849 pfAttribs.push_back(8);
1850 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
1851 pfAttribs.push_back(8);
1852 pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
1853 pfAttribs.push_back(8);
1854 _iNumComponents = 4;
1859 if (_bIsDepthTexture && !iDepthBits)
1863 pfAttribs.push_back(WGL_DEPTH_BITS_ARB);
1864 #elif defined( __MACH__ )
1866 pfAttribs.push_back(AGL_DEPTH_SIZE);
1868 pfAttribs.push_back(kCGLPFADepthSize);
1871 pfAttribs.push_back(GLX_DEPTH_SIZE);
1873 pfAttribs.push_back(iDepthBits); // default
1878 pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
1879 pfAttribs.push_back(0);
1880 #elif defined( __MACH__ )
1882 pfAttribs.push_back(AGL_STENCIL_SIZE);
1884 pfAttribs.push_back(kCGLPFAStencilSize);
1886 pfAttribs.push_back(0);
1888 pfAttribs.push_back(GLX_STENCIL_SIZE);
1889 pfAttribs.push_back(0);
1893 if (_iNumComponents < 4)
1895 // Can't do this right now -- on NVIDIA drivers, currently get
1896 // a non-functioning pbuffer if ALPHA_BITS=0 and
1897 // WGL_BIND_TO_TEXTURE_RGB_ARB=true
1899 //pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
1900 //pfAttribs.push_back(0);
1904 if (!WGL_NV_render_depth_texture && _bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1906 #if defined(DEBUG) || defined(_DEBUG)
1907 SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: No support found for "
1908 "render to depth texture.");
1910 dbg_printf("RenderTexture Warning: No support found for render to depth texture.\n");
1911 _bIsDepthTexture = false;
1915 if ((_bIsTexture || _bIsDepthTexture) &&
1916 (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1921 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1922 pbAttribs.push_back(WGL_TEXTURE_RECTANGLE_NV);
1926 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1927 pbAttribs.push_back(WGL_TEXTURE_CUBE_MAP_ARB);
1931 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1932 pbAttribs.push_back(WGL_TEXTURE_2D_ARB);
1937 pbAttribs.push_back(WGL_MIPMAP_TEXTURE_ARB);
1938 pbAttribs.push_back(true);
1940 #elif defined(__MACH__)
1941 #elif defined(DEBUG) || defined(_DEBUG)
1942 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: Render to Texture not "
1943 "supported in Linux or MacOS");
1947 // Set the pixel type
1951 if (WGL_NV_float_buffer)
1953 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1954 pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
1956 pfAttribs.push_back(WGL_FLOAT_COMPONENTS_NV);
1957 pfAttribs.push_back(true);
1961 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1962 pfAttribs.push_back(WGL_TYPE_RGBA_FLOAT_ATI);
1964 #elif defined( __MACH__ )
1965 // if (GL_MACH_float_pixels) // FIXME
1967 pfAttribs.push_back(kCGLPFAColorFloat);
1970 if (GLX_NV_float_buffer)
1972 pfAttribs.push_back(GLX_FLOAT_COMPONENTS_NV);
1973 pfAttribs.push_back(1);
1980 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1981 pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
1985 // Set up texture binding for render to texture
1986 if (_bIsTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1992 if (WGL_NV_float_buffer)
1994 switch(_iNumComponents)
1997 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
1998 pfAttribs.push_back(true);
2000 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2001 pbAttribs.push_back(WGL_TEXTURE_FLOAT_R_NV);
2004 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
2005 pfAttribs.push_back(true);
2007 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2008 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RG_NV);
2011 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
2012 pfAttribs.push_back(true);
2014 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2015 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGB_NV);
2018 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
2019 pfAttribs.push_back(true);
2021 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2022 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
2025 SG_LOG(SG_GL, SG_ALERT,
2026 "RenderTexture Warning: Bad number of components "
2027 "(r=1,rg=2,rgb=3,rgba=4): " <<
2029 dbg_printf("RenderTexture Warning 1: Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n",
2036 if (4 == _iNumComponents)
2038 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2039 pfAttribs.push_back(true);
2041 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2042 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2046 // standard ARB_render_texture only supports 3 or 4 channels
2047 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2048 pfAttribs.push_back(true);
2050 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2051 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2058 switch(_iNumComponents)
2061 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2062 pfAttribs.push_back(true);
2064 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2065 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2068 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2069 pfAttribs.push_back(true);
2071 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2072 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2075 SG_LOG(SG_GL, SG_ALERT,
2076 "RenderTexture Warning: Bad number of components "
2077 "(r=1,rg=2,rgb=3,rgba=4): " << _iNumComponents);
2078 dbg_printf("RenderTexture Warning 2: Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n",
2083 #elif defined(__MACH__)
2087 //if (WGLEW_NV_float_buffer) // FIXME
2089 switch(_iNumComponents)
2092 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
2093 pfAttribs.push_back(true);
2095 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2096 pbAttribs.push_back(WGL_TEXTURE_FLOAT_R_NV);
2099 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
2100 pfAttribs.push_back(true);
2102 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2103 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RG_NV);
2106 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
2107 pfAttribs.push_back(true);
2109 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2110 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGB_NV);
2113 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
2114 pfAttribs.push_back(true);
2116 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2117 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
2121 "RenderTexture Warning: Bad number of components "
2122 "(r=1,rg=2,rgb=3,rgba=4): %d.\n",
2129 if (4 == _iNumComponents)
2131 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2132 pfAttribs.push_back(true);
2134 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2135 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2139 // standard ARB_render_texture only supports 3 or 4 channels
2140 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2141 pfAttribs.push_back(true);
2143 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2144 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2152 switch(_iNumComponents)
2155 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2156 pfAttribs.push_back(true);
2158 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2159 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2162 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2163 pfAttribs.push_back(true);
2165 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2166 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2170 "RenderTexture Warning: Bad number of components "
2171 "(r=1,rg=2,rgb=3,rgba=4): %d.\n", _iNumComponents);
2176 #elif defined(DEBUG) || defined(_DEBUG)
2177 SG_LOG(SG_GL, SG_ALERT,
2178 "RenderTexture Error: Render to Texture not supported in Linux or MacOS");
2180 dbg_printf( "RenderTexture Error 1: Render to Texture not supported in Linux or MacOS\n");
2183 if (_bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
2188 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV);
2189 pfAttribs.push_back(true);
2191 pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
2192 pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
2196 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_DEPTH_NV);
2197 pfAttribs.push_back(true);
2199 pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
2200 pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
2202 #elif defined(__MACH__)
2203 #elif defined(DEBUG) || defined(_DEBUG)
2204 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: Render to Texture not supported in "
2207 dbg_printf( "RenderTexture Error 2: Render to Texture not supported in Linux or MacOS\n");
2209 dbg_printf("RenderTexture::_ParseModeString(%s). END vf=%d vp=%d\n", modeString, pfAttribs.size(), pbAttribs.size() );
2213 //---------------------------------------------------------------------------
2214 // Function : RenderTexture::_GetKeyValuePair
2216 //---------------------------------------------------------------------------
2218 * @fn RenderTexture::_GetKeyValuePair()
2219 * @brief Parses expressions of the form "X=Y" into a pair (X,Y).
2221 RenderTexture::KeyVal RenderTexture::_GetKeyValuePair(string token)
2223 string::size_type pos = 0;
2224 if ((pos = token.find("=")) != token.npos)
2226 string key = token.substr(0, pos);
2227 string value = token.substr(pos+1, token.length()-pos+1);
2228 return KeyVal(key, value);
2231 return KeyVal(token, "");
2234 //---------------------------------------------------------------------------
2235 // Function : RenderTexture::_ParseBitVector
2237 //---------------------------------------------------------------------------
2239 * @fn RenderTexture::_ParseBitVector()
2240 * @brief Parses expressions of the form "=r,g,b,a" into a vector: (r,g,b,a)
2242 vector<int> RenderTexture::_ParseBitVector(string bitVector)
2244 vector<string> pieces;
2247 if (bitVector == "")
2249 bits.push_back(8); // if a depth isn't specified, use default 8 bits
2253 string::size_type pos = 0;
2254 string::size_type nextpos = 0;
2257 nextpos = bitVector.find_first_of(", ", pos);
2258 pieces.push_back(string(bitVector, pos, nextpos - pos));
2260 } while (nextpos != bitVector.npos );
2262 for ( vector<string>::iterator it = pieces.begin(); it != pieces.end(); it++)
2264 bits.push_back(strtol(it->c_str(), 0, 10));
2270 //---------------------------------------------------------------------------
2271 // Function : RenderTexture::_VerifyExtensions
2273 //---------------------------------------------------------------------------
2275 * @fn RenderTexture::_VerifyExtensions()
2276 * @brief Checks that the necessary extensions are available based on RT mode.
2278 bool RenderTexture::_VerifyExtensions()
2280 dbg_printf("RenderTexture::_VerifyExtensions() called...\n");
2282 // a second call to _VerifyExtensions will allways return true, causing a crash
2283 // if the extension is not supported
2284 if ( true || !fctPtrInited )
2286 fctPtrInited = true;
2287 wglGetExtensionsStringARBProc wglGetExtensionsStringARBPtr = (wglGetExtensionsStringARBProc)wglGetProcAddress( "wglGetExtensionsStringARB" );
2288 if ( wglGetExtensionsStringARBPtr == 0 )
2290 PrintExtensionError("WGL_ARB_extensions_string");
2293 string wglExtensionsString = wglGetExtensionsStringARBPtr( wglGetCurrentDC() );
2294 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pixel_format" ) )
2296 wglChoosePixelFormatARBPtr = (wglChoosePixelFormatARBProc)SGLookupFunction("wglChoosePixelFormatARB");
2297 wglGetPixelFormatAttribivARBPtr = (wglGetPixelFormatAttribivARBProc)SGLookupFunction("wglGetPixelFormatAttribivARB");
2301 PrintExtensionError("WGL_ARB_pixel_format");
2304 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pbuffer" ) )
2306 wglCreatePbufferARBPtr = (wglCreatePbufferARBProc)SGLookupFunction("wglCreatePbufferARB");
2307 wglGetPbufferDCARBPtr = (wglGetPbufferDCARBProc)SGLookupFunction("wglGetPbufferDCARB");
2308 wglQueryPbufferARBPtr = (wglQueryPbufferARBProc)SGLookupFunction("wglQueryPbufferARB");
2309 wglReleasePbufferDCARBPtr = (wglReleasePbufferDCARBProc)SGLookupFunction("wglReleasePbufferDCARB");
2310 wglDestroyPbufferARBPtr = (wglDestroyPbufferARBProc)SGLookupFunction("wglDestroyPbufferARB");
2314 PrintExtensionError("WGL_ARB_pbuffer");
2317 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_render_texture" ) )
2319 wglBindTexImageARBPtr = (wglBindTexImageARBProc)SGLookupFunction("wglBindTexImageARB");
2320 wglReleaseTexImageARBPtr = (wglReleaseTexImageARBProc)SGLookupFunction("wglReleaseTexImageARB");
2322 else if ( _bIsTexture )
2324 PrintExtensionError("WGL_ARB_render_texture");
2327 if (_bRectangle && !SGIsOpenGLExtensionSupported( "GL_NV_texture_rectangle" ))
2329 PrintExtensionError("GL_NV_texture_rectangle");
2332 if (_bFloat && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) ||
2333 SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ATI_pixel_format_float" )))
2335 PrintExtensionError("GL_NV_float_buffer or GL_ATI_pixel_format_float");
2339 if (_bFloat && _bIsTexture && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) || SGIsOpenGLExtensionSupported( "GL_ATI_texture_float" )))
2341 PrintExtensionError("NV_float_buffer or ATI_texture_float");
2343 if (_bIsDepthTexture && !SGIsOpenGLExtensionSupported( "GL_ARB_depth_texture" ))
2346 #if defined(_DEBUG) | defined(DEBUG)
2347 SG_LOG(SG_GL, SG_ALERT,
2348 "RenderTexture Warning: "
2349 "OpenGL extension GL_ARB_depth_texture not available."
2350 " Using glReadPixels() to emulate behavior.");
2352 _bHasARBDepthTexture = false;
2353 //PrintExtensionError("GL_ARB_depth_texture");
2359 #elif defined( __MACH__ )
2360 // FIXME! Check extensions!
2362 Display* dpy = glXGetCurrentDisplay();
2363 int minor = 0, major = 0;
2365 dbg_printf("_VerifyExtensions: glXGetCurrentDisplay() returned NULL! returning false\n");
2368 if (!glXQueryVersion(dpy, &major, &minor))
2370 dbg_printf("_VerifyExtensions: glXQueryVersion(dpy, &major, &minor) FAILED! returning false\n");
2375 dbg_printf("_VerifyExtensions: glXQueryVersion(dpy, major=%d, minor=%d)\n", major, minor);
2378 int screen = DefaultScreen(dpy);
2379 const char* extString = glXQueryExtensionsString(dpy, screen);
2380 dbg_printf("_VerifyExtensions: glXQueryExtensionsString(dpy, screen) returned -\n[%s]\n",
2381 (extString ? extString : "<NULL>") );
2382 if (!SGSearchExtensionsString(extString, "GLX_SGIX_fbconfig") ||
2383 !SGSearchExtensionsString(extString, "GLX_SGIX_pbuffer"))
2385 dbg_printf("_VerifyExtensions: glXQueryExtensionsString(dpy,screen) does NOT contain GLX_SGIX_fbconfig or GLX_SGIX_pbuffer!\n" );
2386 const char * extClient = glXGetClientString( dpy, GLX_EXTENSIONS );
2388 !SGSearchExtensionsString(extClient, "GLX_SGIX_fbconfig") ||
2389 !SGSearchExtensionsString(extClient, "GLX_SGIX_pbuffer"))
2391 dbg_printf("_VerifyExtensions: AND glXGetClientString(dpy,GLX_EXTENSIONS) also! returning false\n" );
2396 dbg_printf("_VerifyExtensions: BUT glXGetClientString(dpy,GLX_EXTENSIONS) returned \n[%s]\n", extClient );
2397 dbg_printf("Since this DOES contain fbconfig and pbuffer, continuing...\n");
2400 // First try the glX version 1.3 functions.
2401 glXChooseFBConfigPtr = (glXChooseFBConfigProc)SGLookupFunction("glXChooseFBConfig");
2402 glXCreatePbufferPtr = (glXCreatePbufferProc)SGLookupFunction("glXCreatePbuffer");
2403 glXGetVisualFromFBConfigPtr = (glXGetVisualFromFBConfigProc)SGLookupFunction("glXGetVisualFromFBConfig");
2404 glXCreateContextPtr = (glXCreateContextProc)SGLookupFunction("glXCreateContext");
2405 glXDestroyPbufferPtr = (glXDestroyPbufferProc)SGLookupFunction("glXDestroyPbuffer");
2406 glXQueryDrawablePtr = (glXQueryDrawableProc)SGLookupFunction("glXQueryDrawable");
2408 if (((1 <= major && 3 <= minor) || 2 <= major) &&
2409 glXChooseFBConfigPtr &&
2410 glXCreatePbufferPtr &&
2411 glXGetVisualFromFBConfigPtr &&
2412 glXCreateContextPtr &&
2413 glXDestroyPbufferPtr &&
2414 glXQueryDrawablePtr) {
2415 dbg_printf("_VerifyExtensions: setting glXVersion1_3Present TRUE\n" );
2416 glXVersion1_3Present = true;
2420 dbg_printf("_VerifyExtensions: setting glXVersion1_3Present FALSE\n Reason: " );
2421 if ( !((1 <= major && 3 <= minor) || 2 <= major) ) { dbg_printf( "Version wrong %d.%d ", major, minor ); }
2422 if ( !glXChooseFBConfigPtr ) { dbg_printf( "missing glXChooseFBConfigPtr " ); }
2423 if ( !glXCreatePbufferPtr ) { dbg_printf( "missing glXCreatePbufferPtr " ); }
2424 if ( !glXGetVisualFromFBConfigPtr ) { dbg_printf( "missing glXGetVisualFromFBConfigPtr " ); }
2425 if ( !glXCreateContextPtr ) { dbg_printf( "missing glXCreateContextPtr " ); }
2426 if ( !glXDestroyPbufferPtr ) { dbg_printf( "missing glXDestroyPbufferPtr " ); }
2427 if ( !glXQueryDrawablePtr ) { dbg_printf( "missing glXQueryDrawablePtr " ); }
2430 glXChooseFBConfigPtr = (glXChooseFBConfigProc)SGLookupFunction("glXChooseFBConfigSGIX");
2431 glXCreateGLXPbufferPtr = (glXCreateGLXPbufferProc)SGLookupFunction("glXCreateGLXPbufferSGIX");
2432 glXGetVisualFromFBConfigPtr = (glXGetVisualFromFBConfigProc)SGLookupFunction("glXGetVisualFromFBConfigSGIX");
2433 glXCreateContextWithConfigPtr = (glXCreateContextWithConfigProc)SGLookupFunction("glXCreateContextWithConfigSGIX");
2434 glXDestroyPbufferPtr = (glXDestroyPbufferProc)SGLookupFunction("glXDestroyGLXPbufferSGIX");
2435 glXQueryGLXPbufferSGIXPtr = (glXQueryGLXPbufferSGIXProc)SGLookupFunction("glXQueryGLXPbufferSGIX");
2437 if (!glXChooseFBConfigPtr ||
2438 !glXCreateGLXPbufferPtr ||
2439 !glXGetVisualFromFBConfigPtr ||
2440 !glXCreateContextWithConfigPtr ||
2441 !glXDestroyPbufferPtr ||
2442 !glXQueryGLXPbufferSGIXPtr)
2444 dbg_printf("_VerifyExtensions: some pointer is NULL! return false\n" );
2445 if ( !glXCreateGLXPbufferPtr ) {
2446 dbg_printf("RenderTexture::Initialize: ERROR glXCreateGLXPbufferPtr = NULL!\n");
2447 } else if ( !glXCreateContextWithConfigPtr ) {
2448 dbg_printf("RenderTexture::Initialize: ERROR glXCreateContextWithConfigPtr = NULL!\n");
2449 } else if ( !glXVersion1_3Present && !glXQueryGLXPbufferSGIXPtr ) {
2450 dbg_printf("RenderTexture::Initialize: ERROR glXQueryGLXPbufferSGIXPtr = NULL!\n");
2454 dbg_printf("_VerifyExtensions: appear to have all 'procs' glXCreateGLXPbufferPtr=[%p]\n", glXCreateGLXPbufferPtr );
2458 if (_bIsDepthTexture && !GL_ARB_depth_texture)
2460 PrintExtensionError("GL_ARB_depth_texture");
2463 if (_bFloat && _bIsTexture && !GLX_NV_float_buffer)
2465 PrintExtensionError("GLX_NV_float_buffer");
2468 if (_eUpdateMode == RT_RENDER_TO_TEXTURE)
2470 PrintExtensionError("Some GLX render texture extension: Please implement me!");
2475 dbg_printf("RenderTexture::_VerifyExtensions: return true.\n");
2479 //---------------------------------------------------------------------------
2480 // Function : RenderTexture::_InitializeTextures
2482 //---------------------------------------------------------------------------
2484 * @fn RenderTexture::_InitializeTextures()
2485 * @brief Initializes the state of textures used by the RenderTexture.
2487 bool RenderTexture::_InitializeTextures()
2489 dbg_printf( "RenderTexture::_InitializeTextures() called\n" );
2490 // Determine the appropriate texture formats and filtering modes.
2492 if (_bIsTexture || _bIsDepthTexture)
2494 if (_bRectangle && GL_NV_texture_rectangle)
2495 _iTextureTarget = GL_TEXTURE_RECTANGLE_NV;
2496 else if (_bRectangle && GL_EXT_texture_rectangle)
2497 _iTextureTarget = GL_TEXTURE_RECTANGLE_EXT;
2499 _iTextureTarget = GL_TEXTURE_2D;
2504 glGenTextures(1, (GLuint*)&_iTextureID);
2505 glBindTexture(_iTextureTarget, _iTextureID);
2507 // Use clamp to edge as the default texture wrap mode for all tex
2508 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2509 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2510 // Use NEAREST as the default texture filtering mode.
2511 glTexParameteri(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2512 glTexParameteri(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2515 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2517 GLuint iInternalFormat;
2524 SG_LOG(SG_GL, SG_ALERT,
2525 "RenderTexture Error: mipmapped float textures not "
2527 dbg_printf( "RenderTexture Error: mipmapped float textures not supported. return false\n");
2531 switch(_iNumComponents)
2534 if (GL_NV_float_buffer)
2536 iInternalFormat = (_iNumColorBits[0] > 16) ?
2537 GL_FLOAT_R32_NV : GL_FLOAT_R16_NV;
2539 else if (GL_ATI_texture_float)
2541 iInternalFormat = (_iNumColorBits[0] > 16) ?
2542 GL_LUMINANCE_FLOAT32_ATI :
2543 GL_LUMINANCE_FLOAT16_ATI;
2545 iFormat = GL_LUMINANCE;
2548 if (GL_NV_float_buffer)
2550 iInternalFormat = (_iNumColorBits[0] > 16) ?
2551 GL_FLOAT_RG32_NV : GL_FLOAT_RG16_NV;
2553 else if (GL_ATI_texture_float)
2555 iInternalFormat = (_iNumColorBits[0] > 16) ?
2556 GL_LUMINANCE_ALPHA_FLOAT32_ATI :
2557 GL_LUMINANCE_ALPHA_FLOAT16_ATI;
2559 iFormat = GL_LUMINANCE_ALPHA;
2562 if (GL_NV_float_buffer)
2564 iInternalFormat = (_iNumColorBits[0] > 16) ?
2565 GL_FLOAT_RGB32_NV : GL_FLOAT_RGB16_NV;
2567 else if (GL_ATI_texture_float)
2569 iInternalFormat = (_iNumColorBits[0] > 16) ?
2570 GL_RGB_FLOAT32_ATI : GL_RGB_FLOAT16_ATI;
2575 if (GL_NV_float_buffer)
2577 iInternalFormat = (_iNumColorBits[0] > 16) ?
2578 GL_FLOAT_RGBA32_NV : GL_FLOAT_RGBA16_NV;
2580 else if (GL_ATI_texture_float)
2582 iInternalFormat = (_iNumColorBits[0] > 16) ?
2583 GL_RGBA_FLOAT32_ATI : GL_RGBA_FLOAT16_ATI;
2588 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: "
2589 "Invalid number of components: " <<
2591 dbg_printf( "RenderTexture Error: Invalid number of components: %d - return false\n",
2598 if (4 == _iNumComponents)
2600 iInternalFormat = GL_RGBA8;
2605 iInternalFormat = GL_RGB8;
2610 // Allocate the texture image (but pass it no data for now).
2611 glTexImage2D(_iTextureTarget, 0, iInternalFormat,
2612 _iWidth, _iHeight, 0, iFormat, GL_FLOAT, NULL);
2616 if (_bIsDepthTexture)
2618 glGenTextures(1, (GLuint*)&_iDepthTextureID);
2619 glBindTexture(_iTextureTarget, _iDepthTextureID);
2621 // Use clamp to edge as the default texture wrap mode for all tex
2622 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2623 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2624 // Use NEAREST as the default texture filtering mode.
2625 glTexParameteri(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2626 glTexParameteri(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2628 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2631 if (_bHasARBDepthTexture)
2633 // Allocate the texture image (but pass it no data for now).
2634 glTexImage2D(_iTextureTarget, 0, GL_DEPTH_COMPONENT,
2635 _iWidth, _iHeight, 0, GL_DEPTH_COMPONENT,
2640 // allocate memory for depth texture
2641 // Since this is slow, we warn the user in debug mode. (above)
2642 _pPoorDepthTexture = new unsigned short[_iWidth * _iHeight];
2643 glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16,
2644 _iWidth, _iHeight, 0, GL_LUMINANCE,
2645 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
2651 dbg_printf( "RenderTexture::_InitializeTextures() returning true\n" );
2656 //---------------------------------------------------------------------------
2657 // Function : RenderTexture::_MaybeCopyBuffer
2659 //---------------------------------------------------------------------------
2661 * @fn RenderTexture::_MaybeCopyBuffer()
2662 * @brief Does the actual copying for RenderTextures with RT_COPY_TO_TEXTURE
2664 void RenderTexture::_MaybeCopyBuffer()
2667 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2671 glBindTexture(_iTextureTarget, _iTextureID);
2672 glCopyTexSubImage2D(_iTextureTarget,
2673 0, 0, 0, 0, 0, _iWidth, _iHeight);
2675 if (_bIsDepthTexture)
2677 glBindTexture(_iTextureTarget, _iDepthTextureID);
2678 // HOW TO COPY DEPTH TEXTURE??? Supposedly this just magically works...
2680 if (_bHasARBDepthTexture)
2682 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0,
2687 // no 'real' depth texture available, so behavior has to be emulated
2688 // using glReadPixels (beware, this is (naturally) slow ...)
2689 glReadPixels(0, 0, _iWidth, _iHeight, GL_DEPTH_COMPONENT,
2690 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
2691 glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16,
2692 _iWidth, _iHeight, 0, GL_LUMINANCE,
2693 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
2699 #elif defined(__MACH__)
2700 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2704 glBindTexture(_iTextureTarget, _iTextureID);
2705 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2707 if (_bIsDepthTexture)
2709 glBindTexture(_iTextureTarget, _iDepthTextureID);
2710 assert(_bHasARBDepthTexture);
2711 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2717 glBindTexture(_iTextureTarget, _iTextureID);
2718 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2720 if (_bIsDepthTexture)
2722 glBindTexture(_iTextureTarget, _iDepthTextureID);
2723 assert(_bHasARBDepthTexture);
2724 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2730 //---------------------------------------------------------------------------
2731 // Function : RenderTexture::_ReleaseBoundBuffers
2733 //---------------------------------------------------------------------------
2735 * @fn RenderTexture::_ReleaseBoundBuffers()
2736 * @brief Releases buffer bindings on RenderTextures with RT_RENDER_TO_TEXTURE
2738 bool RenderTexture::_ReleaseBoundBuffers()
2741 if (_bIsTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
2743 glBindTexture(_iTextureTarget, _iTextureID);
2745 // release the pbuffer from the render texture object
2746 if (0 != _iCurrentBoundBuffer && _bIsBufferBound)
2748 if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, _iCurrentBoundBuffer))
2753 _bIsBufferBound = false;
2757 if (_bIsDepthTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
2759 glBindTexture(_iTextureTarget, _iDepthTextureID);
2761 // release the pbuffer from the render texture object
2762 if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
2770 // textures can't be bound in Linux
2775 //---------------------------------------------------------------------------
2776 // Function : RenderTexture::_MakeCurrent
2778 //---------------------------------------------------------------------------
2780 * @fn RenderTexture::_MakeCurrent()
2781 * @brief Makes the RenderTexture's context current
2783 bool RenderTexture::_MakeCurrent()
2786 // make the pbuffer's rendering context current.
2787 if (FALSE == wglMakeCurrent( _hDC, _hGLContext))
2792 #elif defined( __MACH__ )
2795 if (err = CGLSetCurrentContext(_hGLContext))
2797 _cglCheckError(err);
2801 static GLXContext last_hGLContext = 0;
2802 if (false == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
2804 dbg_printf( "_MakeCurrent: glXMakeCurrent FAILED! returning false\n");
2808 if ( last_hGLContext != _hGLContext ) {
2809 last_hGLContext = _hGLContext;
2810 dbg_printf( "_MakeCurrent: glXMakeCurrent set to [%p] SUCCESS! returning true\n", _hGLContext );
2816 /////////////////////////////////////////////////////////////////////////////
2818 // Begin Deprecated Interface
2820 /////////////////////////////////////////////////////////////////////////////
2822 //---------------------------------------------------------------------------
2823 // Function : RenderTexture::RenderTexture
2825 //---------------------------------------------------------------------------
2827 * @fn RenderTexture::RenderTexture()
2828 * @brief Constructor.
2830 RenderTexture::RenderTexture(int width, int height,
2831 bool bIsTexture /* = true */,
2832 bool bIsDepthTexture /* = false */)
2835 _bIsTexture(bIsTexture),
2836 _bIsDepthTexture(bIsDepthTexture),
2837 _bHasARBDepthTexture(true), // [Redge]
2838 _eUpdateMode(RT_RENDER_TO_TEXTURE),
2839 _bInitialized(false),
2841 _iCurrentBoundBuffer(0),
2843 _iNumStencilBits(0),
2845 _bDoubleBuffered(false),
2849 _bShareObjects(false),
2850 _bCopyContext(false),
2856 _hPreviousContext(0),
2857 #elif defined( __MACH__ )
2860 _hPreviousContext(NULL),
2865 _hPreviousDrawable(0),
2866 _hPreviousContext(0),
2868 _iTextureTarget(GL_NONE),
2870 _iDepthTextureID(0),
2871 _pPoorDepthTexture(0) // [Redge]
2873 assert(width > 0 && height > 0);
2874 #if defined DEBUG || defined _DEBUG
2875 SG_LOG(SG_GL, SG_ALERT,
2876 "RenderTexture Warning: Deprecated Contructor interface used.");
2878 dbg_printf("RenderTexture Warning: Deprecated Contructor interface used.\n");
2880 _iNumColorBits[0] = _iNumColorBits[1] =
2881 _iNumColorBits[2] = _iNumColorBits[3] = 0;
2882 _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
2885 //------------------------------------------------------------------------------
2886 // Function : RenderTexture::Initialize
2888 //------------------------------------------------------------------------------
2890 * @fn RenderTexture::Initialize(bool bShare, bool bDepth, bool bStencil, bool bMipmap, unsigned int iRBits, unsigned int iGBits, unsigned int iBBits, unsigned int iABits);
2891 * @brief Initializes the RenderTexture, sharing display lists and textures if specified.
2893 * This function actually does the creation of the p-buffer. It can only be called
2894 * once a GL context has already been created. Note that if the texture is not
2895 * power of two dimensioned, or has more than 8 bits per channel, enabling mipmapping
2896 * will cause an error.
2898 bool RenderTexture::Initialize(bool bShare /* = true */,
2899 bool bDepth /* = false */,
2900 bool bStencil /* = false */,
2901 bool bMipmap /* = false */,
2902 bool bAnisoFilter /* = false */,
2903 unsigned int iRBits /* = 8 */,
2904 unsigned int iGBits /* = 8 */,
2905 unsigned int iBBits /* = 8 */,
2906 unsigned int iABits /* = 8 */,
2907 UpdateMode updateMode /* = RT_RENDER_TO_TEXTURE */)
2909 if (0 == _iWidth || 0 == _iHeight)
2912 #if defined DEBUG || defined _DEBUG
2913 SG_LOG(SG_GL, SG_ALERT,
2914 "RenderTexture Warning: Deprecated Initialize() interface used.");
2916 dbg_printf("RenderTexture Warning: Deprecated Initialize() interface used.\n");
2918 // create a mode string.
2921 mode.append("depth ");
2923 mode.append("stencil ");
2925 mode.append("mipmap ");
2926 if (iRBits + iGBits + iBBits + iABits > 0)
2937 char bitVector[100];
2938 snprintf( bitVector, 100,
2939 "%d%s,%d%s,%d%s,%d%s",
2940 iRBits, (iRBits >= 16) ? "f" : "",
2941 iGBits, (iGBits >= 16) ? "f" : "",
2942 iBBits, (iBBits >= 16) ? "f" : "",
2943 iABits, (iABits >= 16) ? "f" : "");
2944 mode.append(bitVector);
2949 if ((GL_NV_texture_rectangle || GL_EXT_texture_rectangle) &&
2950 ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
2951 || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
2952 mode.append("texRECT ");
2954 mode.append("tex2D ");
2956 if (_bIsDepthTexture)
2958 if ((GL_NV_texture_rectangle || GL_EXT_texture_rectangle) &&
2959 ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
2960 || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
2961 mode.append("texRECT ");
2963 mode.append("tex2D ");
2965 if (RT_COPY_TO_TEXTURE == updateMode)
2968 _pixelFormatAttribs.clear();
2969 _pbufferAttribs.clear();
2972 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
2973 _pixelFormatAttribs.push_back(true);
2974 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
2975 _pixelFormatAttribs.push_back(true);
2977 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
2978 _pbufferAttribs.push_back(true);
2979 #elif defined( __MACH__ )
2980 //_pixelFormatAttribs.push_back(kCGLPFANoRecovery);
2981 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
2982 _pixelFormatAttribs.push_back(kCGLPFAWindow);
2983 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
2985 _pixelFormatAttribs.push_back(GLX_RENDER_TYPE_SGIX);
2986 _pixelFormatAttribs.push_back(GLX_RGBA_BIT_SGIX);
2987 _pixelFormatAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
2988 _pixelFormatAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
2991 _ParseModeString(mode.c_str(), _pixelFormatAttribs, _pbufferAttribs);
2994 _pixelFormatAttribs.push_back(0);
2995 _pbufferAttribs.push_back(0);
2996 #elif defined(__MACH__)
2997 _pixelFormatAttribs.push_back(0);
2999 _pixelFormatAttribs.push_back(None);
3002 Initialize(_iWidth, _iHeight, bShare);
3008 //---------------------------------------------------------------------------
3009 // Function : RenderTexture::Reset
3011 //---------------------------------------------------------------------------
3013 * @fn RenderTexture::Reset(int iWidth, int iHeight, unsigned int iMode, bool bIsTexture, bool bIsDepthTexture)
3014 * @brief Resets the resolution of the offscreen buffer.
3016 * Causes the buffer to delete itself. User must call Initialize() again
3019 bool RenderTexture::Reset(int iWidth, int iHeight)
3021 SG_LOG(SG_GL, SG_ALERT,
3022 "RenderTexture Warning: Deprecated Reset() interface used.");
3024 dbg_printf("RenderTexture Warning: Deprecated Reset(x,y) interface used.\n");
3028 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Reset(): failed to invalidate.");
3029 dbg_printf( "RenderTexture::Reset(x,y): failed to invalidate. returning false\n");
3035 dbg_printf( "RenderTexture::Reset(x,y): succeeded. returning true\n");
3039 #if defined( _DEBUG ) && !defined( _WIN32 ) && !defined( __MACH__ )
3040 /* just some DEBUG ONLY code, to show the 'attributes' */
3042 typedef struct tagPXATTS {
3049 static PXATTS pxAtts[] = {
3050 { GLX_FBCONFIG_ID, "GLX_FBCONFIG_ID",
3051 "followed by a valid XID that indicates the desired GLX frame buffer configuration. "
3052 "When a GLX_FBCONFIG_ID is specified, all attributes are ignored. The default value is GLX_DONT_CARE.",
3054 { GLX_BUFFER_SIZE, "GLX_BUFFER_SIZE",
3055 "Must be followed by a nonnegative integer that indicates the desired color index buffer size."
3056 "The smallest index buffer of at least the specified size is preferred. This attribute is ignored if GLX_COLOR_INDEX_BIT is not set "
3057 "in GLX_RENDER_TYPE. The default value is 0.",
3059 { GLX_LEVEL, "GLX_LEVEL",
3060 "Must be followed by an integer buffer-level specification. This specification is honored exactly."
3061 "Buffer level 0 corresponds to the default frame buffer of the display. "
3062 "Buffer level 1 is the first overlay frame buffer, level two the second overlay frame buffer, and so on."
3063 "Negative buffer levels correspond to underlay frame buffers. The default value is 0.",
3065 { GLX_DOUBLEBUFFER, "GLX_DOUBLEBUFFER",
3066 "Must be followed by True or False. If True is specified, then only double-buffered frame buffer configurations are considered;"
3067 "if False is specified, then only single-buffered frame buffer configurations are considered. The default value is GLX_DONT_CARE.",
3069 { GLX_STEREO, "GLX_STEREO",
3070 "Must be followed by True or False. If True is specified, then only stereo frame buffer configurations are considered;"
3071 " if False is specified, then only monoscopic frame buffer configurations are considered. The default value is False.",
3073 { GLX_AUX_BUFFERS, "GLX_AUX_BUFFERS",
3074 "Must be followed by a nonnegative integer that indicates the desired number of auxiliary buffers."
3075 " Configurations with the smallest number of auxiliary buffers that meet or exceed the specified number are preferred."
3076 " The default value is 0.",
3078 { GLX_RED_SIZE, "GLX_RED_SIZE",
3079 "must be followed by a nonnegative minimum size",
3081 { GLX_GREEN_SIZE, "GLX_GREEN_SIZE",
3082 "must be followed by a nonnegative minimum size",
3084 { GLX_BLUE_SIZE, "GLX_BLUE_SIZE",
3085 "must be followed by a nonnegative minimum size",
3087 { GLX_ALPHA_SIZE, "GLX_ALPHA_SIZE",
3088 "Each attribute, if present, must be followed by a nonnegative minimum size specification or GLX_DONT_CARE."
3089 " The largest available total RGBA color buffer size (sum of GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE) "
3090 " of at least the minimum size specified for each color component is preferred. If the requested number of bits for a color "
3091 " component is 0 or GLX_DONT_CARE, it is not considered. The default value for each color component is 0.",
3093 { GLX_DEPTH_SIZE, "GLX_DEPTH_SIZE",
3094 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3095 "frame buffer configurations with no depth buffer are preferred."
3096 "Otherwise, the largest available depth buffer of at least the minimum size is preferred. The default value is 0.",
3098 { GLX_STENCIL_SIZE, "GLX_STENCIL_SIZE",
3099 "Must be followed by a nonnegative integer that indicates the desired number of stencil bitplanes."
3100 "The smallest stencil buffer of at least the specified size is preferred. If the desired value is zero,"
3101 " frame buffer configurations with no stencil buffer are preferred. The default value is 0.",
3103 { GLX_ACCUM_RED_SIZE, "GLX_ACCUM_RED_SIZE",
3104 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3105 " frame buffer configurations with no red accumulation buffer are preferred."
3106 " Otherwise, the largest possible red accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3108 { GLX_ACCUM_GREEN_SIZE, "GLX_ACCUM_GREEN_SIZE",
3109 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3110 "frame buffer configurations with no green accumulation buffer are preferred. "
3111 "Otherwise, the largest possible green accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3113 { GLX_ACCUM_BLUE_SIZE, "GLX_ACCUM_BLUE_SIZE",
3114 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3115 "frame buffer configurations with no blue accumulation buffer are preferred. "
3116 "Otherwise, the largest possible blue accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3118 { GLX_ACCUM_ALPHA_SIZE, "GLX_ACCUM_ALPHA_SIZE",
3119 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3120 "frame buffer configurations with no alpha accumulation buffer are preferred. "
3121 "Otherwise, the largest possible alpha accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3123 { GLX_RENDER_TYPE, "GLX_RENDER_TYPE",
3124 "Must be followed by a mask indicating which OpenGL rendering modes the frame buffer configuration must support. "
3125 "Valid bits are GLX_RGBA_BIT and GLX_COLOR_INDEX_BIT. If the mask is set to GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT, "
3126 "then only frame buffer configurations that can be bound to both RGBA contexts and color index contexts will be considered. "
3127 "The default value is GLX_RGBA_BIT.",
3129 { GLX_DRAWABLE_TYPE, "GLX_DRAWABLE_TYPE",
3130 "Must be followed by a mask indicating which GLX drawable types the frame buffer configuration must support. "
3131 "Valid bits are GLX_WINDOW_BIT, GLX_PIXMAP_BIT, and GLX_PBUFFER_BIT. For example, if mask is set to "
3132 "GLX_WINDOW_BIT | GLX_PIXMAP_BIT, only frame buffer configurations that support both windows and GLX pixmaps "
3133 "will be considered. The default value is GLX_WINDOW_BIT.",
3135 { GLX_X_RENDERABLE, "GLX_X_RENDERABLE",
3136 "Must be followed by True or False. If True is specified, then only frame buffer configurations that "
3137 "have associated X visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. "
3138 "The default value is GLX_DONT_CARE. ",
3140 { GLX_X_VISUAL_TYPE, "GLX_X_VISUAL_TYPE",
3141 "Must be followed by one of GLX_TRUE_COLOR, GLX_DIRECT_COLOR, GLX_PSEUDO_COLOR, GLX_STATIC_COLOR, "
3142 "GLX_GRAY_SCALE, or GLX_STATIC_GRAY, indicating the desired X visual type. "
3143 "Not all frame buffer configurations have an associated X visual. If GLX_DRAWABLE_TYPE is specified in attrib_list and the "
3144 "mask that follows does not have GLX_WINDOW_BIT set, then this value is ignored. It is also ignored if "
3145 "GLX_X_RENDERABLE is specified as False. RGBA rendering may be supported for visuals of type "
3146 "GLX_TRUE_COLOR, GLX_DIRECT_COLOR, GLX_PSEUDO_COLOR, or GLX_STATIC_COLOR, "
3147 "but color index rendering is only supported for visuals of type GLX_PSEUDO_COLOR or GLX_STATIC_COLOR "
3148 "(i.e., single-channel visuals). The tokens GLX_GRAY_SCALE and GLX_STATIC_GRAY will "
3149 "not match current OpenGL enabled visuals, but are included for future use."
3150 "The default value for GLX_X_VISUAL_TYPE is GLX_DONT_CARE.",
3152 { GLX_CONFIG_CAVEAT, "GLX_CONFIG_CAVEAT",
3153 "Must be followed by one of GLX_NONE, GLX_SLOW_CONFIG, GLX_NON_CONFORMANT_CONFIG. "
3154 "If GLX_NONE is specified, then only frame buffer configurations with "
3155 "no caveats will be considered; if GLX_SLOW_CONFIG is specified, then only slow frame buffer configurations will be considered; if "
3156 "GLX_NON_CONFORMANT_CONFIG is specified, then only nonconformant frame buffer configurations will be considered."
3157 "The default value is GLX_DONT_CARE.",
3159 { GLX_TRANSPARENT_TYPE, "GLX_TRANSPARENT_TYPE",
3160 "Must be followed by one of GLX_NONE, GLX_TRANSPARENT_RGB, GLX_TRANSPARENT_INDEX. "
3161 "If GLX_NONE is specified, then only opaque frame buffer configurations will be considered; "
3162 "if GLX_TRANSPARENT_RGB is specified, then only transparent frame buffer configurations that support RGBA rendering will be considered; "
3163 "if GLX_TRANSPARENT_INDEX is specified, then only transparent frame buffer configurations that support color index rendering will be considered."
3164 "The default value is GLX_NONE.",
3166 { GLX_TRANSPARENT_INDEX_VALUE, "GLX_TRANSPARENT_INDEX_VALUE",
3167 "Must be followed by an integer value indicating the transparent index value; the value must be between 0 and the maximum "
3168 "frame buffer value for indices. Only frame buffer configurations that use the "
3169 "specified transparent index value will be considered. The default value is GLX_DONT_CARE. "
3170 "This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in attrib_list and specified as GLX_TRANSPARENT_INDEX.",
3172 { GLX_TRANSPARENT_RED_VALUE, "GLX_TRANSPARENT_RED_VALUE",
3173 "Must be followed by an integer value indicating the transparent red value; the value must be between 0 and the maximum "
3174 "frame buffer value for red. Only frame buffer configurations that use the specified transparent red value will be considered. "
3175 "The default value is GLX_DONT_CARE. This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in "
3176 "attrib_list and specified as GLX_TRANSPARENT_RGB.",
3178 { GLX_TRANSPARENT_GREEN_VALUE, "GLX_TRANSPARENT_GREEN_VALUE",
3179 "Must be followed by an integer value indicating the transparent green value; the value must be between 0 and the maximum "
3180 "frame buffer value for green. Only frame buffer configurations that use the specified transparent green value will be considered."
3181 "The default value is GLX_DONT_CARE. This attribute is "
3182 "ignored unless GLX_TRANSPARENT_TYPE is included in attrib_list and specified as GLX_TRANSPARENT_RGB.",
3184 { GLX_TRANSPARENT_BLUE_VALUE, "GLX_TRANSPARENT_BLUE_VALUE",
3185 "Must be followed by an integer value indicating the transparent blue value; the value must be between 0 and the maximum "
3186 "frame buffer value for blue. Only frame buffer configurations that use the specified transparent blue value will be considered."
3187 "The default value is GLX_DONT_CARE. This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in "
3188 "attrib_list and specified as GLX_TRANSPARENT_RGB. ",
3190 { GLX_TRANSPARENT_ALPHA_VALUE, "GLX_TRANSPARENT_ALPHA_VALUE",
3191 "Must be followed by an integer value indicating the transparent alpha value; the value must be between 0 and the maximum "
3192 "frame buffer value for alpha. Only frame buffer configurations that use the "
3193 "specified transparent alpha value will be considered. The default value is GLX_DONT_CARE.",
3195 { 0, NULL, NULL, -1 }
3198 const char * get_attr_name( int val, int * pdef )
3200 PPXATTS pat = &pxAtts[0];
3203 if ( pat->attr == val ) {
3210 return "VALUE NOT IN LIST";
3214 // eof - RenderTexture.cpp