# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

texture_bump.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "std3d.h"
00027 
00028 #include "3d/texture_bump.h"
00029 
00030 
00031 namespace NL3D {
00032 
00033 
00035 static void BuildDsDt(uint32 *src, sint width, sint height, uint16 *dest, bool absolute)
00036 {       
00037         #define GET_HGT(x, y) ((sint) ((src[(uint) (x) % width + ((uint) (y) % height) * width] & 0x00ff00) >> 8))
00038         sint x, y;      
00039         for (x = 0; x < width; ++x)
00040         {
00041                 for (y = 0; y < height; ++y)
00042                 {                       
00043                         sint off = x + y * width;
00044                         sint16 ds = (sint16) (GET_HGT(x + 1, y) - GET_HGT(x - 1, y));
00045                         sint16 dt = (sint16) (GET_HGT(x, y + 1) - GET_HGT(x, y - 1));
00046 
00047                         if (!absolute)
00048                         {
00049 
00050                                 dest[off] = (uint16) ((ds & 0xff)  | ((dt & 0xff) << 8));               
00051                         }
00052                         else
00053                         {
00054                                 dest[off] = (uint16) (abs(ds) |  (abs(dt) << 8));
00055                         }
00056                 }
00057         }
00058 }
00059 
00061 static float NormalizeDsDt(uint16 *src, sint width, sint height, bool absolute)
00062 {
00063         const uint size = width * height;
00064         uint highestDelta = 0;
00065         uint k;
00066 
00068         if (absolute)
00069         {
00070                 for (k = 0; k < size; ++k)
00071                 {
00072                         highestDelta = std::max(highestDelta, (uint) (src[k] & 255));
00073                         highestDelta = std::max(highestDelta, (uint) src[k] >> 8);
00074                 }
00075 
00076                 if (highestDelta == 0)
00077                 {
00078                         return 1.f;
00079                 }
00080                 float normalizationFactor = 255.f / highestDelta;
00081                 for (k = 0; k < size; ++k)
00082                 {
00083                         uint8 du = (uint8) ((uint) (src[k] & 0xff) * normalizationFactor);
00084                         uint16 dv = (uint16) (((uint) src[k] >> 8) * normalizationFactor);
00085                         src[k] = (uint16) du | (dv << 8); 
00086                 }
00087                 return 1.f / normalizationFactor;
00088         }
00089         else
00090         {               
00091                 for (k = 0; k < size; ++k)
00092                 {
00093                         highestDelta = std::max(highestDelta, (uint) ::abs((sint) (sint8) (src[k] & 255)));
00094                         highestDelta = std::max(highestDelta, (uint) ::abs((sint) (sint8) (src[k] >> 8)));                      
00095                 }
00096 
00097                 if (highestDelta == 0)
00098                 {
00099                         return 1.f;
00100                 }
00101                 float normalizationFactor = 127.f / highestDelta;
00102                 for (k = 0; k < size; ++k)
00103                 {
00104                         float fdu = (sint8) (src[k] & 255) * normalizationFactor;
00105                         float fdv = (sint8) (src[k] >> 8) * normalizationFactor;
00106                         NLMISC::clamp(fdu, -128, 127);
00107                         NLMISC::clamp(fdv, -128, 127);
00108                         uint8 du = (uint8) (sint8) fdu;
00109                         uint8 dv = (uint8) (sint8) fdv;
00110                         src[k] = (uint16) du | (((uint16) dv) << 8); 
00111                 }
00112                 return 1.f / normalizationFactor;
00113         }
00114 }
00115 
00116 
00117 
00118 /*
00119  * Constructor
00120  */
00121 CTextureBump::CTextureBump() : _NormalizationFactor(0.f),
00122                                                            _DisableSharing(false),
00123                                                            _UseAbsoluteOffsets(false),
00124                                                            _ForceNormalize(true)
00125 {
00126         // mipmapping not supported for now, disable it
00127         ITexture::setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff);
00128 }
00129 
00131 void CTextureBump::setFilterMode(TMagFilter magf, TMinFilter minf)
00132 {       
00133         nlstop; // set filter mode not allowed with bump textures (not supported by some GPUs)
00134 }
00135 
00136 void CTextureBump::setHeightMap(ITexture *heightMap)
00137 {
00138         if (heightMap != _HeightMap)
00139         {
00140                 _HeightMap = heightMap;
00141                 touch();
00142         }
00143 }
00144 
00145 
00147 void CTextureBump::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00148 {
00150         sint ver = f.serialVersion(2);
00151         ITexture::serial(f);
00152         ITexture *tex = NULL;   
00153         if (f.isReading())
00154         {               
00155                 f.serialPolyPtr(tex);
00156                 _HeightMap = tex;
00157                 touch();
00158         }
00159         else
00160         {
00161                 tex = _HeightMap;
00162                 f.serialPolyPtr(tex);
00163         }
00164         f.serial(_DisableSharing);
00165         if (ver >= 1)
00166         {
00167                 f.serial(_UseAbsoluteOffsets);
00168         }
00169         if (ver >= 2)
00170         {
00171                 f.serial(_ForceNormalize);
00172         }
00173 }
00174 
00176 void CTextureBump::doGenerate()
00177 {       
00178         if (!_HeightMap)
00179         {
00180                 makeDummy();
00181                 return;
00182         }
00183         // generate the height map
00184         _HeightMap->generate();
00185         if (!_HeightMap->convertToType(CBitmap::RGBA))
00186         {
00187                 makeDummy();
00188                 return;
00189         }
00190         releaseMipMaps();
00191         uint width = _HeightMap->getWidth();
00192         uint height = _HeightMap->getHeight();
00193         CBitmap::resize(_HeightMap->getWidth(), _HeightMap->getHeight(), CBitmap::DsDt);        
00194         // build the DsDt map
00195         BuildDsDt((uint32 *) &(_HeightMap->getPixels()[0]), width, height, (uint16 *) &(getPixels()[0]), _UseAbsoluteOffsets);
00196 
00197         // Normalize the map if needed
00198         if (_ForceNormalize)
00199         {
00200                 _NormalizationFactor = NormalizeDsDt((uint16 *) &(getPixels()[0]), width, height, _UseAbsoluteOffsets);
00201         }
00202 
00203         if (_HeightMap->getReleasable())
00204         {
00205                 _HeightMap->release();
00206         }
00207 }
00208 
00210 void CTextureBump::release()
00211 {
00212         ITexture::release();
00213         if (_HeightMap != NULL)
00214         {
00215                 if (_HeightMap->getReleasable())
00216                 {
00217                         _HeightMap->release();
00218                 }
00219         }
00220 }
00221 
00222 
00224 bool    CTextureBump::supportSharing() const
00225 {       
00226         return !_DisableSharing && _HeightMap && _HeightMap->supportSharing();  
00227 }
00228 
00229 
00231         std::string     CTextureBump::getShareName() const
00232 {
00233         nlassert(supportSharing());
00234         return "BumpDsDt:" + _HeightMap->getShareName();
00235 }
00236 
00237 
00238 } // NL3D