00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "3d/ps_dot.h"
00029 #include "3d/ps_macro.h"
00030 #include "3d/ps_iterator.h"
00031 #include "3d/driver.h"
00032 #include "3d/particle_system.h"
00033
00034
00035 namespace NL3D
00036 {
00037
00038 static const uint dotBufSize = 1024;
00039
00040
00042
00044
00046
00047 CVertexBuffer CPSDot::_DotVbColor;
00048
00049
00051 template <class T>
00052 inline void DrawDot(T it,
00053 CVertexBuffer &vb,
00054 const CPSAttribMaker<NLMISC::CRGBA> *colorScheme,
00055 uint leftToDo,
00056 CPSLocated *owner,
00057 CMaterial &mat,
00058 IDriver *driver,
00059 uint32 srcStep
00060 )
00061 {
00062 nlassert(leftToDo != 0);
00063 const uint total = leftToDo;
00064 T itEnd;
00065 do
00066 {
00067 uint toProcess = leftToDo < dotBufSize ? leftToDo : dotBufSize;
00068
00069 if (colorScheme)
00070 {
00071
00072 colorScheme->make(owner,
00073 total - leftToDo,
00074 vb.getColorPointer(),
00075 vb.getVertexSize(),
00076 toProcess,
00077 false,
00078 srcStep
00079 );
00080
00081 itEnd = it + toProcess;
00082 uint8 *currPos = (uint8 *) vb.getVertexCoordPointer();
00083 uint32 stride = vb.getVertexSize();
00084 do
00085 {
00086 CHECK_VERTEX_BUFFER(vb, currPos);
00087 *((CVector *) currPos) = *it;
00088 ++it ;
00089 currPos += stride;
00090 }
00091 while (it != itEnd);
00092 }
00093 else if (srcStep == (1 << 16))
00094 {
00095
00096 ::memcpy(vb.getVertexCoordPointer(), &(*it), sizeof(NLMISC::CVector) * toProcess);
00097 it += toProcess;
00098 }
00099 else
00100 {
00101 itEnd = it + toProcess;
00102 uint8 *currPos = (uint8 *) vb.getVertexCoordPointer();
00103 do
00104 {
00105 CHECK_VERTEX_BUFFER(vb, currPos);
00106 *((CVector *) currPos) = *it;
00107 ++it ;
00108 currPos += sizeof(float[3]);
00109 }
00110 while (it != itEnd);
00111 }
00112
00113 driver->renderPoints(mat, toProcess);
00114
00115 leftToDo -= toProcess;
00116 }
00117 while (leftToDo);
00118 }
00119
00120
00122 void CPSDot::draw(bool opaque)
00123 {
00124 PARTICLES_CHECK_MEM;
00125 if (!_Owner->getSize()) return;
00126
00127 uint32 step;
00128 uint numToProcess;
00129 computeSrcStep(step, numToProcess);
00130 if (!numToProcess) return;
00131
00132 _Owner->incrementNbDrawnParticles(numToProcess);
00133 setupDriverModelMatrix();
00134 IDriver *driver = getDriver();
00135 CVertexBuffer &vb = _ColorScheme ? _DotVbColor : _DotVb;
00136 driver->activeVertexBuffer(vb);
00137
00138
00140 CParticleSystem &ps = *(_Owner->getOwner());
00141 if (!_ColorScheme)
00142 {
00143 if (ps.getColorAttenuationScheme() == NULL)
00144 {
00145 _Mat.setColor(_Color);
00146 }
00147 else
00148 {
00149 NLMISC::CRGBA col;
00150 col.modulateFromColor(ps.getGlobalColor(), _Color);
00151 _Mat.setColor(col);
00152 }
00153 forceTexturedMaterialStages(0);
00154 }
00155 else
00156 {
00157 forceTexturedMaterialStages(1);
00158 _Mat.texConstantColor(0, ps.getGlobalColor());
00159 SetupModulatedStage(_Mat, 0, CMaterial::Diffuse, CMaterial::Constant);
00160 }
00162
00163
00164
00165
00166 if (step == (1 << 16))
00167 {
00168 DrawDot(_Owner->getPos().begin(),
00169 vb,
00170 _ColorScheme,
00171 numToProcess,
00172 _Owner,
00173 _Mat,
00174 driver,
00175 step
00176 );
00177 }
00178 else
00179 {
00180 DrawDot(TIteratorVectStep1616(_Owner->getPos().begin(), 0, step),
00181 vb,
00182 _ColorScheme,
00183 numToProcess,
00184 _Owner,
00185 _Mat,
00186 driver,
00187 step
00188 );
00189 }
00190
00191 PARTICLES_CHECK_MEM;
00192 }
00193
00194
00197 void CPSDot::initVertexBuffers()
00198 {
00199 _DotVb.setVertexFormat(CVertexBuffer::PositionFlag);
00200 _DotVbColor.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::PrimaryColorFlag);
00201 _DotVb.setNumVertices(dotBufSize);
00202 _DotVbColor.setNumVertices(dotBufSize);
00203 }
00204
00206 void CPSDot::init(void)
00207 {
00208 _Mat.setLighting(false);
00209 _Mat.setZFunc(CMaterial::less);
00210
00211 updateMatAndVbForColor();
00212 }
00213
00215 uint32 CPSDot::getMaxNumFaces(void) const
00216 {
00217 nlassert(_Owner);
00218 return _Owner->getMaxSize();
00219 }
00220
00222 void CPSDot::newElement(CPSLocated *emitterLocated, uint32 emitterIndex)
00223 {
00224 newColorElement(emitterLocated, emitterIndex);
00225 }
00226
00228 void CPSDot::deleteElement(uint32 index)
00229 {
00230 deleteColorElement(index);
00231 }
00232
00234 void CPSDot::updateMatAndVbForColor(void)
00235 {
00236 }
00237
00239 bool CPSDot::hasTransparentFaces(void)
00240 {
00241 return getBlendingMode() != CPSMaterial::alphaTest ;
00242 }
00243
00245 bool CPSDot::hasOpaqueFaces(void)
00246 {
00247 return !hasTransparentFaces();
00248 }
00249
00251 void CPSDot::resize(uint32 size)
00252 {
00253 nlassert(size < (1 << 16));
00254 resizeColor(size);
00255 }
00256
00258 void CPSDot::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00259 {
00260
00261 f.serialVersion(1);
00262
00263
00264 CPSParticle::serial(f);
00265 CPSColoredParticle::serialColorScheme(f);
00266 serialMaterial(f);
00267 if (f.isReading())
00268 {
00269 init();
00270 }
00271 }
00272
00273 }