#include "OgreTechniqueGroup.h" #include "OgreIllumVolumeRenderTechnique.h" #include "OgreChildPSystemRenderingRun.h" #include "OgreLightVolumeRenderingRun.h" OgreIllumVolumeRenderTechnique::OgreIllumVolumeRenderTechnique( unsigned long startFrame, unsigned long illumVolumeUpdateInterval, unsigned int illumTextureResolution, unsigned int textureDepth, unsigned char illumTexID, bool useDistCalc, String materialName, String lightMatrixGPUParamName, bool useHierarchicalImpostor, unsigned char impostorTexID, Pass* pass, OgreRenderable* parentRenderable, OgreTechniqueGroup* parentTechniqueGroup) :OgreRenderTechnique( pass, parentRenderable, parentTechniqueGroup), IllumVolumeRenderTechnique(startFrame, illumVolumeUpdateInterval, illumTextureResolution, textureDepth, useDistCalc, useHierarchicalImpostor, parentRenderable, parentTechniqueGroup), RenderTechnique(parentRenderable, parentTechniqueGroup) { this->illumTexID = illumTexID; this->materialName = materialName; this->lightMatrixGPUParamName = lightMatrixGPUParamName; this->impostorTexID = impostorTexID; this->lightMatrixGPUParamName = lightMatrixGPUParamName; if(sharedRuns->getRun(ILLUMRUN_LIGHTVOLUME_MAP) == 0) sharedRuns->addRun(ILLUMRUN_LIGHTVOLUME_MAP, createLightVolumeRenderingRun()); lightVolumeChanged(sharedRuns->getRun(ILLUMRUN_LIGHTVOLUME_MAP)); } OgreIllumVolumeRenderTechnique::~OgreIllumVolumeRenderTechnique() { } void OgreIllumVolumeRenderTechnique::lightVolumeChanged(RenderingRun* run) { OgreLightVolumeRenderingRun* r = (OgreLightVolumeRenderingRun*) run->asOgreRenderingRun(); pass->getTextureUnitState(illumTexID)->setTextureName(r->getLightVolumeTextureName()); } void OgreIllumVolumeRenderTechnique::lightVolumeUpdated(RenderingRun* run) { OgreLightVolumeRenderingRun* r = (OgreLightVolumeRenderingRun*) run->asOgreRenderingRun(); pass->getVertexProgramParameters()->setNamedConstant(lightMatrixGPUParamName, r->getLightViewProjectionMatrix()); } void OgreIllumVolumeRenderTechnique::hierarchicalImpostorUpdated(RenderingRun* run) { if(useHierarchicalImpostor) { OgreChildPSystemRenderingRun* r = (OgreChildPSystemRenderingRun*) run->asOgreRenderingRun(); Material* m = (Material*) MaterialManager::getSingleton().getByName(materialName).getPointer(); m->getTechnique(0)->getPass(0)->getTextureUnitState(impostorTexID) ->setTextureName(r->getImpostorTextureName()); } } RenderingRun* OgreIllumVolumeRenderTechnique::createLightVolumeRenderingRun() { return new OgreLightVolumeRenderingRun( (OgreSharedRuns*) parentTechniqueGroup->getSharedRuns(), parentOgreRenderable->getName() + "_LIGHT_VOLUME", startFrame, illumVolumeUpdateInterval, illumTextureResolution, textureDepth, materialName); } ///Technique Parsers namespace IllumVolumeParsers { void parseStartFrame(String& params, RenderTechniqueFactory* factory) { OgreIllumVolumeRenderTechniqueFactory* f = (OgreIllumVolumeRenderTechniqueFactory*) factory; f->startFrame = StringConverter::parseUnsignedLong(params); } void parseIllumVolumeUpdateInterval(String& params, RenderTechniqueFactory* factory) { OgreIllumVolumeRenderTechniqueFactory* f = (OgreIllumVolumeRenderTechniqueFactory*) factory; f->illumVolumeUpdateInterval = StringConverter::parseUnsignedLong(params); } void parseIllumTextureResolution(String& params, RenderTechniqueFactory* factory) { OgreIllumVolumeRenderTechniqueFactory* f = (OgreIllumVolumeRenderTechniqueFactory*) factory; f->illumTextureResolution = StringConverter::parseUnsignedInt(params); } void parseIllumTextureDepth(String& params, RenderTechniqueFactory* factory) { OgreIllumVolumeRenderTechniqueFactory* f = (OgreIllumVolumeRenderTechniqueFactory*) factory; f->textureDepth = StringConverter::parseUnsignedInt(params); } void parseIllumTexID(String& params, RenderTechniqueFactory* factory) { OgreIllumVolumeRenderTechniqueFactory* f = (OgreIllumVolumeRenderTechniqueFactory*) factory; f->illumTexID = 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 parseMaterialName(String& params, RenderTechniqueFactory* factory) { OgreIllumVolumeRenderTechniqueFactory* f = (OgreIllumVolumeRenderTechniqueFactory*) factory; f->materialName = params; } void parseLightMatrixGPUParamName(String& params, RenderTechniqueFactory* factory) { OgreIllumVolumeRenderTechniqueFactory* f = (OgreIllumVolumeRenderTechniqueFactory*) factory; f->lightMatrixGPUParamName = params; } void parseImpostorTexID(String& params, RenderTechniqueFactory* factory) { OgreIllumVolumeRenderTechniqueFactory* f = (OgreIllumVolumeRenderTechniqueFactory*) factory; f->impostorTexID = StringConverter::parseUnsignedInt(params); } void parseUseHierarchicalImpostor(String& params, RenderTechniqueFactory* factory) { OgreIllumVolumeRenderTechniqueFactory* f = (OgreIllumVolumeRenderTechniqueFactory*) factory; f->useHierarchicalImpostor = StringConverter::parseBool(params); } } ///Technique factory OgreIllumVolumeRenderTechniqueFactory::OgreIllumVolumeRenderTechniqueFactory() { typeName = "IllumVolume"; using namespace IllumVolumeParsers; //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) parseIllumVolumeUpdateInterval)); this->attributeParsers.insert(AttribParserList::value_type("resolution", (ILLUM_ATTRIBUTE_PARSER) parseIllumTextureResolution)); this->attributeParsers.insert(AttribParserList::value_type("depths", (ILLUM_ATTRIBUTE_PARSER) parseIllumTextureDepth)); this->attributeParsers.insert(AttribParserList::value_type("texture_unit_id", (ILLUM_ATTRIBUTE_PARSER) parseIllumTexID)); this->attributeParsers.insert(AttribParserList::value_type("impostor_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("material", (ILLUM_ATTRIBUTE_PARSER) parseMaterialName)); this->attributeParsers.insert(AttribParserList::value_type("use_hier_system", (ILLUM_ATTRIBUTE_PARSER) parseUseHierarchicalImpostor)); this->attributeParsers.insert(AttribParserList::value_type("lightmatrix_param_name", (ILLUM_ATTRIBUTE_PARSER) parseLightMatrixGPUParamName)); } OgreRenderTechnique* OgreIllumVolumeRenderTechniqueFactory::createInstance( IllumTechniqueParams* params, Pass* pass, OgreRenderable* parentRenderable, OgreTechniqueGroup* parentTechniqueGroup) { materialName = "Smoke_IllumVolume"; illumTexID = 2; startFrame = 0; illumVolumeUpdateInterval = 1; illumTextureResolution = 256; textureDepth = 1; useDistCalc = false; lightMatrixGPUParamName = "lightViewProj"; impostorTexID = 0; useHierarchicalImpostor = false; parseParams(params); OgreIllumVolumeRenderTechnique* result = new OgreIllumVolumeRenderTechnique( startFrame, illumVolumeUpdateInterval, illumTextureResolution, textureDepth, illumTexID, useDistCalc, materialName, lightMatrixGPUParamName, useHierarchicalImpostor, impostorTexID, pass, parentRenderable, parentTechniqueGroup); return result; }