X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscreen%2FRenderTexture.cpp;h=ad594117edfefbe1049ab4a41aea54e0da8b9933;hb=4c2dd553f2e5065b0fad55aa28915bf7c4a204e3;hp=f27813f9ad84452e700b7abd59d82a3a5a76bbde;hpb=66075d620eb0d33fe365f10a7da045cb850de016;p=simgear.git diff --git a/simgear/screen/RenderTexture.cpp b/simgear/screen/RenderTexture.cpp index f27813f9..ad594117 100644 --- a/simgear/screen/RenderTexture.cpp +++ b/simgear/screen/RenderTexture.cpp @@ -1,4 +1,3 @@ -//--------------------------------------------------------------------------- // File : RenderTexture.cpp //--------------------------------------------------------------------------- // Copyright (c) 2002-2004 Mark J. Harris @@ -27,8 +26,11 @@ // Original RenderTexture class: Mark J. Harris // Original Render to Depth Texture support: Thorsten Scheuermann // Linux Copy-to-texture: Eric Werness +// OS X: Alexander Powell (someone please help) // Various Bug Fixes: Daniel (Redge) Sperl // Bill Baxter +// Ubuntu 8.04 64bit: Geoff McLane - 2009-07-01 +// to work even when version 1.2 is returned. // // -------------------------------------------------------------------------- /** @@ -37,23 +39,19 @@ * Implementation of class RenderTexture. A multi-format render to * texture wrapper. */ -#pragma warning(disable:4786) /* * Changelog: * * Jan. 2005, Removed GLEW dependencies, Erik Hofman, Fred Bouvier * Nov. 2005, Use the simgear logging facility, Erik Hofman + * Mar. 2006, Add MAC OS X support, Alexander Powell */ #ifdef HAVE_CONFIG_H # include #endif -#ifdef HAVE_WINDOWS_H -# include -#endif - #include #include #include @@ -64,12 +62,36 @@ #include #include +#include + #ifdef _WIN32 #pragma comment(lib, "gdi32.lib") // required for GetPixelFormat() #endif using namespace std; +// DEBUG - add a lot of noise +//#ifndef _DEBUG +//#define _DEBUG +//#endif + +#if defined (_DEBUG) +const char * get_attr_name( int val, int * pdef ); +#define dbg_printf printf +#else +#if defined (__GNUC__) +#define dbg_printf(format,args...) ((void)0) +#else // defined (__GNUC__) +#define dbg_printf +#endif // defined (__GNUC__) +#endif // defined (_DEBUG) + +// CHOP/NOT CHOP SOME CODE TO GET SOMETHING WORKING! +#define ADD_QUERY_BUFFER +#define ADD_GET_DRAWABLE +// ======================================= + + #ifdef _WIN32 static bool fctPtrInited = false; /* WGL_ARB_pixel_format */ @@ -85,7 +107,7 @@ static wglDestroyPbufferARBProc wglDestroyPbufferARBPtr = 0; static wglBindTexImageARBProc wglBindTexImageARBPtr = 0; static wglReleaseTexImageARBProc wglReleaseTexImageARBPtr = 0; -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) #else /* !_WIN32 */ static bool glXVersion1_3Present = false; static glXChooseFBConfigProc glXChooseFBConfigPtr = 0; @@ -113,7 +135,7 @@ RenderTexture::RenderTexture(const char *strMode) _bIsTexture(false), _bIsDepthTexture(false), _bHasARBDepthTexture(true), // [Redge] -#ifdef _WIN32 +#if defined(_WIN32) || defined(__MACH__) _eUpdateMode(RT_RENDER_TO_TEXTURE), #else _eUpdateMode(RT_COPY_TO_TEXTURE), @@ -137,23 +159,28 @@ RenderTexture::RenderTexture(const char *strMode) _hPBuffer(NULL), _hPreviousDC(0), _hPreviousContext(0), -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) + _hGLContext(NULL), + _hPBuffer(0), + _hPreviousContext(NULL), #else _pDisplay(NULL), _hGLContext(NULL), _hPBuffer(0), - _hPreviousContext(0), _hPreviousDrawable(0), + _hPreviousContext(0), #endif _iTextureTarget(GL_NONE), _iTextureID(0), _iDepthTextureID(0), _pPoorDepthTexture(0) // [Redge] { + dbg_printf("RenderTexture::RenderTexture(%s) BGN instantiation.\n", strMode ); _iNumColorBits[0] = _iNumColorBits[1] = _iNumColorBits[2] = _iNumColorBits[3] = 0; #ifdef _WIN32 + dbg_printf("RenderTexture::RenderTexture in _WIN32.\n" ); _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB); _pixelFormatAttribs.push_back(true); _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB); @@ -161,8 +188,14 @@ RenderTexture::RenderTexture(const char *strMode) _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB); _pbufferAttribs.push_back(true); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) + dbg_printf("RenderTexture::RenderTexture in __MACH__.\n" ); + //_pixelFormatAttribs.push_back(kCGLPFANoRecovery); + _pixelFormatAttribs.push_back(kCGLPFAAccelerated); + _pixelFormatAttribs.push_back(kCGLPFAWindow); + _pixelFormatAttribs.push_back(kCGLPFAPBuffer); #else + dbg_printf("RenderTexture::RenderTexture !_WIN32 and !__MACH__.\n" ); _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX); _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX); _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX); @@ -174,9 +207,16 @@ RenderTexture::RenderTexture(const char *strMode) #ifdef _WIN32 _pixelFormatAttribs.push_back(0); _pbufferAttribs.push_back(0); +#elif defined(__MACH__) + _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0); + _pbufferAttribs.push_back((CGLPixelFormatAttribute)0); #else _pixelFormatAttribs.push_back(None); #endif + + dbg_printf("RenderTexture::RenderTexture(%s) END instantiation. pf=%d pb=%d\n", + strMode, (int)_pixelFormatAttribs.size(), (int)_pbufferAttribs.size() ); + } @@ -190,9 +230,34 @@ RenderTexture::RenderTexture(const char *strMode) */ RenderTexture::~RenderTexture() { + dbg_printf("RenderTexture::~RenderTexture: destructor.\n" ); _Invalidate(); } + //--------------------------------------------------------------------------- +// Function : _cglcheckError +// Description : +//--------------------------------------------------------------------------- +/** +* @fn _cglCheckError() +* @brief Prints to stderr a description when an OS X error is found. +*/ +#ifdef __MACH__ +static void _cglCheckErrorHelper(CGLError err, char *sourceFile, int sourceLine) +{ +# ifdef _DEBUG + if (err) + { + fprintf(stderr, "RenderTexture CGL Error: %s at (%s,%d)", + CGLErrorString(err), sourceFile, sourceLine); + } +# endif +} + +# define _cglCheckError(err) _cglCheckErrorHelper(err,__FILE__,__LINE__) + +#endif + //--------------------------------------------------------------------------- // Function : _wglGetLastError @@ -263,7 +328,7 @@ void _wglGetLastError() * @fn PrintExtensionError( char* strMsg, ... ) * @brief Prints an error about missing OpenGL extensions. */ -void PrintExtensionError( char* strMsg, ... ) +void PrintExtensionError( const char* strMsg, ... ) { SG_LOG(SG_GL, SG_ALERT, "Error: RenderTexture requires the following unsupported " @@ -271,17 +336,13 @@ void PrintExtensionError( char* strMsg, ... ) char strBuffer[512]; va_list args; va_start(args, strMsg); -#if defined _WIN32 && !defined __CYGWIN__ - _vsnprintf( strBuffer, 512, strMsg, args ); -#else vsnprintf( strBuffer, 512, strMsg, args ); -#endif va_end(args); SG_LOG(SG_GL, SG_ALERT, strMsg); + dbg_printf("Error: RenderTexture requires the following unsupported OpenGL extensions: \n[%s]\n", strMsg); } - //--------------------------------------------------------------------------- // Function : RenderTexture::Initialize // Description : @@ -299,6 +360,8 @@ bool RenderTexture::Initialize(int width, int height, { assert(width > 0 && height > 0); + dbg_printf("RenderTexture::Initialize w=%d h=%d\n", width, height ); + _iWidth = width; _iHeight = height; _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height); @@ -306,8 +369,10 @@ bool RenderTexture::Initialize(int width, int height, _bCopyContext = copyContext; // Check if this is an NVXX GPU and verify necessary extensions. - if (!_VerifyExtensions()) - return false; + if (!_VerifyExtensions()) { + dbg_printf("RenderTexture::Initialize: _VerifyExtensions() FAILED - returning false.\n" ); + return false; + } if (_bInitialized) _Invalidate(); @@ -456,35 +521,199 @@ bool RenderTexture::Initialize(int width, int height, if (_bDoubleBuffered) SG_LOG(SG_GL, SG_ALERT, " double buffered"); #endif -#elif defined( __APPLE__ ) -#else // !_WIN32 +#elif defined( __MACH__ ) + // Get the current context. + CGLContextObj hglrc = CGLGetCurrentContext(); + if (NULL == hglrc) + fprintf(stderr, "Couldn't get current context!"); + + CGLPixelFormatObj pixFormat = NULL; + GLint iNumFormats; + CGLError error; + + // Copy the _pixelFormatAttribs into another array to fix + // typecast issues + CGLPixelFormatAttribute *pixFormatAttribs = + (CGLPixelFormatAttribute *)malloc(sizeof(CGLPixelFormatAttribute) + * _pixelFormatAttribs.size()); + + for (unsigned int ii = 0; ii < _pixelFormatAttribs.size(); ii++) + { + pixFormatAttribs[ii] = + (CGLPixelFormatAttribute)_pixelFormatAttribs[ii]; + } + + if (error = + CGLChoosePixelFormat(&pixFormatAttribs[0], &pixFormat, &iNumFormats)) + { + fprintf(stderr, + "RenderTexture Error: CGLChoosePixelFormat() failed.\n"); + _cglCheckError(error); + return false; + } + if ( iNumFormats <= 0 ) + { + SG_LOG(SG_GL, SG_ALERT, + "RenderTexture Error: Couldn't find a suitable " + "pixel format."); + return false; + } + + // Free the copy of the _pixelFormatAttribs array + free(pixFormatAttribs); + + // Create the context. + error = CGLCreateContext(pixFormat, (_bShareObjects) + ? CGLGetCurrentContext() : NULL, &_hGLContext); + if (error) + { + fprintf(stderr, + "RenderTexture Error: CGLCreateContext() failed.\n"); + _cglCheckError(error); + return false; + } + CGLDestroyPixelFormat(pixFormat); + + // Create the p-buffer. + error = CGLCreatePBuffer(_iWidth, _iHeight, (_bRectangle) + ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D, GL_RGBA, 0, &_hPBuffer); + if (error) + { + fprintf(stderr, + "RenderTexture Error: CGLCreatePBuffer() failed.\n"); + _cglCheckError(error); + return false; + } + + GLint screen; + if (error = CGLGetVirtualScreen(CGLGetCurrentContext(), &screen)) + { + _cglCheckError(error); + return false; + } + if (error = CGLSetPBuffer(_hGLContext, _hPBuffer, 0, 0, screen)) + { + _cglCheckError(error); + return false; + } + + // Determine the actual width and height we were able to create. + //wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth ); + //wglQueryPbufferARB( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight ); + + _bInitialized = true; + + /* + // get the actual number of bits allocated: + int attrib = WGL_RED_BITS_ARB; + //int bits[6]; + int value; + _iNumColorBits[0] = + (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) + ? value : 0; + attrib = WGL_GREEN_BITS_ARB; + _iNumColorBits[1] = + (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) + ? value : 0; + attrib = WGL_BLUE_BITS_ARB; + _iNumColorBits[2] = + (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) + ? value : 0; + attrib = WGL_ALPHA_BITS_ARB; + _iNumColorBits[3] = + (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) + ? value : 0; + attrib = WGL_DEPTH_BITS_ARB; + _iNumDepthBits = + (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) + ? value : 0; + attrib = WGL_STENCIL_BITS_ARB; + _iNumStencilBits = + (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) + ? value : 0; + attrib = WGL_DOUBLE_BUFFER_ARB; + _bDoubleBuffered = + (wglGetPixelFormatAttribivARB(_hDC, iFormat, 0, 1, &attrib, &value)) + ? (value?true:false) : false; + */ + +#if defined(_DEBUG) | defined(DEBUG) + fprintf(stderr, "Created a %dx%d RenderTexture with BPP(%d, %d, %d, %d)", + _iWidth, _iHeight, + _iNumColorBits[0], _iNumColorBits[1], + _iNumColorBits[2], _iNumColorBits[3]); + if (_iNumDepthBits) fprintf(stderr, " depth=%d", _iNumDepthBits); + if (_iNumStencilBits) fprintf(stderr, " stencil=%d", _iNumStencilBits); + if (_bDoubleBuffered) fprintf(stderr, " double buffered"); + fprintf(stderr, "\n"); +#endif + +#else // !_WIN32, !__MACH_ + _pDisplay = glXGetCurrentDisplay(); + if ( !_pDisplay ) { + dbg_printf("RenderTexture::Initialize: ERROR: glXGetCurrentDisplay() returned NULL! return false\n"); + return false; + } + dbg_printf("RenderTexture::Initialize: got glXGetCurrentDisplay() _pDisplay=[%p]\n", _pDisplay); + // glXGetCurrentContext returns the current context, as specified by glXMakeCurrent. + // If there is no current context, NULL is returned. GLXContext context = glXGetCurrentContext(); + if ( !context ) { + dbg_printf("RenderTexture::Initialize: ERROR: glXGetCurrentContext() returned NULL! return false\n"); + return false; + } + dbg_printf("RenderTexture::Initialize: got glXGetCurrentContext() context=[%p]\n", context); int screen = DefaultScreen(_pDisplay); - XVisualInfo *visInfo; + dbg_printf("RenderTexture::Initialize: DefaultScreen(_pDisplay) screen=%d\n", screen); + + XVisualInfo *visInfo = NULL; GLXFBConfig *fbConfigs; int nConfigs; - +#ifdef _DEBUG + dbg_printf("Using %d pixelFormatAttribs array\n", (int)_pixelFormatAttribs.size()); + size_t max = _pixelFormatAttribs.size() / 2; + int dat = 0; + size_t n; + for (n = 0; n < max; n++) { + const char * cp = get_attr_name(_pixelFormatAttribs[n*2], &dat); + printf( "%s(%d) = %d (def=%d)\n", + cp, _pixelFormatAttribs[n*2], _pixelFormatAttribs[(n*2)+1], dat ); + } + n *= 2; + if ( n < _pixelFormatAttribs.size() ) + printf( "Array ends with %d\n", _pixelFormatAttribs[n] ); + else + printf( "WARNING: Array does not appear ODD! which is ODD\n" ); + +#endif fbConfigs = glXChooseFBConfigPtr(_pDisplay, screen, &_pixelFormatAttribs[0], &nConfigs); + // NOTE: ref: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseFBConfig.xml says + // Next, call glXGetFBConfigAttrib to retrieve additional attributes for the frame buffer configurations and then select between them. - if (nConfigs == 0 || !fbConfigs) + if (nConfigs <= 0 || !fbConfigs) { SG_LOG(SG_GL, SG_ALERT, "RenderTexture Error: Couldn't find a suitable pixel format."); + dbg_printf("RenderTexture Error: Couldn't find a suitable pixel format. return false\n"); return false; } + dbg_printf("RenderTexture::Initialize: glXChooseFBConfigPtr() nConfigs = %d, fbConfigs=[%p]\n", nConfigs, fbConfigs); + + int pbufAttrib[] = { + GLX_PBUFFER_WIDTH, _iWidth, + GLX_PBUFFER_HEIGHT, _iHeight, + GLX_LARGEST_PBUFFER, False, + None + }; // Pick the first returned format that will return a pbuffer - if (glXVersion1_3Present) + // if (glXVersion1_3Present) + if (glXCreatePbufferPtr && glXGetVisualFromFBConfigPtr && glXCreateContextPtr) { - int pbufAttrib[] = { - GLX_PBUFFER_WIDTH, _iWidth, - GLX_PBUFFER_HEIGHT, _iHeight, - GLX_LARGEST_PBUFFER, False, - None - }; + dbg_printf("RenderTexture::Initialize: glXVersion1_3Present = TRUE\n"); for (int i=0;i_hPreviousContext; if (NULL == _hPreviousContext) _wglGetLastError(); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) + _hPreviousContext = current->_hPreviousContext; #else _hPreviousContext = current->_hPreviousContext; _hPreviousDrawable = current->_hPreviousDrawable; @@ -1033,6 +1364,18 @@ bool RenderTexture::BindBuffer( int iBuffer ) _bIsBufferBound = true; _iCurrentBoundBuffer = iBuffer; } +#elif defined(__MACH__) + if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture && + (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer)) + { + CGLError err; + if (err=CGLTexImagePBuffer(CGLGetCurrentContext(), _hPBuffer, iBuffer)) + { + _cglCheckError(err); + } + _bIsBufferBound = true; + _iCurrentBoundBuffer = iBuffer; + } #endif } return true; @@ -1040,7 +1383,7 @@ bool RenderTexture::BindBuffer( int iBuffer ) //--------------------------------------------------------------------------- -// Function : RenderTexture::BindBuffer +// Function : RenderTexture::BindDepthBuffer // Description : //--------------------------------------------------------------------------- /** @@ -1060,6 +1403,17 @@ bool RenderTexture::_BindDepthBuffer() const return false; } } +#elif defined(__MACH__) + if (_bInitialized && _bIsDepthTexture && + RT_RENDER_TO_TEXTURE == _eUpdateMode) + { + glBindTexture(_iTextureTarget, _iDepthTextureID); + //if (FALSE == CGLTexImagePBuffer(<#CGLContextObj ctx#>,<#CGLPBufferObj pbuffer#>,<#unsigned long source#>)(_hPBuffer, WGL_DEPTH_COMPONENT_NV)) + //{ + // _wglGetLastError(); + // return false; + //} + } #endif return true; } @@ -1076,11 +1430,12 @@ void RenderTexture::_ParseModeString(const char *modeString, vector &pfAttribs, vector &pbAttribs) { + dbg_printf("RenderTexture::_ParseModeString(%s). BGN vf=%d vp=%d\n", modeString, (int)pfAttribs.size(), (int)pbAttribs.size() ); if (!modeString || strcmp(modeString, "") == 0) return; _iNumComponents = 0; -#ifdef _WIN32 +#if defined(_WIN32) || defined(__MACH__) _eUpdateMode = RT_RENDER_TO_TEXTURE; #else _eUpdateMode = RT_COPY_TO_TEXTURE; @@ -1102,7 +1457,7 @@ void RenderTexture::_ParseModeString(const char *modeString, tokens.push_back(buf); buf = strtok(NULL, " "); } - + free(mode); for (unsigned int i = 0; i < tokens.size(); i++) { string token = tokens[i]; @@ -1130,13 +1485,18 @@ void RenderTexture::_ParseModeString(const char *modeString, pfAttribs.push_back(bitVec[1]); pfAttribs.push_back(WGL_BLUE_BITS_ARB); pfAttribs.push_back(bitVec[2]); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) +# if 0 pfAttribs.push_back(AGL_RED_SIZE); pfAttribs.push_back(bitVec[0]); pfAttribs.push_back(AGL_GREEN_SIZE); pfAttribs.push_back(bitVec[1]); pfAttribs.push_back(AGL_BLUE_SIZE); pfAttribs.push_back(bitVec[2]); +# else + pfAttribs.push_back(kCGLPFAColorSize); + pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2]); +# endif #else pfAttribs.push_back(GLX_RED_SIZE); pfAttribs.push_back(bitVec[0]); @@ -1148,10 +1508,14 @@ void RenderTexture::_ParseModeString(const char *modeString, _iNumComponents += 3; continue; } - else if (kv.first == "rgb") + else if (kv.first == "rgb") + { SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: mistake in components definition " "(rgb + " << _iNumComponents << ")."); + dbg_printf("RenderTexture Warning 1: mistake in components definition " + "(rgb + %d).\n", _iNumComponents ); + } if (kv.first == "rgba" && (_iNumComponents == 0)) { @@ -1176,7 +1540,8 @@ void RenderTexture::_ParseModeString(const char *modeString, pfAttribs.push_back(bitVec[2]); pfAttribs.push_back(WGL_ALPHA_BITS_ARB); pfAttribs.push_back(bitVec[3]); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) +# if 0 pfAttribs.push_back(AGL_RED_SIZE); pfAttribs.push_back(bitVec[0]); pfAttribs.push_back(AGL_GREEN_SIZE); @@ -1185,6 +1550,14 @@ void RenderTexture::_ParseModeString(const char *modeString, pfAttribs.push_back(bitVec[2]); pfAttribs.push_back(AGL_ALPHA_SIZE); pfAttribs.push_back(bitVec[3]); +# else + pfAttribs.push_back(kCGLPFAColorSize); + pfAttribs.push_back(bitVec[0] + bitVec[1] + bitVec[2] + bitVec[3]); + //pfAttribs.push_back(kCGLPFAAlphaSize); + //pfAttribs.push_back(bitVec[3]); + // printf("Color size: %d\n", bitVec[0] + bitVec[1] + bitVec[2] + bitVec[3]); + +# endif #else pfAttribs.push_back(GLX_RED_SIZE); pfAttribs.push_back(bitVec[0]); @@ -1199,9 +1572,13 @@ void RenderTexture::_ParseModeString(const char *modeString, continue; } else if (kv.first == "rgba") + { SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: mistake in components definition " "(rgba + " << _iNumComponents << ")."); + dbg_printf("RenderTexture Warning 2: mistake in components definition " + "(rgb + %d).\n", _iNumComponents ); + } if (kv.first == "r" && (_iNumComponents <= 1)) { @@ -1213,9 +1590,14 @@ void RenderTexture::_ParseModeString(const char *modeString, #ifdef _WIN32 pfAttribs.push_back(WGL_RED_BITS_ARB); pfAttribs.push_back(bitVec[0]); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) +# if 0 pfAttribs.push_back(AGL_RED_SIZE); pfAttribs.push_back(bitVec[0]); +# else + pfAttribs.push_back(kCGLPFAColorSize); + pfAttribs.push_back(bitVec[0]); +# endif #else pfAttribs.push_back(GLX_RED_SIZE); pfAttribs.push_back(bitVec[0]); @@ -1224,10 +1606,13 @@ void RenderTexture::_ParseModeString(const char *modeString, continue; } else if (kv.first == "r") + { SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: mistake in components definition " "(r + " << _iNumComponents << ")."); - + dbg_printf("RenderTexture Warning 3: mistake in components definition " + "(rgb + %d).\n", _iNumComponents ); + } if (kv.first == "rg" && (_iNumComponents <= 1)) { if (kv.second.find("f") != kv.second.npos) @@ -1245,11 +1630,16 @@ void RenderTexture::_ParseModeString(const char *modeString, pfAttribs.push_back(bitVec[0]); pfAttribs.push_back(WGL_GREEN_BITS_ARB); pfAttribs.push_back(bitVec[1]); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) +# if 0 pfAttribs.push_back(AGL_RED_SIZE); pfAttribs.push_back(bitVec[0]); pfAttribs.push_back(AGL_GREEN_SIZE); pfAttribs.push_back(bitVec[1]); +# else + pfAttribs.push_back(kCGLPFAColorSize); + pfAttribs.push_back(bitVec[0] + bitVec[1]); +# endif #else pfAttribs.push_back(GLX_RED_SIZE); pfAttribs.push_back(bitVec[0]); @@ -1260,9 +1650,13 @@ void RenderTexture::_ParseModeString(const char *modeString, continue; } else if (kv.first == "rg") + { SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: mistake in components definition " "(rg + " << _iNumComponents << ")."); + dbg_printf("RenderTexture Warning 4: mistake in components definition " + "(rgb + %d).\n", _iNumComponents ); + } if (kv.first == "depth") { @@ -1278,8 +1672,12 @@ void RenderTexture::_ParseModeString(const char *modeString, bHasStencil = true; #ifdef _WIN32 pfAttribs.push_back(WGL_STENCIL_BITS_ARB); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) +# if 0 pfAttribs.push_back(AGL_STENCIL_SIZE); +# else + pfAttribs.push_back(kCGLPFAStencilSize); +# endif #else pfAttribs.push_back(GLX_STENCIL_SIZE); #endif @@ -1297,10 +1695,15 @@ void RenderTexture::_ParseModeString(const char *modeString, pfAttribs.push_back(1); pfAttribs.push_back(WGL_SAMPLES_ARB); pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10)); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) +# if 0 pfAttribs.push_back(AGL_SAMPLE_BUFFERS_ARB); pfAttribs.push_back(1); pfAttribs.push_back(AGL_SAMPLES_ARB); +# else + pfAttribs.push_back(kCGLPFAMultisample); + pfAttribs.push_back(kCGLPFASamples); +# endif pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10)); #else pfAttribs.push_back(GLX_SAMPLE_BUFFERS_ARB); @@ -1317,9 +1720,13 @@ void RenderTexture::_ParseModeString(const char *modeString, #ifdef _WIN32 pfAttribs.push_back(WGL_DOUBLE_BUFFER_ARB); pfAttribs.push_back(true); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) +# if 0 pfAttribs.push_back(AGL_DOUBLEBUFFER); pfAttribs.push_back(True); +# else + pfAttribs.push_back(kCGLPFADoubleBuffer); +# endif #else pfAttribs.push_back(GLX_DOUBLEBUFFER); pfAttribs.push_back(True); @@ -1331,8 +1738,12 @@ void RenderTexture::_ParseModeString(const char *modeString, { #ifdef _WIN32 pfAttribs.push_back(WGL_AUX_BUFFERS_ARB); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) +# if 0 pfAttribs.push_back(AGL_AUX_BUFFERS); +# else + pfAttribs.push_back(kCGLPFAAuxBuffers); +# endif #else pfAttribs.push_back(GLX_AUX_BUFFERS); #endif @@ -1347,7 +1758,8 @@ void RenderTexture::_ParseModeString(const char *modeString, { _bIsTexture = true; - if ((kv.first == "texRECT") && GL_NV_texture_rectangle) + if ((kv.first == "texRECT") && (GL_NV_texture_rectangle || + GL_EXT_texture_rectangle)) { _bRectangle = true; bBindRECT = true; @@ -1368,7 +1780,8 @@ void RenderTexture::_ParseModeString(const char *modeString, { _bIsDepthTexture = true; - if ((kv.first == "depthTexRECT") && GL_NV_texture_rectangle) + if ((kv.first == "depthTexRECT") && (GL_NV_texture_rectangle || + GL_EXT_texture_rectangle)) { _bRectangle = true; bBindRECT = true; @@ -1406,6 +1819,8 @@ void RenderTexture::_ParseModeString(const char *modeString, SG_LOG(SG_GL, SG_ALERT, "RenderTexture Error: Unknown pbuffer attribute: " << token.c_str()); + dbg_printf("RenderTexture Error: Uknown pbuffer attribute: %s\n", + token.c_str() ); } // Processing of some options must be last because of interactions. @@ -1416,6 +1831,7 @@ void RenderTexture::_ParseModeString(const char *modeString, SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: Depth and Color texture targets " "should match."); + dbg_printf( "RenderTexture Warning: Depth and Color texture targets should match.\n"); } // Apply default bit format if none specified @@ -1440,8 +1856,12 @@ void RenderTexture::_ParseModeString(const char *modeString, #ifdef _WIN32 pfAttribs.push_back(WGL_DEPTH_BITS_ARB); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) +# if 0 pfAttribs.push_back(AGL_DEPTH_SIZE); +# else + pfAttribs.push_back(kCGLPFADepthSize); +# endif #else pfAttribs.push_back(GLX_DEPTH_SIZE); #endif @@ -1452,8 +1872,12 @@ void RenderTexture::_ParseModeString(const char *modeString, #ifdef _WIN32 pfAttribs.push_back(WGL_STENCIL_BITS_ARB); pfAttribs.push_back(0); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) +# if 0 pfAttribs.push_back(AGL_STENCIL_SIZE); +# else + pfAttribs.push_back(kCGLPFAStencilSize); +# endif pfAttribs.push_back(0); #else pfAttribs.push_back(GLX_STENCIL_SIZE); @@ -1478,6 +1902,7 @@ void RenderTexture::_ParseModeString(const char *modeString, SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: No support found for " "render to depth texture."); #endif + dbg_printf("RenderTexture Warning: No support found for render to depth texture.\n"); _bIsDepthTexture = false; } #endif @@ -1507,7 +1932,7 @@ void RenderTexture::_ParseModeString(const char *modeString, pbAttribs.push_back(WGL_MIPMAP_TEXTURE_ARB); pbAttribs.push_back(true); } - +#elif defined(__MACH__) #elif defined(DEBUG) || defined(_DEBUG) SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: Render to Texture not " "supported in Linux or MacOS"); @@ -1531,7 +1956,11 @@ void RenderTexture::_ParseModeString(const char *modeString, pfAttribs.push_back(WGL_PIXEL_TYPE_ARB); pfAttribs.push_back(WGL_TYPE_RGBA_FLOAT_ATI); } -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) + // if (GL_MACH_float_pixels) // FIXME + { + pfAttribs.push_back(kCGLPFAColorFloat); + } #else if (GLX_NV_float_buffer) { @@ -1592,6 +2021,8 @@ void RenderTexture::_ParseModeString(const char *modeString, "RenderTexture Warning: Bad number of components " "(r=1,rg=2,rgb=3,rgba=4): " << _iNumComponents); + dbg_printf("RenderTexture Warning 1: Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n", + _iNumComponents); break; } } @@ -1639,14 +2070,109 @@ void RenderTexture::_ParseModeString(const char *modeString, SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: Bad number of components " "(r=1,rg=2,rgb=3,rgba=4): " << _iNumComponents); + dbg_printf("RenderTexture Warning 2: Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n", + _iNumComponents); break; } - } + } +#elif defined(__MACH__) + if (_bFloat) + { + /* + //if (WGLEW_NV_float_buffer) // FIXME + { + switch(_iNumComponents) + { + case 1: + pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV); + pfAttribs.push_back(true); + + pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB); + pbAttribs.push_back(WGL_TEXTURE_FLOAT_R_NV); + break; + case 2: + pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV); + pfAttribs.push_back(true); + + pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB); + pbAttribs.push_back(WGL_TEXTURE_FLOAT_RG_NV); + break; + case 3: + pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV); + pfAttribs.push_back(true); + + pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB); + pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGB_NV); + break; + case 4: + pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV); + pfAttribs.push_back(true); + + pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB); + pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGBA_NV); + break; + default: + fprintf(stderr, + "RenderTexture Warning: Bad number of components " + "(r=1,rg=2,rgb=3,rgba=4): %d.\n", + _iNumComponents); + break; + } + } + else + { + if (4 == _iNumComponents) + { + pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB); + pfAttribs.push_back(true); + + pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB); + pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB); + } + else + { + // standard ARB_render_texture only supports 3 or 4 channels + pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB); + pfAttribs.push_back(true); + + pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB); + pbAttribs.push_back(WGL_TEXTURE_RGB_ARB); + } + } + */ + } + else + { + /* + switch(_iNumComponents) + { + case 3: + pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB); + pfAttribs.push_back(true); + + pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB); + pbAttribs.push_back(WGL_TEXTURE_RGB_ARB); + break; + case 4: + pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB); + pfAttribs.push_back(true); + + pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB); + pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB); + break; + default: + fprintf(stderr, + "RenderTexture Warning: Bad number of components " + "(r=1,rg=2,rgb=3,rgba=4): %d.\n", _iNumComponents); + break; + } + */ + } #elif defined(DEBUG) || defined(_DEBUG) SG_LOG(SG_GL, SG_ALERT, - "RenderTexture Error: Render to Texture not supported in " - "Linux or MacOS\ n"); + "RenderTexture Error: Render to Texture not supported in Linux or MacOS"); #endif + dbg_printf( "RenderTexture Error 1: Render to Texture not supported in Linux or MacOS\n"); } if (_bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode)) @@ -1668,11 +2194,15 @@ void RenderTexture::_ParseModeString(const char *modeString, pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV); pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV); } +#elif defined(__MACH__) #elif defined(DEBUG) || defined(_DEBUG) SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: Render to Texture not supported in " "Linux or MacOS"); #endif + dbg_printf( "RenderTexture Error 2: Render to Texture not supported in Linux or MacOS\n"); } + dbg_printf("RenderTexture::_ParseModeString(%s). END vf=%d vp=%d\n", modeString, (int)pfAttribs.size(), (int)pbAttribs.size() ); + } //--------------------------------------------------------------------------- @@ -1742,6 +2272,7 @@ vector RenderTexture::_ParseBitVector(string bitVector) */ bool RenderTexture::_VerifyExtensions() { + dbg_printf("RenderTexture::_VerifyExtensions() called...\n"); #ifdef _WIN32 // a second call to _VerifyExtensions will allways return true, causing a crash // if the extension is not supported @@ -1793,7 +2324,8 @@ bool RenderTexture::_VerifyExtensions() PrintExtensionError("GL_NV_texture_rectangle"); return false; } - if (_bFloat && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) || SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ATI_pixel_format_float" ))) + if (_bFloat && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) || + SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ATI_pixel_format_float" ))) { PrintExtensionError("GL_NV_float_buffer or GL_ATI_pixel_format_float"); return false; @@ -1819,9 +2351,47 @@ bool RenderTexture::_VerifyExtensions() } SetLastError(0); } -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) + // FIXME! Check extensions! #else + Display* dpy = glXGetCurrentDisplay(); + int minor = 0, major = 0; + if (!dpy) { + dbg_printf("_VerifyExtensions: glXGetCurrentDisplay() returned NULL! returning false\n"); + return false; + } + if (!glXQueryVersion(dpy, &major, &minor)) + { + dbg_printf("_VerifyExtensions: glXQueryVersion(dpy, &major, &minor) FAILED! returning false\n"); + return false; + } + else + { + dbg_printf("_VerifyExtensions: glXQueryVersion(dpy, major=%d, minor=%d)\n", major, minor); + } + int screen = DefaultScreen(dpy); + const char* extString = glXQueryExtensionsString(dpy, screen); + dbg_printf("_VerifyExtensions: glXQueryExtensionsString(dpy, screen) returned -\n[%s]\n", + (extString ? extString : "") ); + if (!SGSearchExtensionsString(extString, "GLX_SGIX_fbconfig") || + !SGSearchExtensionsString(extString, "GLX_SGIX_pbuffer")) + { + dbg_printf("_VerifyExtensions: glXQueryExtensionsString(dpy,screen) does NOT contain GLX_SGIX_fbconfig or GLX_SGIX_pbuffer!\n" ); + const char * extClient = glXGetClientString( dpy, GLX_EXTENSIONS ); + if (!extClient || + !SGSearchExtensionsString(extClient, "GLX_SGIX_fbconfig") || + !SGSearchExtensionsString(extClient, "GLX_SGIX_pbuffer")) + { + dbg_printf("_VerifyExtensions: AND glXGetClientString(dpy,GLX_EXTENSIONS) also! returning false\n" ); + return false; + } + else + { + dbg_printf("_VerifyExtensions: BUT glXGetClientString(dpy,GLX_EXTENSIONS) returned \n[%s]\n", extClient ); + dbg_printf("Since this DOES contain fbconfig and pbuffer, continuing...\n"); + } + } // First try the glX version 1.3 functions. glXChooseFBConfigPtr = (glXChooseFBConfigProc)SGLookupFunction("glXChooseFBConfig"); glXCreatePbufferPtr = (glXCreatePbufferProc)SGLookupFunction("glXCreatePbuffer"); @@ -1830,15 +2400,28 @@ bool RenderTexture::_VerifyExtensions() glXDestroyPbufferPtr = (glXDestroyPbufferProc)SGLookupFunction("glXDestroyPbuffer"); glXQueryDrawablePtr = (glXQueryDrawableProc)SGLookupFunction("glXQueryDrawable"); - if (glXChooseFBConfigPtr && + if (((1 <= major && 3 <= minor) || 2 <= major) && + glXChooseFBConfigPtr && glXCreatePbufferPtr && glXGetVisualFromFBConfigPtr && glXCreateContextPtr && glXDestroyPbufferPtr && - glXQueryDrawablePtr) + glXQueryDrawablePtr) { + dbg_printf("_VerifyExtensions: setting glXVersion1_3Present TRUE\n" ); glXVersion1_3Present = true; + } else { + dbg_printf("_VerifyExtensions: setting glXVersion1_3Present FALSE\n Reason: " ); + if ( !((1 <= major && 3 <= minor) || 2 <= major) ) { dbg_printf( "Version wrong %d.%d ", major, minor ); } + if ( !glXChooseFBConfigPtr ) { dbg_printf( "missing glXChooseFBConfigPtr " ); } + if ( !glXCreatePbufferPtr ) { dbg_printf( "missing glXCreatePbufferPtr " ); } + if ( !glXGetVisualFromFBConfigPtr ) { dbg_printf( "missing glXGetVisualFromFBConfigPtr " ); } + if ( !glXCreateContextPtr ) { dbg_printf( "missing glXCreateContextPtr " ); } + if ( !glXDestroyPbufferPtr ) { dbg_printf( "missing glXDestroyPbufferPtr " ); } + if ( !glXQueryDrawablePtr ) { dbg_printf( "missing glXQueryDrawablePtr " ); } + dbg_printf("\n"); + glXChooseFBConfigPtr = (glXChooseFBConfigProc)SGLookupFunction("glXChooseFBConfigSGIX"); glXCreateGLXPbufferPtr = (glXCreateGLXPbufferProc)SGLookupFunction("glXCreateGLXPbufferSGIX"); glXGetVisualFromFBConfigPtr = (glXGetVisualFromFBConfigProc)SGLookupFunction("glXGetVisualFromFBConfigSGIX"); @@ -1846,14 +2429,25 @@ bool RenderTexture::_VerifyExtensions() glXDestroyPbufferPtr = (glXDestroyPbufferProc)SGLookupFunction("glXDestroyGLXPbufferSGIX"); glXQueryGLXPbufferSGIXPtr = (glXQueryGLXPbufferSGIXProc)SGLookupFunction("glXQueryGLXPbufferSGIX"); - if (!glXChooseFBConfigPtr || !glXCreateGLXPbufferPtr || !glXGetVisualFromFBConfigPtr || !glXCreateContextWithConfigPtr || !glXDestroyPbufferPtr || !glXQueryGLXPbufferSGIXPtr) - return false; + { + dbg_printf("_VerifyExtensions: some pointer is NULL! return false\n" ); + if ( !glXCreateGLXPbufferPtr ) { + dbg_printf("RenderTexture::Initialize: ERROR glXCreateGLXPbufferPtr = NULL!\n"); + } else if ( !glXCreateContextWithConfigPtr ) { + dbg_printf("RenderTexture::Initialize: ERROR glXCreateContextWithConfigPtr = NULL!\n"); + } else if ( !glXVersion1_3Present && !glXQueryGLXPbufferSGIXPtr ) { + dbg_printf("RenderTexture::Initialize: ERROR glXQueryGLXPbufferSGIXPtr = NULL!\n"); + } + return false; + } else { + dbg_printf("_VerifyExtensions: appear to have all 'procs' glXCreateGLXPbufferPtr=[%p]\n", glXCreateGLXPbufferPtr ); + } } if (_bIsDepthTexture && !GL_ARB_depth_texture) @@ -1873,6 +2467,7 @@ bool RenderTexture::_VerifyExtensions() } #endif + dbg_printf("RenderTexture::_VerifyExtensions: return true.\n"); return true; } @@ -1886,11 +2481,15 @@ bool RenderTexture::_VerifyExtensions() */ bool RenderTexture::_InitializeTextures() { + dbg_printf( "RenderTexture::_InitializeTextures() called\n" ); // Determine the appropriate texture formats and filtering modes. + if (_bIsTexture || _bIsDepthTexture) { if (_bRectangle && GL_NV_texture_rectangle) _iTextureTarget = GL_TEXTURE_RECTANGLE_NV; + else if (_bRectangle && GL_EXT_texture_rectangle) + _iTextureTarget = GL_TEXTURE_RECTANGLE_EXT; else _iTextureTarget = GL_TEXTURE_2D; } @@ -1920,6 +2519,7 @@ bool RenderTexture::_InitializeTextures() SG_LOG(SG_GL, SG_ALERT, "RenderTexture Error: mipmapped float textures not " "supported."); + dbg_printf( "RenderTexture Error: mipmapped float textures not supported. return false\n"); return false; } @@ -1983,6 +2583,8 @@ bool RenderTexture::_InitializeTextures() SG_LOG(SG_GL, SG_INFO, "RenderTexture Error: " "Invalid number of components: " << _iNumComponents); + dbg_printf( "RenderTexture Error: Invalid number of components: %d - return false\n", + _iNumComponents); return false; } } @@ -2041,6 +2643,7 @@ bool RenderTexture::_InitializeTextures() } } + dbg_printf( "RenderTexture::_InitializeTextures() returning true\n" ); return true; } @@ -2088,6 +2691,21 @@ void RenderTexture::_MaybeCopyBuffer() } } +#elif defined(__MACH__) + if (RT_COPY_TO_TEXTURE == _eUpdateMode) + { + if (_bIsTexture) + { + glBindTexture(_iTextureTarget, _iTextureID); + glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight); + } + if (_bIsDepthTexture) + { + glBindTexture(_iTextureTarget, _iDepthTextureID); + assert(_bHasARBDepthTexture); + glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight); + } + } #else if (_bIsTexture) { @@ -2157,7 +2775,6 @@ bool RenderTexture::_ReleaseBoundBuffers() * @fn RenderTexture::_MakeCurrent() * @brief Makes the RenderTexture's context current */ - bool RenderTexture::_MakeCurrent() { #ifdef _WIN32 @@ -2167,14 +2784,27 @@ bool RenderTexture::_MakeCurrent() _wglGetLastError(); return false; } -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) + CGLError err; + + if (err = CGLSetCurrentContext(_hGLContext)) + { + _cglCheckError(err); + return false; + } #else +static GLXContext last_hGLContext = 0; if (false == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext)) { + dbg_printf( "_MakeCurrent: glXMakeCurrent FAILED! returning false\n"); return false; } -#endif + if ( last_hGLContext != _hGLContext ) { + last_hGLContext = _hGLContext; + dbg_printf( "_MakeCurrent: glXMakeCurrent set to [%p] SUCCESS! returning true\n", _hGLContext ); + } +#endif return true; } @@ -2206,8 +2836,8 @@ RenderTexture::RenderTexture(int width, int height, _iCurrentBoundBuffer(0), _iNumDepthBits(0), _iNumStencilBits(0), - _bDoubleBuffered(false), _bFloat(false), + _bDoubleBuffered(false), _bPowerOf2(true), _bRectangle(false), _bMipmap(false), @@ -2219,13 +2849,16 @@ RenderTexture::RenderTexture(int width, int height, _hPBuffer(NULL), _hPreviousDC(0), _hPreviousContext(0), -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) + _hGLContext(NULL), + _hPBuffer(NULL), + _hPreviousContext(NULL), #else _pDisplay(NULL), _hGLContext(NULL), _hPBuffer(0), - _hPreviousContext(0), _hPreviousDrawable(0), + _hPreviousContext(0), #endif _iTextureTarget(GL_NONE), _iTextureID(0), @@ -2237,6 +2870,7 @@ RenderTexture::RenderTexture(int width, int height, SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: Deprecated Contructor interface used."); #endif + dbg_printf("RenderTexture Warning: Deprecated Contructor interface used.\n"); _iNumColorBits[0] = _iNumColorBits[1] = _iNumColorBits[2] = _iNumColorBits[3] = 0; @@ -2274,6 +2908,7 @@ bool RenderTexture::Initialize(bool bShare /* = true */, SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: Deprecated Initialize() interface used."); #endif + dbg_printf("RenderTexture Warning: Deprecated Initialize() interface used.\n"); // create a mode string. string mode = ""; @@ -2306,7 +2941,7 @@ bool RenderTexture::Initialize(bool bShare /* = true */, } if (_bIsTexture) { - if (GL_NV_texture_rectangle && + if ((GL_NV_texture_rectangle || GL_EXT_texture_rectangle) && ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight)) || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16)) mode.append("texRECT "); @@ -2315,7 +2950,7 @@ bool RenderTexture::Initialize(bool bShare /* = true */, } if (_bIsDepthTexture) { - if (GL_NV_texture_rectangle && + if ((GL_NV_texture_rectangle || GL_EXT_texture_rectangle) && ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight)) || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16)) mode.append("texRECT "); @@ -2336,7 +2971,11 @@ bool RenderTexture::Initialize(bool bShare /* = true */, _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB); _pbufferAttribs.push_back(true); -#elif defined( __APPLE__ ) +#elif defined( __MACH__ ) + //_pixelFormatAttribs.push_back(kCGLPFANoRecovery); + _pixelFormatAttribs.push_back(kCGLPFAAccelerated); + _pixelFormatAttribs.push_back(kCGLPFAWindow); + _pixelFormatAttribs.push_back(kCGLPFAPBuffer); #else _pixelFormatAttribs.push_back(GLX_RENDER_TYPE_SGIX); _pixelFormatAttribs.push_back(GLX_RGBA_BIT_SGIX); @@ -2349,6 +2988,8 @@ bool RenderTexture::Initialize(bool bShare /* = true */, #ifdef _WIN32 _pixelFormatAttribs.push_back(0); _pbufferAttribs.push_back(0); +#elif defined(__MACH__) + _pixelFormatAttribs.push_back(0); #else _pixelFormatAttribs.push_back(None); #endif @@ -2374,14 +3015,195 @@ bool RenderTexture::Reset(int iWidth, int iHeight) { SG_LOG(SG_GL, SG_ALERT, "RenderTexture Warning: Deprecated Reset() interface used."); + + dbg_printf("RenderTexture Warning: Deprecated Reset(x,y) interface used.\n"); if (!_Invalidate()) { SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Reset(): failed to invalidate."); + dbg_printf( "RenderTexture::Reset(x,y): failed to invalidate. returning false\n"); return false; } _iWidth = iWidth; _iHeight = iHeight; + dbg_printf( "RenderTexture::Reset(x,y): succeeded. returning true\n"); return true; } + +#if defined( _DEBUG ) && !defined( _WIN32 ) && !defined( __MACH__ ) +/* just some DEBUG ONLY code, to show the 'attributes' */ + +typedef struct tagPXATTS { + int attr; + const char * name; + const char * desc; + int def; +}PXATTS, * PPXATTS; + +static PXATTS pxAtts[] = { + { GLX_FBCONFIG_ID, "GLX_FBCONFIG_ID", + "followed by a valid XID that indicates the desired GLX frame buffer configuration. " + "When a GLX_FBCONFIG_ID is specified, all attributes are ignored. The default value is GLX_DONT_CARE.", + GLX_DONT_CARE }, + { GLX_BUFFER_SIZE, "GLX_BUFFER_SIZE", + "Must be followed by a nonnegative integer that indicates the desired color index buffer size." + "The smallest index buffer of at least the specified size is preferred. This attribute is ignored if GLX_COLOR_INDEX_BIT is not set " + "in GLX_RENDER_TYPE. The default value is 0.", + 0 }, + { GLX_LEVEL, "GLX_LEVEL", + "Must be followed by an integer buffer-level specification. This specification is honored exactly." + "Buffer level 0 corresponds to the default frame buffer of the display. " + "Buffer level 1 is the first overlay frame buffer, level two the second overlay frame buffer, and so on." + "Negative buffer levels correspond to underlay frame buffers. The default value is 0.", + 0 }, + { GLX_DOUBLEBUFFER, "GLX_DOUBLEBUFFER", + "Must be followed by True or False. If True is specified, then only double-buffered frame buffer configurations are considered;" + "if False is specified, then only single-buffered frame buffer configurations are considered. The default value is GLX_DONT_CARE.", + GLX_DONT_CARE }, + { GLX_STEREO, "GLX_STEREO", + "Must be followed by True or False. If True is specified, then only stereo frame buffer configurations are considered;" + " if False is specified, then only monoscopic frame buffer configurations are considered. The default value is False.", + False }, + { GLX_AUX_BUFFERS, "GLX_AUX_BUFFERS", + "Must be followed by a nonnegative integer that indicates the desired number of auxiliary buffers." + " Configurations with the smallest number of auxiliary buffers that meet or exceed the specified number are preferred." + " The default value is 0.", + 0 }, + { GLX_RED_SIZE, "GLX_RED_SIZE", + "must be followed by a nonnegative minimum size", + 0 }, + { GLX_GREEN_SIZE, "GLX_GREEN_SIZE", + "must be followed by a nonnegative minimum size", + 0 }, + { GLX_BLUE_SIZE, "GLX_BLUE_SIZE", + "must be followed by a nonnegative minimum size", + 0 }, + { GLX_ALPHA_SIZE, "GLX_ALPHA_SIZE", + "Each attribute, if present, must be followed by a nonnegative minimum size specification or GLX_DONT_CARE." + " The largest available total RGBA color buffer size (sum of GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE) " + " of at least the minimum size specified for each color component is preferred. If the requested number of bits for a color " + " component is 0 or GLX_DONT_CARE, it is not considered. The default value for each color component is 0.", + 0 }, + { GLX_DEPTH_SIZE, "GLX_DEPTH_SIZE", + "Must be followed by a nonnegative minimum size specification. If this value is zero, " + "frame buffer configurations with no depth buffer are preferred." + "Otherwise, the largest available depth buffer of at least the minimum size is preferred. The default value is 0.", + 0 }, + { GLX_STENCIL_SIZE, "GLX_STENCIL_SIZE", + "Must be followed by a nonnegative integer that indicates the desired number of stencil bitplanes." + "The smallest stencil buffer of at least the specified size is preferred. If the desired value is zero," + " frame buffer configurations with no stencil buffer are preferred. The default value is 0.", + 0 }, + { GLX_ACCUM_RED_SIZE, "GLX_ACCUM_RED_SIZE", + "Must be followed by a nonnegative minimum size specification. If this value is zero, " + " frame buffer configurations with no red accumulation buffer are preferred." + " Otherwise, the largest possible red accumulation buffer of at least the minimum size is preferred. The default value is 0.", + 0 }, + { GLX_ACCUM_GREEN_SIZE, "GLX_ACCUM_GREEN_SIZE", + "Must be followed by a nonnegative minimum size specification. If this value is zero, " + "frame buffer configurations with no green accumulation buffer are preferred. " + "Otherwise, the largest possible green accumulation buffer of at least the minimum size is preferred. The default value is 0.", + 0 }, + { GLX_ACCUM_BLUE_SIZE, "GLX_ACCUM_BLUE_SIZE", + "Must be followed by a nonnegative minimum size specification. If this value is zero, " + "frame buffer configurations with no blue accumulation buffer are preferred. " + "Otherwise, the largest possible blue accumulation buffer of at least the minimum size is preferred. The default value is 0.", + 0 }, + { GLX_ACCUM_ALPHA_SIZE, "GLX_ACCUM_ALPHA_SIZE", + "Must be followed by a nonnegative minimum size specification. If this value is zero, " + "frame buffer configurations with no alpha accumulation buffer are preferred. " + "Otherwise, the largest possible alpha accumulation buffer of at least the minimum size is preferred. The default value is 0.", + 0 }, + { GLX_RENDER_TYPE, "GLX_RENDER_TYPE", + "Must be followed by a mask indicating which OpenGL rendering modes the frame buffer configuration must support. " + "Valid bits are GLX_RGBA_BIT and GLX_COLOR_INDEX_BIT. If the mask is set to GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT, " + "then only frame buffer configurations that can be bound to both RGBA contexts and color index contexts will be considered. " + "The default value is GLX_RGBA_BIT.", + GLX_RGBA_BIT }, + { GLX_DRAWABLE_TYPE, "GLX_DRAWABLE_TYPE", + "Must be followed by a mask indicating which GLX drawable types the frame buffer configuration must support. " + "Valid bits are GLX_WINDOW_BIT, GLX_PIXMAP_BIT, and GLX_PBUFFER_BIT. For example, if mask is set to " + "GLX_WINDOW_BIT | GLX_PIXMAP_BIT, only frame buffer configurations that support both windows and GLX pixmaps " + "will be considered. The default value is GLX_WINDOW_BIT.", + GLX_WINDOW_BIT }, + { GLX_X_RENDERABLE, "GLX_X_RENDERABLE", + "Must be followed by True or False. If True is specified, then only frame buffer configurations that " + "have associated X visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. " + "The default value is GLX_DONT_CARE. ", + GLX_DONT_CARE }, + { GLX_X_VISUAL_TYPE, "GLX_X_VISUAL_TYPE", + "Must be followed by one of GLX_TRUE_COLOR, GLX_DIRECT_COLOR, GLX_PSEUDO_COLOR, GLX_STATIC_COLOR, " + "GLX_GRAY_SCALE, or GLX_STATIC_GRAY, indicating the desired X visual type. " + "Not all frame buffer configurations have an associated X visual. If GLX_DRAWABLE_TYPE is specified in attrib_list and the " + "mask that follows does not have GLX_WINDOW_BIT set, then this value is ignored. It is also ignored if " + "GLX_X_RENDERABLE is specified as False. RGBA rendering may be supported for visuals of type " + "GLX_TRUE_COLOR, GLX_DIRECT_COLOR, GLX_PSEUDO_COLOR, or GLX_STATIC_COLOR, " + "but color index rendering is only supported for visuals of type GLX_PSEUDO_COLOR or GLX_STATIC_COLOR " + "(i.e., single-channel visuals). The tokens GLX_GRAY_SCALE and GLX_STATIC_GRAY will " + "not match current OpenGL enabled visuals, but are included for future use." + "The default value for GLX_X_VISUAL_TYPE is GLX_DONT_CARE.", + GLX_DONT_CARE }, + { GLX_CONFIG_CAVEAT, "GLX_CONFIG_CAVEAT", + "Must be followed by one of GLX_NONE, GLX_SLOW_CONFIG, GLX_NON_CONFORMANT_CONFIG. " + "If GLX_NONE is specified, then only frame buffer configurations with " + "no caveats will be considered; if GLX_SLOW_CONFIG is specified, then only slow frame buffer configurations will be considered; if " + "GLX_NON_CONFORMANT_CONFIG is specified, then only nonconformant frame buffer configurations will be considered." + "The default value is GLX_DONT_CARE.", + GLX_DONT_CARE }, + { GLX_TRANSPARENT_TYPE, "GLX_TRANSPARENT_TYPE", + "Must be followed by one of GLX_NONE, GLX_TRANSPARENT_RGB, GLX_TRANSPARENT_INDEX. " + "If GLX_NONE is specified, then only opaque frame buffer configurations will be considered; " + "if GLX_TRANSPARENT_RGB is specified, then only transparent frame buffer configurations that support RGBA rendering will be considered; " + "if GLX_TRANSPARENT_INDEX is specified, then only transparent frame buffer configurations that support color index rendering will be considered." + "The default value is GLX_NONE.", + GLX_NONE }, + { GLX_TRANSPARENT_INDEX_VALUE, "GLX_TRANSPARENT_INDEX_VALUE", + "Must be followed by an integer value indicating the transparent index value; the value must be between 0 and the maximum " + "frame buffer value for indices. Only frame buffer configurations that use the " + "specified transparent index value will be considered. The default value is GLX_DONT_CARE. " + "This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in attrib_list and specified as GLX_TRANSPARENT_INDEX.", + GLX_DONT_CARE }, + { GLX_TRANSPARENT_RED_VALUE, "GLX_TRANSPARENT_RED_VALUE", + "Must be followed by an integer value indicating the transparent red value; the value must be between 0 and the maximum " + "frame buffer value for red. Only frame buffer configurations that use the specified transparent red value will be considered. " + "The default value is GLX_DONT_CARE. This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in " + "attrib_list and specified as GLX_TRANSPARENT_RGB.", + GLX_DONT_CARE }, + { GLX_TRANSPARENT_GREEN_VALUE, "GLX_TRANSPARENT_GREEN_VALUE", + "Must be followed by an integer value indicating the transparent green value; the value must be between 0 and the maximum " + "frame buffer value for green. Only frame buffer configurations that use the specified transparent green value will be considered." + "The default value is GLX_DONT_CARE. This attribute is " + "ignored unless GLX_TRANSPARENT_TYPE is included in attrib_list and specified as GLX_TRANSPARENT_RGB.", + GLX_DONT_CARE }, + { GLX_TRANSPARENT_BLUE_VALUE, "GLX_TRANSPARENT_BLUE_VALUE", + "Must be followed by an integer value indicating the transparent blue value; the value must be between 0 and the maximum " + "frame buffer value for blue. Only frame buffer configurations that use the specified transparent blue value will be considered." + "The default value is GLX_DONT_CARE. This attribute is ignored unless GLX_TRANSPARENT_TYPE is included in " + "attrib_list and specified as GLX_TRANSPARENT_RGB. ", + GLX_DONT_CARE }, + { GLX_TRANSPARENT_ALPHA_VALUE, "GLX_TRANSPARENT_ALPHA_VALUE", + "Must be followed by an integer value indicating the transparent alpha value; the value must be between 0 and the maximum " + "frame buffer value for alpha. Only frame buffer configurations that use the " + "specified transparent alpha value will be considered. The default value is GLX_DONT_CARE.", + GLX_DONT_CARE }, + { 0, NULL, NULL, -1 } +}; + +const char * get_attr_name( int val, int * pdef ) +{ + PPXATTS pat = &pxAtts[0]; + while( pat->name ) + { + if ( pat->attr == val ) { + *pdef = pat->def; + return pat->name; + } + pat++; + } + *pdef = -1; + return "VALUE NOT IN LIST"; +} + +#endif +// eof - RenderTexture.cpp