4#include <OgreParticle.h>
5#include <OgreStringConverter.h>
6#include <OgreTagPoint.h>
9#include <OgreSceneNode.h>
10#include <OgreSceneManager.h>
28 : mDefaultParticleSize(1, 1)
29 , mKeepInLocalSpace(false)
31 , mParentIsTagPoint(false)
32 , mSortMode(SM_DISTANCE)
33 , mLightListUpdated(0)
35 , mRenderQueueID(RENDER_QUEUE_MAIN)
36 , mVertexFormatTexture(false)
37 , mVertexFormatSize(false)
38 , mVertexFormatRotation(false)
39 , mVertexFormatRotationSpeed(false)
40 , mVertexFormatDirection(false)
41 , mVertexFormatColour(false )
42 , mVertexFormatTTL(false)
43 , mVertexFormatTotalTTL(false)
44 , mVertexFormatTimeFragment(false)
45 , mVertexFormatTimeFragmentInv(false)
48 if (createParamDictionary(
"ShaderParticleRenderer"))
50 ParamDictionary* dict = getParamDictionary();
51 dict->addParameter(ParameterDef(
"diffuse_colour",
52 "Adds diffuse colour to vertex format (type = float4)",
56 dict->addParameter(ParameterDef(
"texture_coord",
57 "Adds general texture coordinate to vertex format (type = float2)",
61 dict->addParameter(ParameterDef(
"particle_size",
62 "Adds particle size to vertex format (type = float2)",
66 dict->addParameter(ParameterDef(
"particle_rotation",
67 "Adds particle rotation (in radians) to vertex format (type = float1)"
68 "note: if particle_rotation_speed present in script, they are packed together as float2",
72 dict->addParameter(ParameterDef(
"particle_rotation_speed",
73 "Adds particle rotation speed (in radians/s) to vertex format (type = float1)"
74 "note: if particle_rotation present in script, they are packed together as float2",
78 dict->addParameter(ParameterDef(
"particle_direction",
79 "Adds particle direction to vertex format (type = float3)"
80 "note: it represent particle speed",
84 dict->addParameter(ParameterDef(
"time_to_live",
85 "Adds particle current time to live to vertex format (type = float1)"
86 "note: this parameter can be packed with total_time_to_live, time_frag and time_frag_inv",
90 dict->addParameter(ParameterDef(
"total_time_to_live",
91 "Adds particle total time to live to vertex format (type = float1)"
92 "note: this parameter can be packed with time_to_live, time_frag and time_frag_inv",
96 dict->addParameter(ParameterDef(
"time_frag",
97 "Adds particle time fragment to vertex format (type = float1), which is ratio between ttl and total ttl"
98 "note: this parameter can be packed with time_to_live, total_time_to_live and time_frag_inv",
102 dict->addParameter(ParameterDef(
"time_frag_inv",
103 "Adds particle inverse time fragment to vertex format (type = float1), which is 1.0f - time_frag"
104 "note: this parameter can be packed with time_to_live, total_time_to_live and time_frag",
136 assert(0 &&
"Cannot allocate buffers");
142 if (!currentParticles.empty()) {
143 HardwareVertexBufferSharedPtr pVB =
mVertexData->vertexBufferBinding->getBuffer(0);
144 uchar* pDataVB =
reinterpret_cast<uchar*
>(pVB->lock(HardwareBuffer::HBL_DISCARD));
145 for (Ogre::list<Particle*>::type::iterator it=currentParticles.begin(); it!=currentParticles.end(); ++it) {
146 Particle* pParticle = *it;
150 float fDist = (
mParentNode != NULL) ?
mParentNode->getPosition().distance(pParticle->mPosition) : pParticle->mPosition.length();
158 mVertexData->vertexCount = currentParticles.size() * 4;
159 mIndexData->indexCount = currentParticles.size() * 6;
168 visitor->visit(
this, 0, debugRenderables);
257 op.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
258 op.useIndexes =
true;
259 op.srcRenderable =
this;
283 *xform = Matrix4::IDENTITY;
291 return cam->getRealPosition().squaredDistance(
mParentNode->getPosition());
304 TagPoint* tp =
static_cast<TagPoint*
>(
mParentNode);
305 return tp->getParentEntity()->queryLights();
310 SceneNode* sn =
static_cast<SceneNode*
>(
mParentNode);
313 ulong frame = sn->getCreator()->_getLightsDirtyCounter();
337 if (
mVertexData->vertexDeclaration->getElementCount() == 0) {
338 VertexDeclaration* pDecl =
mVertexData->vertexDeclaration;
340 ofs += pDecl->addElement(0, ofs, VET_FLOAT4, VES_POSITION).getSize();
342 ofs += pDecl->addElement(0, ofs, VET_FLOAT4, VES_DIFFUSE).getSize();
347 ofs += pDecl->addElement(0, ofs, VET_FLOAT2, VES_TEXTURE_COORDINATES, ix++).getSize();
350 ofs += pDecl->addElement(0, ofs, VET_FLOAT2, VES_TEXTURE_COORDINATES, ix++).getSize();
354 ofs += pDecl->addElement(0, ofs, VET_FLOAT2, VES_TEXTURE_COORDINATES, ix++).getSize();
356 ofs += pDecl->addElement(0, ofs, VET_FLOAT1, VES_TEXTURE_COORDINATES, ix++).getSize();
360 ofs += pDecl->addElement(0, ofs, VET_FLOAT3, VES_TEXTURE_COORDINATES, ix++).getSize();
363 size_t iNumTimes = 0;
370 ofs += pDecl->addElement(0, ofs, VET_FLOAT1, VES_TEXTURE_COORDINATES, ix++).getSize();
373 ofs += pDecl->addElement(0, ofs, VET_FLOAT2, VES_TEXTURE_COORDINATES, ix++).getSize();
376 ofs += pDecl->addElement(0, ofs, VET_FLOAT3, VES_TEXTURE_COORDINATES, ix++).getSize();
379 ofs += pDecl->addElement(0, ofs, VET_FLOAT4, VES_TEXTURE_COORDINATES, ix++).getSize();
384 ofs += pDecl->addElement(0, ofs, VET_FLOAT4, VES_TEXTURE_COORDINATES, ix++).getSize();
391 Ogre::HardwareVertexBufferSharedPtr pVB;
392 if (
mVertexData->vertexBufferBinding->isBufferBound(0))
393 pVB =
mVertexData->vertexBufferBinding->getBuffer(0);
396 if (!pVB || pVB->getNumVertices() < iNumParticles * 4) {
397 assert(iNumParticles * 4 < 65536);
398 pVB = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
mVertexSize, 4 * iNumParticles, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
402 mVertexData->vertexBufferBinding->setBinding(0, pVB);
406 Ogre::HardwareIndexBufferSharedPtr pIB =
mIndexData->indexBuffer;
407 if (!pIB || pIB->getNumIndexes() < iNumParticles * 6) {
408 pIB = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, iNumParticles * 6, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
415 Ogre::uint16* pDataIB =
reinterpret_cast<Ogre::uint16*
>(pIB->lock(Ogre::HardwareBuffer::HBL_NORMAL));
416 for (Ogre::uint16 k=0; k<static_cast<Ogre::uint16>(iNumParticles); ++k) {
417 pDataIB[0] = k*4 + 0;
418 pDataIB[1] = k*4 + 1;
419 pDataIB[2] = k*4 + 2;
421 pDataIB[3] = k*4 + 0;
422 pDataIB[4] = k*4 + 2;
423 pDataIB[5] = k*4 + 3;
437 for (
int k=0; k<4; ++k) {
438 float* pPosition =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
439 pPosition[0] = particle.mPosition.x;
440 pPosition[1] = particle.mPosition.y;
441 pPosition[2] = particle.mPosition.z;
444 ofs +=
sizeof(float) * 4;
448 for (
int k=0; k<4; ++k) {
449 float* pColour =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
450 pColour[0] = particle.mColour.r;
451 pColour[1] = particle.mColour.g;
452 pColour[2] = particle.mColour.b;
453 pColour[3] = particle.mColour.a;
455 ofs +=
sizeof(float) * 4;
460 for (
int k=0; k<4; ++k) {
461 float* pTexCoord =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
465 ofs +=
sizeof(float) * 2;
472 if (particle.hasOwnDimensions()) {
473 w = particle.getOwnWidth();
474 h = particle.getOwnHeight();
477 for (
int k=0; k<4; ++k) {
478 float* pSize =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
482 ofs +=
sizeof(float) * 2;
487 for (
int k=0; k<4; ++k) {
488 float* pRotation =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
489 *pRotation = particle.mRotation.valueRadians();
491 ofs +=
sizeof(float);
496 for (
int k=0; k<4; ++k) {
497 float* pRotation =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
498 *pRotation = particle.mRotationSpeed.valueRadians();
500 ofs +=
sizeof(float);
505 for (
int k=0; k<4; ++k) {
506 float* pDirection =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
507 pDirection[0] = particle.mDirection.x;
508 pDirection[1] = particle.mDirection.y;
509 pDirection[2] = particle.mDirection.z;
511 ofs +=
sizeof(float) * 3;
516 for (
int k=0; k<4; ++k) {
517 float* pTime =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
518 *pTime = particle.mTimeToLive;
520 ofs +=
sizeof(float);
525 for (
int k=0; k<4; ++k) {
526 float* pTime =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
527 *pTime = particle.mTotalTimeToLive;
529 ofs +=
sizeof(float);
534 float fFrag = particle.mTimeToLive / particle.mTotalTimeToLive;
535 for (
int k=0; k<4; ++k) {
536 float* pTime =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
539 ofs +=
sizeof(float);
544 float fFrag = 1.0f - particle.mTimeToLive / particle.mTotalTimeToLive;
545 for (
int k=0; k<4; ++k) {
546 float* pTime =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
549 ofs +=
sizeof(float);
554 const Vector4& customData = pCustom != NULL ? pCustom->
paramValue : Vector4::ZERO;
555 for (
int k=0; k<4; ++k) {
556 float* pParams =
reinterpret_cast<float*
>(pDataVB + k*
mVertexSize + ofs);
557 pParams[0] = customData.x;
558 pParams[1] = customData.y;
559 pParams[2] = customData.z;
560 pParams[3] = customData.w;
562 ofs +=
sizeof(float) * 4;
593 return StringConverter::toString(
599 StringConverter::parseBool(val));
608 return StringConverter::toString(
614 StringConverter::parseBool(val));
620 return StringConverter::toString(
626 StringConverter::parseBool(val));
632 return StringConverter::toString(
638 StringConverter::parseBool(val));
644 return StringConverter::toString(
650 StringConverter::parseBool(val));
656 return StringConverter::toString(
662 StringConverter::parseBool(val));
668 return StringConverter::toString(
674 StringConverter::parseBool(val));
680 return StringConverter::toString(
686 StringConverter::parseBool(val));
692 return StringConverter::toString(
698 StringConverter::parseBool(val));
704 return StringConverter::toString(
710 StringConverter::parseBool(val));
custom visual data for shader renderer
String doGet(const void *target) const
void doSet(void *target, const String &val)
void doSet(void *target, const String &val)
String doGet(const void *target) const
void doSet(void *target, const String &val)
String doGet(const void *target) const
String doGet(const void *target) const
void doSet(void *target, const String &val)
String doGet(const void *target) const
void doSet(void *target, const String &val)
String doGet(const void *target) const
void doSet(void *target, const String &val)
void doSet(void *target, const String &val)
String doGet(const void *target) const
void doSet(void *target, const String &val)
String doGet(const void *target) const
String doGet(const void *target) const
void doSet(void *target, const String &val)
void doSet(void *target, const String &val)
String doGet(const void *target) const
ParticleSystemRenderer * createInstance(const String &name) override
const String & getType() const override
const String rendererTypeName
void destroyInstance(ParticleSystemRenderer *inst) override
Specialisation of ParticleSystemRenderer to render particles using a custom shaders.
bool mVertexFormatColour
vertex format for particles
virtual void _destroyVisualData(ParticleVisualData *vis) override
bool getVertexFormatRotationSpeed() const
virtual void visitRenderables(Renderable::Visitor *visitor, bool debugRenderables=false) override
static CmdVertexFormatTimeFrag msVertexFmtTimeFrag
bool mVertexFormatTTL
particle ttl (float1)
static CmdVertexFormatRotation msVertexFmtRotation
bool mVertexFormatSize
particle size (width and height - float2)
void setVertexFormatTotalTTL(bool bUse)
virtual void setKeepParticlesInLocalSpace(bool keepLocal) override
Real mRadius
maximum distance between particles and parent node
static CmdVertexFormatTexture msVertexFmtTexture
void setVertexFormatTimeFragmentInv(bool bUse)
static CmdVertexFormatSize msVertexFmtSize
static CmdVertexFormatTotalTTL msVertexFmtTotalTTL
bool mParentIsTagPoint
true if parent node is tag point
bool mVertexFormatRotationSpeed
particle rotation speed (radians/s - float1)
virtual const LightList & getLights(void) const override
bool mKeepInLocalSpace
control transformation matrix for particles
virtual const String & getType(void) const override
bool mVertexFormatDirection
particle direction (float3)
virtual void _notifyParticleRotated(void) override
void setVertexFormatTexture(bool bUse)
bool mVertexFormatTotalTTL
particle total ttl (float1)
void setVertexFormatRotation(bool bUse)
virtual void _notifyCurrentCamera(Camera *cam) override
virtual void getWorldTransforms(Matrix4 *xform) const override
bool getVertexFormatTTL() const
static CmdVertexFormatRotationSpeed msVertexFmtRotationSpeed
bool mVertexFormatRotation
particle rotation (radians - float1)
void setVertexFormatTTL(bool bUse)
bool mVertexFormatTimeFragmentInv
particle inverse time fragment (1.0f - ttl / total ttl) (float1) (value 0.0f - 1.0f)
bool getVertexFormatRotation() const
bool getVertexFormatDirection() const
bool getVertexFormatTimeFragment() const
bool getVertexFormatColour() const
void setVertexFormatSize(bool bUse)
bool getVertexFormatSize() const
virtual void _notifyAttached(Node *parent, bool isTagPoint=false) override
void setVertexFormatDirection(bool bUse)
const String rendererTypeName
static CmdVertexFormatTimeFragInv msVertexFmtTimeFragInv
static CmdVertexFormatDirection msVertexFmtDirection
SortMode mSortMode
particle sorting
void addParticle(uint8 *pDataVB, const Particle &particle) const
add particle to vertex buffer
virtual void _notifyDefaultDimensions(Real width, Real height) override
virtual void _notifyParticleQuota(size_t quota) override
static CmdVertexFormatTTL msVertexFmtTTL
Vector2 mTexCoordTable[4]
default texture coordinates
virtual ParticleVisualData * _createVisualData(void) override
virtual Real getSquaredViewDepth(const Camera *cam) const override
virtual void _notifyParticleResized(void) override
virtual void _updateRenderQueue(RenderQueue *queue, Ogre::list< Particle * >::type ¤tParticles, bool cullIndividually) override
void setVertexFormatRotationSpeed(bool bUse)
static CmdVertexFormatColour msVertexFmtColour
virtual void setRenderQueueGroup(uint8 queueID) override
bool getVertexFormatTimeFragmentInv() const
Node * mParentNode
parent node for particle system - used for world transformation
virtual const MaterialPtr & getMaterial(void) const override
bool mVertexFormatTimeFragment
particle time fragment (ttl / total ttl) (float1) (value 0.0f - 1.0f)
bool mVertexFormatTexture
true if particles use texture (float2)
bool getVertexFormatTotalTTL() const
virtual void getRenderOperation(RenderOperation &op) override
MaterialPtr mMaterial
rendering data
bool allocateBuffers(size_t iNumParticles)
allocate hardware buffers and prepare them for filling particles
virtual void _setMaterial(MaterialPtr &mat) override
LightList mLightList
light list for renderable
void setVertexFormatTimeFragment(bool bUse)
virtual ~ShaderParticleRenderer()
bool getVertexFormatTexture() const
ulong mLightListUpdated
indicator if we need update light list
virtual SortMode _getSortMode(void) const override
void setRenderQueueGroupAndPriority(Ogre::uint8, Ogre::ushort)
void setVertexFormatColour(bool bUse)
Vector2 mDefaultParticleSize
other informations