00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "std3d.h"
00025
00026 #include "nel/3d/ps_dot.h"
00027 #include "nel/3d/ps_macro.h"
00028 #include "nel/3d/ps_iterator.h"
00029 #include "nel/3d/driver.h"
00030 #include "nel/3d/particle_system.h"
00031 #include "nel/misc/fast_mem.h"
00032
00033 namespace NL3D
00034 {
00035
00036 static const uint dotBufSize = 1024;
00037
00038
00040
00042
00044 CVertexBuffer CPSDot::_DotVb;
00045 CVertexBuffer CPSDot::_DotVbColor;
00046
00047
00049 template <class T>
00050 inline void DrawDot(T it,
00051 CVertexBuffer &vb,
00052 CPSAttribMaker<NLMISC::CRGBA> *colorScheme,
00053 uint leftToDo,
00054 CPSLocated *owner,
00055 CMaterial &mat,
00056 IDriver *driver,
00057 uint32 srcStep
00058 )
00059 {
00060 NL_PS_FUNC(DrawDot)
00061 nlassert(leftToDo != 0);
00062 const uint total = leftToDo;
00063 T itEnd;
00064 if (colorScheme)
00065 {
00066
00067 colorScheme->setColorType(driver->getVertexColorFormat());
00068 }
00069 do
00070 {
00071 uint toProcess = leftToDo < dotBufSize ? leftToDo : dotBufSize;
00072 vb.setNumVertices(toProcess);
00073 {
00074 CVertexBufferReadWrite vba;
00075 vb.lock (vba);
00076 if (colorScheme)
00077 {
00078
00079 colorScheme->make(owner,
00080 total - leftToDo,
00081 vba.getColorPointer(),
00082 vb.getVertexSize(),
00083 toProcess,
00084 false,
00085 srcStep
00086 );
00087
00088 itEnd = it + toProcess;
00089 uint8 *currPos = (uint8 *) vba.getVertexCoordPointer();
00090 uint32 stride = vb.getVertexSize();
00091 do
00092 {
00093 CHECK_VERTEX_BUFFER(vb, currPos);
00094 *((CVector *) currPos) = *it;
00095 ++it ;
00096 currPos += stride;
00097 }
00098 while (it != itEnd);
00099 }
00100 else if (srcStep == (1 << 16))
00101 {
00102
00103 NLMISC::CFastMem::memcpy(vba.getVertexCoordPointer(), &(*it), sizeof(NLMISC::CVector) * toProcess);
00104 it += toProcess;
00105 }
00106 else
00107 {
00108 itEnd = it + toProcess;
00109 uint8 *currPos = (uint8 *) vba.getVertexCoordPointer();
00110 do
00111 {
00112 CHECK_VERTEX_BUFFER(vb, currPos);
00113 *((CVector *) currPos) = *it;
00114 ++it ;
00115 currPos += sizeof(float[3]);
00116 }
00117 while (it != itEnd);
00118 }
00119 }
00120 driver->activeVertexBuffer(vb);
00121 driver->renderRawPoints(mat, 0, toProcess);
00122
00123 leftToDo -= toProcess;
00124 }
00125 while (leftToDo);
00126 }
00127
00128
00130 void CPSDot::draw(bool opaque)
00131 {
00132
00133 NL_PS_FUNC(CPSDot_draw)
00134 PARTICLES_CHECK_MEM;
00135 if (!_Owner->getSize()) return;
00136
00137 uint32 step;
00138 uint numToProcess;
00139 computeSrcStep(step, numToProcess);
00140 if (!numToProcess) return;
00141
00142 _Owner->incrementNbDrawnParticles(numToProcess);
00143 setupDriverModelMatrix();
00144 IDriver *driver = getDriver();
00145 CVertexBuffer &vb = _ColorScheme ? _DotVbColor : _DotVb;
00146
00147
00148
00150 CParticleSystem &ps = *(_Owner->getOwner());
00151 if (_ColorScheme == NULL)
00152 {
00153 NLMISC::CRGBA col;
00154 if (ps.getForceGlobalColorLightingFlag() || usesGlobalColorLighting())
00155 {
00156 col.modulateFromColor(ps.getGlobalColorLighted(), _Color);
00157 }
00158 else if (ps.getColorAttenuationScheme() != NULL || ps.isUserColorUsed())
00159 {
00160 col.modulateFromColor(ps.getGlobalColor(), _Color);
00161 }
00162 else
00163 {
00164 col = _Color;
00165 }
00166 _Mat.setColor(col);
00167 forceTexturedMaterialStages(0);
00168 }
00169 else
00170 {
00171 forceTexturedMaterialStages(1);
00172 if (ps.getForceGlobalColorLightingFlag() || usesGlobalColorLighting())
00173 {
00174 _Mat.texConstantColor(0, ps.getGlobalColorLighted());
00175 }
00176 else
00177 {
00178 _Mat.texConstantColor(0, ps.getGlobalColor());
00179 }
00180 SetupModulatedStage(_Mat, 0, CMaterial::Diffuse, CMaterial::Constant);
00181 }
00183
00184
00185
00186
00187 if (step == (1 << 16))
00188 {
00189 DrawDot(_Owner->getPos().begin(),
00190 vb,
00191 _ColorScheme,
00192 numToProcess,
00193 _Owner,
00194 _Mat,
00195 driver,
00196 step
00197 );
00198 }
00199 else
00200 {
00201 DrawDot(TIteratorVectStep1616(_Owner->getPos().begin(), 0, step),
00202 vb,
00203 _ColorScheme,
00204 numToProcess,
00205 _Owner,
00206 _Mat,
00207 driver,
00208 step
00209 );
00210 }
00211
00212 PARTICLES_CHECK_MEM;
00213 }
00214
00215
00218 void CPSDot::initVertexBuffers()
00219 {
00220 NL_PS_FUNC(CPSDot_initVertexBuffers)
00221 _DotVb.setName("CPSDot::_DotVb");
00222 _DotVb.setPreferredMemory(CVertexBuffer::AGPVolatile, false);
00223 _DotVb.setVertexFormat(CVertexBuffer::PositionFlag);
00224 _DotVb.setNumVertices(dotBufSize);
00225 _DotVbColor.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::PrimaryColorFlag);
00226 _DotVbColor.setPreferredMemory(CVertexBuffer::AGPVolatile, true);
00227 _DotVbColor.setNumVertices(dotBufSize);
00228 _DotVbColor.setName("CPSDot::_DotVbColor");
00229
00230 }
00231
00233 void CPSDot::init(void)
00234 {
00235 NL_PS_FUNC(CPSDot_init)
00236 _Mat.setLighting(false);
00237 _Mat.setZFunc(CMaterial::less);
00238
00239 updateMatAndVbForColor();
00240 }
00241
00243 uint32 CPSDot::getNumWantedTris() const
00244 {
00245 NL_PS_FUNC(CPSDot_getNumWantedTris)
00246 nlassert(_Owner);
00247
00248 return _Owner->getSize();
00249 }
00250
00252 void CPSDot::newElement(const CPSEmitterInfo &info)
00253 {
00254 NL_PS_FUNC(CPSDot_newElement)
00255 newColorElement(info);
00256 }
00257
00259 void CPSDot::deleteElement(uint32 index)
00260 {
00261 NL_PS_FUNC(CPSDot_deleteElement)
00262 deleteColorElement(index);
00263 }
00264
00266 void CPSDot::updateMatAndVbForColor(void)
00267 {
00268 NL_PS_FUNC(CPSDot_updateMatAndVbForColor)
00269 }
00270
00272 bool CPSDot::hasTransparentFaces(void)
00273 {
00274 NL_PS_FUNC(CPSDot_hasTransparentFaces)
00275 return getBlendingMode() != CPSMaterial::alphaTest ;
00276 }
00277
00279 bool CPSDot::hasOpaqueFaces(void)
00280 {
00281 NL_PS_FUNC(CPSDot_hasOpaqueFaces)
00282 return !hasTransparentFaces();
00283 }
00284
00286 void CPSDot::resize(uint32 size)
00287 {
00288 NL_PS_FUNC(CPSDot_resize)
00289 nlassert(size < (1 << 16));
00290 resizeColor(size);
00291 }
00292
00294 void CPSDot::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00295 {
00296 NL_PS_FUNC(CPSDot_IStream )
00297
00298 f.serialVersion(1);
00299
00300
00301 CPSParticle::serial(f);
00302 CPSColoredParticle::serialColorScheme(f);
00303 serialMaterial(f);
00304 if (f.isReading())
00305 {
00306 init();
00307 }
00308 }
00309
00310 }