Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / 3d / ps_dot.cpp
blob3082e506b8ec58a30b01c4ebdf746ce616ef6c52
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/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"
28 #ifdef DEBUG_NEW
29 #define new DEBUG_NEW
30 #endif
32 namespace NL3D
35 static const uint dotBufSize = 1024; // size used for point particles batching
38 ///////////////////////////
39 // CPSDot implementation //
40 ///////////////////////////
42 /// static members
43 CVertexBuffer CPSDot::_DotVb;
44 CVertexBuffer CPSDot::_DotVbColor;
47 ///===================================================================
48 template <class T>
49 inline void DrawDot(T it,
50 CVertexBuffer &vb,
51 CPSAttribMaker<NLMISC::CRGBA> *colorScheme,
52 uint leftToDo,
53 CPSLocated *owner,
54 CMaterial &mat,
55 IDriver *driver,
56 uint32 srcStep
59 NL_PS_FUNC(DrawDot)
60 nlassert(leftToDo != 0);
61 const uint total = leftToDo;
62 T itEnd;
63 if (colorScheme)
65 // compute the colors
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;
74 vb.lock (vba);
75 if (colorScheme)
77 // compute the colors
78 colorScheme->make(owner,
79 total - leftToDo,
80 vba.getColorPointer(),
81 vb.getVertexSize(),
82 toProcess,
83 false,
84 srcStep
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;
94 ++it ;
95 currPos += stride;
97 while (it != itEnd);
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);
103 it += toProcess;
105 else
107 itEnd = it + toProcess;
108 uint8 *currPos = (uint8 *) vba.getVertexCoordPointer();
111 CHECK_VERTEX_BUFFER(vb, currPos);
112 *((CVector *) currPos) = *it;
113 ++it ;
114 currPos += sizeof(float[3]);
116 while (it != itEnd);
119 driver->activeVertexBuffer(vb);
120 driver->renderRawPoints(mat, 0, toProcess);
122 leftToDo -= toProcess;
124 while (leftToDo);
128 ///===================================================================
129 void CPSDot::draw(bool opaque)
131 // if (!FilterPS[0]) return;
132 NL_PS_FUNC(CPSDot_draw)
133 PARTICLES_CHECK_MEM;
134 if (!_Owner->getSize()) return;
136 uint32 step;
137 uint numToProcess;
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)
152 NLMISC::CRGBA col;
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);
161 else
163 col = _Color;
165 _Mat.setColor(col);
166 forceTexturedMaterialStages(0);
168 else
170 forceTexturedMaterialStages(1);
171 if (ps.getForceGlobalColorLightingFlag() || usesGlobalColorLighting())
173 _Mat.texConstantColor(0, ps.getGlobalColorLighted());
175 else
177 _Mat.texConstantColor(0, ps.getGlobalColor());
179 SetupModulatedStage(_Mat, 0, CMaterial::Diffuse, CMaterial::Constant);
181 //////
185 // Use the right drawing routine (auto-lod and non auto-lod)
186 if (step == (1 << 16))
188 DrawDot(_Owner->getPos().begin(),
190 _ColorScheme,
191 numToProcess,
192 _Owner,
193 _Mat,
194 driver,
195 step
198 else
200 DrawDot(TIteratorVectStep1616(_Owner->getPos().begin(), 0, step),
202 _ColorScheme,
203 numToProcess,
204 _Owner,
205 _Mat,
206 driver,
207 step
211 PARTICLES_CHECK_MEM;
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)
245 nlassert(_Owner);
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));
289 resizeColor(size);
292 ///===================================================================
293 void CPSDot::serial(NLMISC::IStream &f)
295 NL_PS_FUNC(CPSDot_IStream )
297 f.serialVersion(1);
300 CPSParticle::serial(f);
301 CPSColoredParticle::serialColorScheme(f);
302 serialMaterial(f);
303 if (f.isReading())
305 init();
309 } // NL3D