4 #include <OgreParticle.h>
5 #include <OgreStringConverter.h>
6 #include <OgreTagPoint.h>
7 #include <OgreCamera.h>
8 #include <OgreEntity.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.isNull() || 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.isNull() || 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));