// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "std3d.h" #include "nel/3d/texture_cube.h" #include "nel/misc/file.h" #include "nel/misc/path.h" #include "nel/misc/debug.h" #include using namespace std; using namespace NLMISC; namespace NL3D { // *************************************************************************** CTextureCube::CTextureCube() { for( uint i = 0; i < 6; ++i ) _Textures[i] = NULL; } // *************************************************************************** void CTextureCube::setTexture(TFace f, ITexture *t) { _Textures[f] = t; } // *************************************************************************** string CTextureCube::getShareName() const { string sTemp; for( uint i = 0; i < 6; ++i ) if( _Textures[i] != NULL ) sTemp += _Textures[i]->getShareName(); return sTemp; } // *************************************************************************** void CTextureCube::doGenerate(bool /* async */) { uint i; ITexture *pRefTex = NULL; for( i = 0; i < 6; ++i ) if( _Textures[i] != NULL ) { pRefTex = _Textures[i]; break; } if( pRefTex == NULL ) return; // There are NO texture pRefTex->generate(); // The reference texture must be square and power of 2 // If not power of 2 resize to the power of 2 just below the current size /* if( ( !isPowerOf2(pRefTex->getWidth()) ) || ( pRefTex->getWidth() != pRefTex->getHeight() ) ) { uint32 nNewSize = pRefTex->getWidth(); if( !isPowerOf2(nNewSize) ) { nNewSize = raiseToNextPowerOf2(nNewSize); // 5 -> 8 | 20 -> 32 nNewSize = getPowerOf2(nNewSize); // 8 -> 3 | 32 -> 5 nNewSize -= 1; // 3 -> 2 | 5 -> 4 nNewSize = 1< 4 | 4 -> 16 } pRefTex->resample( nNewSize, nNewSize ); } */ // All textures must be like the reference texture for( i = 0; i < 6; ++i ) { if( _Textures[i] != NULL ) _Textures[i]->generate(); else _Textures[i] = pRefTex; // The texture must have the same UpLoadFormat if( _Textures[i]->getUploadFormat()!=pRefTex->getUploadFormat() ) { nlwarning("Bad TextureCube: different UpLoad format: %s and %s", _Textures[i]->getShareName().c_str(), pRefTex->getShareName().c_str() ); // => replace the texture with the reference _Textures[i] = pRefTex; } // if Auto format, must have the same PixelFormat else if( _Textures[i]->getUploadFormat()==ITexture::Auto && _Textures[i]->getPixelFormat()!=pRefTex->getPixelFormat() ) { nlwarning("Bad TextureCube: different Pixel format: %s and %s", _Textures[i]->getShareName().c_str(), pRefTex->getShareName().c_str() ); // => replace the texture with the reference _Textures[i] = pRefTex; } // The textures must have the same size. if( ( _Textures[i]->getWidth() != pRefTex->getWidth() ) || ( _Textures[i]->getHeight() != pRefTex->getHeight() ) ) { // If can't resample the bitmap if( _Textures[i]->getPixelFormat()!=CBitmap::RGBA ) { nlwarning("Bad TextureCube: different Size (not RGBA): %s and %s", _Textures[i]->getShareName().c_str(), pRefTex->getShareName().c_str() ); // => replace the texture with the reference _Textures[i] = pRefTex; } else { // Ok, can resample the bitmap. _Textures[i]->resample( pRefTex->getWidth(), pRefTex->getHeight() ); } } } } // *************************************************************************** void CTextureCube::release() { uint i; for( i = 0; i < 6; ++i ) if( _Textures[i] != NULL ) _Textures[i]->release(); } // *************************************************************************** void CTextureCube::serial(NLMISC::IStream &f) throw(NLMISC::EStream) { sint ver= f.serialVersion(2); // serial the base part of ITexture. ITexture::serial(f); for( uint i = 0; i < 6; ++i ) { ITexture *tex = _Textures[i]; f.serialPolyPtr( tex ); _Textures[i] = tex; } if( f.isReading() ) touch(); if (ver == 1) { bool temp; f.serial(temp); } } // *************************************************************************** void CTextureCube::selectTexture(uint index) { for( uint i = 0; i < 6; ++i ) { if (_Textures[i]) _Textures[i]->selectTexture(index); } touch(); } // *************************************************************************** bool CTextureCube::isSelectable() const { for( uint i = 0; i < 6; ++i ) { if (_Textures[i] && _Textures[i]->isSelectable()) return true; } return false; } // *************************************************************************** ITexture *CTextureCube::buildNonSelectableVersion(uint index) { if (!isSelectable()) return this; std::auto_ptr tc(new CTextureCube); // copy basic texture parameters (ITexture &) *tc.get() = (ITexture &) *this; // invoke ITexture = op for basics parameters for( uint i = 0; i < 6; ++i ) { tc->_Textures[i] = _Textures[i]->buildNonSelectableVersion(index); } return tc.release(); } } // NL3D