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 "GLResourceManager.h" 00025 #include "GpuDevice.h" 00026 #include "GraphicsEngine.h" 00027 #include "GLTextureResourceManager.h" 00028 00029 namespace nux 00030 { 00031 00032 NUX_IMPLEMENT_OBJECT_TYPE (BaseTexture); 00033 NUX_IMPLEMENT_OBJECT_TYPE (Texture2D); 00034 NUX_IMPLEMENT_OBJECT_TYPE (TextureRectangle); 00035 NUX_IMPLEMENT_OBJECT_TYPE (TextureCube); 00036 NUX_IMPLEMENT_OBJECT_TYPE (TextureVolume); 00037 NUX_IMPLEMENT_OBJECT_TYPE (TextureFrameAnimation); 00038 00039 NUX_IMPLEMENT_OBJECT_TYPE (CachedBaseTexture); 00040 NUX_IMPLEMENT_OBJECT_TYPE (CachedTexture2D); 00041 NUX_IMPLEMENT_OBJECT_TYPE (CachedTextureRectangle); 00042 NUX_IMPLEMENT_OBJECT_TYPE (CachedTextureCube); 00043 NUX_IMPLEMENT_OBJECT_TYPE (CachedTextureVolume); 00044 NUX_IMPLEMENT_OBJECT_TYPE (CachedTextureFrameAnimation); 00045 00052 template < class T, class U > 00053 static T *UpCastResource (U *Src) 00054 { 00055 if (!Src || !Src->Type().IsDerivedFromType (T::StaticObjectType)) 00056 nuxError (TEXT ("[UpCastResource] Cast of %s to %s failed"), U::StaticObjectType.name, T::StaticObjectType.name); 00057 00058 return (T *) Src; 00059 } 00060 00061 BaseTexture *CreateTexture2DFromPixbuf (GdkPixbuf *pixbuf, bool premultiply) 00062 { 00063 const unsigned int rowstride = gdk_pixbuf_get_rowstride (pixbuf); 00064 const unsigned int width = gdk_pixbuf_get_width (pixbuf); 00065 const unsigned int height = gdk_pixbuf_get_height (pixbuf); 00066 00067 // Put the RGB or RGBA pixels in a RGBA texture data object taking care 00068 // of alpha premultiplication if requested. 00069 // FIXME(loicm) Implies a useless copy. NTextureData should be able to 00070 // take ownership of pre-allocated memory. 00071 // FIXME(loicm) Add support for big-endian systems. For performance 00072 // reasons, pixels are loaded by block of 4 bytes with the color 00073 // components bit-shifted considering little-endian ordering. Nux 00074 // doesn't seem to be big-endian aware anyway. 00075 // FIXME(loicm) Surface::Write32b does branching, splits the 32-bit value 00076 // as four 8-bit values (using bit-shifts) that are then stored 00077 // separately, that's slow considering it's meant to be used a lot in 00078 // deep loops. 00079 NTextureData *data = new NTextureData (BITFMT_R8G8B8A8, width, height, 1); 00080 ImageSurface &surface = data->GetSurface (0); 00081 if (gdk_pixbuf_get_has_alpha (pixbuf) == TRUE) 00082 { 00083 unsigned char *pixels_u8 = gdk_pixbuf_get_pixels (pixbuf); 00084 unsigned int *pixels_u32 = reinterpret_cast<unsigned int *> (pixels_u8); 00085 00086 if (premultiply == true) 00087 { 00088 // Copy from pixbuf (RGBA) to surface (premultiplied RGBA). 00089 for (unsigned int i = 0; i < height; i++) 00090 { 00091 for (unsigned int j = 0; j < width; j++) 00092 { 00093 const unsigned int pixel = pixels_u32[j]; 00094 const unsigned int a = pixel >> 24; 00095 if (a == 0) 00096 surface.Write32b (j, i, 0); 00097 else 00098 { 00099 const unsigned int b = (((pixel >> 16) & 0xff) * a) / 255; 00100 const unsigned int g = (((pixel >> 8) & 0xff) * a) / 255; 00101 const unsigned int r = ((pixel & 0xff) * a) / 255; 00102 const unsigned int p = a << 24 | b << 16 | g << 8 | r; 00103 surface.Write32b (j, i, p); 00104 } 00105 } 00106 pixels_u8 += rowstride; 00107 pixels_u32 = reinterpret_cast<unsigned int *> (pixels_u8); 00108 } 00109 } 00110 else 00111 { 00112 // Copy from pixbuf (RGBA) to surface (RGBA). 00113 for (unsigned int i = 0; i < height; i++) 00114 { 00115 for (unsigned int j = 0; j < width; j++) 00116 surface.Write32b (j, i, pixels_u32[j]); 00117 pixels_u8 += rowstride; 00118 pixels_u32 = reinterpret_cast<unsigned int *> (pixels_u8); 00119 } 00120 } 00121 } 00122 else 00123 { 00124 // Copy from pixbuf (RGB) to surface (RGBA). 00125 unsigned char *pixels = gdk_pixbuf_get_pixels (pixbuf); 00126 for (unsigned int i = 0; i < height; i++) 00127 { 00128 for (unsigned int j = 0; j < width; j++) 00129 { 00130 const unsigned char r = pixels[j*3]; 00131 const unsigned char g = pixels[j*3+1]; 00132 const unsigned char b = pixels[j*3+2]; 00133 surface.Write (j, i, r, g, b, 0xff); 00134 } 00135 pixels += rowstride; 00136 } 00137 } 00138 00139 // Create a 2D texture and upload the pixels. 00140 BaseTexture *texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture (); 00141 texture->Update (data); 00142 00143 delete data; // data is deleted as texture->Update () copies it. 00144 return texture; 00145 } 00146 00147 BaseTexture *CreateTexture2DFromFile (const TCHAR *filename, int max_size, 00148 bool premultiply) 00149 { 00150 GError *error = NULL; 00151 GdkPixbuf *pixbuf = 00152 gdk_pixbuf_new_from_file_at_size (filename, max_size, max_size, &error); 00153 if (error == NULL) 00154 { 00155 BaseTexture *texture = CreateTexture2DFromPixbuf (pixbuf, premultiply); 00156 g_object_unref (pixbuf); 00157 return texture; 00158 } 00159 else 00160 { 00161 nuxDebugMsg ("%s", error->message); 00162 return NULL; 00163 } 00164 } 00165 00166 BaseTexture *CreateTextureFromPixbuf (GdkPixbuf *pixbuf) 00167 { 00168 NBitmapData *BitmapData = LoadGdkPixbuf (pixbuf); 00169 NUX_RETURN_VALUE_IF_NULL (BitmapData, 0); 00170 00171 if (BitmapData->IsTextureData() ) 00172 { 00173 BaseTexture *texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); 00174 texture->Update (BitmapData); 00175 return texture; 00176 } 00177 delete BitmapData; 00178 return 0; 00179 } 00180 00181 BaseTexture *CreateTextureFromFile (const TCHAR *TextureFilename) 00182 { 00183 BaseTexture* texture = nullptr; 00184 00185 NBitmapData* BitmapData = LoadImageFile (TextureFilename); 00186 NUX_RETURN_VALUE_IF_NULL (BitmapData, 0); 00187 00188 if (BitmapData->IsTextureData() ) 00189 { 00190 texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); 00191 } 00192 else if (BitmapData->IsCubemapTextureData() ) 00193 { 00194 texture = new TextureCube(); 00195 } 00196 else if (BitmapData->IsVolumeTextureData() ) 00197 { 00198 texture = new TextureVolume(); 00199 } 00200 else if (BitmapData->IsAnimatedTextureData() ) 00201 { 00202 texture = new TextureFrameAnimation(); 00203 } 00204 00205 if (texture) 00206 { 00207 texture->Update(BitmapData); 00208 } 00209 else 00210 { 00211 nuxDebugMsg ("[CreateTextureFromFile] Invalid texture format type for file (%s)", TextureFilename); 00212 } 00213 00214 delete BitmapData; 00215 return texture; 00216 } 00217 00218 BaseTexture *CreateTextureFromBitmapData (const NBitmapData *BitmapData) 00219 { 00220 if (BitmapData == 0) 00221 return 0; 00222 00223 if (BitmapData->IsTextureData() ) 00224 { 00225 BaseTexture *texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); 00226 texture->Update (BitmapData); 00227 return texture; 00228 } 00229 else if (BitmapData->IsCubemapTextureData() ) 00230 { 00231 TextureCube *texture = new TextureCube(); 00232 texture->Update (BitmapData); 00233 return texture; 00234 } 00235 else if (BitmapData->IsVolumeTextureData() ) 00236 { 00237 TextureVolume *texture = new TextureVolume(); 00238 texture->Update (BitmapData); 00239 return texture; 00240 } 00241 else if (BitmapData->IsAnimatedTextureData() ) 00242 { 00243 TextureFrameAnimation *texture = new TextureFrameAnimation(); 00244 texture->Update (BitmapData); 00245 return texture; 00246 } 00247 return 0; 00248 } 00249 00250 BaseTexture::BaseTexture(NUX_FILE_LINE_DECL) 00251 : ResourceData (NUX_FILE_LINE_PARAM) 00252 { 00253 00254 } 00255 00256 BaseTexture::~BaseTexture() 00257 { 00258 00259 } 00260 00261 ObjectPtr < IOpenGLBaseTexture > BaseTexture::GetDeviceTexture() 00262 { 00263 ObjectPtr<CachedBaseTexture> CachedTexture = GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource (this); 00264 return CachedTexture->m_Texture; 00265 } 00266 00267 ObjectPtr<CachedBaseTexture> BaseTexture::GetCachedTexture() 00268 { 00269 return GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(this); 00270 } 00271 00272 Texture2D::Texture2D(NUX_FILE_LINE_DECL) 00273 : BaseTexture(NUX_FILE_LINE_PARAM) 00274 { 00275 } 00276 00277 Texture2D::Texture2D (const Texture2D &texture, NUX_FILE_LINE_DECL) 00278 : BaseTexture(NUX_FILE_LINE_PARAM) 00279 { 00280 _image = texture._image; 00281 } 00282 00283 Texture2D::Texture2D (const NTextureData &texture_data, NUX_FILE_LINE_DECL) 00284 : BaseTexture(NUX_FILE_LINE_PARAM) 00285 { 00286 _image = texture_data; 00287 } 00288 00289 Texture2D &Texture2D::operator = (const Texture2D &texture) 00290 { 00291 if (this == &texture) 00292 return *this; // Handle self assignment 00293 00294 _image = texture._image; 00295 return *this; 00296 } 00297 00298 Texture2D::~Texture2D() 00299 { 00300 } 00301 00302 bool Texture2D::Update (const NBitmapData *BitmapData, bool UpdateAndCacheResource) 00303 { 00304 nuxAssertMsg (BitmapData, TEXT ("[Texture2D::Update] Argument BitmapData is NULL.")); 00305 NUX_RETURN_VALUE_IF_NULL (BitmapData, false); 00306 00307 if (!BitmapData->IsTextureData()) 00308 { 00309 nuxAssertMsg (0, TEXT ("[Texture2D::Update] Argument BitmapData is not a 2D texture")); 00310 return false; 00311 } 00312 00313 _image = *static_cast<const NTextureData *> (BitmapData); 00314 00315 if (UpdateAndCacheResource) 00316 { 00317 // call the texture manager and recreate the texture (CachedTexture2D) associated with this object if any. 00318 GetGraphicsDisplay()->GetGraphicsEngine()->UpdateResource (this); 00319 } 00320 00321 return true; 00322 } 00323 00324 bool Texture2D::Update (const TCHAR *filename, bool UpdateAndCacheResource) 00325 { 00326 NBitmapData *BitmapData = LoadImageFile (filename); 00327 nuxAssertMsg (BitmapData, TEXT ("[Texture2D::Update] Bitmap for file (%s) is NULL."), filename); 00328 NUX_RETURN_VALUE_IF_NULL (BitmapData, false); 00329 bool ret = Update (BitmapData, UpdateAndCacheResource); 00330 NUX_SAFE_DELETE (BitmapData); 00331 return ret; 00332 } 00333 00334 void Texture2D::GetData (void *Buffer, int MipIndex, int StrideY, int face) 00335 { 00336 BYTE *Dest = (BYTE *) Buffer; 00337 const BYTE *Src = _image.GetSurface (MipIndex).GetPtrRawData(); 00338 int RowByteSize = _image.GetSurface (MipIndex).GetPitch(); 00339 int NumRows = _image.GetSurface (MipIndex).GetBlockHeight(); 00340 00341 for ( int Y = 0; Y < NumRows; Y++ ) 00342 { 00343 // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but 00344 // they contain the same amount of valid data since they have the same width, height and format. 00345 Memcpy (Dest + Y * StrideY, &Src[Y * RowByteSize], Min (RowByteSize, StrideY) ); 00346 } 00347 } 00348 00349 BaseTexture* Texture2D::Clone () const 00350 { 00351 Texture2D* texture = new Texture2D(*this); 00352 return texture; 00353 } 00354 00355 CachedBaseTexture::CachedBaseTexture (NResourceSet *ResourceManager) 00356 : CachedResourceData (ResourceManager), 00357 SourceWidth (0), 00358 SourceHeight (0), 00359 SourceDepth (0), 00360 SourceFormat (BITFMT_UNKNOWN) 00361 { 00362 00363 } 00364 00365 CachedBaseTexture::~CachedBaseTexture() 00366 { 00367 m_Texture.Release (); 00368 } 00369 00370 bool CachedBaseTexture::UpdateResource (ResourceData *Resource) 00371 { 00372 UpdateTexture ( (BaseTexture *) Resource); 00373 return TRUE; 00374 } 00375 00376 bool CachedBaseTexture::RecreateTexture (BaseTexture *Source) 00377 { 00378 int CurrentWidth = m_Texture->GetWidth(); 00379 int CurrentHeight = m_Texture->GetHeight(); 00380 int CurrentDepth = m_Texture->GetDepth(); 00381 int CurrentNumMipmap = m_Texture->GetNumMipLevel(); 00382 BitmapFormat CurrentFormat = m_Texture->GetPixelFormat(); 00383 00384 bool Recreate = 00385 (CurrentWidth != Source->GetWidth() ) || 00386 (CurrentHeight != Source->GetHeight() ) || 00387 (CurrentDepth != Source->GetDepth() ) || 00388 (CurrentNumMipmap != Source->GetNumMipLevel() ) || 00389 (CurrentFormat != Source->GetFormat() ); 00390 00391 return Recreate; 00392 } 00393 00394 CachedTexture2D::CachedTexture2D (NResourceSet *ResourceManager, Texture2D *SourceTexture) 00395 : CachedBaseTexture (ResourceManager) 00396 { 00397 if (SourceTexture->IsNull()) 00398 { 00399 m_Texture = ObjectPtr <IOpenGLBaseTexture> (0); 00400 return; 00401 } 00402 00403 m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateTexture (SourceTexture->GetWidth(), 00404 SourceTexture->GetHeight(), 00405 SourceTexture->GetNumMipLevel(), 00406 SourceTexture->GetFormat()); 00407 00408 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00409 { 00410 LoadMipLevel (SourceTexture, i); 00411 } 00412 } 00413 00414 CachedTexture2D::~CachedTexture2D() 00415 { 00416 00417 } 00418 00419 void CachedTexture2D::UpdateTexture ( BaseTexture *SourceTexture ) 00420 { 00421 if ( (SourceTexture == 0) || SourceTexture->IsNull() ) 00422 { 00423 m_Texture = ObjectPtr <IOpenGLBaseTexture> (0); 00424 return; 00425 } 00426 00427 if (!SourceTexture->Type().IsObjectType (Texture2D::StaticObjectType) ) 00428 { 00429 nuxAssertMsg (0, TEXT ("[Texture2D::UpdateTexture] Source texture is not of type Texture2D.") ); 00430 return; 00431 } 00432 00433 if ( RecreateTexture (SourceTexture) ) 00434 { 00435 m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateTexture (SourceTexture->GetWidth(), 00436 SourceTexture->GetHeight(), 00437 SourceTexture->GetNumMipLevel(), 00438 SourceTexture->GetFormat() ); 00439 00440 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00441 { 00442 LoadMipLevel (SourceTexture, i); 00443 } 00444 } 00445 else 00446 { 00447 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00448 { 00449 LoadMipLevel (SourceTexture, i); 00450 } 00451 } 00452 } 00453 00454 void CachedTexture2D::LoadMipLevel (BaseTexture *SourceTexture, int MipLevel) 00455 { 00456 SURFACE_LOCKED_RECT LockedRect; 00457 ObjectPtr < IOpenGLTexture2D > Texture2D = m_Texture; //m_Texture.CastRef<IOpenGLTexture2D>(); 00458 00459 OGL_CALL ( Texture2D->LockRect ( MipLevel, &LockedRect, NULL) ); 00460 SourceTexture->GetData ( LockedRect.pBits, MipLevel, LockedRect.Pitch ); 00461 OGL_CALL ( Texture2D->UnlockRect ( MipLevel ) ); 00462 } 00463 00464 TextureRectangle::TextureRectangle (NUX_FILE_LINE_DECL) 00465 : BaseTexture (NUX_FILE_LINE_PARAM) 00466 { 00467 } 00468 00469 TextureRectangle::TextureRectangle (const TextureRectangle &texture) 00470 { 00471 _image = texture._image; 00472 } 00473 00474 TextureRectangle::TextureRectangle (const NTextureData &BaseTexture) 00475 { 00476 _image = BaseTexture; 00477 } 00478 00479 TextureRectangle &TextureRectangle::operator = (const TextureRectangle &texture) 00480 { 00481 if (this == &texture) 00482 return *this; // Handle self assignment 00483 00484 _image = texture._image; 00485 return *this; 00486 } 00487 00488 TextureRectangle::~TextureRectangle() 00489 { 00490 00491 } 00492 00493 bool TextureRectangle::Update (const NBitmapData *BitmapData, bool UpdateAndCacheResource) 00494 { 00495 nuxAssertMsg (BitmapData, TEXT ("[TextureRectangle::Update] Argument BitmapData is NULL.") ); 00496 NUX_RETURN_VALUE_IF_NULL (BitmapData, false); 00497 00498 if (!BitmapData->IsTextureData() ) 00499 { 00500 nuxAssertMsg (0, TEXT ("[TextureRectangle::Update] Argument BitmapData is not a 2D texture") ); 00501 return false; 00502 } 00503 00504 _image = *static_cast<const NTextureData *> (BitmapData); 00505 00506 if (UpdateAndCacheResource) 00507 { 00508 // call the texture manager and recreate the texture (CachedTexture2D) associated with this object if any. 00509 GetGraphicsDisplay()->GetGraphicsEngine()->UpdateResource (this); 00510 } 00511 return true; 00512 } 00513 00514 bool TextureRectangle::Update (const TCHAR *filename, bool UpdateAndCacheResource) 00515 { 00516 bool b = false; 00517 NBitmapData *BitmapData = LoadImageFile (filename); 00518 nuxAssertMsg (BitmapData, TEXT ("[TextureRectangle::Update] Bitmap for file (%s) is NULL."), filename); 00519 NUX_RETURN_VALUE_IF_NULL (BitmapData, false); 00520 b = Update (BitmapData); 00521 NUX_SAFE_DELETE (BitmapData); 00522 return b; 00523 } 00524 00525 void TextureRectangle::GetData (void *Buffer, int MipIndex, int StrideY, int face) 00526 { 00527 BYTE *Dest = (BYTE *) Buffer; 00528 const BYTE *Src = _image.GetSurface (MipIndex).GetPtrRawData(); 00529 int RowByteSize = _image.GetSurface (MipIndex).GetPitch(); 00530 int NumRows = _image.GetSurface (MipIndex).GetBlockHeight(); 00531 00532 for ( int Y = 0; Y < NumRows; Y++ ) 00533 { 00534 // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but 00535 // they contain the same amount of valid data since they have the same width, height and format. 00536 Memcpy (Dest + Y * StrideY, &Src[Y * RowByteSize], Min (RowByteSize, StrideY) ); 00537 } 00538 } 00539 00540 BaseTexture* TextureRectangle::Clone () const 00541 { 00542 TextureRectangle* texture = new TextureRectangle(*this); 00543 return texture; 00544 } 00545 00546 CachedTextureRectangle::CachedTextureRectangle (NResourceSet *ResourceManager, TextureRectangle *SourceTexture) 00547 : CachedBaseTexture (ResourceManager) 00548 { 00549 if (SourceTexture->IsNull() ) 00550 { 00551 m_Texture = ObjectPtr<IOpenGLBaseTexture> (0); 00552 return; 00553 } 00554 00555 m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateRectangleTexture (SourceTexture->GetWidth(), 00556 SourceTexture->GetHeight(), 00557 SourceTexture->GetNumMipLevel(), 00558 SourceTexture->GetFormat() ); 00559 00560 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00561 { 00562 LoadMipLevel (SourceTexture, i); 00563 } 00564 } 00565 00566 CachedTextureRectangle::~CachedTextureRectangle() 00567 { 00568 00569 } 00570 00571 void CachedTextureRectangle::UpdateTexture ( BaseTexture *SourceTexture ) 00572 { 00573 if ( (SourceTexture == 0) || SourceTexture->IsNull() ) 00574 { 00575 m_Texture = ObjectPtr<IOpenGLBaseTexture> (0); 00576 return; 00577 } 00578 00579 if (!SourceTexture->Type().IsObjectType (TextureRectangle::StaticObjectType) ) 00580 { 00581 nuxAssertMsg (0, TEXT ("[CachedTextureRectangle::UpdateTexture] Source texture is not of type TextureRectangle.") ); 00582 return; 00583 } 00584 00585 if ( RecreateTexture (SourceTexture) ) 00586 { 00587 m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateRectangleTexture (SourceTexture->GetWidth(), 00588 SourceTexture->GetHeight(), 00589 SourceTexture->GetNumMipLevel(), 00590 SourceTexture->GetFormat() ); 00591 00592 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00593 { 00594 LoadMipLevel (SourceTexture, i); 00595 } 00596 } 00597 else 00598 { 00599 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00600 { 00601 LoadMipLevel (SourceTexture, i); 00602 } 00603 } 00604 } 00605 00606 void CachedTextureRectangle::LoadMipLevel (BaseTexture *SourceTexture, int MipLevel) 00607 { 00608 SURFACE_LOCKED_RECT LockedRect; 00609 ObjectPtr <IOpenGLRectangleTexture> TextureRectangle = m_Texture; //m_Texture.CastRef<IOpenGLRectangleTexture>(); 00610 00611 OGL_CALL (TextureRectangle->LockRect ( MipLevel, &LockedRect, NULL) ); 00612 SourceTexture->GetData ( LockedRect.pBits, MipLevel, LockedRect.Pitch ); 00613 OGL_CALL (TextureRectangle->UnlockRect ( MipLevel ) ); 00614 } 00615 00616 TextureCube::TextureCube(NUX_FILE_LINE_DECL) 00617 : BaseTexture (NUX_FILE_LINE_PARAM) 00618 { 00619 } 00620 00621 TextureCube::TextureCube (const TextureCube &texture) 00622 { 00623 _image = texture._image; 00624 } 00625 00626 TextureCube &TextureCube::operator = (const TextureCube &texture) 00627 { 00628 if (this == &texture) 00629 return *this; // Handle self assignment 00630 00631 _image = texture._image; 00632 return *this; 00633 } 00634 00635 TextureCube::~TextureCube() 00636 { 00637 00638 } 00639 00640 bool TextureCube::Update (const NBitmapData *BitmapData, bool UpdateAndCacheResource) 00641 { 00642 nuxAssertMsg (BitmapData, TEXT ("[TextureCube::Update] Argument BitmapData is NULL.") ); 00643 NUX_RETURN_VALUE_IF_NULL (BitmapData, false); 00644 00645 if (!BitmapData->IsCubemapTextureData() ) 00646 { 00647 nuxAssertMsg (0, TEXT ("[TextureCube::Update] Argument BitmapData is not a Cube texture") ); 00648 return false; 00649 } 00650 00651 _image = *static_cast<const NCubemapData *> (BitmapData); 00652 00653 if (UpdateAndCacheResource) 00654 { 00655 // call the texture manager and recreate the texture (CachedTexture2D) associated with this object if any. 00656 GetGraphicsDisplay()->GetGraphicsEngine()->UpdateResource (this); 00657 } 00658 00659 return true; 00660 } 00661 00662 bool TextureCube::Update (const TCHAR *filename, bool UpdateAndCacheResource) 00663 { 00664 NBitmapData *BitmapData = LoadImageFile (filename); 00665 nuxAssertMsg (BitmapData, TEXT ("[TextureCube::Update] Bitmap for file (%s) is NULL."), filename); 00666 NUX_RETURN_VALUE_IF_NULL (BitmapData, false); 00667 bool ret = Update (BitmapData); 00668 NUX_SAFE_DELETE (BitmapData); 00669 return ret; 00670 } 00671 00672 void TextureCube::GetData (void *Buffer, int MipIndex, int StrideY, int face) 00673 { 00674 BYTE *Dest = (BYTE *) Buffer; 00675 const BYTE *Src = _image.GetSurface (face, MipIndex).GetPtrRawData(); 00676 int RowByteSize = _image.GetSurface (face, MipIndex).GetPitch(); 00677 int NumRows = _image.GetSurface (face, MipIndex).GetBlockHeight(); 00678 00679 for ( int Y = 0; Y < NumRows; Y++ ) 00680 { 00681 // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but 00682 // they contain the same amount of valid data since they have the same width, height and format. 00683 Memcpy (Dest + Y * StrideY, &Src[Y * RowByteSize], Min (RowByteSize, StrideY) ); 00684 } 00685 } 00686 00687 BaseTexture* TextureCube::Clone () const 00688 { 00689 TextureCube* texture = new TextureCube(*this); 00690 return texture; 00691 } 00692 00693 CachedTextureCube::CachedTextureCube (NResourceSet *ResourceManager, TextureCube *SourceTexture) 00694 : CachedBaseTexture (ResourceManager) 00695 { 00696 if (SourceTexture->IsNull() ) 00697 { 00698 m_Texture = ObjectPtr<IOpenGLBaseTexture> (0); 00699 return; 00700 } 00701 00702 m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateCubeTexture (SourceTexture->GetWidth(), 00703 SourceTexture->GetNumMipLevel(), 00704 SourceTexture->GetFormat() ); 00705 00706 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00707 { 00708 LoadMipLevel (SourceTexture, i); 00709 } 00710 } 00711 00712 CachedTextureCube::~CachedTextureCube() 00713 { 00714 00715 } 00716 00717 void CachedTextureCube::UpdateTexture ( BaseTexture *SourceTexture ) 00718 { 00719 if ( (SourceTexture == 0) || SourceTexture->IsNull() ) 00720 { 00721 m_Texture = ObjectPtr<IOpenGLBaseTexture> (0); 00722 return; 00723 } 00724 00725 if (!SourceTexture->Type().IsObjectType (TextureCube::StaticObjectType) ) 00726 { 00727 nuxAssertMsg (0, TEXT ("[CachedTextureCube::UpdateTexture] Source texture is not of type TextureCube.") ); 00728 return; 00729 } 00730 00731 if ( RecreateTexture (SourceTexture) ) 00732 { 00733 m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateCubeTexture (SourceTexture->GetWidth(), 00734 SourceTexture->GetNumMipLevel(), 00735 SourceTexture->GetFormat() ); 00736 00737 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00738 { 00739 LoadMipLevel (SourceTexture, i); 00740 } 00741 } 00742 else 00743 { 00744 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00745 { 00746 LoadMipLevel (SourceTexture, i); 00747 } 00748 } 00749 } 00750 00751 void CachedTextureCube::LoadMipLevel (BaseTexture *SourceTexture, int MipLevel) 00752 { 00753 SURFACE_LOCKED_RECT LockedRect; 00754 ObjectPtr <IOpenGLCubeTexture> CubemapTexture = m_Texture; //m_Texture.CastRef<IOpenGLCubeTexture>(); 00755 00756 for (int face = CUBEMAP_FACE_POSITIVE_X; face < GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + 1; face++) 00757 { 00758 OGL_CALL ( CubemapTexture->LockRect (eCUBEMAP_FACES (face), MipLevel, &LockedRect, NULL) ); 00759 SourceTexture->GetData (LockedRect.pBits, MipLevel, LockedRect.Pitch, face - CUBEMAP_FACE_POSITIVE_X); 00760 OGL_CALL ( CubemapTexture->UnlockRect (eCUBEMAP_FACES (face), MipLevel ) ); 00761 } 00762 } 00763 00764 TextureVolume::TextureVolume(NUX_FILE_LINE_DECL) 00765 : BaseTexture (NUX_FILE_LINE_PARAM) 00766 { 00767 } 00768 00769 TextureVolume::TextureVolume (const TextureVolume &texture) 00770 { 00771 _image = texture._image; 00772 } 00773 00774 TextureVolume &TextureVolume::operator = (const TextureVolume &texture) 00775 { 00776 if (this == &texture) 00777 return *this; // Handle self assignment 00778 00779 _image = texture._image; 00780 return *this; 00781 } 00782 00783 TextureVolume::~TextureVolume() 00784 { 00785 00786 } 00787 00788 bool TextureVolume::Update (const NBitmapData *BitmapData, bool UpdateAndCacheResource) 00789 { 00790 nuxAssertMsg (BitmapData, TEXT ("[TextureVolume::Update] Argument BitmapData is NULL.") ); 00791 NUX_RETURN_VALUE_IF_NULL (BitmapData, false); 00792 00793 if (!BitmapData->IsVolumeTextureData() ) 00794 { 00795 nuxAssertMsg (0, TEXT ("[TextureVolume::Update] Argument BitmapData is not a Volume texture") ); 00796 return false; 00797 } 00798 00799 _image = *static_cast<const NVolumeData *> (BitmapData); 00800 00801 if (UpdateAndCacheResource) 00802 { 00803 // call the texture manager and recreate the texture (CachedTexture2D) associated with this object if any. 00804 GetGraphicsDisplay()->GetGraphicsEngine()->UpdateResource (this); 00805 } 00806 00807 return true; 00808 } 00809 00810 bool TextureVolume::Update (const TCHAR *filename, bool UpdateAndCacheResource) 00811 { 00812 NBitmapData *BitmapData = LoadImageFile (filename); 00813 nuxAssertMsg (BitmapData, TEXT ("[TextureVolume::Update] Bitmap for file (%s) is NULL."), filename); 00814 NUX_RETURN_VALUE_IF_NULL (BitmapData, false); 00815 bool ret = Update (filename); 00816 NUX_SAFE_DELETE (BitmapData); 00817 return ret; 00818 } 00819 00820 void TextureVolume::GetData (void *Buffer, int MipIndex, int StrideY, int slice) 00821 { 00822 BYTE *Dest = (BYTE *) Buffer; 00823 // const BYTE* Src = _image.GetSurface(MipIndex, slice).GetPtrRawData(); 00824 // int RowByteSize = _image.GetSurface(MipIndex, slice).GetPitch(); 00825 // int NumRows = _image.GetSurface(MipIndex, slice).GetBlockHeight(); 00826 00827 for (t_s32 slice = 0; slice < ImageSurface::GetLevelDim (_image.GetFormat(), _image.GetDepth(), MipIndex); slice++) 00828 { 00829 const BYTE *Src = _image.GetSurface (MipIndex, slice).GetPtrRawData(); 00830 int RowByteSize = _image.GetSurface (MipIndex, slice).GetPitch(); 00831 int NumRows = _image.GetSurface (MipIndex, slice).GetBlockHeight(); 00832 00833 for ( int Y = 0; Y < NumRows; Y++ ) 00834 { 00835 // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but 00836 // they contain the same amount of valid data since they have the same width, height and format. 00837 Memcpy (Dest + Y * StrideY, &Src[Y * RowByteSize], Min (RowByteSize, StrideY) ); 00838 } 00839 00840 Dest += NumRows * StrideY; 00841 } 00842 00843 // BYTE* Dest = (BYTE*)Buffer; 00844 // const BYTE* Src = _image.GetSurface(MipIndex, slice).GetPtrRawData(); 00845 // int RowByteSize = _image.GetSurface(MipIndex, slice).GetPitch(); 00846 // int NumRows = _image.GetSurface(MipIndex, slice).GetBlockHeight(); 00847 // 00848 // for( int Y = 0; Y < NumRows; Y++ ) 00849 // { 00850 // // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but 00851 // // they contain the same amount of valid data since they have the same width, height and format. 00852 // Memcpy(Dest + Y * StrideY,&Src[Y * RowByteSize], Min(RowByteSize, StrideY)); 00853 // } 00854 } 00855 00856 BaseTexture* TextureVolume::Clone () const 00857 { 00858 TextureVolume* texture = new TextureVolume(*this); 00859 return texture; 00860 } 00861 00862 CachedTextureVolume::CachedTextureVolume (NResourceSet *ResourceManager, TextureVolume *SourceTexture) 00863 : CachedBaseTexture (ResourceManager) 00864 { 00865 if (SourceTexture->IsNull() ) 00866 { 00867 m_Texture = ObjectPtr<IOpenGLBaseTexture> (0); 00868 return; 00869 } 00870 00871 m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateVolumeTexture (SourceTexture->GetWidth(), 00872 SourceTexture->GetHeight(), 00873 SourceTexture->GetDepth(), 00874 SourceTexture->GetNumMipLevel(), 00875 SourceTexture->GetFormat() ); 00876 00877 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00878 { 00879 LoadMipLevel (SourceTexture, i); 00880 } 00881 } 00882 00883 CachedTextureVolume::~CachedTextureVolume() 00884 { 00885 00886 } 00887 00888 void CachedTextureVolume::UpdateTexture ( BaseTexture *SourceTexture ) 00889 { 00890 if ( (SourceTexture == 0) || SourceTexture->IsNull() ) 00891 { 00892 m_Texture = ObjectPtr<IOpenGLBaseTexture> (0); 00893 return; 00894 } 00895 00896 if (!SourceTexture->Type().IsObjectType (TextureVolume::StaticObjectType) ) 00897 { 00898 nuxAssertMsg (0, TEXT ("[CachedTextureVolume::UpdateTexture] Source texture is not of type TextureVolume.") ); 00899 return; 00900 } 00901 00902 if ( RecreateTexture (SourceTexture) ) 00903 { 00904 m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateVolumeTexture (SourceTexture->GetWidth(), 00905 SourceTexture->GetHeight(), 00906 SourceTexture->GetDepth(), 00907 SourceTexture->GetNumMipLevel(), 00908 SourceTexture->GetFormat() ); 00909 00910 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00911 { 00912 LoadMipLevel (SourceTexture, i); 00913 } 00914 } 00915 else 00916 { 00917 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 00918 { 00919 LoadMipLevel (SourceTexture, i); 00920 } 00921 } 00922 } 00923 00924 void CachedTextureVolume::LoadMipLevel (BaseTexture *SourceTexture, int MipLevel) 00925 { 00926 VOLUME_LOCKED_BOX LockedBox; 00927 ObjectPtr <IOpenGLVolumeTexture> VolumeTexture = m_Texture; //m_Texture.CastRef<IOpenGLVolumeTexture>(); 00928 //TextureVolume* Source = UpCastResource<TextureVolume, BaseTexture>(SourceTexture); 00929 00930 //for(int slice = 0; slice < ImageSurface::GetLevelDim(Source->GetFormat(), Source->GetDepth(), MipLevel); slice++) 00931 { 00932 OGL_CALL ( VolumeTexture->LockBox (MipLevel, &LockedBox, NULL) ); 00933 SourceTexture->GetData (LockedBox.pBits, MipLevel, LockedBox.RowPitch, 0); 00934 OGL_CALL ( VolumeTexture->UnlockBox (MipLevel) ); 00935 } 00936 00937 // for(int slice = 0; slice < depth; slice++) 00938 // { 00939 // OGL_CALL( VolumeTexture->LockRect(slice, MipLevel, &LockedRect, NULL) ); 00940 // SourceTexture->GetData(LockedRect.pBits, MipLevel, LockedRect.Pitch, slice); 00941 // OGL_CALL( VolumeTexture->UnlockRect(slice, MipLevel ) ); 00942 // } 00943 } 00944 00945 TextureFrameAnimation::TextureFrameAnimation(NUX_FILE_LINE_DECL) 00946 : BaseTexture (NUX_FILE_LINE_PARAM) 00947 { 00948 } 00949 00950 TextureFrameAnimation::TextureFrameAnimation (const TextureFrameAnimation &texture) 00951 { 00952 _image = texture._image; 00953 } 00954 00955 TextureFrameAnimation &TextureFrameAnimation::operator = (const TextureFrameAnimation &texture) 00956 { 00957 if (this == &texture) 00958 return *this; // Handle self assignment 00959 00960 _image = texture._image; 00961 return *this; 00962 } 00963 00964 TextureFrameAnimation::~TextureFrameAnimation() 00965 { 00966 00967 } 00968 00969 bool TextureFrameAnimation::Update (const NBitmapData *BitmapData, bool UpdateAndCacheResource) 00970 { 00971 nuxAssertMsg (BitmapData, TEXT ("[TextureFrameAnimation::Update] Argument BitmapData is NULL.") ); 00972 NUX_RETURN_VALUE_IF_NULL (BitmapData, false); 00973 00974 if (!BitmapData->IsAnimatedTextureData() ) 00975 { 00976 nuxAssertMsg (0, TEXT ("[TextureFrameAnimation::Update] Argument BitmapData is not a Animated texture") ); 00977 return false; 00978 } 00979 00980 _image = *static_cast<const NAnimatedTextureData *> (BitmapData); 00981 00982 if (UpdateAndCacheResource) 00983 { 00984 // call the texture manager and recreate the texture (CachedTexture2D) associated with this object if any. 00985 GetGraphicsDisplay()->GetGraphicsEngine()->UpdateResource (this); 00986 } 00987 00988 return true; 00989 } 00990 00991 bool TextureFrameAnimation::Update (const TCHAR *filename, bool UpdateAndCacheResource) 00992 { 00993 NBitmapData *BitmapData = LoadImageFile (filename); 00994 nuxAssertMsg (BitmapData, TEXT ("[TextureFrameAnimation::Update] Bitmap for file (%s) is NULL."), filename); 00995 NUX_RETURN_VALUE_IF_NULL (BitmapData, false); 00996 bool ret = Update (BitmapData); 00997 NUX_SAFE_DELETE (BitmapData); 00998 return ret; 00999 } 01000 01001 void TextureFrameAnimation::GetData (void *Buffer, int MipIndex, int StrideY, int slice) 01002 { 01003 BYTE *Dest = (BYTE *) Buffer; 01004 //for(int slice = 0; slice < ImageSurface::GetLevelDim(_image.GetFormat(), _image.GetDepth(), MipIndex); slice++) 01005 { 01006 const BYTE *Src = _image.GetSurface (slice).GetPtrRawData(); 01007 int RowByteSize = _image.GetSurface (slice).GetPitch(); 01008 int NumRows = _image.GetSurface (slice).GetBlockHeight(); 01009 01010 for (int Y = 0; Y < NumRows; Y++) 01011 { 01012 // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but 01013 // they contain the same amount of valid data since they have the same width, height and format. 01014 Memcpy (Dest + Y * StrideY, &Src[Y * RowByteSize], Min (RowByteSize, StrideY) ); 01015 } 01016 01017 //Dest += NumRows * StrideY; 01018 } 01019 } 01020 01021 int TextureFrameAnimation::GetFrameTime (int Frame) 01022 { 01023 return _image.GetFrameTime (Frame); 01024 } 01025 01026 BaseTexture* TextureFrameAnimation::Clone () const 01027 { 01028 TextureFrameAnimation* texture = new TextureFrameAnimation(*this); 01029 return texture; 01030 } 01031 01032 CachedTextureFrameAnimation::CachedTextureFrameAnimation (NResourceSet *ResourceManager, TextureFrameAnimation *SourceTexture) 01033 : CachedBaseTexture (ResourceManager) 01034 { 01035 if (SourceTexture->IsNull() ) 01036 { 01037 m_Texture = ObjectPtr<IOpenGLBaseTexture> (0); 01038 return; 01039 } 01040 01041 m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateAnimatedTexture (SourceTexture->GetWidth(), 01042 SourceTexture->GetHeight(), 01043 SourceTexture->GetDepth(), 01044 SourceTexture->GetFormat() ); 01045 01046 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 01047 { 01048 LoadMipLevel (SourceTexture, i); 01049 } 01050 } 01051 01052 CachedTextureFrameAnimation::~CachedTextureFrameAnimation() 01053 { 01054 01055 } 01056 01057 void CachedTextureFrameAnimation::UpdateTexture ( BaseTexture *SourceTexture ) 01058 { 01059 if ( (SourceTexture == 0) || SourceTexture->IsNull() ) 01060 { 01061 m_Texture = ObjectPtr <IOpenGLBaseTexture> (0); 01062 return; 01063 } 01064 01065 if (!SourceTexture->Type().IsObjectType (TextureFrameAnimation::StaticObjectType) ) 01066 { 01067 nuxAssertMsg (0, TEXT ("[CachedTextureFrameAnimation::UpdateTexture] Source texture is not of type TextureFrameAnimation.") ); 01068 return; 01069 } 01070 01071 if (RecreateTexture (SourceTexture) ) 01072 { 01073 m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateAnimatedTexture (SourceTexture->GetWidth(), 01074 SourceTexture->GetHeight(), 01075 SourceTexture->GetDepth(), 01076 SourceTexture->GetFormat() ); 01077 01078 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 01079 { 01080 LoadMipLevel (SourceTexture, i); 01081 } 01082 } 01083 else 01084 { 01085 for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) 01086 { 01087 LoadMipLevel (SourceTexture, i); 01088 } 01089 } 01090 } 01091 01092 void CachedTextureFrameAnimation::LoadMipLevel (BaseTexture *SourceTexture, int MipLevel) 01093 { 01094 SURFACE_LOCKED_RECT LockedRect; 01095 ObjectPtr <IOpenGLAnimatedTexture> AnimatedTexture = m_Texture; //m_Texture.CastRef<IOpenGLAnimatedTexture>(); 01096 TextureFrameAnimation *Source = UpCastResource<TextureFrameAnimation, BaseTexture> (SourceTexture); 01097 01098 for (int frame = 0; frame < Source->GetDepth(); frame++) 01099 { 01100 OGL_CALL ( AnimatedTexture->LockRect (frame, &LockedRect, NULL) ); 01101 SourceTexture->GetData (LockedRect.pBits, 0, LockedRect.Pitch, frame); 01102 OGL_CALL ( AnimatedTexture->UnlockRect (frame) ); 01103 01104 AnimatedTexture->SetFrameTime (frame, Source->GetFrameTime (frame) ); 01105 } 01106 } 01107 01108 }