# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

ps_dot.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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; // size used for point particles batching
00039 
00040 
00042 // CPSDot implementation //
00044 
00046 CVertexBuffer CPSDot::_DotVb;
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                         // compute the colors
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)) // make sure we haven't got auto-lod and that the step is 1.0
00094                 {
00095                         // there's no color information in the buffer, so we can copy it directly
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); // for benchmark purpose               
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         // Use the right drawing routine (auto-lod and non auto-lod)
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 } // NL3D