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 "NuxCore/NuxCore.h" 00024 #include "NuxCore/Logger.h" 00025 #include "NuxCore/Math/MathFunctions.h" 00026 00027 #include "BitmapFormats.h" 00028 #include "GdkGraphics.h" 00029 00030 #if defined (NUX_OS_WINDOWS) 00031 #include "GdiImageLoader.h" 00032 #include "DDS.h" 00033 #endif 00034 00035 #include "ImageSurface.h" 00036 00037 namespace nux 00038 { 00039 namespace 00040 { 00041 logging::Logger logger("nux.image"); 00042 } 00043 00044 extern PixelFormatInfo GPixelFormats[]; 00045 00046 NBitmapData *LoadGdkPixbuf (GdkPixbuf *pixbuf) 00047 { 00048 unsigned int width = gdk_pixbuf_get_width (pixbuf); 00049 unsigned int height = gdk_pixbuf_get_height (pixbuf); 00050 unsigned int row_bytes = gdk_pixbuf_get_rowstride (pixbuf); 00051 00052 NTextureData *Texture = new NTextureData (BITFMT_R8G8B8A8, width, height, 1); 00053 00054 guchar *img = gdk_pixbuf_get_pixels (pixbuf); 00055 00056 for (unsigned int i = 0; i < width; i++) 00057 for (unsigned int j = 0; j < height; j++) 00058 { 00059 guchar *pixels = img + ( j * row_bytes + i * 4); 00060 UINT value = 00061 (* (pixels + 3) << 24) | // a 00062 (* (pixels + 2) << 16) | // b 00063 (* (pixels + 1) << 8) | // g 00064 * (pixels + 0); // r 00065 00066 Texture->GetSurface (0).Write32b (i, j, value); 00067 } 00068 00069 return Texture; 00070 } 00071 00072 NBitmapData *LoadImageFile (const TCHAR *filename) 00073 { 00074 if (!GFileManager.FileExist (filename) ) 00075 { 00076 nuxAssertMsg (0, TEXT ("[LoadImageFile] Can't find file: %s"), filename); 00077 return 0; 00078 } 00079 00080 NBitmapData *BitmapData = 0; 00081 00082 #if defined(NUX_OS_WINDOWS) 00083 BitmapData = GdiLoadImageFile (filename); 00084 if (BitmapData) return BitmapData; 00085 00086 BitmapData = read_tga_file (filename); 00087 if (BitmapData) return BitmapData; 00088 00089 BitmapData = LoadFileFormat_DDS(filename); 00090 if (BitmapData) return BitmapData; 00091 00092 #elif defined(NUX_OS_LINUX) 00093 GdkGraphics gdkgraphics; 00094 gdkgraphics.LoadImage (filename); 00095 BitmapData = gdkgraphics.GetBitmap(); 00096 if (BitmapData) return BitmapData; 00097 #endif 00098 00099 // Unsupported format 00100 LOG_DEBUG(logger) << "Unknown file format: " << filename; 00101 return 0; 00102 } 00103 00104 bool HasOpenEXRSupport() 00105 { 00106 #ifdef NUX_OPENEXR_SUPPORT 00107 return true; 00108 #else 00109 return false; 00110 #endif 00111 } 00112 00113 void MakeCheckBoardImage (ImageSurface &Image, 00114 int width, int height, 00115 Color const& dark, 00116 Color const& light, 00117 int TileWidth, 00118 int TileHeight) 00119 { 00120 Image.Allocate (BITFMT_R8G8B8A8, width, height); 00121 00122 if (TileWidth <= 0) 00123 TileWidth = 4; 00124 00125 if (TileHeight <= 0) 00126 TileHeight = 4; 00127 00128 for (int j = 0; j < height; ++j) 00129 { 00130 for (int i = 0; i < width; ++i) 00131 { 00132 /*every 8 bits, change color from black to white or vice versa */ 00133 bool even_column = ((i / TileWidth) % 2) == 0; 00134 bool even_row = ((j / TileHeight ) % 2) == 0; 00135 bool is_dark = even_column ^ even_row; 00136 Color const& c = is_dark ? dark : light; 00137 Image.Write(i, j, 00138 c.red * 255, 00139 c.green * 255, 00140 c.blue * 255, 00141 c.alpha * 255); 00142 } 00143 } 00144 00145 Image.FlipVertical(); 00146 } 00147 00148 00149 NBitmapData::NBitmapData() 00150 : m_TotalMemorySize (0) 00151 { 00152 00153 } 00154 00155 NBitmapData::~NBitmapData() 00156 { 00157 } 00158 00159 00160 ImageSurface::ImageSurface() 00161 : width_ (0) 00162 , height_ (0) 00163 , format_ (BITFMT_UNKNOWN) 00164 , m_Pitch (0) 00165 , bpe_ (0) 00166 , Alignment_ (4) 00167 , RawData_ (0) 00168 { 00169 Allocate (format_, width_, height_); 00170 } 00171 00172 ImageSurface::~ImageSurface() 00173 { 00174 delete [] RawData_; 00175 } 00176 00177 ImageSurface::ImageSurface (BitmapFormat format, t_u32 width, t_u32 height) 00178 : width_ (0) 00179 , height_ (0) 00180 , format_ (BITFMT_UNKNOWN) 00181 , m_Pitch (0) 00182 , bpe_ (0) 00183 , Alignment_ (4) 00184 , RawData_ (0) 00185 { 00186 Allocate (format, width, height); 00187 } 00188 00189 ImageSurface::ImageSurface (const ImageSurface &surface) 00190 { 00191 width_ = surface.width_; 00192 height_ = surface.height_; 00193 bpe_ = surface.bpe_; 00194 format_ = surface.format_; 00195 m_Pitch = surface.m_Pitch; 00196 Alignment_ = surface.Alignment_; 00197 00198 RawData_ = new t_u8[surface.GetSize()]; 00199 Memcpy(RawData_, surface.RawData_, surface.GetSize()); 00200 } 00201 00202 ImageSurface &ImageSurface::operator = (const ImageSurface &surface) 00203 { 00204 if (this == &surface) 00205 return *this; // Handle self assignment 00206 00207 width_ = surface.width_; 00208 height_ = surface.height_; 00209 bpe_ = surface.bpe_; 00210 format_ = surface.format_; 00211 m_Pitch = surface.m_Pitch; 00212 Alignment_ = surface.Alignment_; 00213 00214 delete [] RawData_; 00215 00216 RawData_ = new t_u8[surface.GetSize() ]; 00217 Memcpy (RawData_, surface.RawData_, surface.GetSize() ); 00218 return *this; 00219 } 00220 00221 t_s32 ImageSurface::GetPitch() const 00222 { 00223 return m_Pitch; 00224 } 00225 00226 t_s32 ImageSurface::GetBlockHeight() const 00227 { 00228 t_u32 block = GPixelFormats[format_].BlockSizeY; 00229 t_u32 HeightInBlocks = Align (GetHeight(), block) / block; 00230 return HeightInBlocks; 00231 } 00232 00233 BitmapFormat ImageSurface::GetFormat() const 00234 { 00235 return format_; 00236 } 00237 00238 t_s32 ImageSurface::GetAlignment() const 00239 { 00240 return Alignment_; 00241 } 00242 00243 void ImageSurface::Allocate (BitmapFormat format, t_s32 width, t_s32 height) 00244 { 00245 nuxAssert (format < BITFMT_END_GFX_FORMATS); 00246 nuxAssert (width >= 0); 00247 nuxAssert (height >= 0); 00248 00249 if (width < 0) 00250 width = 0; 00251 00252 if (height < 0) 00253 height = 0; 00254 00255 if ( (format_ == format) && 00256 (width_ == width) && 00257 (height_ == height) ) 00258 { 00259 // no need to recreate 00260 Clear(); 00261 return; 00262 } 00263 00264 delete [] RawData_; 00265 00266 if ( (width == 0) || (height == 0) ) 00267 { 00268 width_ = 0; 00269 height_ = 0; 00270 Alignment_ = 1; 00271 bpe_ = 0; 00272 format_ = BITFMT_UNKNOWN; 00273 m_Pitch = 0; 00274 return; 00275 } 00276 00277 width_ = width; 00278 height_ = height; 00279 00280 00281 Alignment_ = GPixelFormats[format].RowMemoryAlignment; 00282 00283 bpe_ = GPixelFormats[format].BlockBytes; 00284 format_ = format; 00285 00286 if ( (format_ == BITFMT_DXT1) || 00287 (format_ == BITFMT_DXT2) || 00288 (format_ == BITFMT_DXT3) || 00289 (format_ == BITFMT_DXT4) || 00290 (format_ == BITFMT_DXT5) ) 00291 { 00292 // For DXT, width and height are rounded up to a multiple of 4 in order 00293 // to create 4x4 blocks of pixels; And in this context, byte alignment 00294 // is 1 ie. data is densely packed. 00295 t_u32 block = GPixelFormats[format].BlockSizeX; 00296 t_u32 shift = Log2 (GPixelFormats[format].BlockSizeX); 00297 m_Pitch = Align ( (bpe_ * ( (width_ + (block - 1) ) >> shift) ), Alignment_); 00298 00299 block = GPixelFormats[format].BlockSizeY; 00300 shift = Log2 (GPixelFormats[format].BlockSizeY); 00301 RawData_ = new t_u8[m_Pitch * Align ( (height + (block-1) ) >> shift, block) ]; 00302 } 00303 else 00304 { 00305 t_u32 block = GPixelFormats[format].BlockSizeX; 00306 t_u32 shift = Log2 (GPixelFormats[format].BlockSizeX); 00307 m_Pitch = Align ( (bpe_ * ( (width_ + (block - 1) ) >> shift) ), Alignment_); 00308 00309 block = GPixelFormats[format].BlockSizeY; 00310 shift = Log2 (GPixelFormats[format].BlockSizeY); 00311 RawData_ = new t_u8[m_Pitch * Align ( (height + (block-1) ) >> shift, block) ]; 00312 } 00313 00314 Clear(); 00315 } 00316 00317 // This computes the correct pitch of a line. For instance if the unpack 00318 // alignment is 4, the pitch must have a number of pixel multiple of 4. See 00319 // Avoiding 16 Common OpenGL Pitfalls 00320 // http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ 00321 // 7. Watch Your Pixel Store Alignment 00322 t_s32 ImageSurface::GetLevelPitch (BitmapFormat format, t_s32 width, 00323 t_s32 height, t_s32 miplevel) 00324 { 00325 t_s32 levelwidth = ImageSurface::GetLevelDim (format, width, miplevel); 00326 00327 t_s32 bpe = GPixelFormats[format].BlockBytes; 00328 t_s32 memalignment = GPixelFormats[format].RowMemoryAlignment; 00329 t_s32 block = GPixelFormats[format].BlockSizeX; 00330 t_s32 shift = Log2 (GPixelFormats[format].BlockSizeX); 00331 t_s32 pitch = Align ( (bpe * ( (levelwidth + (block - 1) ) >> shift) ), memalignment); 00332 00333 return pitch; 00334 } 00335 00336 t_s32 ImageSurface::GetLevelPitchNoMemAlignment (BitmapFormat format, t_s32 width, t_s32 height, t_s32 miplevel) 00337 { 00338 t_s32 levelwidth = ImageSurface::GetLevelDim (format, width, miplevel); 00339 00340 t_s32 bpe = GPixelFormats[format].BlockBytes; 00341 t_s32 block = GPixelFormats[format].BlockSizeX; 00342 t_s32 shift = Log2 (GPixelFormats[format].BlockSizeX); 00343 t_s32 pitch = Align ( (bpe * ( (levelwidth + (block - 1) ) >> shift) ), 1); 00344 00345 return pitch; 00346 } 00347 00348 t_s32 ImageSurface::GetLevelSize (BitmapFormat format, t_s32 width, t_s32 height, t_s32 miplevel) 00349 { 00350 t_s32 pitch = ImageSurface::GetLevelPitch (format, width, height, miplevel); 00351 t_s32 levelheight = ImageSurface::GetLevelDim (format, height, miplevel); 00352 00353 t_s32 block = GPixelFormats[format].BlockSizeY; 00354 t_s32 HeightInBlocks = Align (levelheight, block) / block; 00355 00356 t_s32 size = pitch * HeightInBlocks; 00357 return size; 00358 } 00359 00360 t_s32 ImageSurface::GetLevelSize (BitmapFormat format, t_s32 width, t_s32 height, t_s32 depth, t_s32 miplevel) 00361 { 00362 t_s32 pitch = ImageSurface::GetLevelPitch (format, width, height, miplevel); 00363 t_s32 levelheight = ImageSurface::GetLevelDim (format, height, miplevel); 00364 t_s32 leveldepth = ImageSurface::GetLevelDim (format, depth, miplevel); 00365 00366 t_s32 block = GPixelFormats[format].BlockSizeY; 00367 t_s32 HeightInBlocks = Align (levelheight, block) / block; 00368 00369 t_s32 size = pitch * HeightInBlocks; 00370 return leveldepth * size; 00371 } 00372 00373 t_s32 ImageSurface::GetLevelWidth (BitmapFormat format, t_s32 width, t_s32 miplevel) 00374 { 00375 // return 1 if the mip level does not exist. 00376 return Max<t_s32> (1, width >> miplevel); 00377 } 00378 00379 t_s32 ImageSurface::GetLevelHeight (BitmapFormat format, t_s32 height, t_s32 miplevel) 00380 { 00381 // return 1 if the mip level does not exist. 00382 return Max<t_s32> (1, height >> miplevel); 00383 } 00384 00385 t_s32 ImageSurface::GetLevelDim (BitmapFormat format, t_s32 length, t_s32 miplevel) 00386 { 00387 // return 1 if the mip level does not exist. 00388 return Max<t_s32> (1, length >> miplevel); 00389 } 00390 00391 t_s32 ImageSurface::GetNumMipLevel (BitmapFormat format, t_s32 width, t_s32 height) 00392 { 00393 t_s32 NumTotalMipLevel = 1 + floorf (Log2 (Max (width, height) ) ); 00394 return NumTotalMipLevel; 00395 } 00396 00397 t_s32 ImageSurface::GetMemAlignment (BitmapFormat format) 00398 { 00399 return GPixelFormats[format].RowMemoryAlignment; 00400 } 00401 00402 t_s32 ImageSurface::GetLevelBlockWidth (BitmapFormat format, t_s32 width, t_s32 miplevel) 00403 { 00404 t_s32 block = GPixelFormats[format].BlockSizeX; 00405 t_s32 WidthInBlocks = Align (GetLevelDim (format, width, miplevel), block) / block; 00406 return WidthInBlocks; 00407 } 00408 00409 t_s32 ImageSurface::GetLevelBlockHeight (BitmapFormat format, t_s32 height, t_s32 miplevel) 00410 { 00411 t_s32 block = GPixelFormats[format].BlockSizeY; 00412 t_s32 HeightInBlocks = Align (GetLevelDim (format, height, miplevel), block) / block; 00413 return HeightInBlocks; 00414 } 00415 00416 bool ImageSurface::IsNull() const 00417 { 00418 if ( (width_ == 0) || (height_ == 0) || (format_ == BITFMT_UNKNOWN) ) 00419 return true; 00420 00421 return false; 00422 } 00423 00424 void ImageSurface::Write32b (t_s32 i, t_s32 j, t_u32 value) 00425 { 00426 nuxAssert (i < width_); 00427 nuxAssert (j < height_); 00428 nuxAssert (bpe_ >= 4); 00429 00430 if ( (format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5) ) 00431 return; 00432 00433 RawData_[j *m_Pitch + i *bpe_ + 0] = (t_u8) (value & 0xff); 00434 RawData_[j *m_Pitch + i *bpe_ + 1] = (t_u8) ( (value & 0xff00) >> 8); 00435 RawData_[j *m_Pitch + i *bpe_ + 2] = (t_u8) ( (value & 0xff0000) >> 16); 00436 RawData_[j *m_Pitch + i *bpe_ + 3] = (t_u8) ( (value & 0xff000000) >> 24); 00437 } 00438 00439 void ImageSurface::Write24b (t_s32 i, t_s32 j, t_u32 value) 00440 { 00441 nuxAssert (i < width_); 00442 nuxAssert (j < height_); 00443 nuxAssert (bpe_ >= 3); 00444 00445 if ( (format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5) ) 00446 return; 00447 00448 RawData_[j *m_Pitch + i *bpe_ + 0] = (t_u8) (value & 0xff); 00449 RawData_[j *m_Pitch + i *bpe_ + 1] = (t_u8) ( (value & 0xff00) >> 8); 00450 RawData_[j *m_Pitch + i *bpe_ + 2] = (t_u8) ( (value & 0xff0000) >> 16); 00451 } 00452 00453 void ImageSurface::Write16b (t_s32 i, t_s32 j, t_u16 value) 00454 { 00455 nuxAssert (i < width_); 00456 nuxAssert (j < height_); 00457 nuxAssert (bpe_ >= 2); 00458 00459 if ( (format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5) ) 00460 return; 00461 00462 RawData_[j *m_Pitch + i *bpe_ + 0] = (t_u8) (value & 0xff); 00463 RawData_[j *m_Pitch + i *bpe_ + 1] = (t_u8) ( (value & 0xff00) >> 8); 00464 } 00465 00466 void ImageSurface::Write8b (t_s32 i, t_s32 j, t_u8 value) 00467 { 00468 nuxAssert (i < width_); 00469 nuxAssert (j < height_); 00470 nuxAssert (bpe_ >= 1); 00471 00472 if ( (format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5) ) 00473 return; 00474 00475 RawData_[j *m_Pitch + i *bpe_ + 0] = (t_u8) (value & 0xff); 00476 } 00477 00478 void ImageSurface::Write (t_s32 i, t_s32 j, t_u8 r, t_u8 g, t_u8 b, t_u8 a) 00479 { 00480 nuxAssert (i < width_); 00481 nuxAssert (j < height_); 00482 nuxAssert (bpe_ == 4); 00483 00484 if ( (format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5) ) 00485 return; 00486 00487 if ( (i < 0) || (i > width_) ) 00488 return; 00489 00490 if ( (j < 0) || (j > height_) ) 00491 return; 00492 00493 if (bpe_ != 4) 00494 return; 00495 00496 RawData_[j *m_Pitch + i *bpe_ + 0] = r; 00497 RawData_[j *m_Pitch + i *bpe_ + 1] = g; 00498 RawData_[j *m_Pitch + i *bpe_ + 2] = b; 00499 RawData_[j *m_Pitch + i *bpe_ + 3] = a; 00500 } 00501 00502 t_u32 ImageSurface::Read (t_s32 i, t_s32 j) 00503 { 00504 nuxAssert (i < width_); 00505 nuxAssert (j < height_); 00506 nuxAssert (bpe_); 00507 00508 if ( (format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5) ) 00509 return 0x00000000; 00510 00511 if (bpe_ == 4) 00512 { 00513 return ( (t_u32) RawData_[j * m_Pitch + i * bpe_ + 3] << 24) | 00514 ( (t_u32) RawData_[j * m_Pitch + i * bpe_ + 2] << 16) | 00515 ( (t_u32) RawData_[j * m_Pitch + i * bpe_ + 1] << 8) | 00516 ( (t_u32) RawData_[j * m_Pitch + i * bpe_ + 0] << 0); 00517 } 00518 00519 if (bpe_ == 3) 00520 { 00521 return ( (t_u32) RawData_[j * m_Pitch + i * bpe_ + 2] << 16) | 00522 ( (t_u32) RawData_[j * m_Pitch + i * bpe_ + 1] << 8) | 00523 ( (t_u32) RawData_[j * m_Pitch + i * bpe_ + 0] << 0); 00524 } 00525 00526 if (bpe_ == 2) 00527 { 00528 return ( (t_u32) RawData_[j * m_Pitch + i * bpe_ + 1] << 8) | 00529 ( (t_u32) RawData_[j * m_Pitch + i * bpe_ + 0] << 0); 00530 } 00531 00532 if (bpe_ == 1) 00533 { 00534 return (t_u32) RawData_[j * m_Pitch + i * bpe_ + 0]; 00535 } 00536 00537 return 0x0000000; 00538 } 00539 00540 void ImageSurface::Clear() 00541 { 00542 t_s32 i; 00543 00544 if (RawData_ == 0) 00545 return; 00546 00547 if ( (width_ == 0) || (height_ == 0) ) 00548 return; 00549 00550 auto size = GetSize (); 00551 memset(RawData_, 0, size); 00552 } 00553 00554 void ImageSurface::FlipHorizontal() 00555 { 00556 if ( (format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5) ) 00557 return; 00558 00559 t_s32 i, j, k; 00560 t_u8 *flip_data; 00561 00562 if (RawData_ == 0) 00563 return; 00564 00565 if (width_ == 0 || height_ == 0) 00566 return; 00567 00568 flip_data = new t_u8[m_Pitch*height_]; 00569 00570 for (j = 0; j < height_; j++) 00571 { 00572 for (i = 0; i < width_; i++) 00573 { 00574 for (k = 0; k < bpe_; k++) 00575 { 00576 flip_data[ (j*m_Pitch) + i *bpe_ + k] = RawData_[ (j*m_Pitch) + (width_-i-1) * bpe_ + k]; 00577 } 00578 } 00579 } 00580 00581 delete [] RawData_; 00582 RawData_ = flip_data; 00583 } 00584 00585 void ImageSurface::FlipVertical() 00586 { 00587 00588 t_s32 i, j, k; 00589 t_u8 *flip_data; 00590 00591 if (RawData_ == 0) 00592 return; 00593 00594 if (width_ == 0 || height_ == 0) 00595 return; 00596 00597 if ( (format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5) ) 00598 { 00599 FlipDXTVertical(); 00600 } 00601 else 00602 { 00603 flip_data = new t_u8[m_Pitch*height_]; 00604 00605 for (j = 0; j < height_; j++) 00606 { 00607 for (i = 0; i < width_; i++) 00608 { 00609 for (k = 0; k < bpe_; k++) 00610 { 00611 flip_data[ (j*m_Pitch) + i *bpe_ + k] = RawData_[ (height_-j-1) *m_Pitch + i * bpe_ + k]; 00612 } 00613 } 00614 } 00615 00616 delete [] RawData_; 00617 RawData_ = flip_data; 00618 } 00619 00620 } 00621 00622 void ImageSurface::FlipDXTVertical() 00623 { 00624 //void (CDDSImage::*flipblocks)(DXTColBlock*, t_u32); 00625 t_s32 xblocks = (width_ + 3) / 4; 00626 t_s32 yblocks = (height_ + 3) / 4; 00627 t_s32 blocksize; 00628 t_s32 linesize; 00629 00630 switch (format_) 00631 { 00632 case BITFMT_DXT1: 00633 blocksize = 8; 00634 //flipblocks = &CDDSImage::flip_blocks_dxtc1; 00635 break; 00636 case BITFMT_DXT2: 00637 blocksize = 16; 00638 //flipblocks = &CDDSImage::flip_blocks_dxtc2; 00639 break; 00640 case BITFMT_DXT3: 00641 blocksize = 16; 00642 //flipblocks = &CDDSImage::flip_blocks_dxtc3; 00643 break; 00644 case BITFMT_DXT4: 00645 blocksize = 16; 00646 //flipblocks = &CDDSImage::flip_blocks_dxtc4; 00647 break; 00648 case BITFMT_DXT5: 00649 blocksize = 16; 00650 //flipblocks = &CDDSImage::flip_blocks_dxtc5; 00651 break; 00652 default: 00653 return; 00654 } 00655 00656 linesize = xblocks * blocksize; 00657 00658 DXTColBlock *top; 00659 DXTColBlock *bottom; 00660 00661 for (t_s32 j = 0; j < (yblocks >> 1); j++) 00662 { 00663 top = (DXTColBlock *) ( (unsigned char *) RawData_ + j * linesize); 00664 bottom = (DXTColBlock *) ( (unsigned char *) RawData_ + ( ( (yblocks - j) - 1) * linesize) ); 00665 00666 switch (format_) 00667 { 00668 case BITFMT_DXT1: 00669 FlipBlocksDXT1 (top, xblocks); 00670 FlipBlocksDXT1 (bottom, xblocks); 00671 break; 00672 case BITFMT_DXT2: 00673 FlipBlocksDXT3 (top, xblocks); 00674 FlipBlocksDXT3 (bottom, xblocks); 00675 break; 00676 case BITFMT_DXT3: 00677 FlipBlocksDXT3 (top, xblocks); 00678 FlipBlocksDXT3 (bottom, xblocks); 00679 break; 00680 case BITFMT_DXT4: 00681 FlipBlocksDXT5 (top, xblocks); 00682 FlipBlocksDXT5 (bottom, xblocks); 00683 break; 00684 case BITFMT_DXT5: 00685 FlipBlocksDXT5 (top, xblocks); 00686 FlipBlocksDXT5 (bottom, xblocks); 00687 break; 00688 default: 00689 nuxAssert (TEXT ("[ImageSurface::FlipDXTVertical] Invalid Switch option.") ); 00690 break; 00691 } 00692 00693 SwapBlocks (bottom, top, linesize); 00694 } 00695 } 00696 00697 void ImageSurface::SwapBlocks (void *byte1, void *byte2, t_s32 size) 00698 { 00699 unsigned char *tmp = new unsigned char[size]; 00700 00701 memcpy (tmp, byte1, size); 00702 memcpy (byte1, byte2, size); 00703 memcpy (byte2, tmp, size); 00704 00705 delete [] tmp; 00706 } 00707 00708 void ImageSurface::FlipBlocksDXT1 (DXTColBlock *line, t_s32 numBlocks) 00709 { 00710 DXTColBlock *curblock = line; 00711 00712 for (t_s32 i = 0; i < numBlocks; i++) 00713 { 00714 SwapBlocks (&curblock->row[0], &curblock->row[3], sizeof (unsigned char) ); 00715 SwapBlocks (&curblock->row[1], &curblock->row[2], sizeof (unsigned char) ); 00716 00717 curblock++; 00718 } 00719 } 00720 00721 void ImageSurface::FlipBlocksDXT3 (DXTColBlock *line, t_s32 numBlocks) 00722 { 00723 DXTColBlock *curblock = line; 00724 DXT3AlphaBlock *alphablock; 00725 00726 for (t_s32 i = 0; i < numBlocks; i++) 00727 { 00728 alphablock = (DXT3AlphaBlock *) curblock; 00729 00730 SwapBlocks (&alphablock->row[0], &alphablock->row[3], sizeof (unsigned short) ); 00731 SwapBlocks (&alphablock->row[1], &alphablock->row[2], sizeof (unsigned short) ); 00732 00733 curblock++; 00734 00735 SwapBlocks (&curblock->row[0], &curblock->row[3], sizeof (unsigned char) ); 00736 SwapBlocks (&curblock->row[1], &curblock->row[2], sizeof (unsigned char) ); 00737 00738 curblock++; 00739 } 00740 } 00741 00742 void ImageSurface::FlipBlocksDXT5 (DXTColBlock *line, t_s32 numBlocks) 00743 { 00744 DXTColBlock *curblock = line; 00745 DXT5AlphaBlock *alphablock; 00746 00747 for (t_s32 i = 0; i < numBlocks; i++) 00748 { 00749 alphablock = (DXT5AlphaBlock *) curblock; 00750 00751 FlipDXT5Alpha (alphablock); 00752 00753 curblock++; 00754 00755 SwapBlocks (&curblock->row[0], &curblock->row[3], sizeof (unsigned char) ); 00756 SwapBlocks (&curblock->row[1], &curblock->row[2], sizeof (unsigned char) ); 00757 00758 curblock++; 00759 } 00760 } 00761 00762 void ImageSurface::FlipDXT5Alpha (DXT5AlphaBlock *block) 00763 { 00764 unsigned char gBits[4][4]; 00765 00766 const unsigned long mask = 0x00000007; // bits = 00 00 01 11 00767 unsigned long bits = 0; 00768 memcpy (&bits, &block->row[0], sizeof (unsigned char) * 3); 00769 00770 gBits[0][0] = (unsigned char) (bits & mask); 00771 bits >>= 3; 00772 gBits[0][1] = (unsigned char) (bits & mask); 00773 bits >>= 3; 00774 gBits[0][2] = (unsigned char) (bits & mask); 00775 bits >>= 3; 00776 gBits[0][3] = (unsigned char) (bits & mask); 00777 bits >>= 3; 00778 gBits[1][0] = (unsigned char) (bits & mask); 00779 bits >>= 3; 00780 gBits[1][1] = (unsigned char) (bits & mask); 00781 bits >>= 3; 00782 gBits[1][2] = (unsigned char) (bits & mask); 00783 bits >>= 3; 00784 gBits[1][3] = (unsigned char) (bits & mask); 00785 00786 bits = 0; 00787 memcpy (&bits, &block->row[3], sizeof (unsigned char) * 3); 00788 00789 gBits[2][0] = (unsigned char) (bits & mask); 00790 bits >>= 3; 00791 gBits[2][1] = (unsigned char) (bits & mask); 00792 bits >>= 3; 00793 gBits[2][2] = (unsigned char) (bits & mask); 00794 bits >>= 3; 00795 gBits[2][3] = (unsigned char) (bits & mask); 00796 bits >>= 3; 00797 gBits[3][0] = (unsigned char) (bits & mask); 00798 bits >>= 3; 00799 gBits[3][1] = (unsigned char) (bits & mask); 00800 bits >>= 3; 00801 gBits[3][2] = (unsigned char) (bits & mask); 00802 bits >>= 3; 00803 gBits[3][3] = (unsigned char) (bits & mask); 00804 00805 unsigned long *pBits = ( (unsigned long *) & (block->row[0]) ); 00806 00807 *pBits = *pBits | (gBits[3][0] << 0); 00808 *pBits = *pBits | (gBits[3][1] << 3); 00809 *pBits = *pBits | (gBits[3][2] << 6); 00810 *pBits = *pBits | (gBits[3][3] << 9); 00811 00812 *pBits = *pBits | (gBits[2][0] << 12); 00813 *pBits = *pBits | (gBits[2][1] << 15); 00814 *pBits = *pBits | (gBits[2][2] << 18); 00815 *pBits = *pBits | (gBits[2][3] << 21); 00816 00817 pBits = ( (unsigned long *) & (block->row[3]) ); 00818 00819 #ifdef __APPLE__ 00820 *pBits &= 0x000000ff; 00821 #else 00822 *pBits &= 0xff000000; 00823 #endif 00824 00825 *pBits = *pBits | (gBits[1][0] << 0); 00826 *pBits = *pBits | (gBits[1][1] << 3); 00827 *pBits = *pBits | (gBits[1][2] << 6); 00828 *pBits = *pBits | (gBits[1][3] << 9); 00829 00830 *pBits = *pBits | (gBits[0][0] << 12); 00831 *pBits = *pBits | (gBits[0][1] << 15); 00832 *pBits = *pBits | (gBits[0][2] << 18); 00833 *pBits = *pBits | (gBits[0][3] << 21); 00834 } 00835 00836 const t_u8 *ImageSurface::GetPtrRawData() const 00837 { 00838 return RawData_; 00839 } 00840 00841 t_u8 *ImageSurface::GetPtrRawData() 00842 { 00843 return RawData_; 00844 } 00845 00846 t_s32 ImageSurface::GetSize() const 00847 { 00848 if ( (format_ == BITFMT_DXT1) || 00849 (format_ == BITFMT_DXT2) || 00850 (format_ == BITFMT_DXT3) || 00851 (format_ == BITFMT_DXT4) || 00852 (format_ == BITFMT_DXT5) ) 00853 { 00854 return m_Pitch * ( (height_ + 3) >> 2); 00855 } 00856 else 00857 { 00858 return m_Pitch * height_; 00859 } 00860 } 00861 00862 Color ImageSurface::AverageColor() 00863 { 00864 if (width_ == 0 || height_ == 0) 00865 return Color (0.f, 0.f, 0.f, 0.f); 00866 00867 t_float r, g, b, a; 00868 r = g = b = a = 0; 00869 00870 if (bpe_ == 8) 00871 { 00872 for (int j = 0; j < height_; j++) 00873 { 00874 for (int i = 0; i < width_; i++) 00875 { 00876 t_u32 v = Read (i, j); 00877 r += (v & 0x000000FF); 00878 g += (v & 0x0000FF00) >> 1; 00879 b += (v & 0x00FF0000) >> 2; 00880 a += (v & 0xFF000000) >> 3; 00881 } 00882 } 00883 } 00884 00885 t_u32 num_pixels = width_ * height_; 00886 return Color (r / num_pixels, g / num_pixels, b / num_pixels, a / num_pixels); 00887 } 00888 00889 00891 NTextureData::NTextureData (BitmapFormat f, t_s32 width, t_s32 height, t_s32 NumMipmap) 00892 : m_NumMipmap (0) 00893 { 00894 Allocate (f, width, height, NumMipmap); 00895 } 00896 00897 NTextureData::~NTextureData() 00898 { 00899 ClearData(); 00900 } 00901 00902 void NTextureData::ClearData() 00903 { 00904 for (t_s32 i = 0; i < (t_s32) m_MipSurfaceArray.size(); i++) 00905 delete m_MipSurfaceArray[i]; 00906 00907 m_MipSurfaceArray.clear(); 00908 } 00909 00911 NTextureData::NTextureData (const NTextureData &object) 00912 { 00913 for (t_s32 i = 0; i < object.GetNumMipmap(); i++) 00914 m_MipSurfaceArray.push_back (new ImageSurface (object.GetSurface (i) ) ); 00915 } 00916 00918 NTextureData &NTextureData::operator = (const NTextureData ©) 00919 { 00920 ClearData(); 00921 m_NumMipmap = copy.m_NumMipmap; 00922 m_TotalMemorySize = copy.m_TotalMemorySize; 00923 00924 for (t_s32 i = 0; i < copy.GetNumMipmap(); i++) 00925 m_MipSurfaceArray.push_back (new ImageSurface (copy.GetSurface (i) ) ); 00926 00927 return *this; 00928 } 00929 00930 void NTextureData::Allocate (BitmapFormat format, t_s32 width, t_s32 height, t_s32 NumMipmapRequested) 00931 { 00932 nuxAssertMsg (width >= 0, TEXT ("[NTextureData::Allocate] Error: Negative texture width.") ); 00933 nuxAssertMsg (height >= 0, TEXT ("[NTextureData::Allocate] Error: Negative texture height.") ); 00934 nuxAssert (NumMipmapRequested >= 0); 00935 00936 t_s32 NumTotalMipLevel = 1 + (t_s32) Floor (Log2 (Max (width, height) ) ); 00937 m_NumMipmap = NumMipmapRequested; 00938 00939 if (NumMipmapRequested == 0) 00940 m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; 00941 00942 if (NumMipmapRequested > NumTotalMipLevel) 00943 m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; 00944 00945 m_TotalMemorySize = 0; 00946 ClearData(); 00947 00948 for (t_s32 i = 0; i < m_NumMipmap; i++) 00949 { 00950 t_s32 w = width >> i; 00951 t_s32 h = height >> i; 00952 m_MipSurfaceArray.push_back (new ImageSurface (format, w, h) ); 00953 m_TotalMemorySize += m_MipSurfaceArray[i]->GetSize(); 00954 } 00955 } 00956 00957 void NTextureData::AllocateCheckBoardTexture (t_s32 width, t_s32 height, t_s32 NumMipmap, Color color0, Color color1, t_s32 TileWidth, t_s32 TileHeight) 00958 { 00959 Allocate (BITFMT_R8G8B8A8, width, height, NumMipmap); 00960 00961 for (t_s32 i = 0; i < m_NumMipmap; i++) 00962 { 00963 t_s32 w = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetWidth(), i); 00964 t_s32 h = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetHeight(), i); 00965 MakeCheckBoardImage (*m_MipSurfaceArray[i], w, h, color0, color1, TileWidth, TileHeight); 00966 } 00967 } 00968 00969 void NTextureData::AllocateColorTexture (t_s32 width, t_s32 height, t_s32 NumMipmap, Color color0) 00970 { 00971 Allocate (BITFMT_R8G8B8A8, width, height, NumMipmap); 00972 00973 for (t_s32 i = 0; i < m_NumMipmap; i++) 00974 { 00975 t_s32 w = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetWidth(), i); 00976 t_s32 h = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetHeight(), i); 00977 MakeCheckBoardImage (*m_MipSurfaceArray[i], w, h, color0, color0); 00978 } 00979 } 00980 00981 t_s32 NTextureData::GetNumMipmap() const 00982 { 00983 return m_MipSurfaceArray.size(); 00984 } 00985 00986 bool NTextureData::SetSurface (t_s32 MipLevel, const ImageSurface &targetsurface) 00987 { 00988 nuxAssert (MipLevel >= 0); 00989 nuxAssert (MipLevel < m_NumMipmap); 00990 00991 ImageSurface &surface = GetSurface (MipLevel); 00992 00993 if (surface.GetFormat() != targetsurface.GetFormat() ) 00994 return false; 00995 00996 if (surface.GetWidth() != targetsurface.GetWidth() ) 00997 return false; 00998 00999 if (surface.GetHeight() != targetsurface.GetHeight() ) 01000 return false; 01001 01002 surface = targetsurface; 01003 return true; 01004 } 01005 01007 NCubemapData::NCubemapData (BitmapFormat format, t_s32 width, t_s32 height, t_s32 NumMipmap) 01008 : m_NumMipmap (0) 01009 { 01010 Allocate (format, width, height, NumMipmap); 01011 } 01012 01013 NCubemapData::~NCubemapData() 01014 { 01015 ClearData(); 01016 } 01017 01018 void NCubemapData::ClearData() 01019 { 01020 t_s32 n = (t_s32) m_MipSurfaceArray[0].size(); 01021 01022 for (t_s32 i = 0; i < n; i++) 01023 { 01024 delete m_MipSurfaceArray[0][i]; 01025 delete m_MipSurfaceArray[1][i]; 01026 delete m_MipSurfaceArray[2][i]; 01027 delete m_MipSurfaceArray[3][i]; 01028 delete m_MipSurfaceArray[4][i]; 01029 delete m_MipSurfaceArray[5][i]; 01030 } 01031 01032 m_MipSurfaceArray[0].clear(); 01033 m_MipSurfaceArray[1].clear(); 01034 m_MipSurfaceArray[2].clear(); 01035 m_MipSurfaceArray[3].clear(); 01036 m_MipSurfaceArray[4].clear(); 01037 m_MipSurfaceArray[5].clear(); 01038 } 01039 01041 NCubemapData::NCubemapData (const NCubemapData &object) 01042 { 01043 for (t_s32 face = 0; face < 6; face++) 01044 for (t_s32 i = 0; i < object.GetNumMipmap(); i++) 01045 m_MipSurfaceArray[face].push_back (new ImageSurface (object.GetSurface (face, i) ) ); 01046 } 01047 01049 NCubemapData &NCubemapData::operator = (const NCubemapData ©) 01050 { 01051 ClearData(); 01052 m_NumMipmap = copy.m_NumMipmap; 01053 m_TotalMemorySize = copy.m_TotalMemorySize; 01054 01055 for (t_s32 face = 0; face < 6; face++) 01056 for (t_s32 i = 0; i < copy.GetNumMipmap(); i++) 01057 m_MipSurfaceArray[face].push_back (new ImageSurface (copy.GetSurface (face, i) ) ); 01058 01059 return *this; 01060 } 01061 01062 void NCubemapData::Allocate (BitmapFormat format, t_s32 width, t_s32 height, t_s32 NumMipmapRequested) 01063 { 01064 nuxAssertMsg (width >= 0, TEXT ("[NCubemapData::Allocate] Error: Negative texture width.") ); 01065 nuxAssertMsg (height >= 0, TEXT ("[NCubemapData::Allocate] Error: Negative texture height.") ); 01066 nuxAssert (NumMipmapRequested >= 0); 01067 01068 ClearData(); 01069 01070 t_s32 NumTotalMipLevel = 1 + (t_s32) Floor (Log2 (Max (width, height) ) ); 01071 m_NumMipmap = NumMipmapRequested; 01072 01073 if (NumMipmapRequested == 0) 01074 m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; 01075 01076 if (NumMipmapRequested > NumTotalMipLevel) 01077 m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; 01078 01079 m_TotalMemorySize = 0; 01080 01081 for (t_s32 face = 0; face < 6; face++) 01082 { 01083 for (t_s32 i = 0; i < m_NumMipmap; i++) 01084 { 01085 t_s32 w = width >> i; 01086 t_s32 h = height >> i; 01087 m_MipSurfaceArray[face].push_back (new ImageSurface (format, w, h) ); 01088 m_TotalMemorySize += m_MipSurfaceArray[face][i]->GetSize(); 01089 } 01090 } 01091 } 01092 01093 void NCubemapData::AllocateCheckBoardTexture (t_s32 width, t_s32 height, t_s32 NumMipmap, Color color0, Color color1, t_s32 TileWidth, t_s32 TileHeight) 01094 { 01095 Allocate (BITFMT_R8G8B8A8, width, height, NumMipmap); 01096 01097 for (t_s32 face = 0; face < 6; face++) 01098 { 01099 for (t_s32 i = 0; i < m_NumMipmap; i++) 01100 { 01101 t_s32 w = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetWidth(), i); 01102 t_s32 h = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetHeight(), i); 01103 MakeCheckBoardImage (*m_MipSurfaceArray[face][i], w, h, color0, color1, TileWidth, TileHeight); 01104 } 01105 } 01106 } 01107 01108 void NCubemapData::AllocateColorTexture (t_s32 width, t_s32 height, t_s32 NumMipmap, Color color0) 01109 { 01110 Allocate (BITFMT_R8G8B8A8, width, height, NumMipmap); 01111 01112 for (t_s32 face = 0; face < 6; face++) 01113 { 01114 for (t_s32 i = 0; i < m_NumMipmap; i++) 01115 { 01116 t_s32 w = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetWidth(), i); 01117 t_s32 h = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetHeight(), i); 01118 MakeCheckBoardImage (*m_MipSurfaceArray[face][i], w, h, color0, color0); 01119 } 01120 } 01121 } 01122 01123 t_s32 NCubemapData::GetNumMipmap() const 01124 { 01125 return m_MipSurfaceArray[0].size(); 01126 } 01127 01128 bool NCubemapData::SetSurface (t_s32 face, t_s32 MipLevel, const ImageSurface &targetsurface) 01129 { 01130 nuxAssert (face >= 0); 01131 nuxAssert (face < 6); 01132 nuxAssert (MipLevel >= 0); 01133 nuxAssert (MipLevel < m_NumMipmap); 01134 01135 ImageSurface &surface = GetSurface (face, MipLevel); 01136 01137 if (surface.GetFormat() != targetsurface.GetFormat() ) 01138 return false; 01139 01140 if (surface.GetWidth() != targetsurface.GetWidth() ) 01141 return false; 01142 01143 if (surface.GetHeight() != targetsurface.GetHeight() ) 01144 return false; 01145 01146 surface = targetsurface; 01147 return true; 01148 } 01149 01151 NVolumeData::NVolumeData (BitmapFormat format, t_s32 width, t_s32 height, t_s32 depth, t_s32 NumMipmap) 01152 : m_NumMipmap (0) 01153 , m_Depth (0) 01154 , m_MipSurfaceArray (0) 01155 { 01156 Allocate (format, width, height, depth, NumMipmap); 01157 } 01158 01159 NVolumeData::~NVolumeData() 01160 { 01161 ClearData(); 01162 } 01163 01164 void NVolumeData::ClearData() 01165 { 01166 for (t_s32 mip = 0; mip < GetNumMipmap(); mip++) 01167 { 01168 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (GetFormat(), GetDepth(), mip); s++) 01169 { 01170 delete m_MipSurfaceArray[mip][s]; 01171 } 01172 01173 m_MipSurfaceArray[mip].clear(); 01174 } 01175 01176 delete [] m_MipSurfaceArray; 01177 } 01178 01180 NVolumeData::NVolumeData (const NVolumeData &object) 01181 { 01182 for (t_s32 mip = 0; mip < object.GetNumMipmap(); mip++) 01183 { 01184 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (object.GetFormat(), object.GetDepth(), mip); s++) 01185 { 01186 m_MipSurfaceArray[mip].push_back (new ImageSurface (object.GetSurface (mip, s) ) ); 01187 } 01188 } 01189 } 01190 01192 NVolumeData &NVolumeData::operator = (const NVolumeData ©) 01193 { 01194 ClearData(); 01195 m_Depth = copy.m_Depth; 01196 m_NumMipmap = copy.m_NumMipmap; 01197 m_TotalMemorySize = copy.m_TotalMemorySize; 01198 01199 m_MipSurfaceArray = new std::vector<ImageSurface *>[m_NumMipmap]; 01200 01201 for (t_s32 mip = 0; mip < copy.GetNumMipmap(); mip++) 01202 { 01203 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (copy.GetFormat(), copy.GetDepth(), mip); s++) 01204 { 01205 m_MipSurfaceArray[mip].push_back (new ImageSurface (copy.GetSurface (mip, s) ) ); 01206 } 01207 } 01208 01209 return *this; 01210 } 01211 01212 void NVolumeData::Allocate (BitmapFormat format, t_s32 width, t_s32 height, t_s32 depth, t_s32 NumMipmapRequested) 01213 { 01214 nuxAssertMsg (depth >= 0, TEXT ("[NVolumeData::Allocate] Error: Negative number of slice.") ); 01215 nuxAssertMsg (width >= 0, TEXT ("[NVolumeData::Allocate] Error: Negative texture width.") ); 01216 nuxAssertMsg (height >= 0, TEXT ("[NVolumeData::Allocate] Error: Negative texture height.") ); 01217 nuxAssert (NumMipmapRequested >= 0); 01218 01219 ClearData(); 01220 01221 t_s32 NumTotalMipLevel = 1 + (t_s32) Floor (Log2 (Max (width, height) ) ); 01222 m_NumMipmap = NumMipmapRequested; 01223 01224 if (NumMipmapRequested == 0) 01225 m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; 01226 01227 if (NumMipmapRequested > NumTotalMipLevel) 01228 m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; 01229 01230 m_Depth = depth; 01231 01232 m_MipSurfaceArray = new std::vector<ImageSurface *>[m_NumMipmap]; 01233 m_TotalMemorySize = 0; 01234 01235 for (t_s32 mip = 0; mip < m_NumMipmap; mip++) 01236 { 01237 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (format, depth, mip); s++) 01238 { 01239 t_s32 w = ImageSurface::GetLevelDim (format, width, mip); 01240 t_s32 h = ImageSurface::GetLevelDim (format, height, mip); 01241 m_MipSurfaceArray[mip].push_back (new ImageSurface (format, w, h) ); 01242 m_TotalMemorySize += m_MipSurfaceArray[mip][s]->GetSize(); 01243 } 01244 } 01245 } 01246 01247 void NVolumeData::AllocateCheckBoardTexture (t_s32 width, t_s32 height, t_s32 slice, t_s32 NumMipmap, Color color0, Color color1, t_s32 TileWidth, t_s32 TileHeight) 01248 { 01249 Allocate (BITFMT_R8G8B8A8, width, height, slice, NumMipmap); 01250 01251 for (t_s32 mip = 0; mip < m_NumMipmap; mip++) 01252 { 01253 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetDepth(), mip); s++) 01254 { 01255 t_s32 w = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetWidth(), mip); 01256 t_s32 h = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetHeight(), mip); 01257 MakeCheckBoardImage (* (m_MipSurfaceArray[mip][s]), w, h, color0, color1, TileWidth, TileHeight); 01258 } 01259 } 01260 } 01261 01262 void NVolumeData::AllocateColorTexture (t_s32 width, t_s32 height, t_s32 slice, t_s32 NumMipmap, Color color0) 01263 { 01264 Allocate (BITFMT_R8G8B8A8, width, height, slice, NumMipmap); 01265 01266 for (t_s32 mip = 0; mip < m_NumMipmap; mip++) 01267 { 01268 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetDepth(), mip); s++) 01269 { 01270 t_s32 w = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetWidth(), mip); 01271 t_s32 h = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetHeight(), mip); 01272 MakeCheckBoardImage (* (m_MipSurfaceArray[mip][s]), w, h, color0, color0); 01273 } 01274 } 01275 } 01276 01277 t_s32 NVolumeData::GetNumMipmap() const 01278 { 01279 return m_NumMipmap; 01280 } 01281 01282 bool NVolumeData::SetSurface (t_s32 Slice, t_s32 MipLevel, const ImageSurface &targetsurface) 01283 { 01284 nuxAssert (Slice >= 0); 01285 nuxAssert (Slice < m_Depth); 01286 nuxAssert (MipLevel >= 0); 01287 nuxAssert (MipLevel < m_NumMipmap); 01288 01289 ImageSurface &surface = GetSurface (Slice, MipLevel); 01290 01291 if (surface.GetFormat() != targetsurface.GetFormat() ) 01292 return false; 01293 01294 if (surface.GetWidth() != targetsurface.GetWidth() ) 01295 return false; 01296 01297 if (surface.GetHeight() != targetsurface.GetHeight() ) 01298 return false; 01299 01300 surface = targetsurface; 01301 return true; 01302 } 01303 01305 NAnimatedTextureData::NAnimatedTextureData (BitmapFormat format, t_s32 width, t_s32 height, t_s32 depth) 01306 : m_NumMipmap (0) 01307 , m_Depth (0) 01308 , m_MipSurfaceArray (0) 01309 { 01310 Allocate (format, width, height, depth, 1); 01311 } 01312 01313 NAnimatedTextureData::~NAnimatedTextureData() 01314 { 01315 ClearData(); 01316 } 01317 01318 void NAnimatedTextureData::ClearData() 01319 { 01320 for (t_s32 mip = 0; mip < GetNumMipmap(); mip++) 01321 { 01322 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (GetFormat(), GetDepth(), mip); s++) 01323 { 01324 delete m_MipSurfaceArray[mip][s]; 01325 } 01326 01327 m_MipSurfaceArray[mip].clear(); 01328 } 01329 01330 m_FrameTimeArray.clear(); 01331 delete [] m_MipSurfaceArray; 01332 } 01333 01335 NAnimatedTextureData::NAnimatedTextureData (const NAnimatedTextureData &object) 01336 { 01337 for (t_s32 mip = 0; mip < object.GetNumMipmap(); mip++) 01338 { 01339 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (object.GetFormat(), object.GetDepth(), mip); s++) 01340 { 01341 m_MipSurfaceArray[mip].push_back (new ImageSurface (object.GetSurface (mip, s) ) ); 01342 } 01343 } 01344 01345 for (t_s32 frame = 0; frame < object.GetDepth(); frame++) 01346 { 01347 m_FrameTimeArray.push_back (object.GetFrameTime (frame) ); 01348 } 01349 } 01350 01352 NAnimatedTextureData &NAnimatedTextureData::operator = (const NAnimatedTextureData ©) 01353 { 01354 ClearData(); 01355 m_Depth = copy.GetDepth(); 01356 m_NumMipmap = copy.m_NumMipmap; 01357 m_TotalMemorySize = copy.m_TotalMemorySize; 01358 01359 m_MipSurfaceArray = new std::vector<ImageSurface *>[m_NumMipmap]; 01360 01361 for (t_s32 mip = 0; mip < copy.GetNumMipmap(); mip++) 01362 { 01363 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (copy.GetFormat(), copy.GetDepth(), mip); s++) 01364 { 01365 m_MipSurfaceArray[mip].push_back (new ImageSurface (copy.GetSurface (s) ) ); 01366 } 01367 } 01368 01369 for (t_s32 frame = 0; frame < copy.GetDepth(); frame++) 01370 { 01371 m_FrameTimeArray.push_back (copy.GetFrameTime (frame) ); 01372 } 01373 01374 return *this; 01375 } 01376 01377 void NAnimatedTextureData::Allocate (BitmapFormat format, t_s32 width, t_s32 height, t_s32 depth, t_s32 NumMipmapRequested) 01378 { 01379 nuxAssertMsg (depth >= 0, TEXT ("[NAnimatedTextureData::Allocate] Error: Negative number of slice.") ); 01380 nuxAssertMsg (width >= 0, TEXT ("[NAnimatedTextureData::Allocate] Error: Negative texture width.") ); 01381 nuxAssertMsg (height >= 0, TEXT ("[NAnimatedTextureData::Allocate] Error: Negative texture height.") ); 01382 nuxAssert (NumMipmapRequested >= 0); 01383 01384 ClearData(); 01385 01386 t_s32 NumTotalMipLevel = 1 + (t_s32) Floor (Log2 (Max (width, height) ) ); 01387 m_NumMipmap = NumMipmapRequested; 01388 01389 if (NumMipmapRequested == 0) 01390 m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; 01391 01392 if (NumMipmapRequested > NumTotalMipLevel) 01393 m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; 01394 01395 m_Depth = depth; 01396 01397 m_MipSurfaceArray = new std::vector<ImageSurface *>[m_NumMipmap]; 01398 m_TotalMemorySize = 0; 01399 01400 for (t_s32 mip = 0; mip < m_NumMipmap; mip++) 01401 { 01402 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (format, depth, mip); s++) 01403 { 01404 t_s32 w = ImageSurface::GetLevelDim (format, width, mip); 01405 t_s32 h = ImageSurface::GetLevelDim (format, height, mip); 01406 m_MipSurfaceArray[mip].push_back (new ImageSurface (format, w, h) ); 01407 m_TotalMemorySize += m_MipSurfaceArray[mip][s]->GetSize(); 01408 } 01409 } 01410 } 01411 01412 void NAnimatedTextureData::AllocateCheckBoardTexture (t_s32 width, t_s32 height, t_s32 slice, t_s32 NumMipmap, Color color0, Color color1, t_s32 TileWidth, t_s32 TileHeight) 01413 { 01414 Allocate (BITFMT_R8G8B8A8, width, height, slice, NumMipmap); 01415 01416 for (t_s32 mip = 0; mip < m_NumMipmap; mip++) 01417 { 01418 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetDepth(), mip); s++) 01419 { 01420 t_s32 w = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetWidth(), mip); 01421 t_s32 h = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetHeight(), mip); 01422 MakeCheckBoardImage (* (m_MipSurfaceArray[mip][s]), w, h, color0, color1, TileWidth, TileHeight); 01423 } 01424 } 01425 } 01426 01427 void NAnimatedTextureData::AllocateColorTexture (t_s32 width, t_s32 height, t_s32 slice, t_s32 NumMipmap, Color color0) 01428 { 01429 Allocate (BITFMT_R8G8B8A8, width, height, slice, NumMipmap); 01430 01431 for (t_s32 mip = 0; mip < m_NumMipmap; mip++) 01432 { 01433 for (t_s32 s = 0; s < ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetDepth(), mip); s++) 01434 { 01435 t_s32 w = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetWidth(), mip); 01436 t_s32 h = ImageSurface::GetLevelDim (BITFMT_R8G8B8A8, GetHeight(), mip); 01437 MakeCheckBoardImage (* (m_MipSurfaceArray[mip][s]), w, h, color0, color0); 01438 } 01439 } 01440 } 01441 01442 t_s32 NAnimatedTextureData::GetNumMipmap() const 01443 { 01444 return m_NumMipmap; 01445 } 01446 01447 bool NAnimatedTextureData::SetSurface (t_s32 Slice, t_s32 MipLevel, const ImageSurface &targetsurface) 01448 { 01449 nuxAssert (Slice >= 0); 01450 nuxAssert (Slice < m_Depth); 01451 nuxAssert (MipLevel >= 0); 01452 nuxAssert (MipLevel < m_NumMipmap); 01453 01454 ImageSurface &surface = GetSurface (Slice, MipLevel); 01455 01456 if (surface.GetFormat() != targetsurface.GetFormat() ) 01457 return false; 01458 01459 if (surface.GetWidth() != targetsurface.GetWidth() ) 01460 return false; 01461 01462 if (surface.GetHeight() != targetsurface.GetHeight() ) 01463 return false; 01464 01465 surface = targetsurface; 01466 return true; 01467 } 01468 01469 } 01470