8#include <boost/format.hpp>
9#include <boost/algorithm/string.hpp>
23SShaderGenerator::SShaderGenerator(Ogre::Technique* technique, Ogre::Pass* pass,
ShaderType type,
bool ignoreSlicePlane)
40SShaderGenerator::SShaderGenerator()
55void SShaderGenerator::ComputePass()
57 std::stringstream out;
60 if (
mPass->getAlphaRejectValue() > 120.0f)
67 bool lightSet =
false;
68 Ogre::RTShader::ShaderGenerator* shaderGen = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
69 Ogre::RTShader::RenderState* rs = shaderGen->getRenderState(Ogre::MSN_SHADERGEN, *
mTechnique->getParent(),
mPass->getIndex());
75 rs->resetToBuiltinSubRenderStates();
77 Ogre::Any any =
mPass->getUserObjectBindings().getUserAny(
"_RTSS_nonFFP_TUS");
79 mPass->getUserObjectBindings().eraseUserAny(
"_RTSS_nonFFP_TUS");
81 if ((
mPass->getVertexColourTracking() & Ogre::TVC_AMBIENT) || (
mPass->getVertexColourTracking() == Ogre::TVC_DIFFUSE))
85 Ogre::RTShader::SubRenderState* srs = shaderGen->createSubRenderState(Ogre::RTShader::SRS_VERTEX_COLOUR);
86 rs->addTemplateSubRenderState(srs);
91 Ogre::RTShader::SubRenderState* srs = shaderGen->createSubRenderState(
SRS_CLIP_PLANE);
92 rs->addTemplateSubRenderState(srs);
95 unsigned int refIndex = 0;
96 unsigned int specIndex = 0;
98 Ogre::Pass::TextureUnitStates units =
mPass->getTextureUnitStates();
99 for (
unsigned int i = 0; i < units.size(); i++)
101 Ogre::TextureUnitState* pTex = units[i];
103 Ogre::String tex_filename = pTex->getTextureName();
104 Ogre::StringUtil::toLowerCase(tex_filename);
106 Ogre::TextureUnitState::EffectMap effects = pTex->getEffects();
107 Ogre::TextureUnitState::EffectMap::const_iterator effectEnd = effects.end();
109 bool animatedUv =
false;
110 if (!effects.empty() && ((effects.find(Ogre::TextureUnitState::ET_ROTATE) != effectEnd) ||
111 (effects.find(Ogre::TextureUnitState::ET_TRANSFORM) != effectEnd) ||
112 (effects.find(Ogre::TextureUnitState::ET_USCROLL) != effectEnd) ||
113 (effects.find(Ogre::TextureUnitState::ET_VSCROLL) != effectEnd) ||
114 (effects.find(Ogre::TextureUnitState::ET_UVSCROLL) != effectEnd)))
119 if ((pTex->getTextureUScroll() != 0.0f) || (pTex->getTextureVScroll() != 0.0f) ||
120 (pTex->getTextureUScale() != 1.0f) || (pTex->getTextureVScale() != 1.0f) ||
121 (pTex->getTextureRotate().valueRadians() != 0.0f))
127 if (!effects.empty() && (effects.find(Ogre::TextureUnitState::ET_ENVIRONMENT_MAP) != effectEnd))
133 Ogre::RTShader::ShaderGenerator::_markNonFFP(pTex);
134 Ogre::RTShader::SubRenderState* srs = shaderGen->createSubRenderState(Ogre::RTShader::SRS_NORMALMAP);
135 srs->setParameter(
"texture_index", std::to_string(
mPass->getTextureUnitStateIndex(pTex)));
137 if (tex_filename.find(
"object") != Ogre::String::npos)
138 srs->setParameter(
"normalmap_space",
"object_space");
139 else if (tex_filename.find(
"parallax") != Ogre::String::npos)
140 srs->setParameter(
"normalmap_space",
"parallax");
141 else if ((tex_filename.find(
"parallax_oc") != Ogre::String::npos) || (tex_filename.find(
"normheight") != Ogre::String::npos) || (tex_filename.find(
"parallax_occlusion") != Ogre::String::npos))
142 srs->setParameter(
"normalmap_space",
"parallax_occlusion");
144 srs->setParameter(
"normalmap_space",
"tangent_space");
146 srs->setParameter(
"height_scale",
"0.1");
148 rs->addTemplateSubRenderState(srs);
156 if (
mPass->getCullingMode() == Ogre::CULL_NONE)
157 lightsrs->setParameter(
"two_sided",
"1");
159 Ogre::RTShader::ShaderGenerator::_markNonFFP(pTex);
160 lightsrs->setParameter(
"texture", pTex->getTextureName());
161 if ((tex_filename.find(
"occlusion") != Ogre::String::npos) || (tex_filename.find(
"orm") != Ogre::String::npos) || (tex_filename.find(
"occ_") != Ogre::String::npos))
162 lightsrs->setParameter(
"occlusion",
"YES");
164 rs->addTemplateSubRenderState(lightsrs);
166 Ogre::RTShader::SubRenderState* srs = shaderGen->createSubRenderState(Ogre::RTShader::SRS_TEXTURING);
167 srs->setParameter(
"late_add_blend",
"true");
168 rs->addTemplateSubRenderState(srs);
174 Ogre::RTShader::LayeredBlending* lrs =
static_cast<Ogre::RTShader::LayeredBlending*
>(shaderGen->createSubRenderState(Ogre::RTShader::SRS_LAYERED_BLENDING));
175 lrs->setBlendMode(i,
"add");
176 rs->addTemplateSubRenderState(lrs);
181 Ogre::RTShader::ShaderGenerator::_markNonFFP(pTex);
191 Ogre::RTShader::SubRenderState* srs = shaderGen->createSubRenderState(Ogre::RTShader::SRS_ALPHA_TEST);
192 rs->addTemplateSubRenderState(srs);
197 pTex->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_TEXTURE, Ogre::LBS_SPECULAR, Ogre::ColourValue::White, Ogre::ColourValue::White, 1.0);
203 Ogre::RTShader::ShaderGenerator::_markNonFFP(pTex);
248 Ogre::RTShader::SubRenderState* lightsrs = shaderGen->createSubRenderState(Ogre::RTShader::SRS_PER_PIXEL_LIGHTING);
249 if (
mPass->getCullingMode() == Ogre::CULL_NONE)
250 lightsrs->setParameter(
"two_sided",
"1");
251 rs->addTemplateSubRenderState(lightsrs);
257 Ogre::TextureUnitState* pTex =
mPass->getTextureUnitState(refIndex);
261 const Ogre::LayerBlendModeEx& bl = pTex->getColourBlendMode();
262 Ogre::RTShader::ShaderGenerator::_markNonFFP(pTex);
263 Ogre::RTShader::SubRenderState* srs = shaderGen->createSubRenderState(Ogre::RTShader::SRS_IMAGE_BASED_LIGHTING);
264 srs->setParameter(
"texture", pTex->getTextureName());
265 srs->setParameter(
"luminance", std::to_string((bl.factor == 0.0f) ? 4.0f : bl.factor * 4.0f));
266 rs->addTemplateSubRenderState(srs);
283 if (!
mPass->getLightingEnabled())
285 out <<
"vsNoLightGEN";
292 if ((
mPass->getVertexColourTracking() & Ogre::TVC_AMBIENT) || (
mPass->getVertexColourTracking() == Ogre::TVC_DIFFUSE))
298 Ogre::Pass::TextureUnitStates units =
mPass->getTextureUnitStates();
299 for (
unsigned int i = 0; i < units.size(); i++)
301 Ogre::TextureUnitState* pTex = units[i];
304 Ogre::TextureUnitState::EffectMap effects = pTex->getEffects();
305 Ogre::TextureUnitState::EffectMap::const_iterator effectEnd = effects.end();
307 bool animatedUv =
false;
308 if (!effects.empty() && ((effects.find(Ogre::TextureUnitState::ET_ROTATE) != effectEnd) ||
309 (effects.find(Ogre::TextureUnitState::ET_TRANSFORM) != effectEnd) ||
310 (effects.find(Ogre::TextureUnitState::ET_USCROLL) != effectEnd) ||
311 (effects.find(Ogre::TextureUnitState::ET_VSCROLL) != effectEnd) ||
312 (effects.find(Ogre::TextureUnitState::ET_UVSCROLL) != effectEnd)))
317 if ((pTex->getTextureUScroll() != 0.0f) || (pTex->getTextureVScroll() != 0.0f) ||
318 (pTex->getTextureUScale() != 1.0f) || (pTex->getTextureVScale() != 1.0f) ||
319 (pTex->getTextureRotate().valueRadians() != 0.0f))
325 if (!effects.empty() && (effects.find(Ogre::TextureUnitState::ET_ENVIRONMENT_MAP) != effectEnd))
331 mTexUnits.push_back(pTex->getTextureCoordSet());
334 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
341 mTexUnits.push_back(pTex->getTextureCoordSet());
344 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
349 mTexUnits.push_back(pTex->getTextureCoordSet());
352 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
357 mTexUnits.push_back(pTex->getTextureCoordSet());
360 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
365 mTexUnits.push_back(pTex->getTextureCoordSet());
368 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
373 mTexUnits.push_back(pTex->getTextureCoordSet());
376 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
381 mTexUnits.push_back(pTex->getTextureCoordSet());
384 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
389 mTexUnits.push_back(pTex->getTextureCoordSet());
392 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
397 mTexUnits.push_back(pTex->getTextureCoordSet());
400 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
405 mTexUnits.push_back(pTex->getTextureCoordSet());
408 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
413 mTexUnits.push_back(pTex->getTextureCoordSet());
416 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
428 for (
unsigned int j = 0; j <
mTexUnits.size(); j++)
453 if (!
mPass->getLightingEnabled())
455 out <<
"fpNoLightGEN";
465 if ((
mPass->getVertexColourTracking() & Ogre::TVC_AMBIENT) || (
mPass->getVertexColourTracking() == Ogre::TVC_DIFFUSE))
475 Ogre::Pass::TextureUnitStates units =
mPass->getTextureUnitStates();
476 for (
unsigned int i = 0; i < units.size(); i++)
478 Ogre::TextureUnitState* pTex = units[i];
480 Ogre::String tex_filename = pTex->getTextureName();
481 Ogre::StringUtil::toLowerCase(tex_filename);
483 Ogre::TextureUnitState::EffectMap effects = pTex->getEffects();
484 Ogre::TextureUnitState::EffectMap::const_iterator effectEnd = effects.end();
487 if (!effects.empty() && (effects.find(Ogre::TextureUnitState::ET_ENVIRONMENT_MAP) != effectEnd))
495 out << pTex->getTextureCoordSet();
496 if (pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP)
499 mTexUnits.push_back(pTex->getTextureCoordSet());
501 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
508 out << pTex->getTextureCoordSet();
509 if (pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP)
512 mTexUnits.push_back(pTex->getTextureCoordSet());
514 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
520 out << pTex->getTextureCoordSet();
521 if (pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP)
525 mTexUnits.push_back(pTex->getTextureCoordSet());
527 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
533 out << pTex->getTextureCoordSet();
534 if (pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP)
538 mTexUnits.push_back(pTex->getTextureCoordSet());
540 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
551 if ((tex_filename.find(
"fresn") != Ogre::String::npos))
557 out << pTex->getTextureCoordSet();
558 if (pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP)
562 mTexUnits.push_back(pTex->getTextureCoordSet());
564 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
570 out << pTex->getTextureCoordSet();
571 if (pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP)
575 mTexUnits.push_back(pTex->getTextureCoordSet());
577 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
583 out << pTex->getTextureCoordSet();
584 if (pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP)
588 mTexUnits.push_back(pTex->getTextureCoordSet());
590 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
596 out << pTex->getTextureCoordSet();
597 if (pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP)
601 mTexUnits.push_back(pTex->getTextureCoordSet());
603 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
608 mTexUnits.push_back(pTex->getTextureCoordSet());
610 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
616 out << pTex->getTextureCoordSet();
617 if (pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP)
621 mTexUnits.push_back(pTex->getTextureCoordSet());
623 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
629 mTexUnits.push_back(pTex->getTextureCoordSet());
631 mCubeUv.push_back(pTex->getTextureType() == Ogre::TEX_TYPE_CUBE_MAP);
653 for (
unsigned int j = 0; j <
mTexUnits.size() && !iscube; j++)
676 for (
unsigned int i = 0; i <
mTexUnits.size(); i++)
static SShaderGenerator::ShaderMapType GetTextureUnitType(Ogre::TextureUnitState *unit)
static SRoot * getSingletonPtr()
void InvalidateGeneratedMaterial(Ogre::Material *mat)
std::string GetShaderName()
std::vector< unsigned int > mSortedTexUnits
virtual std::string GetUniformParams()
std::list< Ogre::GpuProgramPtr > GeneratedShaders
Ogre::Technique * mTechnique
std::vector< ShaderMapType > mTexTypes
std::vector< bool > mSortedCubeUv
virtual void ComputeShaderCode()
bool IsUvAnimated(int uvindex)
std::vector< unsigned int > mTexUnits
std::vector< bool > mCubeUv
virtual std::string GetProgram()
std::vector< bool > mAnimatedUv
static GeneratedShaders mGeneratedShaders
virtual void ApplyShader()
const Ogre::String SRS_CLIP_PLANE
const Ogre::String SRS_ADV_COOK_TORRANCE_LIGHTING