]> git.mxchange.org Git - simgear.git/blobdiff - simgear/screen/RenderTexture.cpp
Merge branch 'ehofman/sound'
[simgear.git] / simgear / screen / RenderTexture.cpp
index f45234c7360f371d9038bb8632f99b08d422b6ae..0b2b63590283de24ef72dfa71f2c3c92a74a8a3f 100644 (file)
@@ -1,4 +1,3 @@
-reateContext//
 // File : RenderTexture.cpp
 //---------------------------------------------------------------------------
 // Copyright (c) 2002-2004 Mark J. Harris
@@ -27,8 +26,11 @@ reateContext//
 // 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,22 @@ reateContext//
 * Implementation of class RenderTexture.  A multi-format render to 
 * texture wrapper.
 */
+#ifdef _MSC_VER
 #pragma warning(disable:4786)
+#endif
 
 /*
  * 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 <simgear_config.h>
 #endif
 
-#ifdef HAVE_WINDOWS_H
-#  include <windows.h>
-#endif
-
 #include <simgear/compiler.h>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/screen/extensions.hxx>
@@ -64,12 +65,36 @@ reateContext//
 #include <assert.h>
 #include <stdarg.h>
 
+#include <cstring>
+
 #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 +110,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 +138,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 +162,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 +191,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 +210,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 +233,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 +331,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 "
@@ -279,9 +347,9 @@ void PrintExtensionError( char* strMsg, ... )
     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 +367,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 +376,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 +528,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<nConfigs;i++)
         {
             _hPBuffer = glXCreatePbufferPtr(_pDisplay, fbConfigs[i], pbufAttrib);
@@ -497,6 +733,7 @@ bool RenderTexture::Initialize(int width, int height,
                                                True);
                 if (!_hGLContext)
                 {
+                    dbg_printf("RenderTexture Error: glXCreateContextPtr(_pDisplay, visInfo,..) FAILED! return false\n");
                     return false;
                 }
                 XFree( visInfo );
@@ -506,30 +743,42 @@ bool RenderTexture::Initialize(int width, int height,
     }
     else
     {
+#ifdef WIN32
         int iFormat = 0;
         int iNumFormats;
         int attrib = 0;
-        for (int i=0;i<nConfigs;i++)
+#endif
+        dbg_printf("RenderTexture::Initialize: glXVersion1_3Present = FALSE w=%d h=%d\n", _iWidth, _iHeight);
+        for (int i=0; i < nConfigs; i++)
         {
+             dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() get buffer ptr\n", (i + 1));
             _hPBuffer = glXCreateGLXPbufferPtr(_pDisplay, fbConfigs[i], 
-                                               _iWidth, _iHeight, NULL);
+                                               _iWidth, _iHeight,
+                                               &pbufAttrib[0] ); //NULL);
             if (_hPBuffer) 
             {
+                dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() got buffer [%p]\n", (i + 1), (void*)_hPBuffer);
                 _hGLContext = glXCreateContextWithConfigPtr(_pDisplay, 
                                                              fbConfigs[i], 
                                                              GLX_RGBA_TYPE, 
                                                              _bShareObjects ? context : NULL, 
                                                              True);
+                dbg_printf("RenderTexture::Initialize: %d: glXCreateContextWithConfigPtr() _hGLContext=[%p]\n", (i + 1), _hGLContext);
                 break;
+            } else {
+                dbg_printf("RenderTexture::Initialize: %d: glXCreateGLXPbufferPtr() NO buffer\n", (i + 1));
             }
         }
     }
+    
+    dbg_printf("RenderTexture::Initialize: doing XFree( fbConfigs=[%p].\n", fbConfigs);
     XFree( fbConfigs );
     
     if (!_hPBuffer)
     {
         SG_LOG(SG_GL, SG_ALERT, 
                 "RenderTexture Error: glXCreateGLXPbufferPtr() failed.");
+        dbg_printf("RenderTexture Error: glXCreateGLXPbufferPtr() failed.\n");
         return false;
     }
     
@@ -542,20 +791,29 @@ bool RenderTexture::Initialize(int width, int height,
         {
             SG_LOG(SG_GL, SG_ALERT, 
                     "RenderTexture Error: glXCreateContext() failed.");
+            dbg_printf("RenderTexture Error: glXCreateContext() failed. return false\n");
             return false;
         }
     }
     
-    if (!glXVersion1_3Present)
+    // if (!glXVersion1_3Present)
+    if ((!glXCreatePbufferPtr || !glXGetVisualFromFBConfigPtr || !glXCreateContextPtr) &&
+        (!glXVersion1_3Present))
     {
+#ifdef ADD_QUERY_BUFFER    
+        dbg_printf("RenderTexture::Initialize: Doing glXQueryGLXPbufferSGIXPtr with GLX_WIDTH_SGIX\n");
         glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_WIDTH_SGIX, 
                                   (GLuint*)&_iWidth);
+        dbg_printf("RenderTexture::Initialize: Doing glXQueryGLXPbufferSGIXPtr with GLX_HEIGHT_SGIX\n");
         glXQueryGLXPbufferSGIXPtr(_pDisplay, _hPBuffer, GLX_HEIGHT_SGIX, 
                                   (GLuint*)&_iHeight);
+#else
+        dbg_printf("RenderTexture::Initialize: SKIPPED doing glXQueryGLXPbufferSGIXPtr with GLX_WIDTH_SGIX and GLX_HEIGHT_SGIX\n");
+#endif // #ifdef ADD_QUERY_BUFFER    
     }
     
     _bInitialized = true;
-    
+    dbg_printf( "RenderTexture::Initialize: _bIniialized set TRUE\n" );
     // XXX Query the color format
     
 #endif
@@ -571,15 +829,34 @@ bool RenderTexture::Initialize(int width, int height,
         _wglGetLastError();
         return false;
     }
-#elif defined( __APPLE__ )
+#elif defined( __MACH__ )
+    CGLError err;
+    if (err = CGLSetCurrentContext(_hGLContext))
+    {
+        _cglCheckError(err);
+        return false;
+    }
 #else
+
+#ifdef ADD_GET_DRAWABLE
+     dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentContext()\n" );
     _hPreviousContext = glXGetCurrentContext();
+     dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentDrawable()\n" );
     _hPreviousDrawable = glXGetCurrentDrawable();
+#else
+    _hPreviousContext = context;
+    _hPreviousDrawable = 0;
+     dbg_printf( "RenderTexture::Initialize: SKIPPED doing glXGetCurrentContext(2nd) AND glXGetCurrentDrawable()\n" );
+#endif // #ifdef ADD_GET_DRAWABLE
     
+    dbg_printf( "RenderTexture::Initialize: doing glXMakeCurrent(_pDisplay(%p), _hPBuffer(%p), _hGLContext(%p))\n",
+       _pDisplay, (void*)_hPBuffer, _hGLContext );
     if (False == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext)) 
     {
+        dbg_printf( "glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext) FAILED. return false\n" );
         return false;
     }
+    
 #endif
     
     bool result = _InitializeTextures();   
@@ -596,21 +873,33 @@ bool RenderTexture::Initialize(int width, int height,
         _wglGetLastError();
         return false;
     }
-#elif defined( __APPLE__ )
+#elif defined( __MACH__ )
+    if (err = CGLSetCurrentContext(_hPreviousContext))
+    {
+        _cglCheckError(err);
+        return false;
+    }
 #else
     if (False == glXMakeCurrent(_pDisplay, 
                                 _hPreviousDrawable, _hPreviousContext))
     {
+        dbg_printf("glXMakeCurrent(_pDisplay, _hPreviousDrawable, _hPreviousContext)) FAILED! return false\n" );
         return false;
     }
+    
     if (glXVersion1_3Present)
+    //if ((glXVersion1_3Present) ||
+    //    (glXCreatePbufferPtr && glXGetVisualFromFBConfigPtr && glXCreateContextPtr && glXQueryDrawablePtr)) 
     {
+        dbg_printf( "RenderTexture::Initialize: doing glXGetCurrentDrawable()\n" );
         GLXDrawable draw = glXGetCurrentDrawable();
+        dbg_printf( "RenderTexture::Initialize: doing glXQueryDrawablePtr for GLX_WIDTH and GLX_HEIGHT\n" );
         glXQueryDrawablePtr(_pDisplay, draw, GLX_WIDTH, (unsigned int*)&_iWidth);
         glXQueryDrawablePtr(_pDisplay, draw, GLX_HEIGHT, (unsigned int*)&_iHeight);
     }
 #endif
 
+    dbg_printf( "RenderTexture::Initialize(w=%d,h=%d): returning %s\n", _iWidth, _iHeight, (result ? "TRUE" : "FALSE") );
     return result;
 }
 
@@ -626,6 +915,8 @@ bool RenderTexture::Initialize(int width, int height,
 */ 
 bool RenderTexture::_Invalidate()
 {
+    dbg_printf( "RenderTexture::_Invalidate() called...\n" );
+    
     _iNumColorBits[0] = _iNumColorBits[1] = 
         _iNumColorBits[2] = _iNumColorBits[3] = 0;
     _iNumDepthBits = 0;
@@ -654,7 +945,17 @@ bool RenderTexture::_Invalidate()
         _hPBuffer = 0;
         return true;
     }
-#elif defined( __APPLE__ )
+#elif defined( __MACH__ )
+    if ( _hPBuffer )
+    {
+        if (CGLGetCurrentContext() == _hGLContext)
+            CGLSetCurrentContext(NULL);
+        if (!_bCopyContext)
+            CGLDestroyContext(_hGLContext);
+        CGLDestroyPBuffer(_hPBuffer);
+        _hPBuffer = NULL;
+        return true;
+    }
 #else
     if ( _hPBuffer )
     {
@@ -663,10 +964,12 @@ bool RenderTexture::_Invalidate()
             glXMakeCurrent(_pDisplay, _hPBuffer, 0);
         glXDestroyPbufferPtr(_pDisplay, _hPBuffer);
         _hPBuffer = 0;
+       dbg_printf( "RenderTexture::_Invalidate: glXDestroyPbufferPtr(_pDisplay, _hPBuffer); return true\n" );
         return true;
     }
 #endif
 
+    dbg_printf( "RenderTexture::_Invalidate: return false\n" );
     // [WVB] do we need to call _ReleaseBoundBuffers() too?
     return false;
 }
@@ -685,10 +988,12 @@ bool RenderTexture::_Invalidate()
 */ 
 bool RenderTexture::Reset(const char *strMode, ...)
 {
+   dbg_printf("RenderTexure:Reset(): with %s\n", strMode);
+   
     _iWidth = 0; _iHeight = 0; 
     _bIsTexture = false; _bIsDepthTexture = false,
     _bHasARBDepthTexture = true;
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__MACH__)
     _eUpdateMode = RT_RENDER_TO_TEXTURE;
 #else
     _eUpdateMode = RT_COPY_TO_TEXTURE;
