ps_dot.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright, 2001 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
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; // size used for point particles batching
00037 
00038 
00040 // CPSDot implementation //
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         // compute the colors
00067         colorScheme->setColorType(driver->getVertexColorFormat());
00068     }
00069     do
00070     {
00071         uint toProcess = leftToDo < dotBufSize ? leftToDo : dotBufSize;
00072         vb.setNumVertices(toProcess); // because of volatile vb copy, indicate the numebr of vertices to copy
00073         {
00074             CVertexBufferReadWrite vba;
00075             vb.lock (vba);
00076             if (colorScheme)
00077             {
00078                 // compute the colors
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)) // make sure we haven't got auto-lod and that the step is 1.0
00101             {
00102                 // there's no color information in the buffer, so we can copy it directly
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 //  if (!FilterPS[0]) return;
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); // for benchmark purpose
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     // Use the right drawing routine (auto-lod and non auto-lod)
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); // keep local mem because of interleaved fill
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     //return _Owner->getMaxSize();
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 } // NL3D

Generated on Thu Jan 7 08:26:28 2010 for NeL by  doxygen 1.6.1