Merge branch 'ryzom/ark-features' into main/gingo-test
[ryzomcore.git] / nel / src / 3d / texture_cube.cpp
blob34737af4fca1fd53dbe063b6bd2c4d32a651ba16
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "std3d.h"
19 #include "nel/3d/texture_cube.h"
20 #include "nel/misc/file.h"
21 #include "nel/misc/path.h"
22 #include "nel/misc/debug.h"
23 #include <memory>
25 using namespace std;
26 using namespace NLMISC;
28 #ifdef DEBUG_NEW
29 #define new DEBUG_NEW
30 #endif
32 namespace NL3D
35 // ***************************************************************************
36 CTextureCube::CTextureCube()
38 for( uint i = 0; i < 6; ++i )
39 _Textures[i] = NULL;
42 // ***************************************************************************
43 void CTextureCube::setTexture(TFace f, ITexture *t)
45 _Textures[f] = t;
48 // ***************************************************************************
49 string CTextureCube::getShareName() const
51 string sTemp;
53 for( uint i = 0; i < 6; ++i )
54 if( _Textures[i] != NULL )
55 sTemp += _Textures[i]->getShareName();
56 return sTemp;
59 // ***************************************************************************
60 void CTextureCube::doGenerate(bool /* async */)
62 uint i;
63 ITexture *pRefTex = NULL;
65 for( i = 0; i < 6; ++i )
66 if( _Textures[i] != NULL )
68 pRefTex = _Textures[i];
69 break;
72 if( pRefTex == NULL )
73 return; // There are NO texture
75 pRefTex->generate();
76 // The reference texture must be square and power of 2
77 // If not power of 2 resize to the power of 2 just below the current size
79 if( ( !isPowerOf2(pRefTex->getWidth()) ) || ( pRefTex->getWidth() != pRefTex->getHeight() ) )
81 uint32 nNewSize = pRefTex->getWidth();
82 if( !isPowerOf2(nNewSize) )
84 nNewSize = raiseToNextPowerOf2(nNewSize); // 5 -> 8 | 20 -> 32
85 nNewSize = getPowerOf2(nNewSize); // 8 -> 3 | 32 -> 5
86 nNewSize -= 1; // 3 -> 2 | 5 -> 4
87 nNewSize = 1<<nNewSize; // 2 -> 4 | 4 -> 16
90 pRefTex->resample( nNewSize, nNewSize );
94 // All textures must be like the reference texture
95 for( i = 0; i < 6; ++i )
97 if( _Textures[i] != NULL )
98 _Textures[i]->generate();
99 else
100 _Textures[i] = pRefTex;
102 // The texture must have the same UpLoadFormat
103 if( _Textures[i]->getUploadFormat()!=pRefTex->getUploadFormat() )
105 nlwarning("Bad TextureCube: different UpLoad format: %s and %s",
106 _Textures[i]->getShareName().c_str(), pRefTex->getShareName().c_str() );
107 // => replace the texture with the reference
108 _Textures[i] = pRefTex;
110 // if Auto format, must have the same PixelFormat
111 else if( _Textures[i]->getUploadFormat()==ITexture::Auto && _Textures[i]->getPixelFormat()!=pRefTex->getPixelFormat() )
113 nlwarning("Bad TextureCube: different Pixel format: %s and %s",
114 _Textures[i]->getShareName().c_str(), pRefTex->getShareName().c_str() );
115 // => replace the texture with the reference
116 _Textures[i] = pRefTex;
119 // The textures must have the same size.
120 if( ( _Textures[i]->getWidth() != pRefTex->getWidth() ) ||
121 ( _Textures[i]->getHeight() != pRefTex->getHeight() ) )
123 // If can't resample the bitmap
124 if( _Textures[i]->getPixelFormat()!=CBitmap::RGBA )
126 nlwarning("Bad TextureCube: different Size (not RGBA): %s and %s",
127 _Textures[i]->getShareName().c_str(), pRefTex->getShareName().c_str() );
128 // => replace the texture with the reference
129 _Textures[i] = pRefTex;
131 else
133 // Ok, can resample the bitmap.
134 _Textures[i]->resample( pRefTex->getWidth(), pRefTex->getHeight() );
140 // ***************************************************************************
141 void CTextureCube::release()
143 uint i;
144 for( i = 0; i < 6; ++i )
145 if( _Textures[i] != NULL )
146 _Textures[i]->release();
149 // ***************************************************************************
150 void CTextureCube::serial(NLMISC::IStream &f)
152 sint ver= f.serialVersion(2);
154 // serial the base part of ITexture.
155 ITexture::serial(f);
157 for( uint i = 0; i < 6; ++i )
159 ITexture *tex = _Textures[i];
160 f.serialPolyPtr( tex );
161 _Textures[i] = tex;
163 if( f.isReading() )
164 touch();
166 if (ver == 1)
168 bool temp;
169 f.serial(temp);
175 // ***************************************************************************
176 void CTextureCube::selectTexture(uint index)
178 for( uint i = 0; i < 6; ++i )
180 if (_Textures[i]) _Textures[i]->selectTexture(index);
182 touch();
185 // ***************************************************************************
186 bool CTextureCube::isSelectable() const
188 for( uint i = 0; i < 6; ++i )
190 if (_Textures[i] && _Textures[i]->isSelectable()) return true;
192 return false;
195 // ***************************************************************************
196 ITexture *CTextureCube::buildNonSelectableVersion(uint index)
198 if (!isSelectable()) return this;
199 CUniquePtr<CTextureCube> tc(new CTextureCube);
201 // copy basic texture parameters
202 (ITexture &) *tc.get() = (ITexture &) *this; // invoke ITexture = op for basics parameters
204 for( uint i = 0; i < 6; ++i )
206 tc->_Textures[i] = _Textures[i]->buildNonSelectableVersion(index);
208 return tc.release();
212 } // NL3D