Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / 3d / texture_emboss.cpp
bloba106454f436e46dad946eb6b44c4c32075231cff
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"
18 #include "nel/3d/texture_emboss.h"
20 using namespace NLMISC;
22 #ifdef DEBUG_NEW
23 #define new DEBUG_NEW
24 #endif
26 namespace NL3D {
28 // ***********************************************************************************************************
29 CTextureEmboss::CTextureEmboss() : _Ambient(CRGBA::Black),
30 _Diffuse(CRGBA::White),
31 _DisableSharing(false),
32 _SlopeFactor(1.f)
34 _LightDir.set(1.f, 1.f, 1.f);
35 _LightDir.normalize();
39 // ***********************************************************************************************************
40 void CTextureEmboss::setHeightMap(ITexture *heightMap)
42 if (heightMap != _HeightMap)
44 _HeightMap = heightMap;
45 touch();
49 // ***********************************************************************************************************
50 void CTextureEmboss::serial(NLMISC::IStream &f)
52 f.serialVersion(0);
53 ITexture::serial(f);
54 ITexture *tex = NULL;
55 if (f.isReading())
57 f.serialPolyPtr(tex);
58 _HeightMap = tex;
59 touch();
61 else
63 tex = _HeightMap;
64 f.serialPolyPtr(tex);
66 f.serial(_Ambient);
67 f.serial(_Diffuse);
68 f.serial(_LightDir);
69 f.serial(_DisableSharing);
72 // ***********************************************************************************************************
73 bool CTextureEmboss::supportSharing() const
75 return !_DisableSharing && _HeightMap && _HeightMap->supportSharing();
78 // ***********************************************************************************************************
79 std::string CTextureEmboss::getShareName() const
81 nlassert(supportSharing());
82 return "Emboss:" + _HeightMap->getShareName();
85 // ***********************************************************************************************************
86 void CTextureEmboss::release()
88 ITexture::release();
89 if (_HeightMap != NULL)
91 if (_HeightMap->getReleasable())
93 _HeightMap->release();
98 // ***********************************************************************************************************
99 void CTextureEmboss::doGenerate(bool /* async */)
101 if (!_HeightMap)
103 makeDummy();
104 return;
106 // generate the height map
107 _HeightMap->generate();
108 if (!_HeightMap->convertToType(CBitmap::RGBA))
110 makeDummy();
111 return;
113 CBitmap::resize(_HeightMap->getWidth(), _HeightMap->getHeight(), CBitmap::RGBA);
114 releaseMipMaps();
115 uint width = _HeightMap->getWidth();
116 uint height = _HeightMap->getHeight();
118 const CRGBA *src = (CRGBA *) &(_HeightMap->getPixels(0)[0]);
119 CRGBA *dest = (CRGBA *) &(getPixels(0)[0]);
120 CVector normal;
121 for (uint y = 0; y < height; ++y)
123 for (uint x = 0; x < width; ++x)
125 // get position of each adajacent pixel (sure, it can be optimized)
126 const CRGBA *pixelRight = (x != width - 1) ? (src + 1) : (src + 1 - width );
127 const CRGBA *pixelLeft = (x != 0) ? (src - 1) : (src + width - 1);
128 const CRGBA *pixelTop = (y != 0) ? (src - width) : (src + width * (height - 1));
129 const CRGBA *pixelBottom = (y != (height - 1)) ? (src + width) : (src - width * (height - 1));
131 normal.x = ((sint16) pixelRight->R - (sint16) pixelLeft->R) / 256.f;
132 normal.y = ((sint16) pixelTop->R - (sint16) pixelBottom->R) / 256.f;
133 normal.x *= _SlopeFactor;
134 NLMISC::clamp(normal.x, -1.f, 1.f);
135 normal.y *= _SlopeFactor;
136 NLMISC::clamp(normal.y, -1.f, 1.f);
137 normal.z = 1.f;
138 normal.normalize();
140 float colorValue = _LightDir * normal;
141 if (colorValue <= 0.f) colorValue = 0.f;
143 CRGBA diffuse;
144 *dest = _Ambient;
145 diffuse.modulateFromui(_Diffuse, (uint) (255.f * colorValue));
146 dest->add(*dest, diffuse);
147 dest->A = 255;
149 ++ src;
150 ++ dest;
154 if (_HeightMap->getReleasable())
156 _HeightMap->release();