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/mesh_blender.h"
20 #include "nel/3d/driver.h"
21 #include "nel/misc/fast_floor.h"
30 // ***************************************************************************
31 void CMeshBlender::prepareRenderForGlobalAlpha(CMaterial
&material
, IDriver
*drv
, float globalAlpha
, uint8 globalAlphaInt
, bool gaDisableZWrite
)
36 // Backup and set new the zwrite
37 _BkZWrite
=material
.getZWrite ();
38 material
.setZWrite (false);
42 _BkBlend
=material
.getBlend ();
43 material
.setBlend (true);
45 // Backup opacity and blend
46 _BkOpacity
= material
.getOpacity ();
47 _BkSrcBlend
= material
.getSrcBlend();
48 _BkDstBlend
= material
.getDstBlend();
50 // 2 ways: if Blend Constant Color is supported or not.
51 if(drv
->supportBlendConstantColor())
53 // Set opacity to 255 => If AlphaTest is used, AlphaTexture will be multiplied by 1.
54 material
.setOpacity ( 255 );
56 // set the Blend constant Alpha.
57 drv
->setBlendConstantColor( CRGBA(0,0,0, globalAlphaInt
) );
59 // Active Blend with Blend Constant Alpha .
60 material
.setSrcBlend(CMaterial::blendConstantAlpha
);
62 // Don't set dest if we are in additive blend mode
63 if ((_BkBlend
== false) || (_BkDstBlend
!= CMaterial::one
))
64 material
.setDstBlend(CMaterial::blendConstantInvAlpha
);
66 // if material is Alpha Test, no-op. Keep same threshold, since Use Alpha of the BlendConstantColor
67 // to do the alpha-blending.
69 // not supported, ugly way: modify Opacity, and alpha threshold
73 material
.setOpacity (globalAlphaInt
);
75 // must ensure Std Blend.
76 material
.setSrcBlend(CMaterial::srcalpha
);
78 // Don't set dest if we are in additive blend mode
79 if ((_BkBlend
== false) || (_BkDstBlend
!= CMaterial::one
))
80 material
.setDstBlend(CMaterial::invsrcalpha
);
82 // if material is Alpha Test, must modulate AlphaTest limit to avoid Pop effects
83 if(material
.getAlphaTest())
85 _BkAlphaTestThreshold
= material
.getAlphaTestThreshold();
86 material
.setAlphaTestThreshold(_BkAlphaTestThreshold
* globalAlpha
);
92 // ***************************************************************************
93 void CMeshBlender::restoreRender(CMaterial
&material
, IDriver
*drv
, bool gaDisableZWrite
)
95 // Resetup backuped zwrite
98 material
.setZWrite (_BkZWrite
);
101 // Resetup backuped blend
102 material
.setBlend (_BkBlend
);
104 // Resetup backuped opacity and blend factors
105 material
.setOpacity (_BkOpacity
);
106 material
.setSrcBlend(_BkSrcBlend
);
107 material
.setDstBlend(_BkDstBlend
);
109 // 2 ways: if Blend Constant Color is supported or not.
110 if(drv
->supportBlendConstantColor())
116 // Resetup backuped AlphaTest threshold
117 if(material
.getAlphaTest())
119 material
.setAlphaTestThreshold(_BkAlphaTestThreshold
);
125 // ***************************************************************************
126 void CMeshBlender::prepareRenderForGlobalAlphaCoarseMesh(CMaterial
&material
, IDriver
*drv
, NLMISC::CRGBA color
, float globalAlpha
, bool gaDisableZWrite
)
128 // Don't need to bkup some values, because CoarseMesh.
130 uint8 globalAlphaInt
= (uint8
)NLMISC::OptFastFloor(255 * globalAlpha
);
134 material
.setZWrite (false);
136 material
.setBlend (true);
138 // bkup color and blend factors.
139 _BkupColor
= material
.getColor();
140 _BkSrcBlend
= material
.getSrcBlend();
141 _BkDstBlend
= material
.getDstBlend();
143 // 2 ways: if Blend Constant Color is supported or not.
144 if(drv
->supportBlendConstantColor())
146 // Set opacity to 255 => AlphaTexture will be multiplied by 1.
149 material
.setColor ( color
);
151 // set the Blend constant Alpha.
152 drv
->setBlendConstantColor( CRGBA(0,0,0, globalAlphaInt
) );
154 // Active Blend with Blend Constant Alpha .
155 material
.setSrcBlend(CMaterial::blendConstantAlpha
);
156 material
.setDstBlend(CMaterial::blendConstantInvAlpha
);
160 // Set current Alpha blend transparency (in color becausematerial is unlit)
161 color
.A
= globalAlphaInt
;
163 material
.setColor ( color
);
165 // Active Blend with Blend Constant Alpha .
166 material
.setSrcBlend(CMaterial::srcalpha
);
167 material
.setDstBlend(CMaterial::invsrcalpha
);
169 // must modulate AlphaTest limit to avoid Pop effects
170 material
.setAlphaTestThreshold(0.5f
* globalAlpha
);
174 // ***************************************************************************
175 void CMeshBlender::restoreRenderCoarseMesh(CMaterial
&material
, IDriver
*drv
, bool gaDisableZWrite
)
177 // Resetup backuped color and blend factors
178 material
.setColor ( _BkupColor
);
179 material
.setSrcBlend(_BkSrcBlend
);
180 material
.setDstBlend(_BkDstBlend
);
184 material
.setZWrite (true);
186 material
.setBlend (false);
188 // 2 ways: if Blend Constant Color is supported or not.
189 if(drv
->supportBlendConstantColor())
195 // reset AlphaTest limit
196 material
.setAlphaTestThreshold(0.5f
);