nux-1.14.0
|
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 }