@@ -707,11 +1012,21 @@ bool RenderTexture::Reset(const char *strMode, ...)
     _pPoorDepthTexture = 0;
     _pixelFormatAttribs.clear();
     _pbufferAttribs.clear();
-
-    if (IsInitialized() && !_Invalidate())
+    if (IsInitialized())
     {
-        SG_LOG(SG_GL, SG_ALERT, "RenderTexture::Reset(): failed to invalidate.");
+      if (!_Invalidate())
+      {
+        dbg_printf( "RenderTexture::Reset(): failed to invalidate. return false\n");
         return false;
+      }
+      else
+      {
+        dbg_printf( "RenderTexture::Reset(): was Initialized, and now _Invalidate() ok.");
+      }
+    }
+    else
+    {
+      dbg_printf("RenderTexure:Reset(): previous NOT initialised!\n");
     }
     
     _iNumColorBits[0] = _iNumColorBits[1] = 
@@ -725,7 +1040,11 @@ bool RenderTexture::Reset(const char *strMode, ...)
     
     _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
     _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
     _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
@@ -748,9 +1067,12 @@ bool RenderTexture::Reset(const char *strMode, ...)
 #ifdef _WIN32
     _pixelFormatAttribs.push_back(0);
     _pbufferAttribs.push_back(0);
+#elif defined(__MACH__)
+    _pixelFormatAttribs.push_back((CGLPixelFormatAttribute)0);
 #else
     _pixelFormatAttribs.push_back(None);
 #endif
+    dbg_printf("RenderTexure:Reset(): returning true.\n");
     return true;
 }
 
@@ -795,7 +1117,17 @@ bool RenderTexture::Resize(int iWidth, int iHeight)
         _hPBuffer = 0;
         return true;
     }
