nux-1.14.0
ImageSurface.cpp
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #include "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 &copy)
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 &copy)
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 &copy)
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 &copy)
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 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends