nux-1.16.0
IOpenGLSurface.cpp
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #include "GLResource.h"
00024 #include "GraphicsDisplay.h"
00025 #include "GpuDevice.h"
00026 #include "GLDeviceObjects.h"
00027 #include "IOpenGLSurface.h"
00028 
00029 namespace nux
00030 {
00031 
00032   NUX_IMPLEMENT_OBJECT_TYPE (IOpenGLSurface);
00033 
00034   IOpenGLSurface::~IOpenGLSurface()
00035   {
00036 
00037   }
00038 
00039   int IOpenGLSurface::RefCount() const
00040   {
00041     if (_BaseTexture)
00042       return _BaseTexture->RefCount();
00043 
00044     nuxAssert (0); // Surface with no underlying texture. That should not happen.
00045     return 0;
00046   }
00047 
00048   int IOpenGLSurface::LockRect (
00049     SURFACE_LOCKED_RECT *pLockedRect,
00050     const SURFACE_RECT *pRect)
00051   {
00052     // If _LockedRect.pBits or _LockedRect.Pitch are not equal to zero, then we have already Locked the buffer
00053     // Unlock it before locking again.
00054     nuxAssert (_LockedRect.pBits == 0);
00055     nuxAssert (_LockedRect.Pitch == 0);
00056     nuxAssert (_CompressedDataSize == 0);
00057 
00058     if ( (_LockedRect.pBits != 0) || (_LockedRect.Pitch != 0) || (_CompressedDataSize != 0) )
00059     {
00060       // already locked;
00061       return OGL_INVALID_LOCK;
00062     }
00063 
00064     _Rect.bottom = _Rect.left = _Rect.right = _Rect.top = 0;
00065 
00066     GLint unpack_alignment = GPixelFormats[_BaseTexture->_PixelFormat].RowMemoryAlignment;
00067     unsigned int halfUnpack = Log2 (unpack_alignment);
00068 
00069     CHECKGL ( glBindTexture (_STextureTarget, _BaseTexture->_OpenGLID) );
00070 
00071     unsigned int surface_size = 0;
00072     unsigned int BytePerPixel = 0;
00073 
00074     IOpenGLBaseTexture *texture = _BaseTexture;
00075 
00076     if (!((_BaseTexture->_ResourceType == RTTEXTURE) ||
00077           (_BaseTexture->_ResourceType == RTTEXTURERECTANGLE) ||
00078           (_BaseTexture->_ResourceType == RTCUBETEXTURE) ||
00079           (_BaseTexture->_ResourceType == RTVOLUMETEXTURE) ||
00080           (_BaseTexture->_ResourceType == RTANIMATEDTEXTURE)))
00081     {
00082       nuxAssertMsg (0, TEXT ("Unknown resource type") );
00083     }
00084 
00085     int texwidth, texheight;
00086     texwidth = ImageSurface::GetLevelDim (texture->_PixelFormat, texture->_Width, _SMipLevel);
00087     texheight = ImageSurface::GetLevelDim (texture->_PixelFormat, texture->_Height, _SMipLevel);
00088 
00089     if ( texture->_PixelFormat == BITFMT_DXT1 ||
00090          texture->_PixelFormat == BITFMT_DXT2 ||
00091          texture->_PixelFormat == BITFMT_DXT3 ||
00092          texture->_PixelFormat == BITFMT_DXT4 ||
00093          texture->_PixelFormat == BITFMT_DXT5)
00094     {
00095       if (texture->_PixelFormat == BITFMT_DXT1)
00096       {
00097         // We can conceive a 4x4 DXT1 block as if each texel uses 4 bits.
00098         // Actually, for DXT, we have 2 16-bits colors(5:6:5), and each texel uses 2 bits to interpolate
00099         // between the 2 colors.
00100         //    ---------------------
00101         //    |      COLOR0       | 16 bits
00102         //    ---------------------
00103         //    |      COLOR1       | 16 bits
00104         //    ---------------------
00105         //    | xx | xx | xx | xx | xx = 2 bits
00106         //    ---------------------
00107         //    | xx | xx | xx | xx |
00108         //    ---------------------
00109         //    | xx | xx | xx | xx |
00110         //    ---------------------
00111         //    | xx | xx | xx | xx |
00112         //    ---------------------
00113 
00114         // A line of n texel DXT1 data uses n/2 bytes (4 bits/texel). So the number of bytes used for a
00115         // texwidth texel, is texwidth/2 bytes.
00116         // Note that texwidth is divisible by 4(to to the upper rounding to 4), therefore, it is also divisible
00117         // by 2.
00118 
00119         // glCompressedTexImage2DARB, glCompressedTexImage3DARB,
00120         // glCompressedTexSubImage2DARB, glCompressedTexSubImage3DARB are not affected by glPixelStorei.
00121         surface_size = ImageSurface::GetLevelSize (texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel);
00122         _CompressedDataSize = surface_size;
00123         _LockedRect.Pitch = ImageSurface::GetLevelPitch (texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel);
00124 
00125         if (_Initialized == false)
00126         {
00127           InitializeLevel();
00128         }
00129       }
00130       else
00131       {
00132         // A line of n texel DXT3/5 data uses n bytes (1 byte/texel). So the number of bytes used for a
00133         // texwidth texels, is texwidth bytes.
00134 
00135         // glCompressedTexImage2DARB, glCompressedTexImage3DARB,
00136         // glCompressedTexSubImage2DARB, glCompressedTexSubImage3DARB are not affected by glPixelStorei.
00137         surface_size = ImageSurface::GetLevelSize (texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel);
00138         _CompressedDataSize = surface_size;
00139         _LockedRect.Pitch = ImageSurface::GetLevelPitch (texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel);
00140 
00141         if (_Initialized == false)
00142         {
00143           InitializeLevel();
00144         }
00145       }
00146     }
00147     else
00148     {
00149       _LockedRect.Pitch = ImageSurface::GetLevelPitch (texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel);
00150       surface_size = ImageSurface::GetLevelSize (texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel);
00151 
00152       if (_Initialized == false)
00153       {
00154         InitializeLevel();
00155       }
00156     }
00157 
00158     _Rect.left  = 0;
00159     _Rect.top   = 0;
00160     _Rect.bottom  = texheight;
00161     _Rect.right   = texwidth;
00162 
00163 
00164     if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects() )
00165     {
00166       GetGraphicsDisplay()->GetGpuDevice()->AllocateUnpackPixelBufferIndex (&_AllocatedUnpackBuffer);
00167     }
00168 
00169     if (pRect == 0)
00170     {
00171       if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects() )
00172       {
00173         // Mapping the entire area of the surface
00174         _LockedRect.pBits = GetGraphicsDisplay()->GetGpuDevice()->LockUnpackPixelBufferIndex (_AllocatedUnpackBuffer, surface_size);
00175         pLockedRect->pBits = _LockedRect.pBits;
00176         pLockedRect->Pitch = _LockedRect.Pitch;
00177       }
00178       else
00179       {
00180         //[DEBUGGING - NO PBO]
00181         // Mapping the entire area of the surface
00182         _LockedRect.pBits = new BYTE[surface_size];
00183         pLockedRect->pBits = _LockedRect.pBits;
00184         pLockedRect->Pitch = _LockedRect.Pitch;
00185       }
00186     }
00187     else
00188     {
00189       //[WARNING]
00190       // this section of code is suppose to handle rectangles that are not the size of the entire surface.
00191       // It works for uncompressed texture. However it hasn't been tested for compressed texture.
00192 
00193       // reserve and lock a surface size equal  to (RectWidth * RectHeight * BytePerPixel)
00194       int RectWidth = pRect->right - pRect->left;
00195       int RectHeight = pRect->bottom - pRect->top;
00196 
00197       nuxAssert (RectWidth >= 0);
00198       nuxAssert (RectHeight >= 0);
00199 
00200 
00201       unsigned int RectSize = ( ( (RectWidth * BytePerPixel + (unpack_alignment - 1) ) >> (halfUnpack) ) << (halfUnpack) ) * RectHeight;
00202 
00203       if (RectSize == 0)
00204       {
00205         pLockedRect->pBits = 0;
00206         pLockedRect->Pitch = 0;
00207         return OGL_INVALID_LOCK;
00208       }
00209 
00210       if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects() )
00211       {
00212         _LockedRect.pBits = GetGraphicsDisplay()->GetGpuDevice()->LockUnpackPixelBufferIndex (_AllocatedUnpackBuffer, RectSize);
00213         pLockedRect->pBits = ( (BYTE *) _LockedRect.pBits);
00214         pLockedRect->Pitch = ( ( (RectWidth * BytePerPixel + (unpack_alignment - 1) ) >> (halfUnpack) ) << (halfUnpack) );
00215       }
00216       else
00217       {
00218         //[DEBUGGING - NO PBO]
00219         _LockedRect.pBits = new BYTE[RectSize];
00220         pLockedRect->pBits = ( (BYTE *) _LockedRect.pBits);
00221         pLockedRect->Pitch = ( ( (RectWidth * BytePerPixel + (unpack_alignment - 1) ) >> (halfUnpack) ) << (halfUnpack) );
00222       }
00223 
00224       _Rect.left  = pRect->left;
00225       _Rect.top   = pRect->top;
00226       _Rect.bottom  = pRect->bottom;
00227       _Rect.right   = pRect->right;
00228     }
00229 
00230     return OGL_OK;
00231   }
00232 
00233   int IOpenGLSurface::UnlockRect()
00234   {
00235     if (_LockedRect.pBits == 0)
00236     {
00237       return OGL_INVALID_UNLOCK;
00238     }
00239 
00240     CHECKGL ( glPixelStorei (GL_UNPACK_ALIGNMENT, _BaseTexture->GetFormatRowMemoryAlignment() ) );
00241 
00242     BYTE *DataPtr = 0;
00243 
00244     if (_STextureTarget == GL_TEXTURE_2D || _STextureTarget == GL_TEXTURE_RECTANGLE_ARB || _STextureTarget == GL_TEXTURE_CUBE_MAP || _STextureTarget == GL_TEXTURE_3D)
00245     {
00246       int w = _Rect.right - _Rect.left;
00247       int h = _Rect.bottom - _Rect.top;
00248       CHECKGL ( glBindTexture (_STextureTarget, _BaseTexture->_OpenGLID) );
00249 
00250       if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects() )
00251       {
00252         // Unmap the texture image buffer
00253         GetGraphicsDisplay()->GetGpuDevice()->BindUnpackPixelBufferIndex (_AllocatedUnpackBuffer);
00254         CHECKGL ( glUnmapBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB) );
00255         DataPtr = NUX_BUFFER_OFFSET (0);
00256       }
00257       else
00258       {
00259         CHECKGL ( glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB, 0) );
00260         DataPtr = (BYTE *) _LockedRect.pBits;
00261       }
00262 
00263       IOpenGLTexture2D *texture = (IOpenGLTexture2D *) _BaseTexture;
00264 
00265       if ( /*texture->_PixelFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||*/
00266         texture->_PixelFormat == BITFMT_DXT1 ||
00267         texture->_PixelFormat == BITFMT_DXT2 ||
00268         texture->_PixelFormat == BITFMT_DXT3 ||
00269         texture->_PixelFormat == BITFMT_DXT4 ||
00270         texture->_PixelFormat == BITFMT_DXT5)
00271       {
00272         nuxAssert (_CompressedDataSize != 0);
00273         int width = Max<int> (1, texture->_Width >> _SMipLevel);
00274         int height = Max<int> (1, texture->_Height >> _SMipLevel);
00275 
00276         int xoffset = _Rect.left;
00277         int yoffset = _Rect.top;
00278 
00279         if (_STextureTarget != GL_TEXTURE_3D)
00280         {
00281           glCompressedTexSubImage2DARB (_SSurfaceTarget,
00282                                         _SMipLevel,                 // level
00283                                         xoffset,
00284                                         yoffset,
00285                                         width,
00286                                         height,
00287                                         GPixelFormats[texture->_PixelFormat].PlatformFormat,
00288                                         _CompressedDataSize,        // image Size
00289                                         DataPtr                     // data
00290                                        );
00291           CHECKGL_MSG (glCompressedTexSubImage2DARB);
00292         }
00293         else
00294         {
00295           glCompressedTexSubImage3DARB (_SSurfaceTarget,
00296                                         _SMipLevel,                 // level
00297                                         xoffset,
00298                                         yoffset,
00299                                         0,
00300                                         width,
00301                                         height,
00302                                         _SSlice,
00303                                         GPixelFormats[texture->_PixelFormat].PlatformFormat,
00304                                         _CompressedDataSize,        // image Size
00305                                         DataPtr                     // data
00306                                        );
00307           CHECKGL_MSG (glCompressedTexSubImage3DARB);
00308         }
00309 
00310         // We can use glCompressedTexImage2DARB if we are sure we always lock
00311         // the entire area of the surface.
00312         //            glCompressedTexImage2DARB(_SSurfaceTarget,
00313         //                _SMipLevel,                 // level
00314         //                texture->_Format,
00315         //                width,
00316         //                height,
00317         //                0,                          // border
00318         //                _CompressedDataSize,        // image Size
00319         //                _LockedRect.pBits           // data
00320         //                );
00321         //            CHECKGL_MSG(glCompressedTexImage2DARB);
00322 
00323 
00324         //            { //[DEBUGGING - Red Texture]
00325         //                // This is going to put some red in the texture.
00326         //                // The texture is not compressed.
00327         //                BYTE *color_array = new BYTE[width*height*4];
00328         //                for(int i = 0; i < width*height*4; i += 4)
00329         //                {
00330         //                    color_array[i + 0] = 0xff;
00331         //                    color_array[i + 1] = _SMipLevel * 0x3F;
00332         //                    color_array[i + 2] = 0x0;
00333         //                    color_array[i + 3] = 0xFF;
00334         //                }
00335         //                glTexImage2D(GL_TEXTURE_2D,
00336         //                    _SMipLevel,
00337         //                    GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, color_array);
00338         //                CHECKGL_MSG(glTexImage2D);
00339         //                delete [] color_array;
00340         //            }
00341       }
00342       else
00343       {
00344         //CHECKGL( glPixelStorei(GL_UNPACK_ROW_LENGTH, w) );
00345         if (_STextureTarget != GL_TEXTURE_3D)
00346         {
00347           CHECKGL ( glTexSubImage2D (_SSurfaceTarget,
00348                                      _SMipLevel,
00349                                      _Rect.left,
00350                                      _Rect.top,
00351                                      w,
00352                                      h,
00353                                      GPixelFormats[texture->_PixelFormat].Format,
00354                                      GPixelFormats[texture->_PixelFormat].type,
00355                                      DataPtr
00356                                     ) );
00357         }
00358         else
00359         {
00360           CHECKGL ( glTexSubImage3D (_SSurfaceTarget,
00361                                      _SMipLevel,
00362                                      _Rect.left,
00363                                      _Rect.top,
00364                                      _SSlice,          // z offset
00365                                      w,
00366                                      h,
00367                                      1,
00368                                      GPixelFormats[texture->_PixelFormat].Format,
00369                                      GPixelFormats[texture->_PixelFormat].type,
00370                                      DataPtr
00371                                     ) );
00372         }
00373 
00374         //CHECKGL( glPixelStorei(GL_UNPACK_ROW_LENGTH, 0) );
00375 
00376         //            CHECKGL( glTexImage2D(_SSurfaceTarget,
00377         //                _SMipLevel,
00378         //                GPixelFormats[texture->_PixelFormat].PlatformFormat,
00379         //                w,
00380         //                h,
00381         //                0,
00382         //                //### todo:
00383         //                //  - find the correct format matching the internal format
00384         //                //  - find the correct type matching the internal format
00385         //                GPixelFormats[texture->_PixelFormat].Format,
00386         //                GPixelFormats[texture->_PixelFormat].type,
00387         //                DataPtr
00388         //                ) );
00389 
00390       }
00391     }
00392     else
00393     {
00394       nuxDebugMsg (TEXT("[IOpenGLSurface::UnlockRect] Incorrect Texture Target."));
00395     }
00396 
00397     if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects() )
00398     {
00399       CHECKGL ( glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB, 0) );
00400       GetGraphicsDisplay()->GetGpuDevice()->FreeUnpackPixelBufferIndex (_AllocatedUnpackBuffer);
00401     }
00402     else
00403     {
00404       //[DEBUGGING - NO PBO]
00405       if (_LockedRect.pBits)
00406       {
00407         delete [] ( (BYTE *) _LockedRect.pBits);
00408       }
00409     }
00410 
00411     CHECKGL ( glPixelStorei (GL_UNPACK_ALIGNMENT, GetGraphicsDisplay()->GetGpuDevice()->GetPixelStoreAlignment() ) );
00412 
00413     _LockedRect.pBits = 0;
00414     _LockedRect.Pitch = 0;
00415     _CompressedDataSize = 0;
00416 
00417     return OGL_OK;
00418   }
00419 
00420   int IOpenGLSurface::InitializeLevel()
00421   {
00422     // Because we use SubImage when unlocking surfaces, we must first get some dummy data in the surface before we can make a lock.
00423     int texwidth = ImageSurface::GetLevelWidth (_BaseTexture->_PixelFormat, _BaseTexture->_Width, _SMipLevel);
00424     int texheight = ImageSurface::GetLevelHeight (_BaseTexture->_PixelFormat, _BaseTexture->_Height, _SMipLevel);
00425     int size = ImageSurface::GetLevelSize (_BaseTexture->_PixelFormat, _BaseTexture->_Width, _BaseTexture->_Height, _SMipLevel);
00426     int MemAlignment = ImageSurface::GetMemAlignment (_BaseTexture->_PixelFormat);
00427 
00428     nuxAssert ( texwidth > 0 ); // Should never happen
00429     nuxAssert ( texheight > 0 ); // Should never happen
00430     nuxAssert ( size > 0 ); // Should never happen
00431 
00432     BYTE *DummyBuffer = (BYTE *) calloc (size, sizeof(BYTE));
00433 
00434     CHECKGL ( glPixelStorei (GL_UNPACK_ALIGNMENT, MemAlignment) );
00435 
00436     if ( _BaseTexture->_PixelFormat == BITFMT_DXT1 ||
00437          _BaseTexture->_PixelFormat == BITFMT_DXT2 ||
00438          _BaseTexture->_PixelFormat == BITFMT_DXT3 ||
00439          _BaseTexture->_PixelFormat == BITFMT_DXT4 ||
00440          _BaseTexture->_PixelFormat == BITFMT_DXT5)
00441     {
00442       if (_STextureTarget != GL_TEXTURE_3D)
00443       {
00444         glCompressedTexImage2DARB (
00445           _SSurfaceTarget,
00446           _SMipLevel,                 // level
00447           GPixelFormats[_BaseTexture->_PixelFormat].PlatformFormat,
00448           texwidth,
00449           texheight,
00450           0,                          // border
00451           size,                       // image Size
00452           DummyBuffer                           // data
00453         );
00454         CHECKGL_MSG (glCompressedTexImage2DARB);
00455       }
00456       else
00457       {
00458         //             glCompressedTexImage3DARB(
00459         //                 _SSurfaceTarget,
00460         //                 _SMipLevel,                 // level
00461         //                 GPixelFormats[_BaseTexture->_PixelFormat].PlatformFormat,
00462         //                 texwidth,
00463         //                 texheight,
00464         //                 _SSlice,
00465         //                 0,                          // border
00466         //                 size,                       // image Size
00467         //                 DummyBuffer                           // data
00468         //                 );
00469         //             CHECKGL_MSG(glCompressedTexImage3DARB);
00470       }
00471     }
00472     else
00473     {
00474       if (_STextureTarget != GL_TEXTURE_3D)
00475       {
00476         glTexImage2D (
00477           _SSurfaceTarget,
00478           _SMipLevel,                 // level
00479           GPixelFormats[_BaseTexture->_PixelFormat].PlatformFormat,
00480           texwidth,
00481           texheight,
00482           0,                          // border
00483           GPixelFormats[_BaseTexture->_PixelFormat].Format,
00484           GPixelFormats[_BaseTexture->_PixelFormat].type,
00485           DummyBuffer);
00486         CHECKGL_MSG (glTexImage2D);
00487       }
00488       else
00489       {
00490         //             glTexImage3D(
00491         //                 _SSurfaceTarget,
00492         //                 _SMipLevel,                 // level
00493         //                 GPixelFormats[PixelFormat].PlatformFormat,
00494         //                 texwidth,
00495         //                 texheight,
00496         //                 _SSlice,
00497         //                 0,                          // border
00498         //                 GPixelFormats[PixelFormat].Format,
00499         //                 GPixelFormats[PixelFormat].type,
00500         //                 DummyBuffer);
00501         //             CHECKGL_MSG(glTexImage3D);
00502       }
00503     }
00504 
00505     free (DummyBuffer);
00506 
00507 
00508     //    { //[DEBUGGING - Red Texture]
00509     //        // This is going to put some red in the texture.
00510     //        // The texture is not compressed.
00511     //        BYTE *color_array = new BYTE[texwidth*texheight*4];
00512     //        for(unsigned int i = 0; i < texwidth*texheight*4; i += 4)
00513     //        {
00514     //            color_array[i + 0] = 0xff;
00515     //            color_array[i + 1] = _SMipLevel * 0x3F;
00516     //            color_array[i + 2] = 0x0;
00517     //            color_array[i + 3] = 0xFF;
00518     //        }
00519     //        glTexImage2D(GL_TEXTURE_2D,
00520     //            _SMipLevel,
00521     //            GL_RGBA8, texwidth, texheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, color_array);
00522     //        CHECKGL_MSG(glTexImage2D);
00523     //        delete [] color_array;
00524     //    }
00525 
00526     CHECKGL (glPixelStorei (GL_UNPACK_ALIGNMENT, GetGraphicsDisplay()->GetGpuDevice()->GetPixelStoreAlignment()));
00527 
00528     _Initialized = true;
00529     return OGL_OK;
00530   }
00531 
00532   void IOpenGLSurface::CopyRenderTarget (int x, int y, int width, int height)
00533   {
00534     CHECKGL (glPixelStorei (GL_UNPACK_ALIGNMENT, _BaseTexture->GetFormatRowMemoryAlignment ()));
00535 
00536     if (_STextureTarget == GL_TEXTURE_2D || _STextureTarget == GL_TEXTURE_RECTANGLE_ARB || _STextureTarget == GL_TEXTURE_CUBE_MAP || _STextureTarget == GL_TEXTURE_3D)
00537     {
00538       CHECKGL ( glBindTexture (_STextureTarget, _BaseTexture->_OpenGLID) );
00539 
00540 
00541 #ifndef NUX_OPENGLES_20
00542       if (_STextureTarget != GL_TEXTURE_3D)
00543       {
00544         CHECKGL (glCopyTexImage2D (_SSurfaceTarget,
00545           _SMipLevel,
00546           GPixelFormats [_BaseTexture->_PixelFormat].Format,
00547           x,
00548           y,
00549           width,
00550           height,
00551           0));
00552       }
00553       else
00554       {
00555         CHECKGL (glCopyTexSubImage3D (_SSurfaceTarget,
00556           _SMipLevel,
00557           0,
00558           0,
00559           0,
00560           x,
00561           y,
00562           width,
00563           height));
00564       }
00565 #else
00566       if (_STextureTarget != GL_TEXTURE_3D)
00567       {
00568         CHECKGL (glCopyTexImage2D (_SSurfaceTarget,
00569           _SMipLevel,
00570           GPixelFormats [texture->_PixelFormat].Format,
00571           x,
00572           y,
00573           width,
00574           height,
00575           0));
00576       }
00577 #endif
00578     }
00579   }
00580 
00581   void* IOpenGLSurface::GetSurfaceData (int &width, int &height, int &format)
00582   {
00583     width = 0;
00584     height = 0;
00585     format = BITFMT_UNKNOWN;
00586 
00587     // Because we use SubImage when unlocking surfaces, we must first get some dummy data in the surface before we can make a lock.
00588     int texwidth = ImageSurface::GetLevelWidth (_BaseTexture->_PixelFormat, _BaseTexture->_Width, _SMipLevel);
00589     int texheight = ImageSurface::GetLevelHeight (_BaseTexture->_PixelFormat, _BaseTexture->_Height, _SMipLevel);
00590 
00591     nuxAssert (texwidth > 0); // Should never happen
00592     nuxAssert (texheight > 0); // Should never happen
00593 
00594     CHECKGL (glBindTexture (_STextureTarget, _BaseTexture->_OpenGLID));
00595 
00596     CHECKGL (glPixelStorei (GL_PACK_ALIGNMENT, 1));
00597     int size = texwidth * texheight * 4; // assume a memory alignment of 1
00598 
00599     unsigned char *img = new unsigned char [size];
00600 
00601     CHECKGL (glGetTexImage (_STextureTarget, _SMipLevel, GL_RGBA, GL_UNSIGNED_BYTE, img));
00602 
00603     width = _BaseTexture->_Width;
00604     height = _BaseTexture->_Height;
00605     format = BITFMT_R8G8B8A8;
00606     return img;
00607   }
00608 
00609 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends