void setUpBaseParameters(const Ogre::GpuProgramParametersSharedPtr& params) { assert(params.isNull()==false); struct AutoParamPair { Ogre::String name; Ogre::GpuProgramParameters::AutoConstantType type; }; //A list of auto params that might be present in the shaders generated static const AutoParamPair AUTO_PARAMS[] = { { "vpWidth", Ogre::GpuProgramParameters::ACT_VIEWPORT_WIDTH }, { "vpHeight", Ogre::GpuProgramParameters::ACT_VIEWPORT_HEIGHT }, { "worldView", Ogre::GpuProgramParameters::ACT_WORLDVIEW_MATRIX }, { "invProj", Ogre::GpuProgramParameters::ACT_INVERSE_PROJECTION_MATRIX }, { "invView", Ogre::GpuProgramParameters::ACT_INVERSE_VIEW_MATRIX }, { "flip", Ogre::GpuProgramParameters::ACT_RENDER_TARGET_FLIPPING }, { "lightDiffuseColor", Ogre::GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR }, { "lightSpecularColor", Ogre::GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR }, { "lightFalloff", Ogre::GpuProgramParameters::ACT_LIGHT_ATTENUATION }, { "lightPos", Ogre::GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE }, { "lightDir", Ogre::GpuProgramParameters::ACT_LIGHT_DIRECTION_VIEW_SPACE }, { "spotParams", Ogre::GpuProgramParameters::ACT_SPOTLIGHT_PARAMS }, { "farClipDistance", Ogre::GpuProgramParameters::ACT_FAR_CLIP_DISTANCE }, { "shadowViewProjMat", Ogre::GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX } }; int numParams = sizeof(AUTO_PARAMS) / sizeof(AutoParamPair); for (int i=0; i<numParams; i++) { if (params->_findNamedConstantDefinition(AUTO_PARAMS[i].name)) { params->setNamedAutoConstant(AUTO_PARAMS[i].name, AUTO_PARAMS[i].type); } } }
//! //! Callback when instance of this class is registered as Ogre::CompositorListener. //! //! \param pass_id Id to identifiy current compositor pass. //! \param mat Material this pass is currently using. //! void BadPrintingNode::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) { Ogre::TexturePtr inputTexture = getTextureValue("Input Map"); if (inputTexture.isNull()) return; // watercolor pass if (pass_id == 0000) { // set shader parameters Ogre::GpuProgramParametersSharedPtr fpParams = getShaderParameters(mat); if (!fpParams.isNull()) { // setShaderParameter(fpParams, "speed1", (Ogre::Real)(getDoubleValue("Speed1") / 100.0)); // setShaderParameter(fpParams, "speed2", (Ogre::Real)(getDoubleValue("Speed2") / 100.0)); // setShaderParameter(fpParams, "speed1", (Ogre::Real)(getDoubleValue("Speed1") / 100.0)); // setShaderParameter(fpParams, "scratchIntensity", (Ogre::Real)(getDoubleValue("ScratchIntensity") / 100.0)); // setShaderParameter(fpParams, "is", (Ogre::Real)(getDoubleValue("IS") / 100.0)); } // set texture name setTexture(mat, inputTexture, 0); } if (pass_id == 0001) { // set shader parameters Ogre::GpuProgramParametersSharedPtr fpParams = getShaderParameters(mat); if (!fpParams.isNull()) { // setShaderParameter(fpParams, "speed1", (Ogre::Real)(getDoubleValue("Speed1") / 100.0)); // setShaderParameter(fpParams, "speed2", (Ogre::Real)(getDoubleValue("Speed2") / 100.0)); // setShaderParameter(fpParams, "speed1", (Ogre::Real)(getDoubleValue("Speed1") / 100.0)); // setShaderParameter(fpParams, "scratchIntensity", (Ogre::Real)(getDoubleValue("ScratchIntensity") / 100.0)); // setShaderParameter(fpParams, "is", (Ogre::Real)(getDoubleValue("IS") / 100.0)); } // set texture name setTexture(mat, inputTexture, 0); } }
void OGKSceneManager::update(Ogre::Real timeElapsed) { if(mTransitionTimeRemaining > 0.f) { mTransitionTimeRemaining -= timeElapsed; if(mTransitionTimeRemaining <= 0.f) { OGKLOG("Transition completed"); if(mPreviousScene) mPreviousScene->onExit(); if(mActiveScene) mActiveScene->onEnterTransitionDidFinish(); if(mOverlay) mOverlay->hide(); } else if(mPreviousScene) { mPreviousScene->update(timeElapsed); if(mRenderTexture) { //OGKLOG("updating render texture"); mRenderTexture->update(); } if(mTransitionTextureUnitState) { Ogre::Real fadeAmt = MIN(1.0,MAX(0.0,mTransitionTimeRemaining) / mTransitionTime); //OGKLOG("updating fade amt " + Ogre::StringConverter::toString(fadeAmt) ); #ifdef OGRE_IS_IOS // Retrieve the shader parameters Ogre::GpuProgramParametersSharedPtr pParams = mTransitionMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); if ( !pParams.isNull() ) { if ( pParams->_findNamedConstantDefinition( "quadAlpha" ) ) { pParams->setNamedConstant( "quadAlpha", fadeAmt ); } } #else mTransitionTextureUnitState->setAlphaOperation(Ogre::LBX_SOURCE1, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, fadeAmt); #endif #ifdef INCLUDE_RTSHADER_SYSTEM Ogre::RTShader::ShaderGenerator::getSingletonPtr()->invalidateMaterial(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, kTransitionMaterialName); #endif } } } if(mActiveScene) mActiveScene->update(timeElapsed); }
bool frameRenderingQueued(const FrameEvent& evt) { Real seconds = (Real)(Root::getSingleton().getTimer()->getMilliseconds()) / 1000.0; Pass* renderPass = mOgreEnt->getSubEntity(0)->getMaterial()->getTechnique(0)->getPass(0); if (renderPass->hasFragmentProgram()) { Ogre::GpuProgramParametersSharedPtr pParams = renderPass->getFragmentProgramParameters(); if ( pParams.isNull() ) { //printf("SAD PANDA!"); } else { if ( pParams->_findNamedConstantDefinition( "ColourMe[0]" ) ) { Vector4 constParam = Ogre::Vector4(0.5, 0.1, 0.0, 1.0); renderPass->getFragmentProgramParameters()->setNamedConstant("ColourMe[0]", constParam); Vector4 timeParam = Ogre::Vector4( Ogre::Math::Sin(seconds)*0.5, 0.0, Ogre::Math::Cos(seconds)*0.5, 0.0); renderPass->getFragmentProgramParameters()->setNamedConstant("ColourMe[1]", timeParam); } const Ogre::GpuConstantDefinition* atom_counter_def; if ( (atom_counter_def = &pParams->getConstantDefinition("atom_counter")) ) { //TODO lock buffer, retrieve counter value similar to compute above //const uint* counter = pParams->getUnsignedIntPointer(atom_counter_def->physicalIndex); //const uint* counter2 = ; //std::cout << "FOUND THE ATOMS: " << *counter << " " << std::endl; //<< *counter2 << std::endl; } } } // renderPass->getFragmentProgramParameters()->getConstantDefinition("atom_counter").getValue(); return SdkSample::frameRenderingQueued(evt); }
void GrassLayerBase::_updateShaders() { if (shaderNeedsUpdate) { shaderNeedsUpdate = false; //Proceed only if there is no custom vertex shader and the user's computer supports vertex shaders const RenderSystemCapabilities *caps = Root::getSingleton().getRenderSystem()->getCapabilities(); if (caps->hasCapability(RSC_VERTEX_PROGRAM) && geom->getShadersEnabled()) { //Calculate fade range float farViewDist = geom->getDetailLevels().front()->getFarRange(); float fadeRange = farViewDist / 1.2247449f; //Note: 1.2247449 ~= sqrt(1.5), which is necessary since the far view distance is measured from the centers //of pages, while the vertex shader needs to fade grass completely out (including the closest corner) //before the page center is out of range. //Generate a string ID that identifies the current set of vertex shader options StringUtil::StrStreamType tmpName; tmpName << "GrassVS_"; if (animate) tmpName << "anim_"; if (blend) tmpName << "blend_"; if (lighting) tmpName << "lighting_"; tmpName << renderTechnique << "_"; tmpName << fadeTechnique << "_"; if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) tmpName << maxHeight << "_"; tmpName << farViewDist << "_"; tmpName << "vp"; const String vsName = tmpName.str(); //Generate a string ID that identifies the material combined with the vertex shader const String matName = material->getName() + "_" + vsName; //Check if the desired material already exists (if not, create it) MaterialPtr tmpMat = MaterialManager::getSingleton().getByName(matName); if (tmpMat.isNull()) { //Clone the original material tmpMat = material->clone(matName); //Disable lighting tmpMat->setLightingEnabled(false); //tmpMat->setReceiveShadows(false); //Check if the desired shader already exists (if not, compile it) String shaderLanguage = ShaderHelper::getShaderLanguage(); HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().getByName(vsName); if (vertexShader.isNull()) { //Generate the grass shader String vertexProgSource; if (!shaderLanguage.compare("hlsl") || !shaderLanguage.compare("cg")) { vertexProgSource = "void main( \n" " float4 iPosition : POSITION, \n" " float4 iColor : COLOR, \n" " float2 iUV : TEXCOORD0, \n" " out float4 oPosition : POSITION, \n" " out float4 oColor : COLOR, \n" " out float2 oUV : TEXCOORD0, \n"; if (lighting) vertexProgSource += " uniform float4 objSpaceLight, \n" " uniform float4 lightDiffuse, \n" " uniform float4 lightAmbient, \n"; if (animate) vertexProgSource += " uniform float time, \n" " uniform float frequency, \n" " uniform float4 direction, \n"; if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) vertexProgSource += " uniform float grassHeight, \n"; if (renderTechnique == GRASSTECH_SPRITE || lighting) vertexProgSource += " float4 iNormal : NORMAL, \n"; vertexProgSource += " uniform float4x4 worldViewProj, \n" " uniform float3 camPos, \n" " uniform float fadeRange ) \n" "{ \n" " oColor.rgb = iColor.rgb; \n" " float4 position = iPosition; \n" " float dist = distance(camPos.xz, position.xz); \n"; if (lighting) { vertexProgSource += " float3 light = normalize(objSpaceLight.xyz - (iPosition.xyz * objSpaceLight.w)); \n" " float diffuseFactor = max(dot(float4(0,1,0,0), light), 0); \n" " oColor = (lightAmbient + diffuseFactor * lightDiffuse) * iColor; \n"; } else { vertexProgSource += " oColor.rgb = iColor.rgb; \n"; } if (fadeTechnique == FADETECH_ALPHA || fadeTechnique == FADETECH_ALPHAGROW) vertexProgSource += //Fade out in the distance " oColor.a = 2.0f - (2.0f * dist / fadeRange); \n"; else vertexProgSource += " oColor.a = 1.0f; \n"; vertexProgSource += " float oldposx = position.x; \n"; if (renderTechnique == GRASSTECH_SPRITE) vertexProgSource += //Face the camera " float3 dirVec = (float3)position - (float3)camPos; \n" " float3 p = normalize(cross(float4(0,1,0,0), dirVec)); \n" " position += float4(p.x * iNormal.x, iNormal.y, p.z * iNormal.x, 0); \n"; if (animate) vertexProgSource += " if (iUV.y == 0.0f){ \n" //Wave grass in breeze " float offset = sin(time + oldposx * frequency); \n" " position += direction * offset; \n" " } \n"; if (blend && animate) vertexProgSource += " else { \n"; else if (blend) vertexProgSource += " if (iUV.y != 0.0f){ \n"; if (blend) vertexProgSource += //Blend the base of nearby grass into the terrain " oColor.a = clamp(oColor.a, 0, 1) * 4.0f * ((dist / fadeRange) - 0.1f); \n" " } \n"; if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) vertexProgSource += " float offset = (2.0f * dist / fadeRange) - 1.0f; \n" " position.y -= grassHeight * clamp(offset, 0, 1); "; vertexProgSource += " oPosition = mul(worldViewProj, position); \n"; vertexProgSource += " oUV = iUV;\n" "}"; } else { //Must be glsl if (lighting) { vertexProgSource = "uniform vec4 objSpaceLight; \n" "uniform vec4 lightDiffuse; \n" "uniform vec4 lightAmbient; \n"; } if (animate) { vertexProgSource += "uniform float time; \n" "uniform float frequency; \n" "uniform vec4 direction; \n"; } if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) { vertexProgSource += "uniform float grassHeight; \n"; } vertexProgSource += "uniform vec3 camPos; \n" "uniform float fadeRange; \n" "\n" "void main()" "{ \n" " vec4 color = gl_Color; \n" " vec4 position = gl_Vertex; \n" " float dist = distance(camPos.xz, position.xz); \n"; if (lighting) { vertexProgSource += " vec3 light = normalize(objSpaceLight.xyz - (gl_Vertex.xyz * objSpaceLight.w)); \n" " float diffuseFactor = max( dot( vec3(0.0,1.0,0.0), light), 0.0); \n" " color = (lightAmbient + diffuseFactor * lightDiffuse) * gl_Color; \n"; } else { vertexProgSource += " color.xyz = gl_Color.xyz; \n"; } if (fadeTechnique == FADETECH_ALPHA || fadeTechnique == FADETECH_ALPHAGROW) { vertexProgSource += //Fade out in the distance " color.w = 2.0 - (2.0 * dist / fadeRange); \n"; } else { vertexProgSource += " color.w = 1.0; \n"; } if (renderTechnique == GRASSTECH_SPRITE) { vertexProgSource += //Face the camera " vec3 dirVec = position.xyz - camPos.xyz; \n" " vec3 p = normalize(cross(vec3(0.0,1.0,0.0), dirVec)); \n" " position += vec4(p.x * gl_Normal.x, gl_Normal.y, p.z * gl_Normal.x, 0.0); \n"; } if (animate) { vertexProgSource += " if (gl_MultiTexCoord0.y == 0.0) \n" " { \n" //Wave grass in breeze " position += direction * sin(time + gl_Vertex.x * frequency); \n" " } \n"; } if (blend && animate) { vertexProgSource += " else \n" " { \n"; } else if (blend) { vertexProgSource += " if (gl_MultiTexCoord0.y != 0.0) \n" " { \n"; } if (blend) { vertexProgSource += //Blend the base of nearby grass into the terrain " color.w = clamp(color.w, 0.0, 1.0) * 4.0 * ((dist / fadeRange) - 0.1); \n" " } \n"; } if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) { vertexProgSource += " position.y -= grassHeight * clamp((2.0 * dist / fadeRange) - 1.0, 0.0, 1.0); \n"; } vertexProgSource += " gl_Position = gl_ModelViewProjectionMatrix * position; \n" " gl_FrontColor = color; \n" " gl_TexCoord[0] = gl_MultiTexCoord0; \n"; if (geom->getSceneManager()->getFogMode() == Ogre::FOG_EXP2) { vertexProgSource += " gl_FogFragCoord = clamp(exp(- gl_Fog.density * gl_Fog.density * gl_Position.z * gl_Position.z), 0.0, 1.0); \n"; } else { vertexProgSource += " gl_FogFragCoord = gl_Position.z; \n"; } vertexProgSource += "}"; } vertexShader = HighLevelGpuProgramManager::getSingleton().createProgram(vsName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, shaderLanguage, GPT_VERTEX_PROGRAM); vertexShader->setSource(vertexProgSource); if (shaderLanguage == "hlsl") { vertexShader->setParameter("target", "vs_1_1"); vertexShader->setParameter("entry_point", "main"); } else if (shaderLanguage == "cg") { vertexShader->setParameter("profiles", "vs_1_1 arbvp1"); vertexShader->setParameter("entry_point", "main"); } // GLSL can only have one entry point "main". vertexShader->load(); } //Now the vertex shader (vertexShader) has either been found or just generated //(depending on whether or not it was already generated). tmpMat->load(); Ogre::Material::TechniqueIterator techIterator = tmpMat->getSupportedTechniqueIterator(); while (techIterator.hasMoreElements()) { Ogre::Technique* tech = techIterator.getNext(); //Apply the shader to the material Pass *pass = tech->getPass(0); pass->setVertexProgram(vsName); GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); if (shaderLanguage.compare("glsl")) //glsl can use the built in gl_ModelViewProjectionMatrix params->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); params->setNamedAutoConstant("camPos", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE); params->setNamedAutoConstant("fadeRange", GpuProgramParameters::ACT_CUSTOM, 1); if (animate) { params->setNamedConstant("time", 1.0f); params->setNamedConstant("frequency", 1.0f); params->setNamedConstant("direction", Ogre::Vector4::ZERO); } if (lighting) { params->setNamedAutoConstant("objSpaceLight", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE); params->setNamedAutoConstant("lightDiffuse", GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR); params->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR); } if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) { params->setNamedConstant("grassHeight", maxHeight * 1.05f); } pass->getVertexProgramParameters()->setNamedConstant("fadeRange", fadeRange); } } //Now the material (tmpMat) has either been found or just created (depending on whether or not it was already //created). The appropriate vertex shader should be applied and the material is ready for use. //Apply the new material material = tmpMat; } Ogre::Technique* tech = material->getBestTechnique(); if (tech && tech->getNumPasses()) { Ogre::Pass* pass = tech->getPass(0); if (pass->hasVertexProgram()) { Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); if (!params.isNull()) { params->setIgnoreMissingParams(true); } } } } }
bool OgreMaterialProperties::CreateProperties() { Ogre::MaterialPtr matPtr = material_->GetMaterial(); if (matPtr.isNull()) return false; // Material Ogre::Material::TechniqueIterator tIter = matPtr->getTechniqueIterator(); while(tIter.hasMoreElements()) { // Technique Ogre::Technique *tech = tIter.getNext(); Ogre::Technique::PassIterator pIter = tech->getPassIterator(); while(pIter.hasMoreElements()) { // Pass Ogre::Pass *pass = pIter.getNext(); if (!pass) continue; if(pass->hasVertexProgram()) { // Vertex program const Ogre::GpuProgramPtr &verProg = pass->getVertexProgram(); if (!verProg.isNull()) { Ogre::GpuProgramParametersSharedPtr verPtr = pass->getVertexProgramParameters(); if (verPtr->hasNamedParameters()) { // Named parameters (constants) Ogre::GpuConstantDefinitionIterator mapIter = verPtr->getConstantDefinitionIterator(); while(mapIter.hasMoreElements()) { QString paramName = mapIter.peekNextKey().c_str(); const Ogre::GpuConstantDefinition ¶mDef = mapIter.getNext(); // Filter names that end with '[0]' int found = paramName.indexOf("[0]"); if (found != -1) continue; // Ignore auto parameters bool is_auto_param = false; Ogre::GpuProgramParameters::AutoConstantIterator autoConstIter = verPtr->getAutoConstantIterator(); while(autoConstIter.hasMoreElements()) { Ogre::GpuProgramParameters::AutoConstantEntry autoConstEnt = autoConstIter.getNext(); if (autoConstEnt.physicalIndex == paramDef.physicalIndex) { is_auto_param = true; break; } } if (is_auto_param) continue; if (!paramDef.isFloat()) continue; size_t count = paramDef.elementSize * paramDef.arraySize; QVector<float> paramValue; QVector<float>::iterator iter; paramValue.resize(count); verPtr->_readRawConstants(paramDef.physicalIndex, count, &*paramValue.begin()); QTextStream vector_string; QString string; vector_string.setString(&string, QIODevice::WriteOnly); for(iter = paramValue.begin(); iter != paramValue.end(); ++iter) vector_string << *iter << " "; // Add QPROPERTY. Add to "VP" to the end of the parameter name in order to identify VP parameters. QMap<QString, QVariant> typeValuePair; typeValuePair[GpuConstantTypeToString(paramDef.constType)] = *vector_string.string(); setProperty(paramName.append(" VP").toLatin1(), QVariant(typeValuePair)); } } } } if(pass->hasFragmentProgram()) { // Fragment program const Ogre::GpuProgramPtr fragProg = pass->getFragmentProgram(); if (!fragProg.isNull()) { Ogre::GpuProgramParametersSharedPtr fragPtr = pass->getFragmentProgramParameters(); if (!fragPtr.isNull()) { if (fragPtr->hasNamedParameters()) { // Named parameters (constants) Ogre::GpuConstantDefinitionIterator mapIter = fragPtr->getConstantDefinitionIterator(); while(mapIter.hasMoreElements()) { QString paramName = mapIter.peekNextKey().c_str(); const Ogre::GpuConstantDefinition ¶mDef = mapIter.getNext(); // Filter names that end with '[0]' int found = paramName.indexOf("[0]"); if (found != -1) continue; // Ignore auto parameters bool is_auto_param = false; Ogre::GpuProgramParameters::AutoConstantIterator autoConstIter = fragPtr->getAutoConstantIterator(); while(autoConstIter.hasMoreElements()) { Ogre::GpuProgramParameters::AutoConstantEntry autoConstEnt = autoConstIter.getNext(); if (autoConstEnt.physicalIndex == paramDef.physicalIndex) { is_auto_param = true; break; } } if (is_auto_param) continue; if (!paramDef.isFloat()) continue; size_t count = paramDef.elementSize * paramDef.arraySize; QVector<float> paramValue; QVector<float>::iterator iter; paramValue.resize(count); fragPtr->_readRawConstants(paramDef.physicalIndex, count, &*paramValue.begin()); QTextStream vector_string; QString string; vector_string.setString(&string, QIODevice::WriteOnly); for(iter = paramValue.begin(); iter != paramValue.end(); ++iter) vector_string << *iter << " "; // Add QPROPERTY. Add to " FP" to the end of the parameter name in order to identify FP parameters TypeValuePair typeValuePair; typeValuePair[GpuConstantTypeToString(paramDef.constType)] = *vector_string.string(); setProperty(paramName.append(" FP").toLatin1(), QVariant(typeValuePair)); } } } } } Ogre::Pass::TextureUnitStateIterator texIter = pass->getTextureUnitStateIterator(); while(texIter.hasMoreElements()) { // Texture units const Ogre::TextureUnitState *tu = texIter.getNext(); // Don't insert tu's with empty texture names (i.e. shadowMap) // add to " TU" to the end of the parameter name in order to identify texture units. if(tu->getTextureName().size() > 0) { QString tuName(tu->getName().c_str()); // Add QPROPERTY TypeValuePair typeValuePair; typeValuePair[TextureTypeToString(tu->getTextureType())] = tu->getTextureName().c_str(); setProperty(tuName.append(" TU").toLatin1(), typeValuePair); } } } } return true; }
Ogre::MaterialPtr OgreMaterialProperties::ToOgreMaterial() { // Make clone from the original and uset that for creating the new material. Ogre::MaterialPtr matPtr = material_->GetMaterial(); Ogre::MaterialPtr matPtrClone = matPtr->clone(objectName().toStdString() + "Clone"); // Material if (!matPtrClone.isNull()) { // Technique Ogre::Material::TechniqueIterator tIter = matPtrClone->getTechniqueIterator(); while(tIter.hasMoreElements()) { Ogre::Technique *tech = tIter.getNext(); Ogre::Technique::PassIterator pIter = tech->getPassIterator(); while(pIter.hasMoreElements()) { // Pass Ogre::Pass *pass = pIter.getNext(); if (!pass) continue; if (pass->hasVertexProgram()) { // Vertex program const Ogre::GpuProgramPtr &verProg = pass->getVertexProgram(); if (!verProg.isNull()) { Ogre::GpuProgramParametersSharedPtr verPtr = pass->getVertexProgramParameters(); if (verPtr->hasNamedParameters()) { // Named parameters (constants) Ogre::GpuConstantDefinitionIterator mapIter = verPtr->getConstantDefinitionIterator(); int constNum = 0; while(mapIter.hasMoreElements()) { QString paramName(mapIter.peekNextKey().c_str()); const Ogre::GpuConstantDefinition ¶mDef = mapIter.getNext(); // Filter names that end with '[0]' if (paramName.lastIndexOf("[0]") != -1) continue; if (!paramDef.isFloat()) continue; size_t size = paramDef.elementSize * paramDef.arraySize; QVector<float> newParamValue; QVector<float>::iterator it; newParamValue.resize(size); // Find the corresponding property value. QVariant val = property(paramName.append(" VP").toLatin1()); if (!val.isValid() || val.isNull()) continue; TypeValuePair typeValuePair = val.toMap(); QString newValueString(typeValuePair.begin().value().toByteArray()); newValueString.trimmed(); // fill the float vector with new values it = newParamValue.begin(); int i = 0, j = 0; bool ok = true; while(j != -1 && ok) { j = newValueString.indexOf(' ', i); QString newValue = newValueString.mid(i, j == -1 ? j : j - i); if (!newValue.isEmpty()) { *it = newValue.toFloat(&ok); ++it; } i = j + 1; } // Set the new value. ///\todo use the exact count rather than just 4 values if needed. if (size == 16) { Ogre::Matrix4 matrix(newParamValue[0], newParamValue[1], newParamValue[2], newParamValue[3], newParamValue[4], newParamValue[5], newParamValue[6], newParamValue[7], newParamValue[8], newParamValue[9], newParamValue[10], newParamValue[11], newParamValue[12], newParamValue[13], newParamValue[14], newParamValue[15]); #if OGRE_VERSION_MINOR <= 6 && OGRE_VERSION_MAJOR <= 1 verPtr->_writeRawConstant(paramDef.physicalIndex, matrix); #else verPtr->_writeRawConstant(paramDef.physicalIndex, matrix, size); #endif } else { Ogre::Vector4 vector(newParamValue[0], newParamValue[1], newParamValue[2], newParamValue[3]); verPtr->_writeRawConstant(paramDef.physicalIndex, vector); } } } } } if (pass->hasFragmentProgram()) { // Fragment program const Ogre::GpuProgramPtr &fragProg = pass->getFragmentProgram(); if (!fragProg.isNull()) { Ogre::GpuProgramParametersSharedPtr fragPtr = pass->getFragmentProgramParameters(); if (!fragPtr.isNull()) { if (fragPtr->hasNamedParameters()) { // Named parameters (constants) Ogre::GpuConstantDefinitionIterator mapIter = fragPtr->getConstantDefinitionIterator(); while(mapIter.hasMoreElements()) { QString paramName(mapIter.peekNextKey().c_str()); const Ogre::GpuConstantDefinition ¶mDef = mapIter.getNext(); // Filter names that end with '[0]' if (paramName.lastIndexOf("[0]") != -1) continue; if (!paramDef.isFloat()) continue; size_t size = paramDef.elementSize * paramDef.arraySize; QVector<float> newParamValue; QVector<float>::iterator it; newParamValue.resize(size); // Find the corresponding property value. QVariant val = property(paramName.append(" FP").toLatin1()); if (!val.isValid() || val.isNull()) continue; TypeValuePair typeValuePair = val.toMap(); QString newValueString(typeValuePair.begin().value().toByteArray()); newValueString.trimmed(); // Fill the float vector with new values. it = newParamValue.begin(); int i = 0, j = 0; bool ok = true; while(j != -1 && ok) { j = newValueString.indexOf(' ', i); QString newValue = newValueString.mid(i, j == -1 ? j : j - i); if (!newValue.isEmpty()) { *it = *it = newValue.toFloat(&ok); ++it; } i = j + 1; } // Set the new value. ///\todo use the exact count rather than just 4 values if needed. if (size == 16) { Ogre::Matrix4 matrix(newParamValue[0], newParamValue[1], newParamValue[2], newParamValue[3], newParamValue[4], newParamValue[5], newParamValue[6], newParamValue[7], newParamValue[8], newParamValue[9], newParamValue[10], newParamValue[11], newParamValue[12], newParamValue[13], newParamValue[14], newParamValue[15]); #if OGRE_VERSION_MINOR <= 6 && OGRE_VERSION_MAJOR <= 1 fragPtr->_writeRawConstant(paramDef.physicalIndex, matrix); #else fragPtr->_writeRawConstant(paramDef.physicalIndex, matrix, size); #endif } else { Ogre::Vector4 vector(newParamValue[0], newParamValue[1], newParamValue[2], newParamValue[3]); fragPtr->_writeRawConstant(paramDef.physicalIndex, vector); } } } } } } Ogre::Pass::TextureUnitStateIterator texIter = pass->getTextureUnitStateIterator(); while(texIter.hasMoreElements()) { // Texture units Ogre::TextureUnitState *tu = texIter.getNext(); // Replace the texture name (uuid) with the new one QString tu_name(tu->getName().c_str()); QVariant val = property(tu_name.append(" TU").toLatin1()); if (!val.isValid() || val.isNull()) continue; TypeValuePair typeValuePair = val.toMap(); QString newValueString(typeValuePair.begin().value().toByteArray()); newValueString.trimmed(); tu->setTextureName(newValueString.toStdString()); /* //QString new_texture_name = iter->second; RexUUID new_name(iter->second); // If new texture is UUID-based one, make sure the corresponding RexOgreTexture gets created, // because we may not be able to load it later if load fails now if (RexUUID::IsValid(new_texture_name)) { RexUUID imageID(new_texture_name); if (!imageID.IsNull()) { image* image = imageList.getImage(imageID); if (image) { image->getOgreTexture(); } } } //tu->setTextureName(iter->second); */ } } } return matPtrClone; } matPtrClone.setNull(); return matPtrClone; }