#include "OgreCubeMapRenderTechnique.h" #include "OgreTechniqueGroup.h" #include "OgreHierarchicalParticleSystemTechnique.h" #include "OgreChildPSystemRenderingRun.h" #include "OgreLightVolumeRenderingRun.h" OgreHierarchicalParticleSystemTechnique::OgreHierarchicalParticleSystemTechnique( unsigned long startFrame, unsigned long impostorUpdateInterval, unsigned int impostorResolution, unsigned char impostorTexID, bool useDistCalc, bool perspectiveRendering, String childPSysScriptName, bool useOwnMaterial, String impostorMaterialName, bool useVParam, String VParamRadius, bool useFParam, String FParamRadius, Pass* pass, OgreRenderable* parentRenderable, OgreTechniqueGroup* parentTechniqueGroup) :OgreRenderTechnique( pass, parentRenderable, parentTechniqueGroup), HierarchicalParticleSystemTechnique(startFrame, impostorUpdateInterval, impostorResolution, useDistCalc, perspectiveRendering, parentRenderable, parentTechniqueGroup), RenderTechnique(parentRenderable, parentTechniqueGroup) { this->impostorTexID = impostorTexID; this->childPSysScriptName = childPSysScriptName; this->impostorMaterialName = impostorMaterialName; this->useOwnMaterial = useOwnMaterial; this->VParamRadius = VParamRadius; this->FParamRadius = FParamRadius; this->useVParam = useVParam; this->useFParam = useFParam; //create the Particle system childPSysName = parentOgreRenderable->getName() + "_small_PSYS"; ParticleSystem* psys = Root::getSingleton()._getCurrentSceneManager()->createParticleSystem(childPSysName, childPSysScriptName); SceneNode* node = Root::getSingleton()._getCurrentSceneManager()->getRootSceneNode()->createChildSceneNode(); node->attachObject(psys); psys->setVisible(false); if(sharedRuns->getRun(ILLUMRUN_HPP_IMPOSTOR) == 0) sharedRuns->addRun(ILLUMRUN_HPP_IMPOSTOR, createChildPSysRenderingRun()); ((OgreChildPSystemRenderingRun*) sharedRuns->getRun(ILLUMRUN_HPP_IMPOSTOR)->asOgreRenderingRun())->setNode(node); impostorChanged(sharedRuns->getRun(ILLUMRUN_HPP_IMPOSTOR)); } OgreHierarchicalParticleSystemTechnique::~OgreHierarchicalParticleSystemTechnique() { } void OgreHierarchicalParticleSystemTechnique::impostorChanged(RenderingRun* run) { OgreChildPSystemRenderingRun* r = (OgreChildPSystemRenderingRun*) run->asOgreRenderingRun(); pass->getTextureUnitState(impostorTexID)->setTextureName(r->getImpostorTextureName()); } RenderingRun* OgreHierarchicalParticleSystemTechnique::createChildPSysRenderingRun() { return new OgreChildPSystemRenderingRun( (OgreSharedRuns*) parentTechniqueGroup->getSharedRuns(), parentOgreRenderable->getName() + "_HPP_IMPOSTOR", startFrame, impostorUpdateInterval, impostorResolution, perspectiveRendering, childPSysName, childPSysScriptName, useOwnMaterial, impostorMaterialName); } void OgreHierarchicalParticleSystemTechnique::impostorUpdated(RenderingRun* run) { OgreChildPSystemRenderingRun* r = (OgreChildPSystemRenderingRun*) run->asOgreRenderingRun(); float radius = r->getSmallSysRadius(); if(useVParam) pass->getVertexProgramParameters()->setNamedConstant(VParamRadius, radius); if(useFParam) pass->getFragmentProgramParameters()->setNamedConstant(FParamRadius, radius); } ///Technique Parsers namespace HPSParsers { void parseStartFrame(String& params, RenderTechniqueFactory* factory) { OgreHierarchicalParticleSystemTechniqueFactory* f = (OgreHierarchicalParticleSystemTechniqueFactory*) factory; f->startFrame = StringConverter::parseUnsignedLong(params); } void parseImpostorUpdateInterval(String& params, RenderTechniqueFactory* factory) { OgreHierarchicalParticleSystemTechniqueFactory* f = (OgreHierarchicalParticleSystemTechniqueFactory*) factory; f->impostorUpdateInterval = StringConverter::parseUnsignedLong(params); } void parseImpostorResolution(String& params, RenderTechniqueFactory* factory) { OgreHierarchicalParticleSystemTechniqueFactory* f = (OgreHierarchicalParticleSystemTechniqueFactory*) factory; f->impostorResolution = StringConverter::parseUnsignedInt(params); } void parseImpostorTexID(String& params, RenderTechniqueFactory* factory) { OgreHierarchicalParticleSystemTechniqueFactory* f = (OgreHierarchicalParticleSystemTechniqueFactory*) factory; f->impostorTexID = StringConverter::parseUnsignedInt(params); } void parseUseDistCalc(String& params, RenderTechniqueFactory* factory) { /* OgreHierarchicalParticleSystemTechniqueFactory* f = (OgreHierarchicalParticleSystemTechniqueFactory*) factory; // format: on/off tolerance(float) StringVector vecparams = StringUtil::split(params, " \t"); if(StringConverter::parseBool(vecparams[0]))//on { f->useDistCalc = true; if(vecparams.size()>1) { f->distTolerance = StringConverter::parseReal(vecparams[1]); } } else { f->useDistCalc = false; }*/ ///TODO } void parsePerspectiveRendering(String& params, RenderTechniqueFactory* factory) { OgreHierarchicalParticleSystemTechniqueFactory* f = (OgreHierarchicalParticleSystemTechniqueFactory*) factory; f->perspectiveRendering = StringConverter::parseBool(params); } void parseMaterialName(String& params, RenderTechniqueFactory* factory) { OgreHierarchicalParticleSystemTechniqueFactory* f = (OgreHierarchicalParticleSystemTechniqueFactory*) factory; f->impostorMaterialName = params; f->useOwnMaterial = false; } void parseScriptName(String& params, RenderTechniqueFactory* factory) { OgreHierarchicalParticleSystemTechniqueFactory* f = (OgreHierarchicalParticleSystemTechniqueFactory*) factory; f->childPSysScriptName = params; } void parseVparamRadius(String& params, RenderTechniqueFactory* factory) { OgreHierarchicalParticleSystemTechniqueFactory* f = (OgreHierarchicalParticleSystemTechniqueFactory*) factory; f->VParamRadius = params; f->useVParam = true; } void parseFparamRadius(String& params, RenderTechniqueFactory* factory) { OgreHierarchicalParticleSystemTechniqueFactory* f = (OgreHierarchicalParticleSystemTechniqueFactory*) factory; f->FParamRadius = params; f->useFParam = true; } } ///Technique factory OgreHierarchicalParticleSystemTechniqueFactory::OgreHierarchicalParticleSystemTechniqueFactory() { typeName = "HPS"; using namespace HPSParsers; //register parsers this->attributeParsers.insert(AttribParserList::value_type("start_frame", (ILLUM_ATTRIBUTE_PARSER) parseStartFrame)); this->attributeParsers.insert(AttribParserList::value_type("update_interval", (ILLUM_ATTRIBUTE_PARSER) parseImpostorUpdateInterval)); this->attributeParsers.insert(AttribParserList::value_type("resolution", (ILLUM_ATTRIBUTE_PARSER) parseImpostorResolution)); this->attributeParsers.insert(AttribParserList::value_type("texture_unit_id", (ILLUM_ATTRIBUTE_PARSER) parseImpostorTexID)); this->attributeParsers.insert(AttribParserList::value_type("distance_calc", (ILLUM_ATTRIBUTE_PARSER) parseUseDistCalc)); this->attributeParsers.insert(AttribParserList::value_type("perspective", (ILLUM_ATTRIBUTE_PARSER) parsePerspectiveRendering)); this->attributeParsers.insert(AttribParserList::value_type("particle_script", (ILLUM_ATTRIBUTE_PARSER) parseScriptName)); this->attributeParsers.insert(AttribParserList::value_type("material", (ILLUM_ATTRIBUTE_PARSER) parseMaterialName)); this->attributeParsers.insert(AttribParserList::value_type("vparam_radius", (ILLUM_ATTRIBUTE_PARSER) parseVparamRadius)); this->attributeParsers.insert(AttribParserList::value_type("fparam_radius", (ILLUM_ATTRIBUTE_PARSER) parseFparamRadius)); } OgreRenderTechnique* OgreHierarchicalParticleSystemTechniqueFactory::createInstance( IllumTechniqueParams* params, Pass* pass, OgreRenderable* parentRenderable, OgreTechniqueGroup* parentTechniqueGroup) { impostorUpdateInterval = 1; impostorResolution = 256; startFrame = 1; useDistCalc = false; impostorTexID = 0; perspectiveRendering = true; impostorMaterialName = ""; childPSysScriptName = ""; useOwnMaterial = true; VParamRadius = ""; FParamRadius = ""; useVParam = false; useFParam = false; parseParams(params); OgreHierarchicalParticleSystemTechnique* result = new OgreHierarchicalParticleSystemTechnique( startFrame, impostorUpdateInterval, impostorResolution, impostorTexID, useDistCalc, perspectiveRendering, childPSysScriptName, useOwnMaterial, impostorMaterialName, useVParam, VParamRadius, useFParam, FParamRadius, pass, parentRenderable, parentTechniqueGroup); return result; }