1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
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"
26 using namespace NLMISC
;
35 // ***************************************************************************
36 CTextureCube::CTextureCube()
38 for( uint i
= 0; i
< 6; ++i
)
42 // ***************************************************************************
43 void CTextureCube::setTexture(TFace f
, ITexture
*t
)
48 // ***************************************************************************
49 string
CTextureCube::getShareName() const
53 for( uint i
= 0; i
< 6; ++i
)
54 if( _Textures
[i
] != NULL
)
55 sTemp
+= _Textures
[i
]->getShareName();
59 // ***************************************************************************
60 void CTextureCube::doGenerate(bool /* async */)
63 ITexture
*pRefTex
= NULL
;
65 for( i
= 0; i
< 6; ++i
)
66 if( _Textures
[i
] != NULL
)
68 pRefTex
= _Textures
[i
];
73 return; // There are NO texture
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();
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
;
133 // Ok, can resample the bitmap.
134 _Textures
[i
]->resample( pRefTex
->getWidth(), pRefTex
->getHeight() );
140 // ***************************************************************************
141 void CTextureCube::release()
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.
157 for( uint i
= 0; i
< 6; ++i
)
159 ITexture
*tex
= _Textures
[i
];
160 f
.serialPolyPtr( tex
);
175 // ***************************************************************************
176 void CTextureCube::selectTexture(uint index
)
178 for( uint i
= 0; i
< 6; ++i
)
180 if (_Textures
[i
]) _Textures
[i
]->selectTexture(index
);
185 // ***************************************************************************
186 bool CTextureCube::isSelectable() const
188 for( uint i
= 0; i
< 6; ++i
)
190 if (_Textures
[i
] && _Textures
[i
]->isSelectable()) return true;
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
);