-#elif defined( __APPLE__ )
+#elif defined( __MACH__ )
+    if ( _hPBuffer )
+    {
+        if (CGLGetCurrentContext() == _hGLContext)
+            CGLSetCurrentContext(NULL);
+        if (!_bCopyContext)
+            CGLDestroyContext(_hGLContext);
+        CGLDestroyPBuffer(_hPBuffer);
+        _hPBuffer = NULL;
+        return true;
+    }
 #else
     if ( _hPBuffer )
     {
@@ -838,7 +1170,8 @@ bool RenderTexture::BeginCapture()
     _hPreviousContext = wglGetCurrentContext();
     if (NULL == _hPreviousContext)
         _wglGetLastError();
-#elif defined( __APPLE__ )
+#elif defined( __MACH__ )
+    _hPreviousContext = CGLGetCurrentContext();
 #else
     _hPreviousContext = glXGetCurrentContext();
     _hPreviousDrawable = glXGetCurrentDrawable();
@@ -867,6 +1200,8 @@ bool RenderTexture::EndCapture()
         return false;
     }
 
+    glFlush(); // Added by a-lex
+
     _MaybeCopyBuffer();
 
 #ifdef _WIN32
@@ -876,7 +1211,13 @@ bool RenderTexture::EndCapture()
         _wglGetLastError();
         return false;
     }
-#elif defined( __APPLE__ )
+#elif defined( __MACH__ )
+    CGLError err;
+    if (err = CGLSetCurrentContext(_hPreviousContext))
+    {
+            _cglCheckError(err);
+            return false;
+    }
 #else
     if (False == glXMakeCurrent(_pDisplay, _hPreviousDrawable, 
                                 _hPreviousContext))
@@ -912,7 +1253,7 @@ bool RenderTexture::EndCapture()
  */ 
 bool RenderTexture::BeginCapture(RenderTexture* current)
 {
-    bool bContextReset = false;
+    // bool bContextReset = false;
     
     if (current == this) {
         return true; // no switch necessary
@@ -946,7 +1287,8 @@ bool RenderTexture::BeginCapture(RenderTexture* current)
     _hPreviousContext = current->_hPreviousContext;
     if (NULL == _hPreviousContext)
         _wglGetLastError();
-#elif defined( __APPLE__ )
+#elif defined( __MACH__ )
+    _hPreviousContext = current->_hPreviousContext;
 #else
     _hPreviousContext = current->_hPreviousContext;
     _hPreviousDrawable = current->_hPreviousDrawable;
@@ -1033,6 +1375,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 +1394,7 @@ bool RenderTexture::BindBuffer( int iBuffer )
 
 
 //---------------------------------------------------------------------------
-// Function            : RenderTexture::BindBuffer
+// Function            : RenderTexture::BindDepthBuffer
 // Description     : 
 //---------------------------------------------------------------------------
 /**
@@ -1060,6 +1414,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 +1441,12 @@ void RenderTexture::_ParseModeString(const char *modeString,
                                      vector<int> &pfAttribs, 
                                      vector<int> &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 +1468,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 +1496,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 +1519,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 +1551,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 +1561,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 +1583,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 +1601,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 +1617,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 +1641,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 +1661,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 +1683,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 +1706,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 +1731,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 +1749,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 +1769,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 +1791,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 +1830,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 +1842,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 +1867,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 +1883,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 +1913,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 +1943,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 +1967,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 +2032,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 +2081,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 +2205,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 +2283,7 @@ vector<int> 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 +2335,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 +2362,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 : "<NULL>") );
+    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 +2411,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 +2440,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 +2478,7 @@ bool RenderTexture::_VerifyExtensions()
     }
 #endif
   
+    dbg_printf("RenderTexture::_VerifyExtensions: return true.\n");
     return true;
 }
 
@@ -1886,11 +2492,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 +2530,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 +2594,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 +2654,7 @@ bool RenderTexture::_InitializeTextures()
         }
     }
 
+    dbg_printf( "RenderTexture::_InitializeTextures() returning true\n" );
     return true;
 }
 
@@ -2088,6 +2702,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 +2786,6 @@ bool RenderTexture::_ReleaseBoundBuffers()
 * @fn RenderTexture::_MakeCurrent()
 * @brief Makes the RenderTexture's context current
 */ 
-
 bool RenderTexture::_MakeCurrent() 
 {
 #ifdef _WIN32
@@ -2167,14 +2795,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 +2847,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 +2860,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 +2881,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 +2919,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 +2952,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 +2961,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 +2982,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 +2999,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 +3026,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