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
43 #pragma warning(disable:4786)
49 * Jan. 2005, Removed GLEW dependencies, Erik Hofman, Fred Bouvier
50 * Nov. 2005, Use the simgear logging facility, Erik Hofman
51 * Mar. 2006, Add MAC OS X support, Alexander Powell
55 # include <simgear_config.h>
58 #include <simgear/compiler.h>
59 #include <simgear/debug/logstream.hxx>
60 #include <simgear/screen/extensions.hxx>
61 #include <simgear/screen/RenderTexture.h>
71 #pragma comment(lib, "gdi32.lib") // required for GetPixelFormat()
76 // DEBUG - add a lot of noise
82 const char * get_attr_name( int val, int * pdef );
83 #define dbg_printf printf
85 #if defined (__GNUC__)
86 #define dbg_printf(format,args...) ((void)0)
87 #else // defined (__GNUC__)
89 #endif // defined (__GNUC__)
90 #endif // defined (_DEBUG)
92 // CHOP/NOT CHOP SOME CODE TO GET SOMETHING WORKING!
93 #define ADD_QUERY_BUFFER
94 #define ADD_GET_DRAWABLE
95 // =======================================
99 static bool fctPtrInited = false;
100 /* WGL_ARB_pixel_format */
101 static wglChoosePixelFormatARBProc wglChoosePixelFormatARBPtr = 0;
102 static wglGetPixelFormatAttribivARBProc wglGetPixelFormatAttribivARBPtr = 0;
103 /* WGL_ARB_pbuffer */
104 static wglCreatePbufferARBProc wglCreatePbufferARBPtr = 0;
105 static wglGetPbufferDCARBProc wglGetPbufferDCARBPtr = 0;
106 static wglQueryPbufferARBProc wglQueryPbufferARBPtr = 0;
107 static wglReleasePbufferDCARBProc wglReleasePbufferDCARBPtr = 0;
108 static wglDestroyPbufferARBProc wglDestroyPbufferARBPtr = 0;
109 /* WGL_ARB_render_texture */
110 static wglBindTexImageARBProc wglBindTexImageARBPtr = 0;
111 static wglReleaseTexImageARBProc wglReleaseTexImageARBPtr = 0;
113 #elif defined( __MACH__ )
115 static bool glXVersion1_3Present = false;
116 static glXChooseFBConfigProc glXChooseFBConfigPtr = 0;
117 static glXCreatePbufferProc glXCreatePbufferPtr = 0;
118 static glXCreateGLXPbufferProc glXCreateGLXPbufferPtr = 0;
119 static glXGetVisualFromFBConfigProc glXGetVisualFromFBConfigPtr = 0;
120 static glXCreateContextProc glXCreateContextPtr = 0;
121 static glXCreateContextWithConfigProc glXCreateContextWithConfigPtr = 0;
122 static glXDestroyPbufferProc glXDestroyPbufferPtr = 0;
123 static glXQueryDrawableProc glXQueryDrawablePtr = 0;
124 static glXQueryGLXPbufferSGIXProc glXQueryGLXPbufferSGIXPtr = 0;
127 //---------------------------------------------------------------------------
128 // Function : RenderTexture::RenderTexture
130 //---------------------------------------------------------------------------
132 * @fn RenderTexture::RenderTexture()
133 * @brief Mode-string-based Constructor.
135 RenderTexture::RenderTexture(const char *strMode)
139 _bIsDepthTexture(false),
140 _bHasARBDepthTexture(true), // [Redge]
141 #if defined(_WIN32) || defined(__MACH__)
142 _eUpdateMode(RT_RENDER_TO_TEXTURE),
144 _eUpdateMode(RT_COPY_TO_TEXTURE),
146 _bInitialized(false),
148 _bIsBufferBound(false),
149 _iCurrentBoundBuffer(0),
153 _bDoubleBuffered(false),
157 _bShareObjects(false),
158 _bCopyContext(false),
164 _hPreviousContext(0),
165 #elif defined( __MACH__ )
168 _hPreviousContext(NULL),
173 _hPreviousDrawable(0),
174 _hPreviousContext(0),
176 _iTextureTarget(GL_NONE),
179 _pPoorDepthTexture(0) // [Redge]
181 dbg_printf("RenderTexture::RenderTexture(%s) BGN instantiation.\n", strMode );
182 _iNumColorBits[0] = _iNumColorBits[1] =
183 _iNumColorBits[2] = _iNumColorBits[3] = 0;
186 dbg_printf("RenderTexture::RenderTexture in _WIN32.\n" );
187 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
188 _pixelFormatAttribs.push_back(true);
189 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
190 _pixelFormatAttribs.push_back(true);
192 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
193 _pbufferAttribs.push_back(true);
194 #elif defined( __MACH__ )
195 dbg_printf("RenderTexture::RenderTexture in __MACH__.\n" );
196 //_pixelFormatAttribs.push_back(kCGLPFANoRecovery);
197 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
198 _pixelFormatAttribs.push_back(kCGLPFAWindow);
199 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
201 dbg_printf("RenderTexture::RenderTexture !_WIN32 and !__MACH__.\n" );
202 _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
203 _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
204 _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
205 _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
208 _ParseModeString(strMode, _pixelFormatAttribs, _pbufferAttribs);
211 _pixelFormatAttribs.push_back(0);
212 _pbufferAttribs.push_back(0);
213 #elif defined(__MACH__)
214 _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
215 _pbufferAttribs.push_back((CGLPixelFormatAttribute)0);
217 _pixelFormatAttribs.push_back(None);
220 dbg_printf("RenderTexture::RenderTexture(%s) END instantiation. pf=%d pb=%d\n",
221 strMode, (int)_pixelFormatAttribs.size(), (int)_pbufferAttribs.size() );
226 //---------------------------------------------------------------------------
227 // Function : RenderTexture::~RenderTexture
229 //---------------------------------------------------------------------------
231 * @fn RenderTexture::~RenderTexture()
234 RenderTexture::~RenderTexture()
236 dbg_printf("RenderTexture::~RenderTexture: destructor.\n" );
240 //---------------------------------------------------------------------------
241 // Function : _cglcheckError
243 //---------------------------------------------------------------------------
245 * @fn _cglCheckError()
246 * @brief Prints to stderr a description when an OS X error is found.
249 static void _cglCheckErrorHelper(CGLError err, char *sourceFile, int sourceLine)
254 fprintf(stderr, "RenderTexture CGL Error: %s at (%s,%d)",
255 CGLErrorString(err), sourceFile, sourceLine);
260 # define _cglCheckError(err) _cglCheckErrorHelper(err,__FILE__,__LINE__)
265 //---------------------------------------------------------------------------
266 // Function : _wglGetLastError
268 //---------------------------------------------------------------------------
270 * @fn wglGetLastError()
271 * @brief Returns the last windows error generated.
274 void _wglGetLastError()
278 DWORD err = GetLastError();
281 case ERROR_INVALID_PIXEL_FORMAT:
282 SG_LOG(SG_GL, SG_ALERT,
283 "RenderTexture Win32 Error: ERROR_INVALID_PIXEL_FORMAT");
285 case ERROR_NO_SYSTEM_RESOURCES:
286 SG_LOG(SG_GL, SG_ALERT,
287 "RenderTexture Win32 Error: ERROR_NO_SYSTEM_RESOURCES");
289 case ERROR_INVALID_DATA:
290 SG_LOG(SG_GL, SG_ALERT,
291 "RenderTexture Win32 Error: ERROR_INVALID_DATA");
293 case ERROR_INVALID_WINDOW_HANDLE:
294 SG_LOG(SG_GL, SG_ALERT,
295 "RenderTexture Win32 Error: ERROR_INVALID_WINDOW_HANDLE");
297 case ERROR_RESOURCE_TYPE_NOT_FOUND:
298 SG_LOG(SG_GL, SG_ALERT,
299 "RenderTexture Win32 Error: ERROR_RESOURCE_TYPE_NOT_FOUND");
306 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
307 FORMAT_MESSAGE_FROM_SYSTEM |
308 FORMAT_MESSAGE_IGNORE_INSERTS,
311 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
316 SG_LOG(SG_GL, SG_ALERT, "RenderTexture Win32 Error " << err << ":" << lpMsgBuf);
317 LocalFree( lpMsgBuf );
326 //---------------------------------------------------------------------------
327 // Function : PrintExtensionError
329 //---------------------------------------------------------------------------
331 * @fn PrintExtensionError( char* strMsg, ... )
332 * @brief Prints an error about missing OpenGL extensions.
334 void PrintExtensionError( const char* strMsg, ... )
336 SG_LOG(SG_GL, SG_ALERT,
337 "Error: RenderTexture requires the following unsupported "
338 "OpenGL extensions: ");
341 va_start(args, strMsg);
342 #if defined _WIN32 && !defined __CYGWIN__
343 _vsnprintf( strBuffer, 512, strMsg, args );
345 vsnprintf( strBuffer, 512, strMsg, args );
349 SG_LOG(SG_GL, SG_ALERT, strMsg);
350 dbg_printf("Error: RenderTexture requires the following unsupported OpenGL extensions: \n[%s]\n", strMsg);
353 //---------------------------------------------------------------------------
354 // Function : RenderTexture::Initialize
356 //---------------------------------------------------------------------------
358 * @fn RenderTexture::Initialize(int width, int height, bool shareObjects, bool copyContext);
359 * @brief Initializes the RenderTexture, sharing display lists and textures if specified.
361 * This function creates of the p-buffer. It can only be called once a GL
362 * context has already been created.
364 bool RenderTexture::Initialize(int width, int height,
365 bool shareObjects /* = true */,
366 bool copyContext /* = false */)
368 assert(width > 0 && height > 0);
370 dbg_printf("RenderTexture::Initialize w=%d h=%d\n", width, height );
372 _iWidth = width; _iHeight = height;
373 _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
375 _bShareObjects = shareObjects;
376 _bCopyContext = copyContext;
378 // Check if this is an NVXX GPU and verify necessary extensions.
379 if (!_VerifyExtensions()) {
380 dbg_printf("RenderTexture::Initialize: _VerifyExtensions() FAILED - returning false.\n" );
388 // Get the current context.
389 HDC hdc = wglGetCurrentDC();
392 HGLRC hglrc = wglGetCurrentContext();
397 unsigned int iNumFormats;
401 // Get the pixel format for the on-screen window.
402 iFormat = GetPixelFormat(hdc);
405 SG_LOG(SG_GL, SG_ALERT,
406 "RenderTexture Error: GetPixelFormat() failed.");
412 if (!wglChoosePixelFormatARBPtr(hdc, &_pixelFormatAttribs[0], NULL,
413 1, &iFormat, &iNumFormats))
415 SG_LOG(SG_GL, SG_ALERT,
416 "RenderTexture Error: wglChoosePixelFormatARB() failed.");
420 if ( iNumFormats <= 0 )
422 SG_LOG(SG_GL, SG_ALERT,
423 "RenderTexture Error: Couldn't find a suitable "
430 // Create the p-buffer.
431 _hPBuffer = wglCreatePbufferARBPtr(hdc, iFormat, _iWidth, _iHeight,
432 &_pbufferAttribs[0]);
435 SG_LOG(SG_GL, SG_ALERT,
436 "RenderTexture Error: wglCreatePbufferARB() failed.");
441 // Get the device context.
442 _hDC = wglGetPbufferDCARBPtr( _hPBuffer);
445 SG_LOG(SG_GL, SG_ALERT,
446 "RenderTexture Error: wglGetGetPbufferDCARB() failed.");
451 // Create a gl context for the p-buffer.
454 // Let's use the same gl context..
455 // Since the device contexts are compatible (i.e. same pixelformat),
456 // we should be able to use the same gl rendering context.
461 _hGLContext = wglCreateContext( _hDC );
464 SG_LOG(SG_GL, SG_ALERT,
465 "RenderTexture Error: wglCreateContext() failed.");
471 // Share lists, texture objects, and program objects.
474 if( !wglShareLists(hglrc, _hGLContext) )
476 SG_LOG(SG_GL, SG_ALERT,
477 "RenderTexture Error: wglShareLists() failed.");
483 // Determine the actual width and height we were able to create.
484 wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
485 wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
487 _bInitialized = true;
489 // get the actual number of bits allocated:
490 int attrib = WGL_RED_BITS_ARB;
494 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
496 attrib = WGL_GREEN_BITS_ARB;
498 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
500 attrib = WGL_BLUE_BITS_ARB;
502 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
504 attrib = WGL_ALPHA_BITS_ARB;
506 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
508 attrib = WGL_DEPTH_BITS_ARB;
510 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
512 attrib = WGL_STENCIL_BITS_ARB;
514 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
516 attrib = WGL_DOUBLE_BUFFER_ARB;
518 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
519 ? (value?true:false) : false;
521 #if defined(_DEBUG) | defined(DEBUG)
522 SG_LOG(SG_GL, SG_ALERT, "Created a " << _iWidth << "x" << _iHeight <<
523 " RenderTexture with BPP(" <<
524 _iNumColorBits[0] << "," << _iNumColorBits[1] << "," <<
525 _iNumColorBits[2] << "," << _iNumColorBits[3] << ")");
526 if (_iNumDepthBits) SG_LOG(SG_GL, SG_ALERT, " depth=" << _iNumDepthBits);
527 if (_iNumStencilBits) SG_LOG(SG_GL, SG_ALERT, " stencil=" << _iNumStencilBits);
528 if (_bDoubleBuffered) SG_LOG(SG_GL, SG_ALERT, " double buffered");
531 #elif defined( __MACH__ )
532 // Get the current context.
533 CGLContextObj hglrc = CGLGetCurrentContext();
535 fprintf(stderr, "Couldn't get current context!");
537 CGLPixelFormatObj pixFormat = NULL;
541 // Copy the _pixelFormatAttribs into another array to fix
543 CGLPixelFormatAttribute *pixFormatAttribs =
544 (CGLPixelFormatAttribute *)malloc(sizeof(CGLPixelFormatAttribute)
545 * _pixelFormatAttribs.size());
547 for (unsigned int ii = 0; ii < _pixelFormatAttribs.size(); ii++)
549 pixFormatAttribs[ii] =
550 (CGLPixelFormatAttribute)_pixelFormatAttribs[ii];
554 CGLChoosePixelFormat(&pixFormatAttribs[0], &pixFormat, &iNumFormats))
557 "RenderTexture Error: CGLChoosePixelFormat() failed.\n");
558 _cglCheckError(error);
561 if ( iNumFormats <= 0 )
563 SG_LOG(SG_GL, SG_ALERT,
564 "RenderTexture Error: Couldn't find a suitable "
569 // Free the copy of the _pixelFormatAttribs array
570 free(pixFormatAttribs);
572 // Create the context.
573 error = CGLCreateContext(pixFormat, (_bShareObjects)
574 ? CGLGetCurrentContext() : NULL, &_hGLContext);
578 "RenderTexture Error: CGLCreateContext() failed.\n");
579 _cglCheckError(error);
582 CGLDestroyPixelFormat(pixFormat);
584 // Create the p-buffer.
585 error = CGLCreatePBuffer(_iWidth, _iHeight, (_bRectangle)
586 ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D, GL_RGBA, 0, &_hPBuffer);
590 "RenderTexture Error: CGLCreatePBuffer() failed.\n");
591 _cglCheckError(error);
596 if (error = CGLGetVirtualScreen(CGLGetCurrentContext(), &screen))
598 _cglCheckError(error);
601 if (error = CGLSetPBuffer(_hGLContext, _hPBuffer, 0, 0, screen))
603 _cglCheckError(error);
607 // Determine the actual width and height we were able to create.
608 //wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
609 //wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
611 _bInitialized = true;
614 // get the actual number of bits allocated:
615 int attrib = WGL_RED_BITS_ARB;
619 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
621 attrib = WGL_GREEN_BITS_ARB;
623 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
625 attrib = WGL_BLUE_BITS_ARB;
627 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
629 attrib = WGL_ALPHA_BITS_ARB;
631 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
633 attrib = WGL_DEPTH_BITS_ARB;
635 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
637 attrib = WGL_STENCIL_BITS_ARB;
639 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
641 attrib = WGL_DOUBLE_BUFFER_ARB;
643 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
644 ? (value?true:false) : false;
647 #if defined(_DEBUG) | defined(DEBUG)
648 fprintf(stderr, "Created a %dx%d RenderTexture with BPP(%d, %d, %d, %d)",
650 _iNumColorBits[0], _iNumColorBits[1],
651 _iNumColorBits[2], _iNumColorBits[3]);
652 if (_iNumDepthBits) fprintf(stderr, " depth=%d", _iNumDepthBits);
653 if (_iNumStencilBits) fprintf(stderr, " stencil=%d", _iNumStencilBits);
654 if (_bDoubleBuffered) fprintf(stderr, " double buffered");
655 fprintf(stderr, "\n");
658 #else // !_WIN32, !__MACH_
660 _pDisplay = glXGetCurrentDisplay();
662 dbg_printf("RenderTexture::Initialize: ERROR: glXGetCurrentDisplay() returned NULL! return false\n");
665 dbg_printf("RenderTexture::Initialize: got glXGetCurrentDisplay() _pDisplay=[%p]\n", _pDisplay);
666 // glXGetCurrentContext returns the current context, as specified by glXMakeCurrent.
667 // If there is no current context, NULL is returned.
668 GLXContext context = glXGetCurrentContext();
670 dbg_printf("RenderTexture::Initialize: ERROR: glXGetCurrentContext() returned NULL! return false\n");
673 dbg_printf("RenderTexture::Initialize: got glXGetCurrentContext() context=[%p]\n", context);
674 int screen = DefaultScreen(_pDisplay);
675 dbg_printf("RenderTexture::Initialize: DefaultScreen(_pDisplay) screen=%d\n", screen);
677 XVisualInfo *visInfo = NULL;
679 GLXFBConfig *fbConfigs;
682 dbg_printf("Using %d pixelFormatAttribs array\n", (int)_pixelFormatAttribs.size());
683 size_t max = _pixelFormatAttribs.size() / 2;
686 for (n = 0; n < max; n++) {
687 const char * cp = get_attr_name(_pixelFormatAttribs[n*2], &dat);
688 printf( "%s(%d) = %d (def=%d)\n",
689 cp, _pixelFormatAttribs[n*2], _pixelFormatAttribs[(n*2)+1], dat );
692 if ( n < _pixelFormatAttribs.size() )
693 printf( "Array ends with %d\n", _pixelFormatAttribs[n] );
695 printf( "WARNING: Array does not appear ODD! which is ODD\n" );
698 fbConfigs = glXChooseFBConfigPtr(_pDisplay, screen,
699 &_pixelFormatAttribs[0], &nConfigs);
700 // NOTE: ref: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseFBConfig.xml says
701 // Next, call glXGetFBConfigAttrib to retrieve additional attributes for the frame buffer configurations and then select between them.
703 if (nConfigs <= 0 || !fbConfigs)
705 SG_LOG(SG_GL, SG_ALERT,
706 "RenderTexture Error: Couldn't find a suitable pixel format.");
707 dbg_printf("RenderTexture Error: Couldn't find a suitable pixel format. return false\n");
711 dbg_printf("RenderTexture::Initialize: glXChooseFBConfigPtr() nConfigs = %d, fbConfigs=[%p]\n", nConfigs, fbConfigs);
714 GLX_PBUFFER_WIDTH, _iWidth,
715 GLX_PBUFFER_HEIGHT, _iHeight,
716 GLX_LARGEST_PBUFFER, False,
719 // Pick the first returned format that will return a pbuffer
720 // if (glXVersion1_3Present)
721 if (glXCreatePbufferPtr && glXGetVisualFromFBConfigPtr && glXCreateContextPtr)
723 dbg_printf("RenderTexture::Initialize: glXVersion1_3Present = TRUE\n");
724 for (int i=0;i<nConfigs;i++)
726 _hPBuffer = glXCreatePbufferPtr(_pDisplay, fbConfigs[i], pbufAttrib);
729 XVisualInfo *visInfo = glXGetVisualFromFBConfigPtr(_pDisplay, fbConfigs[i]);
731 _hGLContext = glXCreateContextPtr(_pDisplay, visInfo,
732 _bShareObjects ? context : NULL,
736 dbg_printf("RenderTexture Error: glXCreateContextPtr(_pDisplay, visInfo,..) FAILED! return false\n");
751 dbg_printf("RenderTexture::Initialize: glXVersion1_3Present = FALSE w=%d h=%d\n", _iWidth, _iHeight);
752 for (int i=0; i < nConfigs; i++)
754 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() get buffer ptr\n", (i + 1));
755 _hPBuffer = glXCreateGLXPbufferPtr(_pDisplay, fbConfigs[i],
757 &pbufAttrib[0] ); //NULL);
760 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() got buffer [%p]\n", (i + 1), (void*)_hPBuffer);
761 _hGLContext = glXCreateContextWithConfigPtr(_pDisplay,
764 _bShareObjects ? context : NULL,
766 dbg_printf("RenderTexture::Initialize: %d: glXCreateContextWithConfigPtr() _hGLContext=[%p]\n", (i + 1), _hGLContext);
769 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() NO buffer\n", (i + 1));
774 dbg_printf("RenderTexture::Initialize: doing XFree( fbConfigs=[%p].\n", fbConfigs);
779 SG_LOG(SG_GL, SG_ALERT,
780 "RenderTexture Error: glXCreateGLXPbufferPtr() failed.");
781 dbg_printf("RenderTexture Error: glXCreateGLXPbufferPtr() failed.\n");
788 _hGLContext = glXCreateContext(_pDisplay, visInfo,
789 _bShareObjects ? context : NULL, False);
792 SG_LOG(SG_GL, SG_ALERT,
793 "RenderTexture Error: glXCreateContext() failed.");
794 dbg_printf("RenderTexture Error: glXCreateContext() failed. return false\n");
799 // if (!glXVersion1_3Present)
800 if ((!glXCreatePbufferPtr || !glXGetVisualFromFBConfigPtr || !glXCreateContextPtr) &&
801 (!glXVersion1_3Present))
803 #ifdef ADD_QUERY_BUFFER
804 dbg_printf("RenderTexture::Initialize: Doing glXQueryGLXPbufferSGIXPtr with GLX_WIDTH_SGIX\n");
805 glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_WIDTH_SGIX,
807 dbg_printf("RenderTexture::Initialize: Doing glXQueryGLXPbufferSGIXPtr with GLX_HEIGHT_SGIX\n");
808 glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_HEIGHT_SGIX,
811 dbg_printf("RenderTexture::Initialize: SKIPPED doing glXQueryGLXPbufferSGIXPtr with GLX_WIDTH_SGIX and GLX_HEIGHT_SGIX\n");
812 #endif // #ifdef ADD_QUERY_BUFFER
815 _bInitialized = true;
816 dbg_printf( "RenderTexture::Initialize: _bIniialized set TRUE\n" );
817 // XXX Query the color format
822 // Now that the pbuffer is created, allocate any texture objects needed,
823 // and initialize them (for CTT updates only). These must be allocated
824 // in the context of the pbuffer, though, or the RT won't work without
827 if (false == wglMakeCurrent( _hDC, _hGLContext))
832 #elif defined( __MACH__ )
834 if (err = CGLSetCurrentContext(_hGLContext))
841 #ifdef ADD_GET_DRAWABLE
842 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentContext()\n" );
843 _hPreviousContext = glXGetCurrentContext();
844 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentDrawable()\n" );
845 _hPreviousDrawable = glXGetCurrentDrawable();
847 _hPreviousContext = context;
848 _hPreviousDrawable = 0;
849 dbg_printf( "RenderTexture::Initialize: SKIPPED doing glXGetCurrentContext(2nd) AND glXGetCurrentDrawable()\n" );
850 #endif // #ifdef ADD_GET_DRAWABLE
852 dbg_printf( "RenderTexture::Initialize: doing glXMakeCurrent(_pDisplay(%p), _hPBuffer(%p), _hGLContext(%p))\n",
853 _pDisplay, (void*)_hPBuffer, _hGLContext );
854 if (False == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
856 dbg_printf( "glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext) FAILED. return false\n" );
862 bool result = _InitializeTextures();
864 BindBuffer(WGL_FRONT_LEFT_ARB);
870 // make the previous rendering context current
871 if (false == wglMakeCurrent( hdc, hglrc))
876 #elif defined( __MACH__ )
877 if (err = CGLSetCurrentContext(_hPreviousContext))
883 if (False == glXMakeCurrent(_pDisplay,
884 _hPreviousDrawable, _hPreviousContext))
886 dbg_printf("glXMakeCurrent(_pDisplay, _hPreviousDrawable, _hPreviousContext)) FAILED! return false\n" );
890 if (glXVersion1_3Present)
891 //if ((glXVersion1_3Present) ||
892 // (glXCreatePbufferPtr && glXGetVisualFromFBConfigPtr && glXCreateContextPtr && glXQueryDrawablePtr))
894 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentDrawable()\n" );
895 GLXDrawable draw = glXGetCurrentDrawable();
896 dbg_printf( "RenderTexture::Initialize: doing glXQueryDrawablePtr for GLX_WIDTH and GLX_HEIGHT\n" );
897 glXQueryDrawablePtr(_pDisplay, draw, GLX_WIDTH, (unsigned int*)&_iWidth);
898 glXQueryDrawablePtr(_pDisplay, draw, GLX_HEIGHT, (unsigned int*)&_iHeight);
902 dbg_printf( "RenderTexture::Initialize(w=%d,h=%d): returning %s\n", _iWidth, _iHeight, (result ? "TRUE" : "FALSE") );
907 //---------------------------------------------------------------------------
908 // Function : RenderTexture::_Invalidate
910 //---------------------------------------------------------------------------
912 * @fn RenderTexture::_Invalidate()
913 * @brief Returns the pbuffer memory to the graphics device.
916 bool RenderTexture::_Invalidate()
918 dbg_printf( "RenderTexture::_Invalidate() called...\n" );
920 _iNumColorBits[0] = _iNumColorBits[1] =
921 _iNumColorBits[2] = _iNumColorBits[3] = 0;
923 _iNumStencilBits = 0;
926 glDeleteTextures(1, &_iTextureID);
927 if (_bIsDepthTexture)
930 if (!_bHasARBDepthTexture) delete[] _pPoorDepthTexture;
932 glDeleteTextures(1, &_iDepthTextureID);
938 // Check if we are currently rendering in the pbuffer
939 if (wglGetCurrentContext() == _hGLContext)
942 wglDeleteContext( _hGLContext);
943 wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
944 wglDestroyPbufferARBPtr( _hPBuffer );
948 #elif defined( __MACH__ )
951 if (CGLGetCurrentContext() == _hGLContext)
952 CGLSetCurrentContext(NULL);
954 CGLDestroyContext(_hGLContext);
955 CGLDestroyPBuffer(_hPBuffer);
962 if(glXGetCurrentContext() == _hGLContext)
963 // XXX I don't know if this is right at all
964 glXMakeCurrent(_pDisplay, _hPBuffer, 0);
965 glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
967 dbg_printf( "RenderTexture::_Invalidate: glXDestroyPbufferPtr(_pDisplay, _hPBuffer); return true\n" );
972 dbg_printf( "RenderTexture::_Invalidate: return false\n" );
973 // [WVB] do we need to call _ReleaseBoundBuffers() too?
978 //---------------------------------------------------------------------------
979 // Function : RenderTexture::Reset
981 //---------------------------------------------------------------------------
983 * @fn RenderTexture::Reset()
984 * @brief Resets the resolution of the offscreen buffer.
986 * Causes the buffer to delete itself. User must call Initialize() again
989 bool RenderTexture::Reset(const char *strMode, ...)
991 dbg_printf("RenderTexure:Reset(): with %s\n", strMode);
993 _iWidth = 0; _iHeight = 0;
994 _bIsTexture = false; _bIsDepthTexture = false,
995 _bHasARBDepthTexture = true;
996 #if defined(_WIN32) || defined(__MACH__)
997 _eUpdateMode = RT_RENDER_TO_TEXTURE;
999 _eUpdateMode = RT_COPY_TO_TEXTURE;
1001 _bInitialized = false;
1002 _iNumAuxBuffers = 0;
1003 _bIsBufferBound = false;
1004 _iCurrentBoundBuffer = 0;
1005 _iNumDepthBits = 0; _iNumStencilBits = 0;
1006 _bDoubleBuffered = false;
1007 _bFloat = false; _bPowerOf2 = true;
1008 _bRectangle = false; _bMipmap = false;
1009 _bShareObjects = false; _bCopyContext = false;
1010 _iTextureTarget = GL_NONE; _iTextureID = 0;
1011 _iDepthTextureID = 0;
1012 _pPoorDepthTexture = 0;
1013 _pixelFormatAttribs.clear();
1014 _pbufferAttribs.clear();
1015 if (IsInitialized())
1019 dbg_printf( "RenderTexture::Reset(): failed to invalidate. return false\n");
1024 dbg_printf( "RenderTexture::Reset(): was Initialized, and now _Invalidate() ok.");
1029 dbg_printf("RenderTexure:Reset(): previous NOT initialised!\n");
1032 _iNumColorBits[0] = _iNumColorBits[1] =
1033 _iNumColorBits[2] = _iNumColorBits[3] = 0;
1036 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
1037 _pixelFormatAttribs.push_back(true);
1038 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
1039 _pixelFormatAttribs.push_back(true);
1041 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
1042 _pbufferAttribs.push_back(true);
1043 #elif defined( __MACH__ )
1044 //_pixelFormatAttribs.push_back(kCGLPFANoRecovery);
1045 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
1046 _pixelFormatAttribs.push_back(kCGLPFAWindow);
1047 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
1049 _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
1050 _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
1051 _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
1052 _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
1056 char strBuffer[256];
1057 va_start(args,strMode);
1058 #if defined _WIN32 && !defined __CYGWIN__
1059 _vsnprintf( strBuffer, 256, strMode, args );
1061 vsnprintf( strBuffer, 256, strMode, args );
1065 _ParseModeString(strBuffer, _pixelFormatAttribs, _pbufferAttribs);
1068 _pixelFormatAttribs.push_back(0);
1069 _pbufferAttribs.push_back(0);
1070 #elif defined(__MACH__)
1071 _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
1073 _pixelFormatAttribs.push_back(None);
1075 dbg_printf("RenderTexure:Reset(): returning true.\n");
1079 //------------------------------------------------------------------------------
1080 // Function : RenderTexture::Resize
1082 //------------------------------------------------------------------------------
1084 * @fn RenderTexture::Resize(int iWidth, int iHeight)
1085 * @brief Changes the size of the offscreen buffer.
1087 * Like Reset() this causes the buffer to delete itself.
1088 * But unlike Reset(), this call re-initializes the RenderTexture.
1089 * Note that Resize() will not work after calling Reset(), or before
1090 * calling Initialize() the first time.
1092 bool RenderTexture::Resize(int iWidth, int iHeight)
1094 if (!_bInitialized) {
1095 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Resize(): must Initialize() first.");
1098 if (iWidth == _iWidth && iHeight == _iHeight) {
1102 // Do same basic work as _Invalidate, but don't reset all our flags
1104 glDeleteTextures(1, &_iTextureID);
1105 if (_bIsDepthTexture)
1106 glDeleteTextures(1, &_iDepthTextureID);
1110 // Check if we are currently rendering in the pbuffer
1111 if (wglGetCurrentContext() == _hGLContext)
1112 wglMakeCurrent(0,0);
1114 wglDeleteContext( _hGLContext);
1115 wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
1116 wglDestroyPbufferARBPtr( _hPBuffer );
1120 #elif defined( __MACH__ )
1123 if (CGLGetCurrentContext() == _hGLContext)
1124 CGLSetCurrentContext(NULL);
1126 CGLDestroyContext(_hGLContext);
1127 CGLDestroyPBuffer(_hPBuffer);
1134 if(glXGetCurrentContext() == _hGLContext)
1135 // XXX I don't know if this is right at all
1136 glXMakeCurrent(_pDisplay, _hPBuffer, 0);
1137 glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
1142 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Resize(): failed to resize.");
1145 _bInitialized = false;
1146 return Initialize(iWidth, iHeight, _bShareObjects, _bCopyContext);
1149 //---------------------------------------------------------------------------
1150 // Function : RenderTexture::BeginCapture
1152 //---------------------------------------------------------------------------
1154 * @fn RenderTexture::BeginCapture()
1155 * @brief Activates rendering to the RenderTexture.
1157 bool RenderTexture::BeginCapture()
1161 SG_LOG(SG_GL, SG_ALERT,
1162 "RenderTexture::BeginCapture(): Texture is not initialized!");
1166 // cache the current context so we can reset it when EndCapture() is called.
1167 _hPreviousDC = wglGetCurrentDC();
1168 if (NULL == _hPreviousDC)
1170 _hPreviousContext = wglGetCurrentContext();
1171 if (NULL == _hPreviousContext)
1173 #elif defined( __MACH__ )
1174 _hPreviousContext = CGLGetCurrentContext();
1176 _hPreviousContext = glXGetCurrentContext();
1177 _hPreviousDrawable = glXGetCurrentDrawable();
1180 _ReleaseBoundBuffers();
1182 return _MakeCurrent();
1186 //---------------------------------------------------------------------------
1187 // Function : RenderTexture::EndCapture
1189 //---------------------------------------------------------------------------
1191 * @fn RenderTexture::EndCapture()
1192 * @brief Ends rendering to the RenderTexture.
1194 bool RenderTexture::EndCapture()
1198 SG_LOG(SG_GL, SG_ALERT,
1199 "RenderTexture::EndCapture() : Texture is not initialized!");
1203 glFlush(); // Added by a-lex
1208 // make the previous rendering context current
1209 if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
1214 #elif defined( __MACH__ )
1216 if (err = CGLSetCurrentContext(_hPreviousContext))
1218 _cglCheckError(err);
1222 if (False == glXMakeCurrent(_pDisplay, _hPreviousDrawable,
1229 // rebind the textures to a buffers for RTT
1230 BindBuffer(_iCurrentBoundBuffer);
1236 //---------------------------------------------------------------------------
1237 // Function : RenderTexture::BeginCapture(RenderTexture*)
1239 //---------------------------------------------------------------------------
1241 * @fn RenderTexture::BeginCapture(RenderTexture* other)
1242 * @brief Ends capture of 'other', begins capture on 'this'
1244 * When performing a series of operations where you modify one texture after
1245 * another, it is more efficient to use this method instead of the equivalent
1246 * 'EndCapture'/'BeginCapture' pair. This method switches directly to the
1247 * new context rather than changing to the default context, and then to the
1250 * RenderTexture doesn't have any mechanism for determining if
1251 * 'current' really is currently active, so no error will be thrown
1254 bool RenderTexture::BeginCapture(RenderTexture* current)
1256 // bool bContextReset = false;
1258 if (current == this) {
1259 return true; // no switch necessary
1262 // treat as normal Begin if current is 0.
1263 return BeginCapture();
1267 SG_LOG(SG_GL, SG_ALERT,
1268 "RenderTexture::BeginCapture(RenderTexture*): Texture is not initialized!");
1271 if (!current->_bInitialized)
1273 SG_LOG(SG_GL, SG_ALERT,
1274 "RenderTexture::BeginCapture(RenderTexture): 'current' texture is not initialized!");
1278 // Sync current pbuffer with its CTT texture if necessary
1279 current->_MaybeCopyBuffer();
1281 // pass along the previous context so we can reset it when
1282 // EndCapture() is called.
1284 _hPreviousDC = current->_hPreviousDC;
1285 if (NULL == _hPreviousDC)
1287 _hPreviousContext = current->_hPreviousContext;
1288 if (NULL == _hPreviousContext)
1290 #elif defined( __MACH__ )
1291 _hPreviousContext = current->_hPreviousContext;
1293 _hPreviousContext = current->_hPreviousContext;
1294 _hPreviousDrawable = current->_hPreviousDrawable;
1297 // Unbind textures before making context current
1298 if (!_ReleaseBoundBuffers())
1301 // Make the pbuffer context current
1302 if (!_MakeCurrent())
1305 // Rebind buffers of initial RenderTexture
1306 current->BindBuffer(_iCurrentBoundBuffer);
1307 current->_BindDepthBuffer();
1314 //---------------------------------------------------------------------------
1315 // Function : RenderTexture::Bind
1317 //---------------------------------------------------------------------------
1319 * @fn RenderTexture::Bind()
1320 * @brief Binds RGB texture.
1322 void RenderTexture::Bind() const
1324 if (_bInitialized && _bIsTexture)
1326 glBindTexture(_iTextureTarget, _iTextureID);
1331 //---------------------------------------------------------------------------
1332 // Function : RenderTexture::BindDepth
1334 //---------------------------------------------------------------------------
1336 * @fn RenderTexture::BindDepth()
1337 * @brief Binds depth texture.
1339 void RenderTexture::BindDepth() const
1341 if (_bInitialized && _bIsDepthTexture)
1343 glBindTexture(_iTextureTarget, _iDepthTextureID);
1348 //---------------------------------------------------------------------------
1349 // Function : RenderTexture::BindBuffer
1351 //---------------------------------------------------------------------------
1353 * @fn RenderTexture::BindBuffer()
1354 * @brief Associate the RTT texture id with 'iBuffer' (e.g. WGL_FRONT_LEFT_ARB)
1356 bool RenderTexture::BindBuffer( int iBuffer )
1358 // Must bind the texture too
1359 if (_bInitialized && _bIsTexture)
1361 glBindTexture(_iTextureTarget, _iTextureID);
1364 if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
1365 (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
1367 if (FALSE == wglBindTexImageARBPtr(_hPBuffer, iBuffer))
1369 // WVB: WGL API considers binding twice to the same buffer
1370 // to be an error. But we don't want to
1371 //_wglGetLastError();
1375 _bIsBufferBound = true;
1376 _iCurrentBoundBuffer = iBuffer;
1378 #elif defined(__MACH__)
1379 if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
1380 (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
1383 if (err=CGLTexImagePBuffer(CGLGetCurrentContext(), _hPBuffer, iBuffer))
1385 _cglCheckError(err);
1387 _bIsBufferBound = true;
1388 _iCurrentBoundBuffer = iBuffer;
1396 //---------------------------------------------------------------------------
1397 // Function : RenderTexture::BindDepthBuffer
1399 //---------------------------------------------------------------------------
1401 * @fn RenderTexture::_BindDepthBuffer()
1402 * @brief Associate the RTT depth texture id with the depth buffer
1404 bool RenderTexture::_BindDepthBuffer() const
1407 if (_bInitialized && _bIsDepthTexture &&
1408 RT_RENDER_TO_TEXTURE == _eUpdateMode)
1410 glBindTexture(_iTextureTarget, _iDepthTextureID);
1411 if (FALSE == wglBindTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
1417 #elif defined(__MACH__)
1418 if (_bInitialized && _bIsDepthTexture &&
1419 RT_RENDER_TO_TEXTURE == _eUpdateMode)
1421 glBindTexture(_iTextureTarget, _iDepthTextureID);
1422 //if (FALSE == CGLTexImagePBuffer(<#CGLContextObj ctx#>,<#CGLPBufferObj pbuffer#>,<#unsigned long source#>)(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
1424 // _wglGetLastError();
1432 //---------------------------------------------------------------------------
1433 // Function : RenderTexture::_ParseModeString
1435 //---------------------------------------------------------------------------
1437 * @fn RenderTexture::_ParseModeString()
1438 * @brief Parses the user-specified mode string for RenderTexture parameters.
1440 void RenderTexture::_ParseModeString(const char *modeString,
1441 vector<int> &pfAttribs,
1442 vector<int> &pbAttribs)
1444 dbg_printf("RenderTexture::_ParseModeString(%s). BGN vf=%d vp=%d\n", modeString, (int)pfAttribs.size(), (int)pbAttribs.size() );
1445 if (!modeString || strcmp(modeString, "") == 0)
1448 _iNumComponents = 0;
1449 #if defined(_WIN32) || defined(__MACH__)
1450 _eUpdateMode = RT_RENDER_TO_TEXTURE;
1452 _eUpdateMode = RT_COPY_TO_TEXTURE;
1456 bool bHasStencil = false;
1457 bool bBind2D = false;
1458 bool bBindRECT = false;
1459 bool bBindCUBE = false;
1461 char *mode = strdup(modeString);
1464 vector<string> tokens;
1465 char *buf = strtok(mode, " ");
1468 tokens.push_back(buf);
1469 buf = strtok(NULL, " ");
1472 for (unsigned int i = 0; i < tokens.size(); i++)
1474 string token = tokens[i];
1476 KeyVal kv = _GetKeyValuePair(token);
1479 if (kv.first == "rgb" && (_iNumComponents <= 1))
1481 if (kv.second.find("f") != kv.second.npos)
1484 vector<int> bitVec = _ParseBitVector(kv.second);
1486 if (bitVec.size() < 3) // expand the scalar to a vector
1488 bitVec.push_back(bitVec[0]);
1489 bitVec.push_back(bitVec[0]);
1493 pfAttribs.push_back(WGL_RED_BITS_ARB);
1494 pfAttribs.push_back(bitVec[0]);
1495 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1496 pfAttribs.push_back(bitVec[1]);
1497 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
1498 pfAttribs.push_back(bitVec[2]);
1499 #elif defined( __MACH__ )
1501 pfAttribs.push_back(AGL_RED_SIZE);
1502 pfAttribs.push_back(bitVec[0]);
1503 pfAttribs.push_back(AGL_GREEN_SIZE);
1504 pfAttribs.push_back(bitVec[1]);
1505 pfAttribs.push_back(AGL_BLUE_SIZE);
1506 pfAttribs.push_back(bitVec[2]);
1508 pfAttribs.push_back(kCGLPFAColorSize);
1509 pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2]);
1512 pfAttribs.push_back(GLX_RED_SIZE);
1513 pfAttribs.push_back(bitVec[0]);
1514 pfAttribs.push_back(GLX_GREEN_SIZE);
1515 pfAttribs.push_back(bitVec[1]);
1516 pfAttribs.push_back(GLX_BLUE_SIZE);
1517 pfAttribs.push_back(bitVec[2]);
1519 _iNumComponents += 3;
1522 else if (kv.first == "rgb")
1524 SG_LOG(SG_GL, SG_ALERT,
1525 "RenderTexture Warning: mistake in components definition "
1526 "(rgb + " << _iNumComponents << ").");
1527 dbg_printf("RenderTexture Warning 1: mistake in components definition "
1528 "(rgb + %d).\n", _iNumComponents );
1531 if (kv.first == "rgba" && (_iNumComponents == 0))
1533 if (kv.second.find("f") != kv.second.npos)
1536 vector<int> bitVec = _ParseBitVector(kv.second);
1538 if (bitVec.size() < 4) // expand the scalar to a vector
1540 bitVec.push_back(bitVec[0]);
1541 bitVec.push_back(bitVec[0]);
1542 bitVec.push_back(bitVec[0]);
1546 pfAttribs.push_back(WGL_RED_BITS_ARB);
1547 pfAttribs.push_back(bitVec[0]);
1548 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1549 pfAttribs.push_back(bitVec[1]);
1550 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
1551 pfAttribs.push_back(bitVec[2]);
1552 pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
1553 pfAttribs.push_back(bitVec[3]);
1554 #elif defined( __MACH__ )
1556 pfAttribs.push_back(AGL_RED_SIZE);
1557 pfAttribs.push_back(bitVec[0]);
1558 pfAttribs.push_back(AGL_GREEN_SIZE);
1559 pfAttribs.push_back(bitVec[1]);
1560 pfAttribs.push_back(AGL_BLUE_SIZE);
1561 pfAttribs.push_back(bitVec[2]);
1562 pfAttribs.push_back(AGL_ALPHA_SIZE);
1563 pfAttribs.push_back(bitVec[3]);
1565 pfAttribs.push_back(kCGLPFAColorSize);
1566 pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2] + bitVec[3]);
1567 //pfAttribs.push_back(kCGLPFAAlphaSize);
1568 //pfAttribs.push_back(bitVec[3]);
1569 // printf("Color size: %d\n", bitVec[0] + bitVec[1] + bitVec[2] + bitVec[3]);
1573 pfAttribs.push_back(GLX_RED_SIZE);
1574 pfAttribs.push_back(bitVec[0]);
1575 pfAttribs.push_back(GLX_GREEN_SIZE);
1576 pfAttribs.push_back(bitVec[1]);
1577 pfAttribs.push_back(GLX_BLUE_SIZE);
1578 pfAttribs.push_back(bitVec[2]);
1579 pfAttribs.push_back(GLX_ALPHA_SIZE);
1580 pfAttribs.push_back(bitVec[3]);
1582 _iNumComponents = 4;
1585 else if (kv.first == "rgba")
1587 SG_LOG(SG_GL, SG_ALERT,
1588 "RenderTexture Warning: mistake in components definition "
1589 "(rgba + " << _iNumComponents << ").");
1590 dbg_printf("RenderTexture Warning 2: mistake in components definition "
1591 "(rgb + %d).\n", _iNumComponents );
1594 if (kv.first == "r" && (_iNumComponents <= 1))
1596 if (kv.second.find("f") != kv.second.npos)
1599 vector<int> bitVec = _ParseBitVector(kv.second);
1602 pfAttribs.push_back(WGL_RED_BITS_ARB);
1603 pfAttribs.push_back(bitVec[0]);
1604 #elif defined( __MACH__ )
1606 pfAttribs.push_back(AGL_RED_SIZE);
1607 pfAttribs.push_back(bitVec[0]);
1609 pfAttribs.push_back(kCGLPFAColorSize);
1610 pfAttribs.push_back(bitVec[0]);
1613 pfAttribs.push_back(GLX_RED_SIZE);
1614 pfAttribs.push_back(bitVec[0]);
1619 else if (kv.first == "r")
1621 SG_LOG(SG_GL, SG_ALERT,
1622 "RenderTexture Warning: mistake in components definition "
1623 "(r + " << _iNumComponents << ").");
1624 dbg_printf("RenderTexture Warning 3: mistake in components definition "
1625 "(rgb + %d).\n", _iNumComponents );
1627 if (kv.first == "rg" && (_iNumComponents <= 1))
1629 if (kv.second.find("f") != kv.second.npos)
1632 vector<int> bitVec = _ParseBitVector(kv.second);
1634 if (bitVec.size() < 2) // expand the scalar to a vector
1636 bitVec.push_back(bitVec[0]);
1640 pfAttribs.push_back(WGL_RED_BITS_ARB);
1641 pfAttribs.push_back(bitVec[0]);
1642 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1643 pfAttribs.push_back(bitVec[1]);
1644 #elif defined( __MACH__ )
1646 pfAttribs.push_back(AGL_RED_SIZE);
1647 pfAttribs.push_back(bitVec[0]);
1648 pfAttribs.push_back(AGL_GREEN_SIZE);
1649 pfAttribs.push_back(bitVec[1]);
1651 pfAttribs.push_back(kCGLPFAColorSize);
1652 pfAttribs.push_back(bitVec[0] + bitVec[1]);
1655 pfAttribs.push_back(GLX_RED_SIZE);
1656 pfAttribs.push_back(bitVec[0]);
1657 pfAttribs.push_back(GLX_GREEN_SIZE);
1658 pfAttribs.push_back(bitVec[1]);
1660 _iNumComponents += 2;
1663 else if (kv.first == "rg")
1665 SG_LOG(SG_GL, SG_ALERT,
1666 "RenderTexture Warning: mistake in components definition "
1667 "(rg + " << _iNumComponents << ").");
1668 dbg_printf("RenderTexture Warning 4: mistake in components definition "
1669 "(rgb + %d).\n", _iNumComponents );
1672 if (kv.first == "depth")
1674 if (kv.second == "")
1677 iDepthBits = strtol(kv.second.c_str(), 0, 10);
1681 if (kv.first == "stencil")
1685 pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
1686 #elif defined( __MACH__ )
1688 pfAttribs.push_back(AGL_STENCIL_SIZE);
1690 pfAttribs.push_back(kCGLPFAStencilSize);
1693 pfAttribs.push_back(GLX_STENCIL_SIZE);
1695 if (kv.second == "")
1696 pfAttribs.push_back(8);
1698 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1702 if (kv.first == "samples")
1705 pfAttribs.push_back(WGL_SAMPLE_BUFFERS_ARB);
1706 pfAttribs.push_back(1);
1707 pfAttribs.push_back(WGL_SAMPLES_ARB);
1708 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1709 #elif defined( __MACH__ )
1711 pfAttribs.push_back(AGL_SAMPLE_BUFFERS_ARB);
1712 pfAttribs.push_back(1);
1713 pfAttribs.push_back(AGL_SAMPLES_ARB);
1715 pfAttribs.push_back(kCGLPFAMultisample);
1716 pfAttribs.push_back(kCGLPFASamples);
1718 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1720 pfAttribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
1721 pfAttribs.push_back(1);
1722 pfAttribs.push_back(GLX_SAMPLES_ARB);
1723 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1729 if (kv.first == "doublebuffer" || kv.first == "double")
1732 pfAttribs.push_back(WGL_DOUBLE_BUFFER_ARB);
1733 pfAttribs.push_back(true);
1734 #elif defined( __MACH__ )
1736 pfAttribs.push_back(AGL_DOUBLEBUFFER);
1737 pfAttribs.push_back(True);
1739 pfAttribs.push_back(kCGLPFADoubleBuffer);
1742 pfAttribs.push_back(GLX_DOUBLEBUFFER);
1743 pfAttribs.push_back(True);
1748 if (kv.first == "aux")
1751 pfAttribs.push_back(WGL_AUX_BUFFERS_ARB);
1752 #elif defined( __MACH__ )
1754 pfAttribs.push_back(AGL_AUX_BUFFERS);
1756 pfAttribs.push_back(kCGLPFAAuxBuffers);
1759 pfAttribs.push_back(GLX_AUX_BUFFERS);
1761 if (kv.second == "")
1762 pfAttribs.push_back(0);
1764 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1768 if (token.find("tex") == 0)
1772 if ((kv.first == "texRECT") && (GL_NV_texture_rectangle ||
1773 GL_EXT_texture_rectangle))
1778 else if (kv.first == "texCUBE")
1790 if (token.find("depthTex") == 0)
1792 _bIsDepthTexture = true;
1794 if ((kv.first == "depthTexRECT") && (GL_NV_texture_rectangle ||
1795 GL_EXT_texture_rectangle))
1800 else if (kv.first == "depthTexCUBE")
1812 if (kv.first == "mipmap")
1818 if (kv.first == "rtt")
1820 _eUpdateMode = RT_RENDER_TO_TEXTURE;
1824 if (kv.first == "ctt")
1826 _eUpdateMode = RT_COPY_TO_TEXTURE;
1830 SG_LOG(SG_GL, SG_ALERT,
1831 "RenderTexture Error: Unknown pbuffer attribute: " <<
1833 dbg_printf("RenderTexture Error: Uknown pbuffer attribute: %s\n",
1837 // Processing of some options must be last because of interactions.
1839 // Check for inconsistent texture targets
1840 if (_bIsTexture && _bIsDepthTexture && !(bBind2D ^ bBindRECT ^ bBindCUBE))
1842 SG_LOG(SG_GL, SG_ALERT,
1843 "RenderTexture Warning: Depth and Color texture targets "
1845 dbg_printf( "RenderTexture Warning: Depth and Color texture targets should match.\n");
1848 // Apply default bit format if none specified
1850 if (0 == _iNumComponents)
1852 pfAttribs.push_back(WGL_RED_BITS_ARB);
1853 pfAttribs.push_back(8);
1854 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1855 pfAttribs.push_back(8);
1856 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
1857 pfAttribs.push_back(8);
1858 pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
1859 pfAttribs.push_back(8);
1860 _iNumComponents = 4;
1865 if (_bIsDepthTexture && !iDepthBits)
1869 pfAttribs.push_back(WGL_DEPTH_BITS_ARB);
1870 #elif defined( __MACH__ )
1872 pfAttribs.push_back(AGL_DEPTH_SIZE);
1874 pfAttribs.push_back(kCGLPFADepthSize);
1877 pfAttribs.push_back(GLX_DEPTH_SIZE);
1879 pfAttribs.push_back(iDepthBits); // default
1884 pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
1885 pfAttribs.push_back(0);
1886 #elif defined( __MACH__ )
1888 pfAttribs.push_back(AGL_STENCIL_SIZE);
1890 pfAttribs.push_back(kCGLPFAStencilSize);
1892 pfAttribs.push_back(0);
1894 pfAttribs.push_back(GLX_STENCIL_SIZE);
1895 pfAttribs.push_back(0);
1899 if (_iNumComponents < 4)
1901 // Can't do this right now -- on NVIDIA drivers, currently get
1902 // a non-functioning pbuffer if ALPHA_BITS=0 and
1903 // WGL_BIND_TO_TEXTURE_RGB_ARB=true
1905 //pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
1906 //pfAttribs.push_back(0);
1910 if (!WGL_NV_render_depth_texture && _bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1912 #if defined(DEBUG) || defined(_DEBUG)
1913 SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: No support found for "
1914 "render to depth texture.");
1916 dbg_printf("RenderTexture Warning: No support found for render to depth texture.\n");
1917 _bIsDepthTexture = false;
1921 if ((_bIsTexture || _bIsDepthTexture) &&
1922 (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1927 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1928 pbAttribs.push_back(WGL_TEXTURE_RECTANGLE_NV);
1932 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1933 pbAttribs.push_back(WGL_TEXTURE_CUBE_MAP_ARB);
1937 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1938 pbAttribs.push_back(WGL_TEXTURE_2D_ARB);
1943 pbAttribs.push_back(WGL_MIPMAP_TEXTURE_ARB);
1944 pbAttribs.push_back(true);
1946 #elif defined(__MACH__)
1947 #elif defined(DEBUG) || defined(_DEBUG)
1948 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: Render to Texture not "
1949 "supported in Linux or MacOS");
1953 // Set the pixel type
1957 if (WGL_NV_float_buffer)
1959 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1960 pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
1962 pfAttribs.push_back(WGL_FLOAT_COMPONENTS_NV);
1963 pfAttribs.push_back(true);
1967 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1968 pfAttribs.push_back(WGL_TYPE_RGBA_FLOAT_ATI);
1970 #elif defined( __MACH__ )
1971 // if (GL_MACH_float_pixels) // FIXME
1973 pfAttribs.push_back(kCGLPFAColorFloat);
1976 if (GLX_NV_float_buffer)
1978 pfAttribs.push_back(GLX_FLOAT_COMPONENTS_NV);
1979 pfAttribs.push_back(1);
1986 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1987 pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
1991 // Set up texture binding for render to texture
1992 if (_bIsTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1998 if (WGL_NV_float_buffer)
2000 switch(_iNumComponents)
2003 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
2004 pfAttribs.push_back(true);
2006 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2007 pbAttribs.push_back(WGL_TEXTURE_FLOAT_R_NV);
2010 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
2011 pfAttribs.push_back(true);
2013 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2014 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RG_NV);
2017 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
2018 pfAttribs.push_back(true);
2020 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2021 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGB_NV);
2024 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
2025 pfAttribs.push_back(true);
2027 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2028 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
2031 SG_LOG(SG_GL, SG_ALERT,
2032 "RenderTexture Warning: Bad number of components "
2033 "(r=1,rg=2,rgb=3,rgba=4): " <<
2035 dbg_printf("RenderTexture Warning 1: Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n",
2042 if (4 == _iNumComponents)
2044 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2045 pfAttribs.push_back(true);
2047 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2048 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2052 // standard ARB_render_texture only supports 3 or 4 channels
2053 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2054 pfAttribs.push_back(true);
2056 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2057 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2064 switch(_iNumComponents)
2067 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2068 pfAttribs.push_back(true);
2070 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2071 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2074 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2075 pfAttribs.push_back(true);
2077 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2078 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2081 SG_LOG(SG_GL, SG_ALERT,
2082 "RenderTexture Warning: Bad number of components "
2083 "(r=1,rg=2,rgb=3,rgba=4): " << _iNumComponents);
2084 dbg_printf("RenderTexture Warning 2: Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n",
2089 #elif defined(__MACH__)
2093 //if (WGLEW_NV_float_buffer) // FIXME
2095 switch(_iNumComponents)
2098 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
2099 pfAttribs.push_back(true);
2101 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2102 pbAttribs.push_back(WGL_TEXTURE_FLOAT_R_NV);
2105 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
2106 pfAttribs.push_back(true);
2108 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2109 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RG_NV);
2112 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
2113 pfAttribs.push_back(true);
2115 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2116 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGB_NV);
2119 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
2120 pfAttribs.push_back(true);
2122 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2123 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
2127 "RenderTexture Warning: Bad number of components "
2128 "(r=1,rg=2,rgb=3,rgba=4): %d.\n",
2135 if (4 == _iNumComponents)
2137 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2138 pfAttribs.push_back(true);
2140 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2141 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2145 // standard ARB_render_texture only supports 3 or 4 channels
2146 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2147 pfAttribs.push_back(true);
2149 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2150 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2158 switch(_iNumComponents)
2161 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2162 pfAttribs.push_back(true);
2164 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2165 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2168 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2169 pfAttribs.push_back(true);
2171 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2172 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2176 "RenderTexture Warning: Bad number of components "
2177 "(r=1,rg=2,rgb=3,rgba=4): %d.\n", _iNumComponents);
2182 #elif defined(DEBUG) || defined(_DEBUG)
2183 SG_LOG(SG_GL, SG_ALERT,
2184 "RenderTexture Error: Render to Texture not supported in Linux or MacOS");
2186 dbg_printf( "RenderTexture Error 1: Render to Texture not supported in Linux or MacOS\n");
2189 if (_bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
2194 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV);
2195 pfAttribs.push_back(true);
2197 pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
2198 pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
2202 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_DEPTH_NV);
2203 pfAttribs.push_back(true);
2205 pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
2206 pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
2208 #elif defined(__MACH__)
2209 #elif defined(DEBUG) || defined(_DEBUG)
2210 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: Render to Texture not supported in "
2213 dbg_printf( "RenderTexture Error 2: Render to Texture not supported in Linux or MacOS\n");
2215 dbg_printf("RenderTexture::_ParseModeString(%s). END vf=%d vp=%d\n", modeString, (int)pfAttribs.size(), (int)pbAttribs.size() );
2219 //---------------------------------------------------------------------------
2220 // Function : RenderTexture::_GetKeyValuePair
2222 //---------------------------------------------------------------------------
2224 * @fn RenderTexture::_GetKeyValuePair()
2225 * @brief Parses expressions of the form "X=Y" into a pair (X,Y).
2227 RenderTexture::KeyVal RenderTexture::_GetKeyValuePair(string token)
2229 string::size_type pos = 0;
2230 if ((pos = token.find("=")) != token.npos)
2232 string key = token.substr(0, pos);
2233 string value = token.substr(pos+1, token.length()-pos+1);
2234 return KeyVal(key, value);
2237 return KeyVal(token, "");
2240 //---------------------------------------------------------------------------
2241 // Function : RenderTexture::_ParseBitVector
2243 //---------------------------------------------------------------------------
2245 * @fn RenderTexture::_ParseBitVector()
2246 * @brief Parses expressions of the form "=r,g,b,a" into a vector: (r,g,b,a)
2248 vector<int> RenderTexture::_ParseBitVector(string bitVector)
2250 vector<string> pieces;
2253 if (bitVector == "")
2255 bits.push_back(8); // if a depth isn't specified, use default 8 bits
2259 string::size_type pos = 0;
2260 string::size_type nextpos = 0;
2263 nextpos = bitVector.find_first_of(", ", pos);
2264 pieces.push_back(string(bitVector, pos, nextpos - pos));
2266 } while (nextpos != bitVector.npos );
2268 for ( vector<string>::iterator it = pieces.begin(); it != pieces.end(); it++)
2270 bits.push_back(strtol(it->c_str(), 0, 10));
2276 //---------------------------------------------------------------------------
2277 // Function : RenderTexture::_VerifyExtensions
2279 //---------------------------------------------------------------------------
2281 * @fn RenderTexture::_VerifyExtensions()
2282 * @brief Checks that the necessary extensions are available based on RT mode.
2284 bool RenderTexture::_VerifyExtensions()
2286 dbg_printf("RenderTexture::_VerifyExtensions() called...\n");
2288 // a second call to _VerifyExtensions will allways return true, causing a crash
2289 // if the extension is not supported
2290 if ( true || !fctPtrInited )
2292 fctPtrInited = true;
2293 wglGetExtensionsStringARBProc wglGetExtensionsStringARBPtr = (wglGetExtensionsStringARBProc)wglGetProcAddress( "wglGetExtensionsStringARB" );
2294 if ( wglGetExtensionsStringARBPtr == 0 )
2296 PrintExtensionError("WGL_ARB_extensions_string");
2299 string wglExtensionsString = wglGetExtensionsStringARBPtr( wglGetCurrentDC() );
2300 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pixel_format" ) )
2302 wglChoosePixelFormatARBPtr = (wglChoosePixelFormatARBProc)SGLookupFunction("wglChoosePixelFormatARB");
2303 wglGetPixelFormatAttribivARBPtr = (wglGetPixelFormatAttribivARBProc)SGLookupFunction("wglGetPixelFormatAttribivARB");
2307 PrintExtensionError("WGL_ARB_pixel_format");
2310 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pbuffer" ) )
2312 wglCreatePbufferARBPtr = (wglCreatePbufferARBProc)SGLookupFunction("wglCreatePbufferARB");
2313 wglGetPbufferDCARBPtr = (wglGetPbufferDCARBProc)SGLookupFunction("wglGetPbufferDCARB");
2314 wglQueryPbufferARBPtr = (wglQueryPbufferARBProc)SGLookupFunction("wglQueryPbufferARB");
2315 wglReleasePbufferDCARBPtr = (wglReleasePbufferDCARBProc)SGLookupFunction("wglReleasePbufferDCARB");
2316 wglDestroyPbufferARBPtr = (wglDestroyPbufferARBProc)SGLookupFunction("wglDestroyPbufferARB");
2320 PrintExtensionError("WGL_ARB_pbuffer");
2323 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_render_texture" ) )
2325 wglBindTexImageARBPtr = (wglBindTexImageARBProc)SGLookupFunction("wglBindTexImageARB");
2326 wglReleaseTexImageARBPtr = (wglReleaseTexImageARBProc)SGLookupFunction("wglReleaseTexImageARB");
2328 else if ( _bIsTexture )
2330 PrintExtensionError("WGL_ARB_render_texture");
2333 if (_bRectangle && !SGIsOpenGLExtensionSupported( "GL_NV_texture_rectangle" ))
2335 PrintExtensionError("GL_NV_texture_rectangle");
2338 if (_bFloat && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) ||
2339 SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ATI_pixel_format_float" )))
2341 PrintExtensionError("GL_NV_float_buffer or GL_ATI_pixel_format_float");
2345 if (_bFloat && _bIsTexture && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) || SGIsOpenGLExtensionSupported( "GL_ATI_texture_float" )))
2347 PrintExtensionError("NV_float_buffer or ATI_texture_float");
2349 if (_bIsDepthTexture && !SGIsOpenGLExtensionSupported( "GL_ARB_depth_texture" ))
2352 #if defined(_DEBUG) | defined(DEBUG)
2353 SG_LOG(SG_GL, SG_ALERT,
2354 "RenderTexture Warning: "
2355 "OpenGL extension GL_ARB_depth_texture not available."
2356 " Using glReadPixels() to emulate behavior.");
2358 _bHasARBDepthTexture = false;
2359 //PrintExtensionError("GL_ARB_depth_texture");
2365 #elif defined( __MACH__ )
2366 // FIXME! Check extensions!
2368 Display* dpy = glXGetCurrentDisplay();
2369 int minor = 0, major = 0;
2371 dbg_printf("_VerifyExtensions: glXGetCurrentDisplay() returned NULL! returning false\n");
2374 if (!glXQueryVersion(dpy, &major, &minor))
2376 dbg_printf("_VerifyExtensions: glXQueryVersion(dpy, &major, &minor) FAILED! returning false\n");
2381 dbg_printf("_VerifyExtensions: glXQueryVersion(dpy, major=%d, minor=%d)\n", major, minor);
2384 int screen = DefaultScreen(dpy);
2385 const char* extString = glXQueryExtensionsString(dpy, screen);
2386 dbg_printf("_VerifyExtensions: glXQueryExtensionsString(dpy, screen) returned -\n[%s]\n",
2387 (extString ? extString : "<NULL>") );
2388 if (!SGSearchExtensionsString(extString, "GLX_SGIX_fbconfig") ||
2389 !SGSearchExtensionsString(extString, "GLX_SGIX_pbuffer"))
2391 dbg_printf("_VerifyExtensions: glXQueryExtensionsString(dpy,screen) does NOT contain GLX_SGIX_fbconfig or GLX_SGIX_pbuffer!\n" );
2392 const char * extClient = glXGetClientString( dpy, GLX_EXTENSIONS );
2394 !SGSearchExtensionsString(extClient, "GLX_SGIX_fbconfig") ||
2395 !SGSearchExtensionsString(extClient, "GLX_SGIX_pbuffer"))
2397 dbg_printf("_VerifyExtensions: AND glXGetClientString(dpy,GLX_EXTENSIONS) also! returning false\n" );
2402 dbg_printf("_VerifyExtensions: BUT glXGetClientString(dpy,GLX_EXTENSIONS) returned \n[%s]\n", extClient );
2403 dbg_printf("Since this DOES contain fbconfig and pbuffer, continuing...\n");
2406 // First try the glX version 1.3 functions.
2407 glXChooseFBConfigPtr = (glXChooseFBConfigProc)SGLookupFunction("glXChooseFBConfig");
2408 glXCreatePbufferPtr = (glXCreatePbufferProc)SGLookupFunction("glXCreatePbuffer");
2409 glXGetVisualFromFBConfigPtr = (glXGetVisualFromFBConfigProc)SGLookupFunction("glXGetVisualFromFBConfig");
2410 glXCreateContextPtr = (glXCreateContextProc)SGLookupFunction("glXCreateContext");
2411 glXDestroyPbufferPtr = (glXDestroyPbufferProc)SGLookupFunction("glXDestroyPbuffer");
2412 glXQueryDrawablePtr = (glXQueryDrawableProc)SGLookupFunction("glXQueryDrawable");
2414 if (((1 <= major && 3 <= minor) || 2 <= major) &&
2415 glXChooseFBConfigPtr &&
2416 glXCreatePbufferPtr &&
2417 glXGetVisualFromFBConfigPtr &&
2418 glXCreateContextPtr &&
2419 glXDestroyPbufferPtr &&
2420 glXQueryDrawablePtr) {
2421 dbg_printf("_VerifyExtensions: setting glXVersion1_3Present TRUE\n" );
2422 glXVersion1_3Present = true;
2426 dbg_printf("_VerifyExtensions: setting glXVersion1_3Present FALSE\n Reason: " );
2427 if ( !((1 <= major && 3 <= minor) || 2 <= major) ) { dbg_printf( "Version wrong %d.%d ", major, minor ); }
2428 if ( !glXChooseFBConfigPtr ) { dbg_printf( "missing glXChooseFBConfigPtr " ); }
2429 if ( !glXCreatePbufferPtr ) { dbg_printf( "missing glXCreatePbufferPtr " ); }
2430 if ( !glXGetVisualFromFBConfigPtr ) { dbg_printf( "missing glXGetVisualFromFBConfigPtr " ); }
2431 if ( !glXCreateContextPtr ) { dbg_printf( "missing glXCreateContextPtr " ); }
2432 if ( !glXDestroyPbufferPtr ) { dbg_printf( "missing glXDestroyPbufferPtr " ); }
2433 if ( !glXQueryDrawablePtr ) { dbg_printf( "missing glXQueryDrawablePtr " ); }
2436 glXChooseFBConfigPtr = (glXChooseFBConfigProc)SGLookupFunction("glXChooseFBConfigSGIX");
2437 glXCreateGLXPbufferPtr = (glXCreateGLXPbufferProc)SGLookupFunction("glXCreateGLXPbufferSGIX");
2438 glXGetVisualFromFBConfigPtr = (glXGetVisualFromFBConfigProc)SGLookupFunction("glXGetVisualFromFBConfigSGIX");
2439 glXCreateContextWithConfigPtr = (glXCreateContextWithConfigProc)SGLookupFunction("glXCreateContextWithConfigSGIX");
2440 glXDestroyPbufferPtr = (glXDestroyPbufferProc)SGLookupFunction("glXDestroyGLXPbufferSGIX");
2441 glXQueryGLXPbufferSGIXPtr = (glXQueryGLXPbufferSGIXProc)SGLookupFunction("glXQueryGLXPbufferSGIX");
2443 if (!glXChooseFBConfigPtr ||
2444 !glXCreateGLXPbufferPtr ||
2445 !glXGetVisualFromFBConfigPtr ||
2446 !glXCreateContextWithConfigPtr ||
2447 !glXDestroyPbufferPtr ||
2448 !glXQueryGLXPbufferSGIXPtr)
2450 dbg_printf("_VerifyExtensions: some pointer is NULL! return false\n" );
2451 if ( !glXCreateGLXPbufferPtr ) {
2452 dbg_printf("RenderTexture::Initialize: ERROR glXCreateGLXPbufferPtr = NULL!\n");
2453 } else if ( !glXCreateContextWithConfigPtr ) {
2454 dbg_printf("RenderTexture::Initialize: ERROR glXCreateContextWithConfigPtr = NULL!\n");
2455 } else if ( !glXVersion1_3Present && !glXQueryGLXPbufferSGIXPtr ) {
2456 dbg_printf("RenderTexture::Initialize: ERROR glXQueryGLXPbufferSGIXPtr = NULL!\n");
2460 dbg_printf("_VerifyExtensions: appear to have all 'procs' glXCreateGLXPbufferPtr=[%p]\n", glXCreateGLXPbufferPtr );
2464 if (_bIsDepthTexture && !GL_ARB_depth_texture)
2466 PrintExtensionError("GL_ARB_depth_texture");
2469 if (_bFloat && _bIsTexture && !GLX_NV_float_buffer)
2471 PrintExtensionError("GLX_NV_float_buffer");
2474 if (_eUpdateMode == RT_RENDER_TO_TEXTURE)
2476 PrintExtensionError("Some GLX render texture extension: Please implement me!");
2481 dbg_printf("RenderTexture::_VerifyExtensions: return true.\n");
2485 //---------------------------------------------------------------------------
2486 // Function : RenderTexture::_InitializeTextures
2488 //---------------------------------------------------------------------------
2490 * @fn RenderTexture::_InitializeTextures()
2491 * @brief Initializes the state of textures used by the RenderTexture.
2493 bool RenderTexture::_InitializeTextures()
2495 dbg_printf( "RenderTexture::_InitializeTextures() called\n" );
2496 // Determine the appropriate texture formats and filtering modes.
2498 if (_bIsTexture || _bIsDepthTexture)
2500 if (_bRectangle && GL_NV_texture_rectangle)
2501 _iTextureTarget = GL_TEXTURE_RECTANGLE_NV;
2502 else if (_bRectangle && GL_EXT_texture_rectangle)
2503 _iTextureTarget = GL_TEXTURE_RECTANGLE_EXT;
2505 _iTextureTarget = GL_TEXTURE_2D;
2510 glGenTextures(1, (GLuint*)&_iTextureID);
2511 glBindTexture(_iTextureTarget, _iTextureID);
2513 // Use clamp to edge as the default texture wrap mode for all tex
2514 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2515 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2516 // Use NEAREST as the default texture filtering mode.
2517 glTexParameteri(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2518 glTexParameteri(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2521 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2523 GLuint iInternalFormat;
2530 SG_LOG(SG_GL, SG_ALERT,
2531 "RenderTexture Error: mipmapped float textures not "
2533 dbg_printf( "RenderTexture Error: mipmapped float textures not supported. return false\n");
2537 switch(_iNumComponents)
2540 if (GL_NV_float_buffer)
2542 iInternalFormat = (_iNumColorBits[0] > 16) ?
2543 GL_FLOAT_R32_NV : GL_FLOAT_R16_NV;
2545 else if (GL_ATI_texture_float)
2547 iInternalFormat = (_iNumColorBits[0] > 16) ?
2548 GL_LUMINANCE_FLOAT32_ATI :
2549 GL_LUMINANCE_FLOAT16_ATI;
2551 iFormat = GL_LUMINANCE;
2554 if (GL_NV_float_buffer)
2556 iInternalFormat = (_iNumColorBits[0] > 16) ?
2557 GL_FLOAT_RG32_NV : GL_FLOAT_RG16_NV;
2559 else if (GL_ATI_texture_float)
2561 iInternalFormat = (_iNumColorBits[0] > 16) ?
2562 GL_LUMINANCE_ALPHA_FLOAT32_ATI :
2563 GL_LUMINANCE_ALPHA_FLOAT16_ATI;
2565 iFormat = GL_LUMINANCE_ALPHA;
2568 if (GL_NV_float_buffer)
2570 iInternalFormat = (_iNumColorBits[0] > 16) ?
2571 GL_FLOAT_RGB32_NV : GL_FLOAT_RGB16_NV;
2573 else if (GL_ATI_texture_float)
2575 iInternalFormat = (_iNumColorBits[0] > 16) ?
2576 GL_RGB_FLOAT32_ATI : GL_RGB_FLOAT16_ATI;
2581 if (GL_NV_float_buffer)
2583 iInternalFormat = (_iNumColorBits[0] > 16) ?
2584 GL_FLOAT_RGBA32_NV : GL_FLOAT_RGBA16_NV;
2586 else if (GL_ATI_texture_float)
2588 iInternalFormat = (_iNumColorBits[0] > 16) ?
2589 GL_RGBA_FLOAT32_ATI : GL_RGBA_FLOAT16_ATI;
2594 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: "
2595 "Invalid number of components: " <<
2597 dbg_printf( "RenderTexture Error: Invalid number of components: %d - return false\n",
2604 if (4 == _iNumComponents)
2606 iInternalFormat = GL_RGBA8;
2611 iInternalFormat = GL_RGB8;
2616 // Allocate the texture image (but pass it no data for now).
2617 glTexImage2D(_iTextureTarget, 0, iInternalFormat,
2618 _iWidth, _iHeight, 0, iFormat, GL_FLOAT, NULL);
2622 if (_bIsDepthTexture)
2624 glGenTextures(1, (GLuint*)&_iDepthTextureID);
2625 glBindTexture(_iTextureTarget, _iDepthTextureID);
2627 // Use clamp to edge as the default texture wrap mode for all tex
2628 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2629 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2630 // Use NEAREST as the default texture filtering mode.
2631 glTexParameteri(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2632 glTexParameteri(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2634 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2637 if (_bHasARBDepthTexture)
2639 // Allocate the texture image (but pass it no data for now).
2640 glTexImage2D(_iTextureTarget, 0, GL_DEPTH_COMPONENT,
2641 _iWidth, _iHeight, 0, GL_DEPTH_COMPONENT,
2646 // allocate memory for depth texture
2647 // Since this is slow, we warn the user in debug mode. (above)
2648 _pPoorDepthTexture = new unsigned short[_iWidth * _iHeight];
2649 glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16,
2650 _iWidth, _iHeight, 0, GL_LUMINANCE,
2651 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
2657 dbg_printf( "RenderTexture::_InitializeTextures() returning true\n" );
2662 //---------------------------------------------------------------------------
2663 // Function : RenderTexture::_MaybeCopyBuffer
2665 //---------------------------------------------------------------------------
2667 * @fn RenderTexture::_MaybeCopyBuffer()
2668 * @brief Does the actual copying for RenderTextures with RT_COPY_TO_TEXTURE
2670 void RenderTexture::_MaybeCopyBuffer()
2673 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2677 glBindTexture(_iTextureTarget, _iTextureID);
2678 glCopyTexSubImage2D(_iTextureTarget,
2679 0, 0, 0, 0, 0, _iWidth, _iHeight);
2681 if (_bIsDepthTexture)
2683 glBindTexture(_iTextureTarget, _iDepthTextureID);
2684 // HOW TO COPY DEPTH TEXTURE??? Supposedly this just magically works...
2686 if (_bHasARBDepthTexture)
2688 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0,
2693 // no 'real' depth texture available, so behavior has to be emulated
2694 // using glReadPixels (beware, this is (naturally) slow ...)
2695 glReadPixels(0, 0, _iWidth, _iHeight, GL_DEPTH_COMPONENT,
2696 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
2697 glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16,
2698 _iWidth, _iHeight, 0, GL_LUMINANCE,
2699 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
2705 #elif defined(__MACH__)
2706 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2710 glBindTexture(_iTextureTarget, _iTextureID);
2711 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2713 if (_bIsDepthTexture)
2715 glBindTexture(_iTextureTarget, _iDepthTextureID);
2716 assert(_bHasARBDepthTexture);
2717 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2723 glBindTexture(_iTextureTarget, _iTextureID);
2724 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2726 if (_bIsDepthTexture)
2728 glBindTexture(_iTextureTarget, _iDepthTextureID);
2729 assert(_bHasARBDepthTexture);
2730 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2736 //---------------------------------------------------------------------------
2737 // Function : RenderTexture::_ReleaseBoundBuffers
2739 //---------------------------------------------------------------------------
2741 * @fn RenderTexture::_ReleaseBoundBuffers()
2742 * @brief Releases buffer bindings on RenderTextures with RT_RENDER_TO_TEXTURE
2744 bool RenderTexture::_ReleaseBoundBuffers()
2747 if (_bIsTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
2749 glBindTexture(_iTextureTarget, _iTextureID);
2751 // release the pbuffer from the render texture object
2752 if (0 != _iCurrentBoundBuffer && _bIsBufferBound)
2754 if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, _iCurrentBoundBuffer))
2759 _bIsBufferBound = false;
2763 if (_bIsDepthTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
2765 glBindTexture(_iTextureTarget, _iDepthTextureID);
2767 // release the pbuffer from the render texture object
2768 if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
2776 // textures can't be bound in Linux
2781 //---------------------------------------------------------------------------
2782 // Function : RenderTexture::_MakeCurrent
2784 //---------------------------------------------------------------------------
2786 * @fn RenderTexture::_MakeCurrent()
2787 * @brief Makes the RenderTexture's context current
2789 bool RenderTexture::_MakeCurrent()
2792 // make the pbuffer's rendering context current.
2793 if (FALSE == wglMakeCurrent( _hDC, _hGLContext))
2798 #elif defined( __MACH__ )
2801 if (err = CGLSetCurrentContext(_hGLContext))
2803 _cglCheckError(err);
2807 static GLXContext last_hGLContext = 0;
2808 if (false == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
2810 dbg_printf( "_MakeCurrent: glXMakeCurrent FAILED! returning false\n");
2814 if ( last_hGLContext != _hGLContext ) {
2815 last_hGLContext = _hGLContext;
2816 dbg_printf( "_MakeCurrent: glXMakeCurrent set to [%p] SUCCESS! returning true\n", _hGLContext );
2822 /////////////////////////////////////////////////////////////////////////////
2824 // Begin Deprecated Interface
2826 /////////////////////////////////////////////////////////////////////////////
2828 //---------------------------------------------------------------------------
2829 // Function : RenderTexture::RenderTexture
2831 //---------------------------------------------------------------------------
2833 * @fn RenderTexture::RenderTexture()
2834 * @brief Constructor.
2836 RenderTexture::RenderTexture(int width, int height,
2837 bool bIsTexture /* = true */,
2838 bool bIsDepthTexture /* = false */)
2841 _bIsTexture(bIsTexture),
2842 _bIsDepthTexture(bIsDepthTexture),
2843 _bHasARBDepthTexture(true), // [Redge]
2844 _eUpdateMode(RT_RENDER_TO_TEXTURE),
2845 _bInitialized(false),
2847 _iCurrentBoundBuffer(0),
2849 _iNumStencilBits(0),
2851 _bDoubleBuffered(false),
2855 _bShareObjects(false),
2856 _bCopyContext(false),
2862 _hPreviousContext(0),
2863 #elif defined( __MACH__ )
2866 _hPreviousContext(NULL),
2871 _hPreviousDrawable(0),
2872 _hPreviousContext(0),
2874 _iTextureTarget(GL_NONE),
2876 _iDepthTextureID(0),
2877 _pPoorDepthTexture(0) // [Redge]
2879 assert(width > 0 && height > 0);
2880 #if defined DEBUG || defined _DEBUG
2881 SG_LOG(SG_GL, SG_ALERT,
2882 "RenderTexture Warning: Deprecated Contructor interface used.");
2884 dbg_printf("RenderTexture Warning: Deprecated Contructor interface used.\n");
2886 _iNumColorBits[0] = _iNumColorBits[1] =
2887 _iNumColorBits[2] = _iNumColorBits[3] = 0;
2888 _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
2891 //------------------------------------------------------------------------------
2892 // Function : RenderTexture::Initialize
2894 //------------------------------------------------------------------------------
2896 * @fn RenderTexture::Initialize(bool bShare, bool bDepth, bool bStencil, bool bMipmap, unsigned int iRBits, unsigned int iGBits, unsigned int iBBits, unsigned int iABits);
2897 * @brief Initializes the RenderTexture, sharing display lists and textures if specified.
2899 * This function actually does the creation of the p-buffer. It can only be called
2900 * once a GL context has already been created. Note that if the texture is not
2901 * power of two dimensioned, or has more than 8 bits per channel, enabling mipmapping
2902 * will cause an error.
2904 bool RenderTexture::Initialize(bool bShare /* = true */,
2905 bool bDepth /* = false */,
2906 bool bStencil /* = false */,
2907 bool bMipmap /* = false */,
2908 bool bAnisoFilter /* = false */,
2909 unsigned int iRBits /* = 8 */,
2910 unsigned int iGBits /* = 8 */,
2911 unsigned int iBBits /* = 8 */,
2912 unsigned int iABits /* = 8 */,
2913 UpdateMode updateMode /* = RT_RENDER_TO_TEXTURE */)
2915 if (0 == _iWidth || 0 == _iHeight)
2918 #if defined DEBUG || defined _DEBUG
2919 SG_LOG(SG_GL, SG_ALERT,
2920 "RenderTexture Warning: Deprecated Initialize() interface used.");
2922 dbg_printf("RenderTexture Warning: Deprecated Initialize() interface used.\n");
2924 // create a mode string.
2927 mode.append("depth ");
2929 mode.append("stencil ");
2931 mode.append("mipmap ");
2932 if (iRBits + iGBits + iBBits + iABits > 0)
2943 char bitVector[100];
2944 snprintf( bitVector, 100,
2945 "%d%s,%d%s,%d%s,%d%s",
2946 iRBits, (iRBits >= 16) ? "f" : "",
2947 iGBits, (iGBits >= 16) ? "f" : "",
2948 iBBits, (iBBits >= 16) ? "f" : "",
2949 iABits, (iABits >= 16) ? "f" : "");
2950 mode.append(bitVector);
2955 if ((GL_NV_texture_rectangle || GL_EXT_texture_rectangle) &&
2956 ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
2957 || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
2958 mode.append("texRECT ");
2960 mode.append("tex2D ");
2962 if (_bIsDepthTexture)
2964 if ((GL_NV_texture_rectangle || GL_EXT_texture_rectangle) &&
2965 ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
2966 || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
2967 mode.append("texRECT ");
2969 mode.append("tex2D ");
2971 if (RT_COPY_TO_TEXTURE == updateMode)
2974 _pixelFormatAttribs.clear();
2975 _pbufferAttribs.clear();
2978 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
2979 _pixelFormatAttribs.push_back(true);
2980 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
2981 _pixelFormatAttribs.push_back(true);
2983 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
2984 _pbufferAttribs.push_back(true);
2985 #elif defined( __MACH__ )
2986 //_pixelFormatAttribs.push_back(kCGLPFANoRecovery);
2987 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
2988 _pixelFormatAttribs.push_back(kCGLPFAWindow);
2989 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
2991 _pixelFormatAttribs.push_back(GLX_RENDER_TYPE_SGIX);
2992 _pixelFormatAttribs.push_back(GLX_RGBA_BIT_SGIX);
2993 _pixelFormatAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
2994 _pixelFormatAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
2997 _ParseModeString(mode.c_str(), _pixelFormatAttribs, _pbufferAttribs);
3000 _pixelFormatAttribs.push_back(0);
3001 _pbufferAttribs.push_back(0);
3002 #elif defined(__MACH__)
3003 _pixelFormatAttribs.push_back(0);
3005 _pixelFormatAttribs.push_back(None);
3008 Initialize(_iWidth, _iHeight, bShare);
3014 //---------------------------------------------------------------------------
3015 // Function : RenderTexture::Reset
3017 //---------------------------------------------------------------------------
3019 * @fn RenderTexture::Reset(int iWidth, int iHeight, unsigned int iMode, bool bIsTexture, bool bIsDepthTexture)
3020 * @brief Resets the resolution of the offscreen buffer.
3022 * Causes the buffer to delete itself. User must call Initialize() again
3025 bool RenderTexture::Reset(int iWidth, int iHeight)
3027 SG_LOG(SG_GL, SG_ALERT,
3028 "RenderTexture Warning: Deprecated Reset() interface used.");
3030 dbg_printf("RenderTexture Warning: Deprecated Reset(x,y) interface used.\n");
3034 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Reset(): failed to invalidate.");
3035 dbg_printf( "RenderTexture::Reset(x,y): failed to invalidate. returning false\n");
3041 dbg_printf( "RenderTexture::Reset(x,y): succeeded. returning true\n");
3045 #if defined( _DEBUG ) && !defined( _WIN32 ) && !defined( __MACH__ )
3046 /* just some DEBUG ONLY code, to show the 'attributes' */
3048 typedef struct tagPXATTS {
3055 static PXATTS pxAtts[] = {
3056 { GLX_FBCONFIG_ID, "GLX_FBCONFIG_ID",
3057 "followed by a valid XID that indicates the desired GLX frame buffer configuration. "
3058 "When a GLX_FBCONFIG_ID is specified, all attributes are ignored. The default value is GLX_DONT_CARE.",
3060 { GLX_BUFFER_SIZE, "GLX_BUFFER_SIZE",
3061 "Must be followed by a nonnegative integer that indicates the desired color index buffer size."
3062 "The smallest index buffer of at least the specified size is preferred. This attribute is ignored if GLX_COLOR_INDEX_BIT is not set "
3063 "in GLX_RENDER_TYPE. The default value is 0.",
3065 { GLX_LEVEL, "GLX_LEVEL",
3066 "Must be followed by an integer buffer-level specification. This specification is honored exactly."
3067 "Buffer level 0 corresponds to the default frame buffer of the display. "
3068 "Buffer level 1 is the first overlay frame buffer, level two the second overlay frame buffer, and so on."
3069 "Negative buffer levels correspond to underlay frame buffers. The default value is 0.",
3071 { GLX_DOUBLEBUFFER, "GLX_DOUBLEBUFFER",
3072 "Must be followed by True or False. If True is specified, then only double-buffered frame buffer configurations are considered;"
3073 "if False is specified, then only single-buffered frame buffer configurations are considered. The default value is GLX_DONT_CARE.",
3075 { GLX_STEREO, "GLX_STEREO",
3076 "Must be followed by True or False. If True is specified, then only stereo frame buffer configurations are considered;"
3077 " if False is specified, then only monoscopic frame buffer configurations are considered. The default value is False.",
3079 { GLX_AUX_BUFFERS, "GLX_AUX_BUFFERS",
3080 "Must be followed by a nonnegative integer that indicates the desired number of auxiliary buffers."
3081 " Configurations with the smallest number of auxiliary buffers that meet or exceed the specified number are preferred."
3082 " The default value is 0.",
3084 { GLX_RED_SIZE, "GLX_RED_SIZE",
3085 "must be followed by a nonnegative minimum size",
3087 { GLX_GREEN_SIZE, "GLX_GREEN_SIZE",
3088 "must be followed by a nonnegative minimum size",
3090 { GLX_BLUE_SIZE, "GLX_BLUE_SIZE",
3091 "must be followed by a nonnegative minimum size",
3093 { GLX_ALPHA_SIZE, "GLX_ALPHA_SIZE",
3094 "Each attribute, if present, must be followed by a nonnegative minimum size specification or GLX_DONT_CARE."
3095 " The largest available total RGBA color buffer size (sum of GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE) "
3096 " of at least the minimum size specified for each color component is preferred. If the requested number of bits for a color "
3097 " component is 0 or GLX_DONT_CARE, it is not considered. The default value for each color component is 0.",
3099 { GLX_DEPTH_SIZE, "GLX_DEPTH_SIZE",
3100 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3101 "frame buffer configurations with no depth buffer are preferred."
3102 "Otherwise, the largest available depth buffer of at least the minimum size is preferred. The default value is 0.",
3104 { GLX_STENCIL_SIZE, "GLX_STENCIL_SIZE",
3105 "Must be followed by a nonnegative integer that indicates the desired number of stencil bitplanes."
3106 "The smallest stencil buffer of at least the specified size is preferred. If the desired value is zero,"
3107 " frame buffer configurations with no stencil buffer are preferred. The default value is 0.",
3109 { GLX_ACCUM_RED_SIZE, "GLX_ACCUM_RED_SIZE",
3110 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3111 " frame buffer configurations with no red accumulation buffer are preferred."
3112 " Otherwise, the largest possible red accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3114 { GLX_ACCUM_GREEN_SIZE, "GLX_ACCUM_GREEN_SIZE",
3115 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3116 "frame buffer configurations with no green accumulation buffer are preferred. "
3117 "Otherwise, the largest possible green accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3119 { GLX_ACCUM_BLUE_SIZE, "GLX_ACCUM_BLUE_SIZE",
3120 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3121 "frame buffer configurations with no blue accumulation buffer are preferred. "
3122 "Otherwise, the largest possible blue accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3124 { GLX_ACCUM_ALPHA_SIZE, "GLX_ACCUM_ALPHA_SIZE",
3125 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3126 "frame buffer configurations with no alpha accumulation buffer are preferred. "
3127 "Otherwise, the largest possible alpha accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3129 { GLX_RENDER_TYPE, "GLX_RENDER_TYPE",
3130 "Must be followed by a mask indicating which OpenGL rendering modes the frame buffer configuration must support. "
3131 "Valid bits are GLX_RGBA_BIT and GLX_COLOR_INDEX_BIT. If the mask is set to GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT, "
3132 "then only frame buffer configurations that can be bound to both RGBA contexts and color index contexts will be considered. "
3133 "The default value is GLX_RGBA_BIT.",
3135 { GLX_DRAWABLE_TYPE, "GLX_DRAWABLE_TYPE",
3136 "Must be followed by a mask indicating which GLX drawable types the frame buffer configuration must support. "
3137 "Valid bits are GLX_WINDOW_BIT, GLX_PIXMAP_BIT, and GLX_PBUFFER_BIT. For example, if mask is set to "
3138 "GLX_WINDOW_BIT | GLX_PIXMAP_BIT, only frame buffer configurations that support both windows and GLX pixmaps "
3139 "will be considered. The default value is GLX_WINDOW_BIT.",
3141 { GLX_X_RENDERABLE, "GLX_X_RENDERABLE",
3142 "Must be followed by True or False. If True is specified, then only frame buffer configurations that "
3143 "have associated X visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. "
3144 "The default value is GLX_DONT_CARE. ",
3146 { GLX_X_VISUAL_TYPE, "GLX_X_VISUAL_TYPE",
3147 "Must be followed by one of GLX_TRUE_COLOR, GLX_DIRECT_COLOR, GLX_PSEUDO_COLOR, GLX_STATIC_COLOR, "
3148 "GLX_GRAY_SCALE, or GLX_STATIC_GRAY, indicating the desired X visual type. "
3149 "Not all frame buffer configurations have an associated X visual. If GLX_DRAWABLE_TYPE is specified in attrib_list and the "
3150 "mask that follows does not have GLX_WINDOW_BIT set, then this value is ignored. It is also ignored if "
3151 "GLX_X_RENDERABLE is specified as False. RGBA rendering may be supported for visuals of type "
3152 "GLX_TRUE_COLOR, GLX_DIRECT_COLOR, GLX_PSEUDO_COLOR, or GLX_STATIC_COLOR, "
3153 "but color index rendering is only supported for visuals of type GLX_PSEUDO_COLOR or GLX_STATIC_COLOR "
3154 "(i.e., single-channel visuals). The tokens GLX_GRAY_SCALE and GLX_STATIC_GRAY will "
3155 "not match current OpenGL enabled visuals, but are included for future use."
3156 "The default value for GLX_X_VISUAL_TYPE is GLX_DONT_CARE.",
3158 { GLX_CONFIG_CAVEAT, "GLX_CONFIG_CAVEAT",
3159 "Must be followed by one of GLX_NONE, GLX_SLOW_CONFIG, GLX_NON_CONFORMANT_CONFIG. "
3160 "If GLX_NONE is specified, then only frame buffer configurations with "
3161 "no caveats will be considered; if GLX_SLOW_CONFIG is specified, then only slow frame buffer configurations will be considered; if "
3162 "GLX_NON_CONFORMANT_CONFIG is specified, then only nonconformant frame buffer configurations will be considered."
3163 "The default value is GLX_DONT_CARE.",
3165 { GLX_TRANSPARENT_TYPE, "GLX_TRANSPARENT_TYPE",
3166 "Must be followed by one of GLX_NONE, GLX_TRANSPARENT_RGB, GLX_TRANSPARENT_INDEX. "
3167 "If GLX_NONE is specified, then only opaque frame buffer configurations will be considered; "
3168 "if GLX_TRANSPARENT_RGB is specified, then only transparent frame buffer configurations that support RGBA rendering will be considered; "
3169 "if GLX_TRANSPARENT_INDEX is specified, then only transparent frame buffer configurations that support color index rendering will be considered."
3170 "The default value is GLX_NONE.",
3172 { GLX_TRANSPARENT_INDEX_VALUE, "GLX_TRANSPARENT_INDEX_VALUE",
3173 "Must be followed by an integer value indicating the transparent index value; the value must be between 0 and the maximum "
3174 "frame buffer value for indices. Only frame buffer configurations that use the "
3175 "specified transparent index value will be considered. The default value is GLX_DONT_CARE. "
3176 "This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in attrib_list and specified as GLX_TRANSPARENT_INDEX.",
3178 { GLX_TRANSPARENT_RED_VALUE, "GLX_TRANSPARENT_RED_VALUE",
3179 "Must be followed by an integer value indicating the transparent red value; the value must be between 0 and the maximum "
3180 "frame buffer value for red. Only frame buffer configurations that use the specified transparent red value will be considered. "
3181 "The default value is GLX_DONT_CARE. This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in "
3182 "attrib_list and specified as GLX_TRANSPARENT_RGB.",
3184 { GLX_TRANSPARENT_GREEN_VALUE, "GLX_TRANSPARENT_GREEN_VALUE",
3185 "Must be followed by an integer value indicating the transparent green value; the value must be between 0 and the maximum "
3186 "frame buffer value for green. Only frame buffer configurations that use the specified transparent green value will be considered."
3187 "The default value is GLX_DONT_CARE. This attribute is "
3188 "ignored unless GLX_TRANSPARENT_TYPE is included in attrib_list and specified as GLX_TRANSPARENT_RGB.",
3190 { GLX_TRANSPARENT_BLUE_VALUE, "GLX_TRANSPARENT_BLUE_VALUE",
3191 "Must be followed by an integer value indicating the transparent blue value; the value must be between 0 and the maximum "
3192 "frame buffer value for blue. Only frame buffer configurations that use the specified transparent blue value will be considered."
3193 "The default value is GLX_DONT_CARE. This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in "
3194 "attrib_list and specified as GLX_TRANSPARENT_RGB. ",
3196 { GLX_TRANSPARENT_ALPHA_VALUE, "GLX_TRANSPARENT_ALPHA_VALUE",
3197 "Must be followed by an integer value indicating the transparent alpha value; the value must be between 0 and the maximum "
3198 "frame buffer value for alpha. Only frame buffer configurations that use the "
3199 "specified transparent alpha value will be considered. The default value is GLX_DONT_CARE.",
3201 { 0, NULL, NULL, -1 }
3204 const char * get_attr_name( int val, int * pdef )
3206 PPXATTS pat = &pxAtts[0];
3209 if ( pat->attr == val ) {
3216 return "VALUE NOT IN LIST";
3220 // eof - RenderTexture.cpp