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/ps_dot.h"
20 #include "nel/3d/ps_macro.h"
21 #include "nel/3d/ps_iterator.h"
22 #include "nel/3d/driver.h"
23 #include "nel/3d/particle_system.h"
24 #include "nel/3d/debug_vb.h"
26 #include "nel/misc/fast_mem.h"
35 static const uint dotBufSize
= 1024; // size used for point particles batching
38 ///////////////////////////
39 // CPSDot implementation //
40 ///////////////////////////
43 CVertexBuffer
CPSDot::_DotVb
;
44 CVertexBuffer
CPSDot::_DotVbColor
;
47 ///===================================================================
49 inline void DrawDot(T it
,
51 CPSAttribMaker
<NLMISC::CRGBA
> *colorScheme
,
60 nlassert(leftToDo
!= 0);
61 const uint total
= leftToDo
;
66 colorScheme
->setColorType(driver
->getVertexColorFormat());
70 uint toProcess
= leftToDo
< dotBufSize
? leftToDo
: dotBufSize
;
71 vb
.setNumVertices(toProcess
); // because of volatile vb copy, indicate the numebr of vertices to copy
73 CVertexBufferReadWrite vba
;
78 colorScheme
->make(owner
,
80 vba
.getColorPointer(),
87 itEnd
= it
+ toProcess
;
88 uint8
*currPos
= (uint8
*) vba
.getVertexCoordPointer();
89 uint32 stride
= vb
.getVertexSize();
92 CHECK_VERTEX_BUFFER(vb
, currPos
);
93 *((CVector
*) currPos
) = *it
;
99 else if (srcStep
== (1 << 16)) // make sure we haven't got auto-lod and that the step is 1.0
101 // there's no color information in the buffer, so we can copy it directly
102 NLMISC::CFastMem::memcpy(vba
.getVertexCoordPointer(), &(*it
), sizeof(NLMISC::CVector
) * toProcess
);
107 itEnd
= it
+ toProcess
;
108 uint8
*currPos
= (uint8
*) vba
.getVertexCoordPointer();
111 CHECK_VERTEX_BUFFER(vb
, currPos
);
112 *((CVector
*) currPos
) = *it
;
114 currPos
+= sizeof(float[3]);
119 driver
->activeVertexBuffer(vb
);
120 driver
->renderRawPoints(mat
, 0, toProcess
);
122 leftToDo
-= toProcess
;
128 ///===================================================================
129 void CPSDot::draw(bool opaque
)
131 // if (!FilterPS[0]) return;
132 NL_PS_FUNC(CPSDot_draw
)
134 if (!_Owner
->getSize()) return;
138 computeSrcStep(step
, numToProcess
);
139 if (!numToProcess
) return;
141 _Owner
->incrementNbDrawnParticles(numToProcess
); // for benchmark purpose
142 setupDriverModelMatrix();
143 IDriver
*driver
= getDriver();
144 CVertexBuffer
&vb
= _ColorScheme
? _DotVbColor
: _DotVb
;
148 /// update the material if the global color of the system is variable
149 CParticleSystem
&ps
= *(_Owner
->getOwner());
150 if (_ColorScheme
== NULL
)
153 if (ps
.getForceGlobalColorLightingFlag() || usesGlobalColorLighting())
155 col
.modulateFromColor(ps
.getGlobalColorLighted(), _Color
);
157 else if (ps
.getColorAttenuationScheme() != NULL
|| ps
.isUserColorUsed())
159 col
.modulateFromColor(ps
.getGlobalColor(), _Color
);
166 forceTexturedMaterialStages(0);
170 forceTexturedMaterialStages(1);
171 if (ps
.getForceGlobalColorLightingFlag() || usesGlobalColorLighting())
173 _Mat
.texConstantColor(0, ps
.getGlobalColorLighted());
177 _Mat
.texConstantColor(0, ps
.getGlobalColor());
179 SetupModulatedStage(_Mat
, 0, CMaterial::Diffuse
, CMaterial::Constant
);
185 // Use the right drawing routine (auto-lod and non auto-lod)
186 if (step
== (1 << 16))
188 DrawDot(_Owner
->getPos().begin(),
200 DrawDot(TIteratorVectStep1616(_Owner
->getPos().begin(), 0, step
),
215 ///===================================================================
216 /// init the vertex buffers
217 void CPSDot::initVertexBuffers()
219 NL_PS_FUNC(CPSDot_initVertexBuffers
)
220 _DotVb
.setName("CPSDot::_DotVb");
221 _DotVb
.setPreferredMemory(CVertexBuffer::AGPVolatile
, false);
222 _DotVb
.setVertexFormat(CVertexBuffer::PositionFlag
);
223 _DotVb
.setNumVertices(dotBufSize
);
224 _DotVbColor
.setVertexFormat(CVertexBuffer::PositionFlag
| CVertexBuffer::PrimaryColorFlag
);
225 _DotVbColor
.setPreferredMemory(CVertexBuffer::AGPVolatile
, true); // keep local mem because of interleaved fill
226 _DotVbColor
.setNumVertices(dotBufSize
);
227 _DotVbColor
.setName("CPSDot::_DotVbColor");
231 ///===================================================================
232 void CPSDot::init(void)
234 NL_PS_FUNC(CPSDot_init
)
235 _Mat
.setLighting(false);
236 _Mat
.setZFunc(CMaterial::less
);
238 updateMatAndVbForColor();
241 ///===================================================================
242 uint32
CPSDot::getNumWantedTris() const
244 NL_PS_FUNC(CPSDot_getNumWantedTris
)
246 //return _Owner->getMaxSize();
247 return _Owner
->getSize();
250 ///===================================================================
251 void CPSDot::newElement(const CPSEmitterInfo
&info
)
253 NL_PS_FUNC(CPSDot_newElement
)
254 newColorElement(info
);
257 ///===================================================================
258 void CPSDot::deleteElement(uint32 index
)
260 NL_PS_FUNC(CPSDot_deleteElement
)
261 deleteColorElement(index
);
264 ///===================================================================
265 void CPSDot::updateMatAndVbForColor(void)
267 NL_PS_FUNC(CPSDot_updateMatAndVbForColor
)
270 ///===================================================================
271 bool CPSDot::hasTransparentFaces(void)
273 NL_PS_FUNC(CPSDot_hasTransparentFaces
)
274 return getBlendingMode() != CPSMaterial::alphaTest
;
277 ///===================================================================
278 bool CPSDot::hasOpaqueFaces(void)
280 NL_PS_FUNC(CPSDot_hasOpaqueFaces
)
281 return !hasTransparentFaces();
284 ///===================================================================
285 void CPSDot::resize(uint32 size
)
287 NL_PS_FUNC(CPSDot_resize
)
288 nlassert(size
< (1 << 16));
292 ///===================================================================
293 void CPSDot::serial(NLMISC::IStream
&f
)
295 NL_PS_FUNC(CPSDot_IStream
)
300 CPSParticle::serial(f
);
301 CPSColoredParticle::serialColorScheme(f
);