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
46 * Jan. 2005, Removed GLEW dependencies, Erik Hofman, Fred Bouvier
47 * Nov. 2005, Use the simgear logging facility, Erik Hofman
48 * Mar. 2006, Add MAC OS X support, Alexander Powell
52 # include <simgear_config.h>
55 #include <simgear/compiler.h>
56 #include <simgear/debug/logstream.hxx>
57 #include <simgear/screen/extensions.hxx>
58 #include <simgear/screen/RenderTexture.h>
68 #pragma comment(lib, "gdi32.lib") // required for GetPixelFormat()
73 // DEBUG - add a lot of noise
79 const char * get_attr_name( int val, int * pdef );
80 #define dbg_printf printf
82 #if defined (__GNUC__)
83 #define dbg_printf(format,args...) ((void)0)
84 #else // defined (__GNUC__)
86 #endif // defined (__GNUC__)
87 #endif // defined (_DEBUG)
89 // CHOP/NOT CHOP SOME CODE TO GET SOMETHING WORKING!
90 #define ADD_QUERY_BUFFER
91 #define ADD_GET_DRAWABLE
92 // =======================================
96 static bool fctPtrInited = false;
97 /* WGL_ARB_pixel_format */
98 static wglChoosePixelFormatARBProc wglChoosePixelFormatARBPtr = 0;
99 static wglGetPixelFormatAttribivARBProc wglGetPixelFormatAttribivARBPtr = 0;
100 /* WGL_ARB_pbuffer */
101 static wglCreatePbufferARBProc wglCreatePbufferARBPtr = 0;
102 static wglGetPbufferDCARBProc wglGetPbufferDCARBPtr = 0;
103 static wglQueryPbufferARBProc wglQueryPbufferARBPtr = 0;
104 static wglReleasePbufferDCARBProc wglReleasePbufferDCARBPtr = 0;
105 static wglDestroyPbufferARBProc wglDestroyPbufferARBPtr = 0;
106 /* WGL_ARB_render_texture */
107 static wglBindTexImageARBProc wglBindTexImageARBPtr = 0;
108 static wglReleaseTexImageARBProc wglReleaseTexImageARBPtr = 0;
110 #elif defined( __MACH__ )
112 static bool glXVersion1_3Present = false;
113 static glXChooseFBConfigProc glXChooseFBConfigPtr = 0;
114 static glXCreatePbufferProc glXCreatePbufferPtr = 0;
115 static glXCreateGLXPbufferProc glXCreateGLXPbufferPtr = 0;
116 static glXGetVisualFromFBConfigProc glXGetVisualFromFBConfigPtr = 0;
117 static glXCreateContextProc glXCreateContextPtr = 0;
118 static glXCreateContextWithConfigProc glXCreateContextWithConfigPtr = 0;
119 static glXDestroyPbufferProc glXDestroyPbufferPtr = 0;
120 static glXQueryDrawableProc glXQueryDrawablePtr = 0;
121 static glXQueryGLXPbufferSGIXProc glXQueryGLXPbufferSGIXPtr = 0;
124 //---------------------------------------------------------------------------
125 // Function : RenderTexture::RenderTexture
127 //---------------------------------------------------------------------------
129 * @fn RenderTexture::RenderTexture()
130 * @brief Mode-string-based Constructor.
132 RenderTexture::RenderTexture(const char *strMode)
136 _bIsDepthTexture(false),
137 _bHasARBDepthTexture(true), // [Redge]
138 #if defined(_WIN32) || defined(__MACH__)
139 _eUpdateMode(RT_RENDER_TO_TEXTURE),
141 _eUpdateMode(RT_COPY_TO_TEXTURE),
143 _bInitialized(false),
145 _bIsBufferBound(false),
146 _iCurrentBoundBuffer(0),
150 _bDoubleBuffered(false),
154 _bShareObjects(false),
155 _bCopyContext(false),
161 _hPreviousContext(0),
162 #elif defined( __MACH__ )
165 _hPreviousContext(NULL),
170 _hPreviousDrawable(0),
171 _hPreviousContext(0),
173 _iTextureTarget(GL_NONE),
176 _pPoorDepthTexture(0) // [Redge]
178 dbg_printf("RenderTexture::RenderTexture(%s) BGN instantiation.\n", strMode );
179 _iNumColorBits[0] = _iNumColorBits[1] =
180 _iNumColorBits[2] = _iNumColorBits[3] = 0;
183 dbg_printf("RenderTexture::RenderTexture in _WIN32.\n" );
184 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
185 _pixelFormatAttribs.push_back(true);
186 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
187 _pixelFormatAttribs.push_back(true);
189 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
190 _pbufferAttribs.push_back(true);
191 #elif defined( __MACH__ )
192 dbg_printf("RenderTexture::RenderTexture in __MACH__.\n" );
193 //_pixelFormatAttribs.push_back(kCGLPFANoRecovery);
194 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
195 _pixelFormatAttribs.push_back(kCGLPFAWindow);
196 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
198 dbg_printf("RenderTexture::RenderTexture !_WIN32 and !__MACH__.\n" );
199 _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
200 _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
201 _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
202 _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
205 _ParseModeString(strMode, _pixelFormatAttribs, _pbufferAttribs);
208 _pixelFormatAttribs.push_back(0);
209 _pbufferAttribs.push_back(0);
210 #elif defined(__MACH__)
211 _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
212 _pbufferAttribs.push_back((CGLPixelFormatAttribute)0);
214 _pixelFormatAttribs.push_back(None);
217 dbg_printf("RenderTexture::RenderTexture(%s) END instantiation. pf=%d pb=%d\n",
218 strMode, (int)_pixelFormatAttribs.size(), (int)_pbufferAttribs.size() );
223 //---------------------------------------------------------------------------
224 // Function : RenderTexture::~RenderTexture
226 //---------------------------------------------------------------------------
228 * @fn RenderTexture::~RenderTexture()
231 RenderTexture::~RenderTexture()
233 dbg_printf("RenderTexture::~RenderTexture: destructor.\n" );
237 //---------------------------------------------------------------------------
238 // Function : _cglcheckError
240 //---------------------------------------------------------------------------
242 * @fn _cglCheckError()
243 * @brief Prints to stderr a description when an OS X error is found.
246 static void _cglCheckErrorHelper(CGLError err, char *sourceFile, int sourceLine)
251 fprintf(stderr, "RenderTexture CGL Error: %s at (%s,%d)",
252 CGLErrorString(err), sourceFile, sourceLine);
257 # define _cglCheckError(err) _cglCheckErrorHelper(err,__FILE__,__LINE__)
262 //---------------------------------------------------------------------------
263 // Function : _wglGetLastError
265 //---------------------------------------------------------------------------
267 * @fn wglGetLastError()
268 * @brief Returns the last windows error generated.
271 void _wglGetLastError()
275 DWORD err = GetLastError();
278 case ERROR_INVALID_PIXEL_FORMAT:
279 SG_LOG(SG_GL, SG_ALERT,
280 "RenderTexture Win32 Error: ERROR_INVALID_PIXEL_FORMAT");
282 case ERROR_NO_SYSTEM_RESOURCES:
283 SG_LOG(SG_GL, SG_ALERT,
284 "RenderTexture Win32 Error: ERROR_NO_SYSTEM_RESOURCES");
286 case ERROR_INVALID_DATA:
287 SG_LOG(SG_GL, SG_ALERT,
288 "RenderTexture Win32 Error: ERROR_INVALID_DATA");
290 case ERROR_INVALID_WINDOW_HANDLE:
291 SG_LOG(SG_GL, SG_ALERT,
292 "RenderTexture Win32 Error: ERROR_INVALID_WINDOW_HANDLE");
294 case ERROR_RESOURCE_TYPE_NOT_FOUND:
295 SG_LOG(SG_GL, SG_ALERT,
296 "RenderTexture Win32 Error: ERROR_RESOURCE_TYPE_NOT_FOUND");
303 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
304 FORMAT_MESSAGE_FROM_SYSTEM |
305 FORMAT_MESSAGE_IGNORE_INSERTS,
308 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
313 SG_LOG(SG_GL, SG_ALERT, "RenderTexture Win32 Error " << err << ":" << lpMsgBuf);
314 LocalFree( lpMsgBuf );
323 //---------------------------------------------------------------------------
324 // Function : PrintExtensionError
326 //---------------------------------------------------------------------------
328 * @fn PrintExtensionError( char* strMsg, ... )
329 * @brief Prints an error about missing OpenGL extensions.
331 void PrintExtensionError( const char* strMsg, ... )
333 SG_LOG(SG_GL, SG_ALERT,
334 "Error: RenderTexture requires the following unsupported "
335 "OpenGL extensions: ");
338 va_start(args, strMsg);
339 vsnprintf( strBuffer, 512, strMsg, args );
342 SG_LOG(SG_GL, SG_ALERT, strMsg);
343 dbg_printf("Error: RenderTexture requires the following unsupported OpenGL extensions: \n[%s]\n", strMsg);
346 //---------------------------------------------------------------------------
347 // Function : RenderTexture::Initialize
349 //---------------------------------------------------------------------------
351 * @fn RenderTexture::Initialize(int width, int height, bool shareObjects, bool copyContext);
352 * @brief Initializes the RenderTexture, sharing display lists and textures if specified.
354 * This function creates of the p-buffer. It can only be called once a GL
355 * context has already been created.
357 bool RenderTexture::Initialize(int width, int height,
358 bool shareObjects /* = true */,
359 bool copyContext /* = false */)
361 assert(width > 0 && height > 0);
363 dbg_printf("RenderTexture::Initialize w=%d h=%d\n", width, height );
365 _iWidth = width; _iHeight = height;
366 _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
368 _bShareObjects = shareObjects;
369 _bCopyContext = copyContext;
371 // Check if this is an NVXX GPU and verify necessary extensions.
372 if (!_VerifyExtensions()) {
373 dbg_printf("RenderTexture::Initialize: _VerifyExtensions() FAILED - returning false.\n" );
381 // Get the current context.
382 HDC hdc = wglGetCurrentDC();
385 HGLRC hglrc = wglGetCurrentContext();
390 unsigned int iNumFormats;
394 // Get the pixel format for the on-screen window.
395 iFormat = GetPixelFormat(hdc);
398 SG_LOG(SG_GL, SG_ALERT,
399 "RenderTexture Error: GetPixelFormat() failed.");
405 if (!wglChoosePixelFormatARBPtr(hdc, &_pixelFormatAttribs[0], NULL,
406 1, &iFormat, &iNumFormats))
408 SG_LOG(SG_GL, SG_ALERT,
409 "RenderTexture Error: wglChoosePixelFormatARB() failed.");
413 if ( iNumFormats <= 0 )
415 SG_LOG(SG_GL, SG_ALERT,
416 "RenderTexture Error: Couldn't find a suitable "
423 // Create the p-buffer.
424 _hPBuffer = wglCreatePbufferARBPtr(hdc, iFormat, _iWidth, _iHeight,
425 &_pbufferAttribs[0]);
428 SG_LOG(SG_GL, SG_ALERT,
429 "RenderTexture Error: wglCreatePbufferARB() failed.");
434 // Get the device context.
435 _hDC = wglGetPbufferDCARBPtr( _hPBuffer);
438 SG_LOG(SG_GL, SG_ALERT,
439 "RenderTexture Error: wglGetGetPbufferDCARB() failed.");
444 // Create a gl context for the p-buffer.
447 // Let's use the same gl context..
448 // Since the device contexts are compatible (i.e. same pixelformat),
449 // we should be able to use the same gl rendering context.
454 _hGLContext = wglCreateContext( _hDC );
457 SG_LOG(SG_GL, SG_ALERT,
458 "RenderTexture Error: wglCreateContext() failed.");
464 // Share lists, texture objects, and program objects.
467 if( !wglShareLists(hglrc, _hGLContext) )
469 SG_LOG(SG_GL, SG_ALERT,
470 "RenderTexture Error: wglShareLists() failed.");
476 // Determine the actual width and height we were able to create.
477 wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
478 wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
480 _bInitialized = true;
482 // get the actual number of bits allocated:
483 int attrib = WGL_RED_BITS_ARB;
487 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
489 attrib = WGL_GREEN_BITS_ARB;
491 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
493 attrib = WGL_BLUE_BITS_ARB;
495 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
497 attrib = WGL_ALPHA_BITS_ARB;
499 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
501 attrib = WGL_DEPTH_BITS_ARB;
503 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
505 attrib = WGL_STENCIL_BITS_ARB;
507 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
509 attrib = WGL_DOUBLE_BUFFER_ARB;
511 (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
512 ? (value?true:false) : false;
514 #if defined(_DEBUG) | defined(DEBUG)
515 SG_LOG(SG_GL, SG_ALERT, "Created a " << _iWidth << "x" << _iHeight <<
516 " RenderTexture with BPP(" <<
517 _iNumColorBits[0] << "," << _iNumColorBits[1] << "," <<
518 _iNumColorBits[2] << "," << _iNumColorBits[3] << ")");
519 if (_iNumDepthBits) SG_LOG(SG_GL, SG_ALERT, " depth=" << _iNumDepthBits);
520 if (_iNumStencilBits) SG_LOG(SG_GL, SG_ALERT, " stencil=" << _iNumStencilBits);
521 if (_bDoubleBuffered) SG_LOG(SG_GL, SG_ALERT, " double buffered");
524 #elif defined( __MACH__ )
525 // Get the current context.
526 CGLContextObj hglrc = CGLGetCurrentContext();
528 fprintf(stderr, "Couldn't get current context!");
530 CGLPixelFormatObj pixFormat = NULL;
534 // Copy the _pixelFormatAttribs into another array to fix
536 CGLPixelFormatAttribute *pixFormatAttribs =
537 (CGLPixelFormatAttribute *)malloc(sizeof(CGLPixelFormatAttribute)
538 * _pixelFormatAttribs.size());
540 for (unsigned int ii = 0; ii < _pixelFormatAttribs.size(); ii++)
542 pixFormatAttribs[ii] =
543 (CGLPixelFormatAttribute)_pixelFormatAttribs[ii];
547 CGLChoosePixelFormat(&pixFormatAttribs[0], &pixFormat, &iNumFormats))
550 "RenderTexture Error: CGLChoosePixelFormat() failed.\n");
551 _cglCheckError(error);
554 if ( iNumFormats <= 0 )
556 SG_LOG(SG_GL, SG_ALERT,
557 "RenderTexture Error: Couldn't find a suitable "
562 // Free the copy of the _pixelFormatAttribs array
563 free(pixFormatAttribs);
565 // Create the context.
566 error = CGLCreateContext(pixFormat, (_bShareObjects)
567 ? CGLGetCurrentContext() : NULL, &_hGLContext);
571 "RenderTexture Error: CGLCreateContext() failed.\n");
572 _cglCheckError(error);
575 CGLDestroyPixelFormat(pixFormat);
577 // Create the p-buffer.
578 error = CGLCreatePBuffer(_iWidth, _iHeight, (_bRectangle)
579 ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D, GL_RGBA, 0, &_hPBuffer);
583 "RenderTexture Error: CGLCreatePBuffer() failed.\n");
584 _cglCheckError(error);
589 if (error = CGLGetVirtualScreen(CGLGetCurrentContext(), &screen))
591 _cglCheckError(error);
594 if (error = CGLSetPBuffer(_hGLContext, _hPBuffer, 0, 0, screen))
596 _cglCheckError(error);
600 // Determine the actual width and height we were able to create.
601 //wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
602 //wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
604 _bInitialized = true;
607 // get the actual number of bits allocated:
608 int attrib = WGL_RED_BITS_ARB;
612 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
614 attrib = WGL_GREEN_BITS_ARB;
616 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
618 attrib = WGL_BLUE_BITS_ARB;
620 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
622 attrib = WGL_ALPHA_BITS_ARB;
624 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
626 attrib = WGL_DEPTH_BITS_ARB;
628 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
630 attrib = WGL_STENCIL_BITS_ARB;
632 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
634 attrib = WGL_DOUBLE_BUFFER_ARB;
636 (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value))
637 ? (value?true:false) : false;
640 #if defined(_DEBUG) | defined(DEBUG)
641 fprintf(stderr, "Created a %dx%d RenderTexture with BPP(%d, %d, %d, %d)",
643 _iNumColorBits[0], _iNumColorBits[1],
644 _iNumColorBits[2], _iNumColorBits[3]);
645 if (_iNumDepthBits) fprintf(stderr, " depth=%d", _iNumDepthBits);
646 if (_iNumStencilBits) fprintf(stderr, " stencil=%d", _iNumStencilBits);
647 if (_bDoubleBuffered) fprintf(stderr, " double buffered");
648 fprintf(stderr, "\n");
651 #else // !_WIN32, !__MACH_
653 _pDisplay = glXGetCurrentDisplay();
655 dbg_printf("RenderTexture::Initialize: ERROR: glXGetCurrentDisplay() returned NULL! return false\n");
658 dbg_printf("RenderTexture::Initialize: got glXGetCurrentDisplay() _pDisplay=[%p]\n", _pDisplay);
659 // glXGetCurrentContext returns the current context, as specified by glXMakeCurrent.
660 // If there is no current context, NULL is returned.
661 GLXContext context = glXGetCurrentContext();
663 dbg_printf("RenderTexture::Initialize: ERROR: glXGetCurrentContext() returned NULL! return false\n");
666 dbg_printf("RenderTexture::Initialize: got glXGetCurrentContext() context=[%p]\n", context);
667 int screen = DefaultScreen(_pDisplay);
668 dbg_printf("RenderTexture::Initialize: DefaultScreen(_pDisplay) screen=%d\n", screen);
670 XVisualInfo *visInfo = NULL;
672 GLXFBConfig *fbConfigs;
675 dbg_printf("Using %d pixelFormatAttribs array\n", (int)_pixelFormatAttribs.size());
676 size_t max = _pixelFormatAttribs.size() / 2;
679 for (n = 0; n < max; n++) {
680 const char * cp = get_attr_name(_pixelFormatAttribs[n*2], &dat);
681 printf( "%s(%d) = %d (def=%d)\n",
682 cp, _pixelFormatAttribs[n*2], _pixelFormatAttribs[(n*2)+1], dat );
685 if ( n < _pixelFormatAttribs.size() )
686 printf( "Array ends with %d\n", _pixelFormatAttribs[n] );
688 printf( "WARNING: Array does not appear ODD! which is ODD\n" );
691 fbConfigs = glXChooseFBConfigPtr(_pDisplay, screen,
692 &_pixelFormatAttribs[0], &nConfigs);
693 // NOTE: ref: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseFBConfig.xml says
694 // Next, call glXGetFBConfigAttrib to retrieve additional attributes for the frame buffer configurations and then select between them.
696 if (nConfigs <= 0 || !fbConfigs)
698 SG_LOG(SG_GL, SG_ALERT,
699 "RenderTexture Error: Couldn't find a suitable pixel format.");
700 dbg_printf("RenderTexture Error: Couldn't find a suitable pixel format. return false\n");
704 dbg_printf("RenderTexture::Initialize: glXChooseFBConfigPtr() nConfigs = %d, fbConfigs=[%p]\n", nConfigs, fbConfigs);
707 GLX_PBUFFER_WIDTH, _iWidth,
708 GLX_PBUFFER_HEIGHT, _iHeight,
709 GLX_LARGEST_PBUFFER, False,
712 // Pick the first returned format that will return a pbuffer
713 // if (glXVersion1_3Present)
714 if (glXCreatePbufferPtr && glXGetVisualFromFBConfigPtr && glXCreateContextPtr)
716 dbg_printf("RenderTexture::Initialize: glXVersion1_3Present = TRUE\n");
717 for (int i=0;i<nConfigs;i++)
719 _hPBuffer = glXCreatePbufferPtr(_pDisplay, fbConfigs[i], pbufAttrib);
722 XVisualInfo *visInfo = glXGetVisualFromFBConfigPtr(_pDisplay, fbConfigs[i]);
724 _hGLContext = glXCreateContextPtr(_pDisplay, visInfo,
725 _bShareObjects ? context : NULL,
729 dbg_printf("RenderTexture Error: glXCreateContextPtr(_pDisplay, visInfo,..) FAILED! return false\n");
744 dbg_printf("RenderTexture::Initialize: glXVersion1_3Present = FALSE w=%d h=%d\n", _iWidth, _iHeight);
745 for (int i=0; i < nConfigs; i++)
747 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() get buffer ptr\n", (i + 1));
748 _hPBuffer = glXCreateGLXPbufferPtr(_pDisplay, fbConfigs[i],
750 &pbufAttrib[0] ); //NULL);
753 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() got buffer [%p]\n", (i + 1), (void*)_hPBuffer);
754 _hGLContext = glXCreateContextWithConfigPtr(_pDisplay,
757 _bShareObjects ? context : NULL,
759 dbg_printf("RenderTexture::Initialize: %d: glXCreateContextWithConfigPtr() _hGLContext=[%p]\n", (i + 1), _hGLContext);
762 dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() NO buffer\n", (i + 1));
767 dbg_printf("RenderTexture::Initialize: doing XFree( fbConfigs=[%p].\n", fbConfigs);
772 SG_LOG(SG_GL, SG_ALERT,
773 "RenderTexture Error: glXCreateGLXPbufferPtr() failed.");
774 dbg_printf("RenderTexture Error: glXCreateGLXPbufferPtr() failed.\n");
781 _hGLContext = glXCreateContext(_pDisplay, visInfo,
782 _bShareObjects ? context : NULL, False);
785 SG_LOG(SG_GL, SG_ALERT,
786 "RenderTexture Error: glXCreateContext() failed.");
787 dbg_printf("RenderTexture Error: glXCreateContext() failed. return false\n");
792 // if (!glXVersion1_3Present)
793 if ((!glXCreatePbufferPtr || !glXGetVisualFromFBConfigPtr || !glXCreateContextPtr) &&
794 (!glXVersion1_3Present))
796 #ifdef ADD_QUERY_BUFFER
797 dbg_printf("RenderTexture::Initialize: Doing glXQueryGLXPbufferSGIXPtr with GLX_WIDTH_SGIX\n");
798 glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_WIDTH_SGIX,
800 dbg_printf("RenderTexture::Initialize: Doing glXQueryGLXPbufferSGIXPtr with GLX_HEIGHT_SGIX\n");
801 glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_HEIGHT_SGIX,
804 dbg_printf("RenderTexture::Initialize: SKIPPED doing glXQueryGLXPbufferSGIXPtr with GLX_WIDTH_SGIX and GLX_HEIGHT_SGIX\n");
805 #endif // #ifdef ADD_QUERY_BUFFER
808 _bInitialized = true;
809 dbg_printf( "RenderTexture::Initialize: _bIniialized set TRUE\n" );
810 // XXX Query the color format
815 // Now that the pbuffer is created, allocate any texture objects needed,
816 // and initialize them (for CTT updates only). These must be allocated
817 // in the context of the pbuffer, though, or the RT won't work without
820 if (false == wglMakeCurrent( _hDC, _hGLContext))
825 #elif defined( __MACH__ )
827 if (err = CGLSetCurrentContext(_hGLContext))
834 #ifdef ADD_GET_DRAWABLE
835 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentContext()\n" );
836 _hPreviousContext = glXGetCurrentContext();
837 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentDrawable()\n" );
838 _hPreviousDrawable = glXGetCurrentDrawable();
840 _hPreviousContext = context;
841 _hPreviousDrawable = 0;
842 dbg_printf( "RenderTexture::Initialize: SKIPPED doing glXGetCurrentContext(2nd) AND glXGetCurrentDrawable()\n" );
843 #endif // #ifdef ADD_GET_DRAWABLE
845 dbg_printf( "RenderTexture::Initialize: doing glXMakeCurrent(_pDisplay(%p), _hPBuffer(%p), _hGLContext(%p))\n",
846 _pDisplay, (void*)_hPBuffer, _hGLContext );
847 if (False == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
849 dbg_printf( "glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext) FAILED. return false\n" );
855 bool result = _InitializeTextures();
857 BindBuffer(WGL_FRONT_LEFT_ARB);
863 // make the previous rendering context current
864 if (false == wglMakeCurrent( hdc, hglrc))
869 #elif defined( __MACH__ )
870 if (err = CGLSetCurrentContext(_hPreviousContext))
876 if (False == glXMakeCurrent(_pDisplay,
877 _hPreviousDrawable, _hPreviousContext))
879 dbg_printf("glXMakeCurrent(_pDisplay, _hPreviousDrawable, _hPreviousContext)) FAILED! return false\n" );
883 if (glXVersion1_3Present)
884 //if ((glXVersion1_3Present) ||
885 // (glXCreatePbufferPtr && glXGetVisualFromFBConfigPtr && glXCreateContextPtr && glXQueryDrawablePtr))
887 dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentDrawable()\n" );
888 GLXDrawable draw = glXGetCurrentDrawable();
889 dbg_printf( "RenderTexture::Initialize: doing glXQueryDrawablePtr for GLX_WIDTH and GLX_HEIGHT\n" );
890 glXQueryDrawablePtr(_pDisplay, draw, GLX_WIDTH, (unsigned int*)&_iWidth);
891 glXQueryDrawablePtr(_pDisplay, draw, GLX_HEIGHT, (unsigned int*)&_iHeight);
895 dbg_printf( "RenderTexture::Initialize(w=%d,h=%d): returning %s\n", _iWidth, _iHeight, (result ? "TRUE" : "FALSE") );
900 //---------------------------------------------------------------------------
901 // Function : RenderTexture::_Invalidate
903 //---------------------------------------------------------------------------
905 * @fn RenderTexture::_Invalidate()
906 * @brief Returns the pbuffer memory to the graphics device.
909 bool RenderTexture::_Invalidate()
911 dbg_printf( "RenderTexture::_Invalidate() called...\n" );
913 _iNumColorBits[0] = _iNumColorBits[1] =
914 _iNumColorBits[2] = _iNumColorBits[3] = 0;
916 _iNumStencilBits = 0;
919 glDeleteTextures(1, &_iTextureID);
920 if (_bIsDepthTexture)
923 if (!_bHasARBDepthTexture) delete[] _pPoorDepthTexture;
925 glDeleteTextures(1, &_iDepthTextureID);
931 // Check if we are currently rendering in the pbuffer
932 if (wglGetCurrentContext() == _hGLContext)
935 wglDeleteContext( _hGLContext);
936 wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
937 wglDestroyPbufferARBPtr( _hPBuffer );
941 #elif defined( __MACH__ )
944 if (CGLGetCurrentContext() == _hGLContext)
945 CGLSetCurrentContext(NULL);
947 CGLDestroyContext(_hGLContext);
948 CGLDestroyPBuffer(_hPBuffer);
955 if(glXGetCurrentContext() == _hGLContext)
956 // XXX I don't know if this is right at all
957 glXMakeCurrent(_pDisplay, _hPBuffer, 0);
958 glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
960 dbg_printf( "RenderTexture::_Invalidate: glXDestroyPbufferPtr(_pDisplay, _hPBuffer); return true\n" );
965 dbg_printf( "RenderTexture::_Invalidate: return false\n" );
966 // [WVB] do we need to call _ReleaseBoundBuffers() too?
971 //---------------------------------------------------------------------------
972 // Function : RenderTexture::Reset
974 //---------------------------------------------------------------------------
976 * @fn RenderTexture::Reset()
977 * @brief Resets the resolution of the offscreen buffer.
979 * Causes the buffer to delete itself. User must call Initialize() again
982 bool RenderTexture::Reset(const char *strMode, ...)
984 dbg_printf("RenderTexure:Reset(): with %s\n", strMode);
986 _iWidth = 0; _iHeight = 0;
987 _bIsTexture = false; _bIsDepthTexture = false,
988 _bHasARBDepthTexture = true;
989 #if defined(_WIN32) || defined(__MACH__)
990 _eUpdateMode = RT_RENDER_TO_TEXTURE;
992 _eUpdateMode = RT_COPY_TO_TEXTURE;
994 _bInitialized = false;
996 _bIsBufferBound = false;
997 _iCurrentBoundBuffer = 0;
998 _iNumDepthBits = 0; _iNumStencilBits = 0;
999 _bDoubleBuffered = false;
1000 _bFloat = false; _bPowerOf2 = true;
1001 _bRectangle = false; _bMipmap = false;
1002 _bShareObjects = false; _bCopyContext = false;
1003 _iTextureTarget = GL_NONE; _iTextureID = 0;
1004 _iDepthTextureID = 0;
1005 _pPoorDepthTexture = 0;
1006 _pixelFormatAttribs.clear();
1007 _pbufferAttribs.clear();
1008 if (IsInitialized())
1012 dbg_printf( "RenderTexture::Reset(): failed to invalidate. return false\n");
1017 dbg_printf( "RenderTexture::Reset(): was Initialized, and now _Invalidate() ok.");
1022 dbg_printf("RenderTexure:Reset(): previous NOT initialised!\n");
1025 _iNumColorBits[0] = _iNumColorBits[1] =
1026 _iNumColorBits[2] = _iNumColorBits[3] = 0;
1029 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
1030 _pixelFormatAttribs.push_back(true);
1031 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
1032 _pixelFormatAttribs.push_back(true);
1034 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
1035 _pbufferAttribs.push_back(true);
1036 #elif defined( __MACH__ )
1037 //_pixelFormatAttribs.push_back(kCGLPFANoRecovery);
1038 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
1039 _pixelFormatAttribs.push_back(kCGLPFAWindow);
1040 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
1042 _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
1043 _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
1044 _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
1045 _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
1049 char strBuffer[256];
1050 va_start(args,strMode);
1051 vsnprintf( strBuffer, 256, strMode, args );
1054 _ParseModeString(strBuffer, _pixelFormatAttribs, _pbufferAttribs);
1057 _pixelFormatAttribs.push_back(0);
1058 _pbufferAttribs.push_back(0);
1059 #elif defined(__MACH__)
1060 _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
1062 _pixelFormatAttribs.push_back(None);
1064 dbg_printf("RenderTexure:Reset(): returning true.\n");
1068 //------------------------------------------------------------------------------
1069 // Function : RenderTexture::Resize
1071 //------------------------------------------------------------------------------
1073 * @fn RenderTexture::Resize(int iWidth, int iHeight)
1074 * @brief Changes the size of the offscreen buffer.
1076 * Like Reset() this causes the buffer to delete itself.
1077 * But unlike Reset(), this call re-initializes the RenderTexture.
1078 * Note that Resize() will not work after calling Reset(), or before
1079 * calling Initialize() the first time.
1081 bool RenderTexture::Resize(int iWidth, int iHeight)
1083 if (!_bInitialized) {
1084 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Resize(): must Initialize() first.");
1087 if (iWidth == _iWidth && iHeight == _iHeight) {
1091 // Do same basic work as _Invalidate, but don't reset all our flags
1093 glDeleteTextures(1, &_iTextureID);
1094 if (_bIsDepthTexture)
1095 glDeleteTextures(1, &_iDepthTextureID);
1099 // Check if we are currently rendering in the pbuffer
1100 if (wglGetCurrentContext() == _hGLContext)
1101 wglMakeCurrent(0,0);
1103 wglDeleteContext( _hGLContext);
1104 wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
1105 wglDestroyPbufferARBPtr( _hPBuffer );
1109 #elif defined( __MACH__ )
1112 if (CGLGetCurrentContext() == _hGLContext)
1113 CGLSetCurrentContext(NULL);
1115 CGLDestroyContext(_hGLContext);
1116 CGLDestroyPBuffer(_hPBuffer);
1123 if(glXGetCurrentContext() == _hGLContext)
1124 // XXX I don't know if this is right at all
1125 glXMakeCurrent(_pDisplay, _hPBuffer, 0);
1126 glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
1131 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Resize(): failed to resize.");
1134 _bInitialized = false;
1135 return Initialize(iWidth, iHeight, _bShareObjects, _bCopyContext);
1138 //---------------------------------------------------------------------------
1139 // Function : RenderTexture::BeginCapture
1141 //---------------------------------------------------------------------------
1143 * @fn RenderTexture::BeginCapture()
1144 * @brief Activates rendering to the RenderTexture.
1146 bool RenderTexture::BeginCapture()
1150 SG_LOG(SG_GL, SG_ALERT,
1151 "RenderTexture::BeginCapture(): Texture is not initialized!");
1155 // cache the current context so we can reset it when EndCapture() is called.
1156 _hPreviousDC = wglGetCurrentDC();
1157 if (NULL == _hPreviousDC)
1159 _hPreviousContext = wglGetCurrentContext();
1160 if (NULL == _hPreviousContext)
1162 #elif defined( __MACH__ )
1163 _hPreviousContext = CGLGetCurrentContext();
1165 _hPreviousContext = glXGetCurrentContext();
1166 _hPreviousDrawable = glXGetCurrentDrawable();
1169 _ReleaseBoundBuffers();
1171 return _MakeCurrent();
1175 //---------------------------------------------------------------------------
1176 // Function : RenderTexture::EndCapture
1178 //---------------------------------------------------------------------------
1180 * @fn RenderTexture::EndCapture()
1181 * @brief Ends rendering to the RenderTexture.
1183 bool RenderTexture::EndCapture()
1187 SG_LOG(SG_GL, SG_ALERT,
1188 "RenderTexture::EndCapture() : Texture is not initialized!");
1192 glFlush(); // Added by a-lex
1197 // make the previous rendering context current
1198 if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
1203 #elif defined( __MACH__ )
1205 if (err = CGLSetCurrentContext(_hPreviousContext))
1207 _cglCheckError(err);
1211 if (False == glXMakeCurrent(_pDisplay, _hPreviousDrawable,
1218 // rebind the textures to a buffers for RTT
1219 BindBuffer(_iCurrentBoundBuffer);
1225 //---------------------------------------------------------------------------
1226 // Function : RenderTexture::BeginCapture(RenderTexture*)
1228 //---------------------------------------------------------------------------
1230 * @fn RenderTexture::BeginCapture(RenderTexture* other)
1231 * @brief Ends capture of 'other', begins capture on 'this'
1233 * When performing a series of operations where you modify one texture after
1234 * another, it is more efficient to use this method instead of the equivalent
1235 * 'EndCapture'/'BeginCapture' pair. This method switches directly to the
1236 * new context rather than changing to the default context, and then to the
1239 * RenderTexture doesn't have any mechanism for determining if
1240 * 'current' really is currently active, so no error will be thrown
1243 bool RenderTexture::BeginCapture(RenderTexture* current)
1245 // bool bContextReset = false;
1247 if (current == this) {
1248 return true; // no switch necessary
1251 // treat as normal Begin if current is 0.
1252 return BeginCapture();
1256 SG_LOG(SG_GL, SG_ALERT,
1257 "RenderTexture::BeginCapture(RenderTexture*): Texture is not initialized!");
1260 if (!current->_bInitialized)
1262 SG_LOG(SG_GL, SG_ALERT,
1263 "RenderTexture::BeginCapture(RenderTexture): 'current' texture is not initialized!");
1267 // Sync current pbuffer with its CTT texture if necessary
1268 current->_MaybeCopyBuffer();
1270 // pass along the previous context so we can reset it when
1271 // EndCapture() is called.
1273 _hPreviousDC = current->_hPreviousDC;
1274 if (NULL == _hPreviousDC)
1276 _hPreviousContext = current->_hPreviousContext;
1277 if (NULL == _hPreviousContext)
1279 #elif defined( __MACH__ )
1280 _hPreviousContext = current->_hPreviousContext;
1282 _hPreviousContext = current->_hPreviousContext;
1283 _hPreviousDrawable = current->_hPreviousDrawable;
1286 // Unbind textures before making context current
1287 if (!_ReleaseBoundBuffers())
1290 // Make the pbuffer context current
1291 if (!_MakeCurrent())
1294 // Rebind buffers of initial RenderTexture
1295 current->BindBuffer(_iCurrentBoundBuffer);
1296 current->_BindDepthBuffer();
1303 //---------------------------------------------------------------------------
1304 // Function : RenderTexture::Bind
1306 //---------------------------------------------------------------------------
1308 * @fn RenderTexture::Bind()
1309 * @brief Binds RGB texture.
1311 void RenderTexture::Bind() const
1313 if (_bInitialized && _bIsTexture)
1315 glBindTexture(_iTextureTarget, _iTextureID);
1320 //---------------------------------------------------------------------------
1321 // Function : RenderTexture::BindDepth
1323 //---------------------------------------------------------------------------
1325 * @fn RenderTexture::BindDepth()
1326 * @brief Binds depth texture.
1328 void RenderTexture::BindDepth() const
1330 if (_bInitialized && _bIsDepthTexture)
1332 glBindTexture(_iTextureTarget, _iDepthTextureID);
1337 //---------------------------------------------------------------------------
1338 // Function : RenderTexture::BindBuffer
1340 //---------------------------------------------------------------------------
1342 * @fn RenderTexture::BindBuffer()
1343 * @brief Associate the RTT texture id with 'iBuffer' (e.g. WGL_FRONT_LEFT_ARB)
1345 bool RenderTexture::BindBuffer( int iBuffer )
1347 // Must bind the texture too
1348 if (_bInitialized && _bIsTexture)
1350 glBindTexture(_iTextureTarget, _iTextureID);
1353 if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
1354 (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
1356 if (FALSE == wglBindTexImageARBPtr(_hPBuffer, iBuffer))
1358 // WVB: WGL API considers binding twice to the same buffer
1359 // to be an error. But we don't want to
1360 //_wglGetLastError();
1364 _bIsBufferBound = true;
1365 _iCurrentBoundBuffer = iBuffer;
1367 #elif defined(__MACH__)
1368 if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
1369 (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
1372 if (err=CGLTexImagePBuffer(CGLGetCurrentContext(), _hPBuffer, iBuffer))
1374 _cglCheckError(err);
1376 _bIsBufferBound = true;
1377 _iCurrentBoundBuffer = iBuffer;
1385 //---------------------------------------------------------------------------
1386 // Function : RenderTexture::BindDepthBuffer
1388 //---------------------------------------------------------------------------
1390 * @fn RenderTexture::_BindDepthBuffer()
1391 * @brief Associate the RTT depth texture id with the depth buffer
1393 bool RenderTexture::_BindDepthBuffer() const
1396 if (_bInitialized && _bIsDepthTexture &&
1397 RT_RENDER_TO_TEXTURE == _eUpdateMode)
1399 glBindTexture(_iTextureTarget, _iDepthTextureID);
1400 if (FALSE == wglBindTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
1406 #elif defined(__MACH__)
1407 if (_bInitialized && _bIsDepthTexture &&
1408 RT_RENDER_TO_TEXTURE == _eUpdateMode)
1410 glBindTexture(_iTextureTarget, _iDepthTextureID);
1411 //if (FALSE == CGLTexImagePBuffer(<#CGLContextObj ctx#>,<#CGLPBufferObj pbuffer#>,<#unsigned long source#>)(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
1413 // _wglGetLastError();
1421 //---------------------------------------------------------------------------
1422 // Function : RenderTexture::_ParseModeString
1424 //---------------------------------------------------------------------------
1426 * @fn RenderTexture::_ParseModeString()
1427 * @brief Parses the user-specified mode string for RenderTexture parameters.
1429 void RenderTexture::_ParseModeString(const char *modeString,
1430 vector<int> &pfAttribs,
1431 vector<int> &pbAttribs)
1433 dbg_printf("RenderTexture::_ParseModeString(%s). BGN vf=%d vp=%d\n", modeString, (int)pfAttribs.size(), (int)pbAttribs.size() );
1434 if (!modeString || strcmp(modeString, "") == 0)
1437 _iNumComponents = 0;
1438 #if defined(_WIN32) || defined(__MACH__)
1439 _eUpdateMode = RT_RENDER_TO_TEXTURE;
1441 _eUpdateMode = RT_COPY_TO_TEXTURE;
1445 bool bHasStencil = false;
1446 bool bBind2D = false;
1447 bool bBindRECT = false;
1448 bool bBindCUBE = false;
1450 char *mode = strdup(modeString);
1453 vector<string> tokens;
1454 char *buf = strtok(mode, " ");
1457 tokens.push_back(buf);
1458 buf = strtok(NULL, " ");
1461 for (unsigned int i = 0; i < tokens.size(); i++)
1463 string token = tokens[i];
1465 KeyVal kv = _GetKeyValuePair(token);
1468 if (kv.first == "rgb" && (_iNumComponents <= 1))
1470 if (kv.second.find("f") != kv.second.npos)
1473 vector<int> bitVec = _ParseBitVector(kv.second);
1475 if (bitVec.size() < 3) // expand the scalar to a vector
1477 bitVec.push_back(bitVec[0]);
1478 bitVec.push_back(bitVec[0]);
1482 pfAttribs.push_back(WGL_RED_BITS_ARB);
1483 pfAttribs.push_back(bitVec[0]);
1484 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1485 pfAttribs.push_back(bitVec[1]);
1486 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
1487 pfAttribs.push_back(bitVec[2]);
1488 #elif defined( __MACH__ )
1490 pfAttribs.push_back(AGL_RED_SIZE);
1491 pfAttribs.push_back(bitVec[0]);
1492 pfAttribs.push_back(AGL_GREEN_SIZE);
1493 pfAttribs.push_back(bitVec[1]);
1494 pfAttribs.push_back(AGL_BLUE_SIZE);
1495 pfAttribs.push_back(bitVec[2]);
1497 pfAttribs.push_back(kCGLPFAColorSize);
1498 pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2]);
1501 pfAttribs.push_back(GLX_RED_SIZE);
1502 pfAttribs.push_back(bitVec[0]);
1503 pfAttribs.push_back(GLX_GREEN_SIZE);
1504 pfAttribs.push_back(bitVec[1]);
1505 pfAttribs.push_back(GLX_BLUE_SIZE);
1506 pfAttribs.push_back(bitVec[2]);
1508 _iNumComponents += 3;
1511 else if (kv.first == "rgb")
1513 SG_LOG(SG_GL, SG_ALERT,
1514 "RenderTexture Warning: mistake in components definition "
1515 "(rgb + " << _iNumComponents << ").");
1516 dbg_printf("RenderTexture Warning 1: mistake in components definition "
1517 "(rgb + %d).\n", _iNumComponents );
1520 if (kv.first == "rgba" && (_iNumComponents == 0))
1522 if (kv.second.find("f") != kv.second.npos)
1525 vector<int> bitVec = _ParseBitVector(kv.second);
1527 if (bitVec.size() < 4) // expand the scalar to a vector
1529 bitVec.push_back(bitVec[0]);
1530 bitVec.push_back(bitVec[0]);
1531 bitVec.push_back(bitVec[0]);
1535 pfAttribs.push_back(WGL_RED_BITS_ARB);
1536 pfAttribs.push_back(bitVec[0]);
1537 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1538 pfAttribs.push_back(bitVec[1]);
1539 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
1540 pfAttribs.push_back(bitVec[2]);
1541 pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
1542 pfAttribs.push_back(bitVec[3]);
1543 #elif defined( __MACH__ )
1545 pfAttribs.push_back(AGL_RED_SIZE);
1546 pfAttribs.push_back(bitVec[0]);
1547 pfAttribs.push_back(AGL_GREEN_SIZE);
1548 pfAttribs.push_back(bitVec[1]);
1549 pfAttribs.push_back(AGL_BLUE_SIZE);
1550 pfAttribs.push_back(bitVec[2]);
1551 pfAttribs.push_back(AGL_ALPHA_SIZE);
1552 pfAttribs.push_back(bitVec[3]);
1554 pfAttribs.push_back(kCGLPFAColorSize);
1555 pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2] + bitVec[3]);
1556 //pfAttribs.push_back(kCGLPFAAlphaSize);
1557 //pfAttribs.push_back(bitVec[3]);
1558 // printf("Color size: %d\n", bitVec[0] + bitVec[1] + bitVec[2] + bitVec[3]);
1562 pfAttribs.push_back(GLX_RED_SIZE);
1563 pfAttribs.push_back(bitVec[0]);
1564 pfAttribs.push_back(GLX_GREEN_SIZE);
1565 pfAttribs.push_back(bitVec[1]);
1566 pfAttribs.push_back(GLX_BLUE_SIZE);
1567 pfAttribs.push_back(bitVec[2]);
1568 pfAttribs.push_back(GLX_ALPHA_SIZE);
1569 pfAttribs.push_back(bitVec[3]);
1571 _iNumComponents = 4;
1574 else if (kv.first == "rgba")
1576 SG_LOG(SG_GL, SG_ALERT,
1577 "RenderTexture Warning: mistake in components definition "
1578 "(rgba + " << _iNumComponents << ").");
1579 dbg_printf("RenderTexture Warning 2: mistake in components definition "
1580 "(rgb + %d).\n", _iNumComponents );
1583 if (kv.first == "r" && (_iNumComponents <= 1))
1585 if (kv.second.find("f") != kv.second.npos)
1588 vector<int> bitVec = _ParseBitVector(kv.second);
1591 pfAttribs.push_back(WGL_RED_BITS_ARB);
1592 pfAttribs.push_back(bitVec[0]);
1593 #elif defined( __MACH__ )
1595 pfAttribs.push_back(AGL_RED_SIZE);
1596 pfAttribs.push_back(bitVec[0]);
1598 pfAttribs.push_back(kCGLPFAColorSize);
1599 pfAttribs.push_back(bitVec[0]);
1602 pfAttribs.push_back(GLX_RED_SIZE);
1603 pfAttribs.push_back(bitVec[0]);
1608 else if (kv.first == "r")
1610 SG_LOG(SG_GL, SG_ALERT,
1611 "RenderTexture Warning: mistake in components definition "
1612 "(r + " << _iNumComponents << ").");
1613 dbg_printf("RenderTexture Warning 3: mistake in components definition "
1614 "(rgb + %d).\n", _iNumComponents );
1616 if (kv.first == "rg" && (_iNumComponents <= 1))
1618 if (kv.second.find("f") != kv.second.npos)
1621 vector<int> bitVec = _ParseBitVector(kv.second);
1623 if (bitVec.size() < 2) // expand the scalar to a vector
1625 bitVec.push_back(bitVec[0]);
1629 pfAttribs.push_back(WGL_RED_BITS_ARB);
1630 pfAttribs.push_back(bitVec[0]);
1631 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1632 pfAttribs.push_back(bitVec[1]);
1633 #elif defined( __MACH__ )
1635 pfAttribs.push_back(AGL_RED_SIZE);
1636 pfAttribs.push_back(bitVec[0]);
1637 pfAttribs.push_back(AGL_GREEN_SIZE);
1638 pfAttribs.push_back(bitVec[1]);
1640 pfAttribs.push_back(kCGLPFAColorSize);
1641 pfAttribs.push_back(bitVec[0] + bitVec[1]);
1644 pfAttribs.push_back(GLX_RED_SIZE);
1645 pfAttribs.push_back(bitVec[0]);
1646 pfAttribs.push_back(GLX_GREEN_SIZE);
1647 pfAttribs.push_back(bitVec[1]);
1649 _iNumComponents += 2;
1652 else if (kv.first == "rg")
1654 SG_LOG(SG_GL, SG_ALERT,
1655 "RenderTexture Warning: mistake in components definition "
1656 "(rg + " << _iNumComponents << ").");
1657 dbg_printf("RenderTexture Warning 4: mistake in components definition "
1658 "(rgb + %d).\n", _iNumComponents );
1661 if (kv.first == "depth")
1663 if (kv.second == "")
1666 iDepthBits = strtol(kv.second.c_str(), 0, 10);
1670 if (kv.first == "stencil")
1674 pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
1675 #elif defined( __MACH__ )
1677 pfAttribs.push_back(AGL_STENCIL_SIZE);
1679 pfAttribs.push_back(kCGLPFAStencilSize);
1682 pfAttribs.push_back(GLX_STENCIL_SIZE);
1684 if (kv.second == "")
1685 pfAttribs.push_back(8);
1687 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1691 if (kv.first == "samples")
1694 pfAttribs.push_back(WGL_SAMPLE_BUFFERS_ARB);
1695 pfAttribs.push_back(1);
1696 pfAttribs.push_back(WGL_SAMPLES_ARB);
1697 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1698 #elif defined( __MACH__ )
1700 pfAttribs.push_back(AGL_SAMPLE_BUFFERS_ARB);
1701 pfAttribs.push_back(1);
1702 pfAttribs.push_back(AGL_SAMPLES_ARB);
1704 pfAttribs.push_back(kCGLPFAMultisample);
1705 pfAttribs.push_back(kCGLPFASamples);
1707 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1709 pfAttribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
1710 pfAttribs.push_back(1);
1711 pfAttribs.push_back(GLX_SAMPLES_ARB);
1712 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1718 if (kv.first == "doublebuffer" || kv.first == "double")
1721 pfAttribs.push_back(WGL_DOUBLE_BUFFER_ARB);
1722 pfAttribs.push_back(true);
1723 #elif defined( __MACH__ )
1725 pfAttribs.push_back(AGL_DOUBLEBUFFER);
1726 pfAttribs.push_back(True);
1728 pfAttribs.push_back(kCGLPFADoubleBuffer);
1731 pfAttribs.push_back(GLX_DOUBLEBUFFER);
1732 pfAttribs.push_back(True);
1737 if (kv.first == "aux")
1740 pfAttribs.push_back(WGL_AUX_BUFFERS_ARB);
1741 #elif defined( __MACH__ )
1743 pfAttribs.push_back(AGL_AUX_BUFFERS);
1745 pfAttribs.push_back(kCGLPFAAuxBuffers);
1748 pfAttribs.push_back(GLX_AUX_BUFFERS);
1750 if (kv.second == "")
1751 pfAttribs.push_back(0);
1753 pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1757 if (token.find("tex") == 0)
1761 if ((kv.first == "texRECT") && (GL_NV_texture_rectangle ||
1762 GL_EXT_texture_rectangle))
1767 else if (kv.first == "texCUBE")
1779 if (token.find("depthTex") == 0)
1781 _bIsDepthTexture = true;
1783 if ((kv.first == "depthTexRECT") && (GL_NV_texture_rectangle ||
1784 GL_EXT_texture_rectangle))
1789 else if (kv.first == "depthTexCUBE")
1801 if (kv.first == "mipmap")
1807 if (kv.first == "rtt")
1809 _eUpdateMode = RT_RENDER_TO_TEXTURE;
1813 if (kv.first == "ctt")
1815 _eUpdateMode = RT_COPY_TO_TEXTURE;
1819 SG_LOG(SG_GL, SG_ALERT,
1820 "RenderTexture Error: Unknown pbuffer attribute: " <<
1822 dbg_printf("RenderTexture Error: Uknown pbuffer attribute: %s\n",
1826 // Processing of some options must be last because of interactions.
1828 // Check for inconsistent texture targets
1829 if (_bIsTexture && _bIsDepthTexture && !(bBind2D ^ bBindRECT ^ bBindCUBE))
1831 SG_LOG(SG_GL, SG_ALERT,
1832 "RenderTexture Warning: Depth and Color texture targets "
1834 dbg_printf( "RenderTexture Warning: Depth and Color texture targets should match.\n");
1837 // Apply default bit format if none specified
1839 if (0 == _iNumComponents)
1841 pfAttribs.push_back(WGL_RED_BITS_ARB);
1842 pfAttribs.push_back(8);
1843 pfAttribs.push_back(WGL_GREEN_BITS_ARB);
1844 pfAttribs.push_back(8);
1845 pfAttribs.push_back(WGL_BLUE_BITS_ARB);
1846 pfAttribs.push_back(8);
1847 pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
1848 pfAttribs.push_back(8);
1849 _iNumComponents = 4;
1854 if (_bIsDepthTexture && !iDepthBits)
1858 pfAttribs.push_back(WGL_DEPTH_BITS_ARB);
1859 #elif defined( __MACH__ )
1861 pfAttribs.push_back(AGL_DEPTH_SIZE);
1863 pfAttribs.push_back(kCGLPFADepthSize);
1866 pfAttribs.push_back(GLX_DEPTH_SIZE);
1868 pfAttribs.push_back(iDepthBits); // default
1873 pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
1874 pfAttribs.push_back(0);
1875 #elif defined( __MACH__ )
1877 pfAttribs.push_back(AGL_STENCIL_SIZE);
1879 pfAttribs.push_back(kCGLPFAStencilSize);
1881 pfAttribs.push_back(0);
1883 pfAttribs.push_back(GLX_STENCIL_SIZE);
1884 pfAttribs.push_back(0);
1888 if (_iNumComponents < 4)
1890 // Can't do this right now -- on NVIDIA drivers, currently get
1891 // a non-functioning pbuffer if ALPHA_BITS=0 and
1892 // WGL_BIND_TO_TEXTURE_RGB_ARB=true
1894 //pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
1895 //pfAttribs.push_back(0);
1899 if (!WGL_NV_render_depth_texture && _bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1901 #if defined(DEBUG) || defined(_DEBUG)
1902 SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: No support found for "
1903 "render to depth texture.");
1905 dbg_printf("RenderTexture Warning: No support found for render to depth texture.\n");
1906 _bIsDepthTexture = false;
1910 if ((_bIsTexture || _bIsDepthTexture) &&
1911 (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1916 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1917 pbAttribs.push_back(WGL_TEXTURE_RECTANGLE_NV);
1921 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1922 pbAttribs.push_back(WGL_TEXTURE_CUBE_MAP_ARB);
1926 pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1927 pbAttribs.push_back(WGL_TEXTURE_2D_ARB);
1932 pbAttribs.push_back(WGL_MIPMAP_TEXTURE_ARB);
1933 pbAttribs.push_back(true);
1935 #elif defined(__MACH__)
1936 #elif defined(DEBUG) || defined(_DEBUG)
1937 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: Render to Texture not "
1938 "supported in Linux or MacOS");
1942 // Set the pixel type
1946 if (WGL_NV_float_buffer)
1948 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1949 pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
1951 pfAttribs.push_back(WGL_FLOAT_COMPONENTS_NV);
1952 pfAttribs.push_back(true);
1956 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1957 pfAttribs.push_back(WGL_TYPE_RGBA_FLOAT_ATI);
1959 #elif defined( __MACH__ )
1960 // if (GL_MACH_float_pixels) // FIXME
1962 pfAttribs.push_back(kCGLPFAColorFloat);
1965 if (GLX_NV_float_buffer)
1967 pfAttribs.push_back(GLX_FLOAT_COMPONENTS_NV);
1968 pfAttribs.push_back(1);
1975 pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1976 pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
1980 // Set up texture binding for render to texture
1981 if (_bIsTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1987 if (WGL_NV_float_buffer)
1989 switch(_iNumComponents)
1992 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
1993 pfAttribs.push_back(true);
1995 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
1996 pbAttribs.push_back(WGL_TEXTURE_FLOAT_R_NV);
1999 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
2000 pfAttribs.push_back(true);
2002 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2003 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RG_NV);
2006 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
2007 pfAttribs.push_back(true);
2009 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2010 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGB_NV);
2013 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
2014 pfAttribs.push_back(true);
2016 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2017 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
2020 SG_LOG(SG_GL, SG_ALERT,
2021 "RenderTexture Warning: Bad number of components "
2022 "(r=1,rg=2,rgb=3,rgba=4): " <<
2024 dbg_printf("RenderTexture Warning 1: Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n",
2031 if (4 == _iNumComponents)
2033 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2034 pfAttribs.push_back(true);
2036 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2037 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2041 // standard ARB_render_texture only supports 3 or 4 channels
2042 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2043 pfAttribs.push_back(true);
2045 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2046 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2053 switch(_iNumComponents)
2056 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2057 pfAttribs.push_back(true);
2059 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2060 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2063 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2064 pfAttribs.push_back(true);
2066 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2067 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2070 SG_LOG(SG_GL, SG_ALERT,
2071 "RenderTexture Warning: Bad number of components "
2072 "(r=1,rg=2,rgb=3,rgba=4): " << _iNumComponents);
2073 dbg_printf("RenderTexture Warning 2: Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n",
2078 #elif defined(__MACH__)
2082 //if (WGLEW_NV_float_buffer) // FIXME
2084 switch(_iNumComponents)
2087 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
2088 pfAttribs.push_back(true);
2090 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2091 pbAttribs.push_back(WGL_TEXTURE_FLOAT_R_NV);
2094 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
2095 pfAttribs.push_back(true);
2097 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2098 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RG_NV);
2101 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
2102 pfAttribs.push_back(true);
2104 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2105 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGB_NV);
2108 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
2109 pfAttribs.push_back(true);
2111 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2112 pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
2116 "RenderTexture Warning: Bad number of components "
2117 "(r=1,rg=2,rgb=3,rgba=4): %d.\n",
2124 if (4 == _iNumComponents)
2126 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2127 pfAttribs.push_back(true);
2129 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2130 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2134 // standard ARB_render_texture only supports 3 or 4 channels
2135 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2136 pfAttribs.push_back(true);
2138 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2139 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2147 switch(_iNumComponents)
2150 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
2151 pfAttribs.push_back(true);
2153 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2154 pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
2157 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
2158 pfAttribs.push_back(true);
2160 pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
2161 pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
2165 "RenderTexture Warning: Bad number of components "
2166 "(r=1,rg=2,rgb=3,rgba=4): %d.\n", _iNumComponents);
2171 #elif defined(DEBUG) || defined(_DEBUG)
2172 SG_LOG(SG_GL, SG_ALERT,
2173 "RenderTexture Error: Render to Texture not supported in Linux or MacOS");
2175 dbg_printf( "RenderTexture Error 1: Render to Texture not supported in Linux or MacOS\n");
2178 if (_bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
2183 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV);
2184 pfAttribs.push_back(true);
2186 pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
2187 pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
2191 pfAttribs.push_back(WGL_BIND_TO_TEXTURE_DEPTH_NV);
2192 pfAttribs.push_back(true);
2194 pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
2195 pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
2197 #elif defined(__MACH__)
2198 #elif defined(DEBUG) || defined(_DEBUG)
2199 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: Render to Texture not supported in "
2202 dbg_printf( "RenderTexture Error 2: Render to Texture not supported in Linux or MacOS\n");
2204 dbg_printf("RenderTexture::_ParseModeString(%s). END vf=%d vp=%d\n", modeString, (int)pfAttribs.size(), (int)pbAttribs.size() );
2208 //---------------------------------------------------------------------------
2209 // Function : RenderTexture::_GetKeyValuePair
2211 //---------------------------------------------------------------------------
2213 * @fn RenderTexture::_GetKeyValuePair()
2214 * @brief Parses expressions of the form "X=Y" into a pair (X,Y).
2216 RenderTexture::KeyVal RenderTexture::_GetKeyValuePair(string token)
2218 string::size_type pos = 0;
2219 if ((pos = token.find("=")) != token.npos)
2221 string key = token.substr(0, pos);
2222 string value = token.substr(pos+1, token.length()-pos+1);
2223 return KeyVal(key, value);
2226 return KeyVal(token, "");
2229 //---------------------------------------------------------------------------
2230 // Function : RenderTexture::_ParseBitVector
2232 //---------------------------------------------------------------------------
2234 * @fn RenderTexture::_ParseBitVector()
2235 * @brief Parses expressions of the form "=r,g,b,a" into a vector: (r,g,b,a)
2237 vector<int> RenderTexture::_ParseBitVector(string bitVector)
2239 vector<string> pieces;
2242 if (bitVector == "")
2244 bits.push_back(8); // if a depth isn't specified, use default 8 bits
2248 string::size_type pos = 0;
2249 string::size_type nextpos = 0;
2252 nextpos = bitVector.find_first_of(", ", pos);
2253 pieces.push_back(string(bitVector, pos, nextpos - pos));
2255 } while (nextpos != bitVector.npos );
2257 for ( vector<string>::iterator it = pieces.begin(); it != pieces.end(); it++)
2259 bits.push_back(strtol(it->c_str(), 0, 10));
2265 //---------------------------------------------------------------------------
2266 // Function : RenderTexture::_VerifyExtensions
2268 //---------------------------------------------------------------------------
2270 * @fn RenderTexture::_VerifyExtensions()
2271 * @brief Checks that the necessary extensions are available based on RT mode.
2273 bool RenderTexture::_VerifyExtensions()
2275 dbg_printf("RenderTexture::_VerifyExtensions() called...\n");
2277 // a second call to _VerifyExtensions will allways return true, causing a crash
2278 // if the extension is not supported
2279 if ( true || !fctPtrInited )
2281 fctPtrInited = true;
2282 wglGetExtensionsStringARBProc wglGetExtensionsStringARBPtr = (wglGetExtensionsStringARBProc)wglGetProcAddress( "wglGetExtensionsStringARB" );
2283 if ( wglGetExtensionsStringARBPtr == 0 )
2285 PrintExtensionError("WGL_ARB_extensions_string");
2288 string wglExtensionsString = wglGetExtensionsStringARBPtr( wglGetCurrentDC() );
2289 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pixel_format" ) )
2291 wglChoosePixelFormatARBPtr = (wglChoosePixelFormatARBProc)SGLookupFunction("wglChoosePixelFormatARB");
2292 wglGetPixelFormatAttribivARBPtr = (wglGetPixelFormatAttribivARBProc)SGLookupFunction("wglGetPixelFormatAttribivARB");
2296 PrintExtensionError("WGL_ARB_pixel_format");
2299 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pbuffer" ) )
2301 wglCreatePbufferARBPtr = (wglCreatePbufferARBProc)SGLookupFunction("wglCreatePbufferARB");
2302 wglGetPbufferDCARBPtr = (wglGetPbufferDCARBProc)SGLookupFunction("wglGetPbufferDCARB");
2303 wglQueryPbufferARBPtr = (wglQueryPbufferARBProc)SGLookupFunction("wglQueryPbufferARB");
2304 wglReleasePbufferDCARBPtr = (wglReleasePbufferDCARBProc)SGLookupFunction("wglReleasePbufferDCARB");
2305 wglDestroyPbufferARBPtr = (wglDestroyPbufferARBProc)SGLookupFunction("wglDestroyPbufferARB");
2309 PrintExtensionError("WGL_ARB_pbuffer");
2312 if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_render_texture" ) )
2314 wglBindTexImageARBPtr = (wglBindTexImageARBProc)SGLookupFunction("wglBindTexImageARB");
2315 wglReleaseTexImageARBPtr = (wglReleaseTexImageARBProc)SGLookupFunction("wglReleaseTexImageARB");
2317 else if ( _bIsTexture )
2319 PrintExtensionError("WGL_ARB_render_texture");
2322 if (_bRectangle && !SGIsOpenGLExtensionSupported( "GL_NV_texture_rectangle" ))
2324 PrintExtensionError("GL_NV_texture_rectangle");
2327 if (_bFloat && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) ||
2328 SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ATI_pixel_format_float" )))
2330 PrintExtensionError("GL_NV_float_buffer or GL_ATI_pixel_format_float");
2334 if (_bFloat && _bIsTexture && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) || SGIsOpenGLExtensionSupported( "GL_ATI_texture_float" )))
2336 PrintExtensionError("NV_float_buffer or ATI_texture_float");
2338 if (_bIsDepthTexture && !SGIsOpenGLExtensionSupported( "GL_ARB_depth_texture" ))
2341 #if defined(_DEBUG) | defined(DEBUG)
2342 SG_LOG(SG_GL, SG_ALERT,
2343 "RenderTexture Warning: "
2344 "OpenGL extension GL_ARB_depth_texture not available."
2345 " Using glReadPixels() to emulate behavior.");
2347 _bHasARBDepthTexture = false;
2348 //PrintExtensionError("GL_ARB_depth_texture");
2354 #elif defined( __MACH__ )
2355 // FIXME! Check extensions!
2357 Display* dpy = glXGetCurrentDisplay();
2358 int minor = 0, major = 0;
2360 dbg_printf("_VerifyExtensions: glXGetCurrentDisplay() returned NULL! returning false\n");
2363 if (!glXQueryVersion(dpy, &major, &minor))
2365 dbg_printf("_VerifyExtensions: glXQueryVersion(dpy, &major, &minor) FAILED! returning false\n");
2370 dbg_printf("_VerifyExtensions: glXQueryVersion(dpy, major=%d, minor=%d)\n", major, minor);
2373 int screen = DefaultScreen(dpy);
2374 const char* extString = glXQueryExtensionsString(dpy, screen);
2375 dbg_printf("_VerifyExtensions: glXQueryExtensionsString(dpy, screen) returned -\n[%s]\n",
2376 (extString ? extString : "<NULL>") );
2377 if (!SGSearchExtensionsString(extString, "GLX_SGIX_fbconfig") ||
2378 !SGSearchExtensionsString(extString, "GLX_SGIX_pbuffer"))
2380 dbg_printf("_VerifyExtensions: glXQueryExtensionsString(dpy,screen) does NOT contain GLX_SGIX_fbconfig or GLX_SGIX_pbuffer!\n" );
2381 const char * extClient = glXGetClientString( dpy, GLX_EXTENSIONS );
2383 !SGSearchExtensionsString(extClient, "GLX_SGIX_fbconfig") ||
2384 !SGSearchExtensionsString(extClient, "GLX_SGIX_pbuffer"))
2386 dbg_printf("_VerifyExtensions: AND glXGetClientString(dpy,GLX_EXTENSIONS) also! returning false\n" );
2391 dbg_printf("_VerifyExtensions: BUT glXGetClientString(dpy,GLX_EXTENSIONS) returned \n[%s]\n", extClient );
2392 dbg_printf("Since this DOES contain fbconfig and pbuffer, continuing...\n");
2395 // First try the glX version 1.3 functions.
2396 glXChooseFBConfigPtr = (glXChooseFBConfigProc)SGLookupFunction("glXChooseFBConfig");
2397 glXCreatePbufferPtr = (glXCreatePbufferProc)SGLookupFunction("glXCreatePbuffer");
2398 glXGetVisualFromFBConfigPtr = (glXGetVisualFromFBConfigProc)SGLookupFunction("glXGetVisualFromFBConfig");
2399 glXCreateContextPtr = (glXCreateContextProc)SGLookupFunction("glXCreateContext");
2400 glXDestroyPbufferPtr = (glXDestroyPbufferProc)SGLookupFunction("glXDestroyPbuffer");
2401 glXQueryDrawablePtr = (glXQueryDrawableProc)SGLookupFunction("glXQueryDrawable");
2403 if (((1 <= major && 3 <= minor) || 2 <= major) &&
2404 glXChooseFBConfigPtr &&
2405 glXCreatePbufferPtr &&
2406 glXGetVisualFromFBConfigPtr &&
2407 glXCreateContextPtr &&
2408 glXDestroyPbufferPtr &&
2409 glXQueryDrawablePtr) {
2410 dbg_printf("_VerifyExtensions: setting glXVersion1_3Present TRUE\n" );
2411 glXVersion1_3Present = true;
2415 dbg_printf("_VerifyExtensions: setting glXVersion1_3Present FALSE\n Reason: " );
2416 if ( !((1 <= major && 3 <= minor) || 2 <= major) ) { dbg_printf( "Version wrong %d.%d ", major, minor ); }
2417 if ( !glXChooseFBConfigPtr ) { dbg_printf( "missing glXChooseFBConfigPtr " ); }
2418 if ( !glXCreatePbufferPtr ) { dbg_printf( "missing glXCreatePbufferPtr " ); }
2419 if ( !glXGetVisualFromFBConfigPtr ) { dbg_printf( "missing glXGetVisualFromFBConfigPtr " ); }
2420 if ( !glXCreateContextPtr ) { dbg_printf( "missing glXCreateContextPtr " ); }
2421 if ( !glXDestroyPbufferPtr ) { dbg_printf( "missing glXDestroyPbufferPtr " ); }
2422 if ( !glXQueryDrawablePtr ) { dbg_printf( "missing glXQueryDrawablePtr " ); }
2425 glXChooseFBConfigPtr = (glXChooseFBConfigProc)SGLookupFunction("glXChooseFBConfigSGIX");
2426 glXCreateGLXPbufferPtr = (glXCreateGLXPbufferProc)SGLookupFunction("glXCreateGLXPbufferSGIX");
2427 glXGetVisualFromFBConfigPtr = (glXGetVisualFromFBConfigProc)SGLookupFunction("glXGetVisualFromFBConfigSGIX");
2428 glXCreateContextWithConfigPtr = (glXCreateContextWithConfigProc)SGLookupFunction("glXCreateContextWithConfigSGIX");
2429 glXDestroyPbufferPtr = (glXDestroyPbufferProc)SGLookupFunction("glXDestroyGLXPbufferSGIX");
2430 glXQueryGLXPbufferSGIXPtr = (glXQueryGLXPbufferSGIXProc)SGLookupFunction("glXQueryGLXPbufferSGIX");
2432 if (!glXChooseFBConfigPtr ||
2433 !glXCreateGLXPbufferPtr ||
2434 !glXGetVisualFromFBConfigPtr ||
2435 !glXCreateContextWithConfigPtr ||
2436 !glXDestroyPbufferPtr ||
2437 !glXQueryGLXPbufferSGIXPtr)
2439 dbg_printf("_VerifyExtensions: some pointer is NULL! return false\n" );
2440 if ( !glXCreateGLXPbufferPtr ) {
2441 dbg_printf("RenderTexture::Initialize: ERROR glXCreateGLXPbufferPtr = NULL!\n");
2442 } else if ( !glXCreateContextWithConfigPtr ) {
2443 dbg_printf("RenderTexture::Initialize: ERROR glXCreateContextWithConfigPtr = NULL!\n");
2444 } else if ( !glXVersion1_3Present && !glXQueryGLXPbufferSGIXPtr ) {
2445 dbg_printf("RenderTexture::Initialize: ERROR glXQueryGLXPbufferSGIXPtr = NULL!\n");
2449 dbg_printf("_VerifyExtensions: appear to have all 'procs' glXCreateGLXPbufferPtr=[%p]\n", glXCreateGLXPbufferPtr );
2453 if (_bIsDepthTexture && !GL_ARB_depth_texture)
2455 PrintExtensionError("GL_ARB_depth_texture");
2458 if (_bFloat && _bIsTexture && !GLX_NV_float_buffer)
2460 PrintExtensionError("GLX_NV_float_buffer");
2463 if (_eUpdateMode == RT_RENDER_TO_TEXTURE)
2465 PrintExtensionError("Some GLX render texture extension: Please implement me!");
2470 dbg_printf("RenderTexture::_VerifyExtensions: return true.\n");
2474 //---------------------------------------------------------------------------
2475 // Function : RenderTexture::_InitializeTextures
2477 //---------------------------------------------------------------------------
2479 * @fn RenderTexture::_InitializeTextures()
2480 * @brief Initializes the state of textures used by the RenderTexture.
2482 bool RenderTexture::_InitializeTextures()
2484 dbg_printf( "RenderTexture::_InitializeTextures() called\n" );
2485 // Determine the appropriate texture formats and filtering modes.
2487 if (_bIsTexture || _bIsDepthTexture)
2489 if (_bRectangle && GL_NV_texture_rectangle)
2490 _iTextureTarget = GL_TEXTURE_RECTANGLE_NV;
2491 else if (_bRectangle && GL_EXT_texture_rectangle)
2492 _iTextureTarget = GL_TEXTURE_RECTANGLE_EXT;
2494 _iTextureTarget = GL_TEXTURE_2D;
2499 glGenTextures(1, (GLuint*)&_iTextureID);
2500 glBindTexture(_iTextureTarget, _iTextureID);
2502 // Use clamp to edge as the default texture wrap mode for all tex
2503 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2504 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2505 // Use NEAREST as the default texture filtering mode.
2506 glTexParameteri(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2507 glTexParameteri(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2510 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2512 GLuint iInternalFormat;
2519 SG_LOG(SG_GL, SG_ALERT,
2520 "RenderTexture Error: mipmapped float textures not "
2522 dbg_printf( "RenderTexture Error: mipmapped float textures not supported. return false\n");
2526 switch(_iNumComponents)
2529 if (GL_NV_float_buffer)
2531 iInternalFormat = (_iNumColorBits[0] > 16) ?
2532 GL_FLOAT_R32_NV : GL_FLOAT_R16_NV;
2534 else if (GL_ATI_texture_float)
2536 iInternalFormat = (_iNumColorBits[0] > 16) ?
2537 GL_LUMINANCE_FLOAT32_ATI :
2538 GL_LUMINANCE_FLOAT16_ATI;
2540 iFormat = GL_LUMINANCE;
2543 if (GL_NV_float_buffer)
2545 iInternalFormat = (_iNumColorBits[0] > 16) ?
2546 GL_FLOAT_RG32_NV : GL_FLOAT_RG16_NV;
2548 else if (GL_ATI_texture_float)
2550 iInternalFormat = (_iNumColorBits[0] > 16) ?
2551 GL_LUMINANCE_ALPHA_FLOAT32_ATI :
2552 GL_LUMINANCE_ALPHA_FLOAT16_ATI;
2554 iFormat = GL_LUMINANCE_ALPHA;
2557 if (GL_NV_float_buffer)
2559 iInternalFormat = (_iNumColorBits[0] > 16) ?
2560 GL_FLOAT_RGB32_NV : GL_FLOAT_RGB16_NV;
2562 else if (GL_ATI_texture_float)
2564 iInternalFormat = (_iNumColorBits[0] > 16) ?
2565 GL_RGB_FLOAT32_ATI : GL_RGB_FLOAT16_ATI;
2570 if (GL_NV_float_buffer)
2572 iInternalFormat = (_iNumColorBits[0] > 16) ?
2573 GL_FLOAT_RGBA32_NV : GL_FLOAT_RGBA16_NV;
2575 else if (GL_ATI_texture_float)
2577 iInternalFormat = (_iNumColorBits[0] > 16) ?
2578 GL_RGBA_FLOAT32_ATI : GL_RGBA_FLOAT16_ATI;
2583 SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: "
2584 "Invalid number of components: " <<
2586 dbg_printf( "RenderTexture Error: Invalid number of components: %d - return false\n",
2593 if (4 == _iNumComponents)
2595 iInternalFormat = GL_RGBA8;
2600 iInternalFormat = GL_RGB8;
2605 // Allocate the texture image (but pass it no data for now).
2606 glTexImage2D(_iTextureTarget, 0, iInternalFormat,
2607 _iWidth, _iHeight, 0, iFormat, GL_FLOAT, NULL);
2611 if (_bIsDepthTexture)
2613 glGenTextures(1, (GLuint*)&_iDepthTextureID);
2614 glBindTexture(_iTextureTarget, _iDepthTextureID);
2616 // Use clamp to edge as the default texture wrap mode for all tex
2617 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2618 glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2619 // Use NEAREST as the default texture filtering mode.
2620 glTexParameteri(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2621 glTexParameteri(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2623 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2626 if (_bHasARBDepthTexture)
2628 // Allocate the texture image (but pass it no data for now).
2629 glTexImage2D(_iTextureTarget, 0, GL_DEPTH_COMPONENT,
2630 _iWidth, _iHeight, 0, GL_DEPTH_COMPONENT,
2635 // allocate memory for depth texture
2636 // Since this is slow, we warn the user in debug mode. (above)
2637 _pPoorDepthTexture = new unsigned short[_iWidth * _iHeight];
2638 glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16,
2639 _iWidth, _iHeight, 0, GL_LUMINANCE,
2640 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
2646 dbg_printf( "RenderTexture::_InitializeTextures() returning true\n" );
2651 //---------------------------------------------------------------------------
2652 // Function : RenderTexture::_MaybeCopyBuffer
2654 //---------------------------------------------------------------------------
2656 * @fn RenderTexture::_MaybeCopyBuffer()
2657 * @brief Does the actual copying for RenderTextures with RT_COPY_TO_TEXTURE
2659 void RenderTexture::_MaybeCopyBuffer()
2662 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2666 glBindTexture(_iTextureTarget, _iTextureID);
2667 glCopyTexSubImage2D(_iTextureTarget,
2668 0, 0, 0, 0, 0, _iWidth, _iHeight);
2670 if (_bIsDepthTexture)
2672 glBindTexture(_iTextureTarget, _iDepthTextureID);
2673 // HOW TO COPY DEPTH TEXTURE??? Supposedly this just magically works...
2675 if (_bHasARBDepthTexture)
2677 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0,
2682 // no 'real' depth texture available, so behavior has to be emulated
2683 // using glReadPixels (beware, this is (naturally) slow ...)
2684 glReadPixels(0, 0, _iWidth, _iHeight, GL_DEPTH_COMPONENT,
2685 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
2686 glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16,
2687 _iWidth, _iHeight, 0, GL_LUMINANCE,
2688 GL_UNSIGNED_SHORT, _pPoorDepthTexture);
2694 #elif defined(__MACH__)
2695 if (RT_COPY_TO_TEXTURE == _eUpdateMode)
2699 glBindTexture(_iTextureTarget, _iTextureID);
2700 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2702 if (_bIsDepthTexture)
2704 glBindTexture(_iTextureTarget, _iDepthTextureID);
2705 assert(_bHasARBDepthTexture);
2706 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2712 glBindTexture(_iTextureTarget, _iTextureID);
2713 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2715 if (_bIsDepthTexture)
2717 glBindTexture(_iTextureTarget, _iDepthTextureID);
2718 assert(_bHasARBDepthTexture);
2719 glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2725 //---------------------------------------------------------------------------
2726 // Function : RenderTexture::_ReleaseBoundBuffers
2728 //---------------------------------------------------------------------------
2730 * @fn RenderTexture::_ReleaseBoundBuffers()
2731 * @brief Releases buffer bindings on RenderTextures with RT_RENDER_TO_TEXTURE
2733 bool RenderTexture::_ReleaseBoundBuffers()
2736 if (_bIsTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
2738 glBindTexture(_iTextureTarget, _iTextureID);
2740 // release the pbuffer from the render texture object
2741 if (0 != _iCurrentBoundBuffer && _bIsBufferBound)
2743 if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, _iCurrentBoundBuffer))
2748 _bIsBufferBound = false;
2752 if (_bIsDepthTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
2754 glBindTexture(_iTextureTarget, _iDepthTextureID);
2756 // release the pbuffer from the render texture object
2757 if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
2765 // textures can't be bound in Linux
2770 //---------------------------------------------------------------------------
2771 // Function : RenderTexture::_MakeCurrent
2773 //---------------------------------------------------------------------------
2775 * @fn RenderTexture::_MakeCurrent()
2776 * @brief Makes the RenderTexture's context current
2778 bool RenderTexture::_MakeCurrent()
2781 // make the pbuffer's rendering context current.
2782 if (FALSE == wglMakeCurrent( _hDC, _hGLContext))
2787 #elif defined( __MACH__ )
2790 if (err = CGLSetCurrentContext(_hGLContext))
2792 _cglCheckError(err);
2796 static GLXContext last_hGLContext = 0;
2797 if (false == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
2799 dbg_printf( "_MakeCurrent: glXMakeCurrent FAILED! returning false\n");
2803 if ( last_hGLContext != _hGLContext ) {
2804 last_hGLContext = _hGLContext;
2805 dbg_printf( "_MakeCurrent: glXMakeCurrent set to [%p] SUCCESS! returning true\n", _hGLContext );
2811 /////////////////////////////////////////////////////////////////////////////
2813 // Begin Deprecated Interface
2815 /////////////////////////////////////////////////////////////////////////////
2817 //---------------------------------------------------------------------------
2818 // Function : RenderTexture::RenderTexture
2820 //---------------------------------------------------------------------------
2822 * @fn RenderTexture::RenderTexture()
2823 * @brief Constructor.
2825 RenderTexture::RenderTexture(int width, int height,
2826 bool bIsTexture /* = true */,
2827 bool bIsDepthTexture /* = false */)
2830 _bIsTexture(bIsTexture),
2831 _bIsDepthTexture(bIsDepthTexture),
2832 _bHasARBDepthTexture(true), // [Redge]
2833 _eUpdateMode(RT_RENDER_TO_TEXTURE),
2834 _bInitialized(false),
2836 _iCurrentBoundBuffer(0),
2838 _iNumStencilBits(0),
2840 _bDoubleBuffered(false),
2844 _bShareObjects(false),
2845 _bCopyContext(false),
2851 _hPreviousContext(0),
2852 #elif defined( __MACH__ )
2855 _hPreviousContext(NULL),
2860 _hPreviousDrawable(0),
2861 _hPreviousContext(0),
2863 _iTextureTarget(GL_NONE),
2865 _iDepthTextureID(0),
2866 _pPoorDepthTexture(0) // [Redge]
2868 assert(width > 0 && height > 0);
2869 #if defined DEBUG || defined _DEBUG
2870 SG_LOG(SG_GL, SG_ALERT,
2871 "RenderTexture Warning: Deprecated Contructor interface used.");
2873 dbg_printf("RenderTexture Warning: Deprecated Contructor interface used.\n");
2875 _iNumColorBits[0] = _iNumColorBits[1] =
2876 _iNumColorBits[2] = _iNumColorBits[3] = 0;
2877 _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
2880 //------------------------------------------------------------------------------
2881 // Function : RenderTexture::Initialize
2883 //------------------------------------------------------------------------------
2885 * @fn RenderTexture::Initialize(bool bShare, bool bDepth, bool bStencil, bool bMipmap, unsigned int iRBits, unsigned int iGBits, unsigned int iBBits, unsigned int iABits);
2886 * @brief Initializes the RenderTexture, sharing display lists and textures if specified.
2888 * This function actually does the creation of the p-buffer. It can only be called
2889 * once a GL context has already been created. Note that if the texture is not
2890 * power of two dimensioned, or has more than 8 bits per channel, enabling mipmapping
2891 * will cause an error.
2893 bool RenderTexture::Initialize(bool bShare /* = true */,
2894 bool bDepth /* = false */,
2895 bool bStencil /* = false */,
2896 bool bMipmap /* = false */,
2897 bool bAnisoFilter /* = false */,
2898 unsigned int iRBits /* = 8 */,
2899 unsigned int iGBits /* = 8 */,
2900 unsigned int iBBits /* = 8 */,
2901 unsigned int iABits /* = 8 */,
2902 UpdateMode updateMode /* = RT_RENDER_TO_TEXTURE */)
2904 if (0 == _iWidth || 0 == _iHeight)
2907 #if defined DEBUG || defined _DEBUG
2908 SG_LOG(SG_GL, SG_ALERT,
2909 "RenderTexture Warning: Deprecated Initialize() interface used.");
2911 dbg_printf("RenderTexture Warning: Deprecated Initialize() interface used.\n");
2913 // create a mode string.
2916 mode.append("depth ");
2918 mode.append("stencil ");
2920 mode.append("mipmap ");
2921 if (iRBits + iGBits + iBBits + iABits > 0)
2932 char bitVector[100];
2933 snprintf( bitVector, 100,
2934 "%d%s,%d%s,%d%s,%d%s",
2935 iRBits, (iRBits >= 16) ? "f" : "",
2936 iGBits, (iGBits >= 16) ? "f" : "",
2937 iBBits, (iBBits >= 16) ? "f" : "",
2938 iABits, (iABits >= 16) ? "f" : "");
2939 mode.append(bitVector);
2944 if ((GL_NV_texture_rectangle || GL_EXT_texture_rectangle) &&
2945 ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
2946 || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
2947 mode.append("texRECT ");
2949 mode.append("tex2D ");
2951 if (_bIsDepthTexture)
2953 if ((GL_NV_texture_rectangle || GL_EXT_texture_rectangle) &&
2954 ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
2955 || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
2956 mode.append("texRECT ");
2958 mode.append("tex2D ");
2960 if (RT_COPY_TO_TEXTURE == updateMode)
2963 _pixelFormatAttribs.clear();
2964 _pbufferAttribs.clear();
2967 _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
2968 _pixelFormatAttribs.push_back(true);
2969 _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
2970 _pixelFormatAttribs.push_back(true);
2972 _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
2973 _pbufferAttribs.push_back(true);
2974 #elif defined( __MACH__ )
2975 //_pixelFormatAttribs.push_back(kCGLPFANoRecovery);
2976 _pixelFormatAttribs.push_back(kCGLPFAAccelerated);
2977 _pixelFormatAttribs.push_back(kCGLPFAWindow);
2978 _pixelFormatAttribs.push_back(kCGLPFAPBuffer);
2980 _pixelFormatAttribs.push_back(GLX_RENDER_TYPE_SGIX);
2981 _pixelFormatAttribs.push_back(GLX_RGBA_BIT_SGIX);
2982 _pixelFormatAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
2983 _pixelFormatAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
2986 _ParseModeString(mode.c_str(), _pixelFormatAttribs, _pbufferAttribs);
2989 _pixelFormatAttribs.push_back(0);
2990 _pbufferAttribs.push_back(0);
2991 #elif defined(__MACH__)
2992 _pixelFormatAttribs.push_back(0);
2994 _pixelFormatAttribs.push_back(None);
2997 Initialize(_iWidth, _iHeight, bShare);
3003 //---------------------------------------------------------------------------
3004 // Function : RenderTexture::Reset
3006 //---------------------------------------------------------------------------
3008 * @fn RenderTexture::Reset(int iWidth, int iHeight, unsigned int iMode, bool bIsTexture, bool bIsDepthTexture)
3009 * @brief Resets the resolution of the offscreen buffer.
3011 * Causes the buffer to delete itself. User must call Initialize() again
3014 bool RenderTexture::Reset(int iWidth, int iHeight)
3016 SG_LOG(SG_GL, SG_ALERT,
3017 "RenderTexture Warning: Deprecated Reset() interface used.");
3019 dbg_printf("RenderTexture Warning: Deprecated Reset(x,y) interface used.\n");
3023 SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Reset(): failed to invalidate.");
3024 dbg_printf( "RenderTexture::Reset(x,y): failed to invalidate. returning false\n");
3030 dbg_printf( "RenderTexture::Reset(x,y): succeeded. returning true\n");
3034 #if defined( _DEBUG ) && !defined( _WIN32 ) && !defined( __MACH__ )
3035 /* just some DEBUG ONLY code, to show the 'attributes' */
3037 typedef struct tagPXATTS {
3044 static PXATTS pxAtts[] = {
3045 { GLX_FBCONFIG_ID, "GLX_FBCONFIG_ID",
3046 "followed by a valid XID that indicates the desired GLX frame buffer configuration. "
3047 "When a GLX_FBCONFIG_ID is specified, all attributes are ignored. The default value is GLX_DONT_CARE.",
3049 { GLX_BUFFER_SIZE, "GLX_BUFFER_SIZE",
3050 "Must be followed by a nonnegative integer that indicates the desired color index buffer size."
3051 "The smallest index buffer of at least the specified size is preferred. This attribute is ignored if GLX_COLOR_INDEX_BIT is not set "
3052 "in GLX_RENDER_TYPE. The default value is 0.",
3054 { GLX_LEVEL, "GLX_LEVEL",
3055 "Must be followed by an integer buffer-level specification. This specification is honored exactly."
3056 "Buffer level 0 corresponds to the default frame buffer of the display. "
3057 "Buffer level 1 is the first overlay frame buffer, level two the second overlay frame buffer, and so on."
3058 "Negative buffer levels correspond to underlay frame buffers. The default value is 0.",
3060 { GLX_DOUBLEBUFFER, "GLX_DOUBLEBUFFER",
3061 "Must be followed by True or False. If True is specified, then only double-buffered frame buffer configurations are considered;"
3062 "if False is specified, then only single-buffered frame buffer configurations are considered. The default value is GLX_DONT_CARE.",
3064 { GLX_STEREO, "GLX_STEREO",
3065 "Must be followed by True or False. If True is specified, then only stereo frame buffer configurations are considered;"
3066 " if False is specified, then only monoscopic frame buffer configurations are considered. The default value is False.",
3068 { GLX_AUX_BUFFERS, "GLX_AUX_BUFFERS",
3069 "Must be followed by a nonnegative integer that indicates the desired number of auxiliary buffers."
3070 " Configurations with the smallest number of auxiliary buffers that meet or exceed the specified number are preferred."
3071 " The default value is 0.",
3073 { GLX_RED_SIZE, "GLX_RED_SIZE",
3074 "must be followed by a nonnegative minimum size",
3076 { GLX_GREEN_SIZE, "GLX_GREEN_SIZE",
3077 "must be followed by a nonnegative minimum size",
3079 { GLX_BLUE_SIZE, "GLX_BLUE_SIZE",
3080 "must be followed by a nonnegative minimum size",
3082 { GLX_ALPHA_SIZE, "GLX_ALPHA_SIZE",
3083 "Each attribute, if present, must be followed by a nonnegative minimum size specification or GLX_DONT_CARE."
3084 " The largest available total RGBA color buffer size (sum of GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE) "
3085 " of at least the minimum size specified for each color component is preferred. If the requested number of bits for a color "
3086 " component is 0 or GLX_DONT_CARE, it is not considered. The default value for each color component is 0.",
3088 { GLX_DEPTH_SIZE, "GLX_DEPTH_SIZE",
3089 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3090 "frame buffer configurations with no depth buffer are preferred."
3091 "Otherwise, the largest available depth buffer of at least the minimum size is preferred. The default value is 0.",
3093 { GLX_STENCIL_SIZE, "GLX_STENCIL_SIZE",
3094 "Must be followed by a nonnegative integer that indicates the desired number of stencil bitplanes."
3095 "The smallest stencil buffer of at least the specified size is preferred. If the desired value is zero,"
3096 " frame buffer configurations with no stencil buffer are preferred. The default value is 0.",
3098 { GLX_ACCUM_RED_SIZE, "GLX_ACCUM_RED_SIZE",
3099 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3100 " frame buffer configurations with no red accumulation buffer are preferred."
3101 " Otherwise, the largest possible red accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3103 { GLX_ACCUM_GREEN_SIZE, "GLX_ACCUM_GREEN_SIZE",
3104 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3105 "frame buffer configurations with no green accumulation buffer are preferred. "
3106 "Otherwise, the largest possible green accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3108 { GLX_ACCUM_BLUE_SIZE, "GLX_ACCUM_BLUE_SIZE",
3109 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3110 "frame buffer configurations with no blue accumulation buffer are preferred. "
3111 "Otherwise, the largest possible blue accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3113 { GLX_ACCUM_ALPHA_SIZE, "GLX_ACCUM_ALPHA_SIZE",
3114 "Must be followed by a nonnegative minimum size specification. If this value is zero, "
3115 "frame buffer configurations with no alpha accumulation buffer are preferred. "
3116 "Otherwise, the largest possible alpha accumulation buffer of at least the minimum size is preferred. The default value is 0.",
3118 { GLX_RENDER_TYPE, "GLX_RENDER_TYPE",
3119 "Must be followed by a mask indicating which OpenGL rendering modes the frame buffer configuration must support. "
3120 "Valid bits are GLX_RGBA_BIT and GLX_COLOR_INDEX_BIT. If the mask is set to GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT, "
3121 "then only frame buffer configurations that can be bound to both RGBA contexts and color index contexts will be considered. "
3122 "The default value is GLX_RGBA_BIT.",
3124 { GLX_DRAWABLE_TYPE, "GLX_DRAWABLE_TYPE",
3125 "Must be followed by a mask indicating which GLX drawable types the frame buffer configuration must support. "
3126 "Valid bits are GLX_WINDOW_BIT, GLX_PIXMAP_BIT, and GLX_PBUFFER_BIT. For example, if mask is set to "
3127 "GLX_WINDOW_BIT | GLX_PIXMAP_BIT, only frame buffer configurations that support both windows and GLX pixmaps "
3128 "will be considered. The default value is GLX_WINDOW_BIT.",
3130 { GLX_X_RENDERABLE, "GLX_X_RENDERABLE",
3131 "Must be followed by True or False. If True is specified, then only frame buffer configurations that "
3132 "have associated X visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. "
3133 "The default value is GLX_DONT_CARE. ",
3135 { GLX_X_VISUAL_TYPE, "GLX_X_VISUAL_TYPE",
3136 "Must be followed by one of GLX_TRUE_COLOR, GLX_DIRECT_COLOR, GLX_PSEUDO_COLOR, GLX_STATIC_COLOR, "
3137 "GLX_GRAY_SCALE, or GLX_STATIC_GRAY, indicating the desired X visual type. "
3138 "Not all frame buffer configurations have an associated X visual. If GLX_DRAWABLE_TYPE is specified in attrib_list and the "
3139 "mask that follows does not have GLX_WINDOW_BIT set, then this value is ignored. It is also ignored if "
3140 "GLX_X_RENDERABLE is specified as False. RGBA rendering may be supported for visuals of type "
3141 "GLX_TRUE_COLOR, GLX_DIRECT_COLOR, GLX_PSEUDO_COLOR, or GLX_STATIC_COLOR, "
3142 "but color index rendering is only supported for visuals of type GLX_PSEUDO_COLOR or GLX_STATIC_COLOR "
3143 "(i.e., single-channel visuals). The tokens GLX_GRAY_SCALE and GLX_STATIC_GRAY will "
3144 "not match current OpenGL enabled visuals, but are included for future use."
3145 "The default value for GLX_X_VISUAL_TYPE is GLX_DONT_CARE.",
3147 { GLX_CONFIG_CAVEAT, "GLX_CONFIG_CAVEAT",
3148 "Must be followed by one of GLX_NONE, GLX_SLOW_CONFIG, GLX_NON_CONFORMANT_CONFIG. "
3149 "If GLX_NONE is specified, then only frame buffer configurations with "
3150 "no caveats will be considered; if GLX_SLOW_CONFIG is specified, then only slow frame buffer configurations will be considered; if "
3151 "GLX_NON_CONFORMANT_CONFIG is specified, then only nonconformant frame buffer configurations will be considered."
3152 "The default value is GLX_DONT_CARE.",
3154 { GLX_TRANSPARENT_TYPE, "GLX_TRANSPARENT_TYPE",
3155 "Must be followed by one of GLX_NONE, GLX_TRANSPARENT_RGB, GLX_TRANSPARENT_INDEX. "
3156 "If GLX_NONE is specified, then only opaque frame buffer configurations will be considered; "
3157 "if GLX_TRANSPARENT_RGB is specified, then only transparent frame buffer configurations that support RGBA rendering will be considered; "
3158 "if GLX_TRANSPARENT_INDEX is specified, then only transparent frame buffer configurations that support color index rendering will be considered."
3159 "The default value is GLX_NONE.",
3161 { GLX_TRANSPARENT_INDEX_VALUE, "GLX_TRANSPARENT_INDEX_VALUE",
3162 "Must be followed by an integer value indicating the transparent index value; the value must be between 0 and the maximum "
3163 "frame buffer value for indices. Only frame buffer configurations that use the "
3164 "specified transparent index value will be considered. The default value is GLX_DONT_CARE. "
3165 "This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in attrib_list and specified as GLX_TRANSPARENT_INDEX.",
3167 { GLX_TRANSPARENT_RED_VALUE, "GLX_TRANSPARENT_RED_VALUE",
3168 "Must be followed by an integer value indicating the transparent red value; the value must be between 0 and the maximum "
3169 "frame buffer value for red. Only frame buffer configurations that use the specified transparent red value will be considered. "
3170 "The default value is GLX_DONT_CARE. This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in "
3171 "attrib_list and specified as GLX_TRANSPARENT_RGB.",
3173 { GLX_TRANSPARENT_GREEN_VALUE, "GLX_TRANSPARENT_GREEN_VALUE",
3174 "Must be followed by an integer value indicating the transparent green value; the value must be between 0 and the maximum "
3175 "frame buffer value for green. Only frame buffer configurations that use the specified transparent green value will be considered."
3176 "The default value is GLX_DONT_CARE. This attribute is "
3177 "ignored unless GLX_TRANSPARENT_TYPE is included in attrib_list and specified as GLX_TRANSPARENT_RGB.",
3179 { GLX_TRANSPARENT_BLUE_VALUE, "GLX_TRANSPARENT_BLUE_VALUE",
3180 "Must be followed by an integer value indicating the transparent blue value; the value must be between 0 and the maximum "
3181 "frame buffer value for blue. Only frame buffer configurations that use the specified transparent blue value will be considered."
3182 "The default value is GLX_DONT_CARE. This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in "
3183 "attrib_list and specified as GLX_TRANSPARENT_RGB. ",
3185 { GLX_TRANSPARENT_ALPHA_VALUE, "GLX_TRANSPARENT_ALPHA_VALUE",
3186 "Must be followed by an integer value indicating the transparent alpha value; the value must be between 0 and the maximum "
3187 "frame buffer value for alpha. Only frame buffer configurations that use the "
3188 "specified transparent alpha value will be considered. The default value is GLX_DONT_CARE.",
3190 { 0, NULL, NULL, -1 }
3193 const char * get_attr_name( int val, int * pdef )
3195 PPXATTS pat = &pxAtts[0];
3198 if ( pat->attr == val ) {
3205 return "VALUE NOT IN LIST";
3209 // eof - RenderTexture.cpp