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; }
//----------------------------------------------------------------------- void TerrainLiquidObject::_prepareProjector(void) { if (mProjectorName.empty() || !mProjectorSize) return; Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(mMaterialName); if (material.isNull()) return; bool hasProjector = false; { Ogre::Material::TechniqueIterator ti = material->getTechniqueIterator(); while (ti.hasMoreElements()) { Ogre::Technique* technique = ti.getNext(); Ogre::Technique::PassIterator pi = technique->getPassIterator(); while (pi.hasMoreElements()) { Ogre::Pass* pass = pi.getNext(); Ogre::Pass::TextureUnitStateIterator tusi = pass->getTextureUnitStateIterator(); while (tusi.hasMoreElements()) { Ogre::TextureUnitState* tus = tusi.getNext(); if (Ogre::StringUtil::startsWith(tus->getName(), "Fairy/Projector", false)) { hasProjector = true; } } } } } if (!hasProjector) return; ObjectPtr object = mSystem->getSceneInfo()->findObjectByName(mProjectorName); if (!object) return; Variant directionValue = object->getProperty("direction"); if (directionValue.empty() || directionValue.type() != typeid(Ogre::Vector3)) return; Ogre::Vector3 direction = VariantCast<Ogre::Vector3>(directionValue); direction.normalise(); Ogre::String name = material->getName() + Ogre::StringConverter::toString((Ogre::ulong)this); mProjectionCamera = mTerrainLiquid->getParentSceneNode()->getCreator()->createCamera(name); mProjectionCamera->setAutoAspectRatio(false); mProjectionCamera->setAspectRatio(1.0f); mProjectionCamera->setFixedYawAxis(false); mProjectionCamera->setProjectionType(Ogre::PT_ORTHOGRAPHIC); mProjectionCamera->setFOVy(Ogre::Degree(90)); mProjectionCamera->setDirection(-direction); mProjectionCamera->setNearClipDistance(mProjectorSize / 2); mProjectionCamera->setFarClipDistance(mProjectorSize + 5000.0f); mTerrainLiquid->setProjectionCamera(mProjectionCamera); mProjectionMaterial = material->clone(name); { Ogre::Material::TechniqueIterator ti = mProjectionMaterial->getTechniqueIterator(); while (ti.hasMoreElements()) { Ogre::Technique* technique = ti.getNext(); Ogre::Technique::PassIterator pi = technique->getPassIterator(); while (pi.hasMoreElements()) { Ogre::Pass* pass = pi.getNext(); Ogre::Pass::TextureUnitStateIterator tusi = pass->getTextureUnitStateIterator(); while (tusi.hasMoreElements()) { Ogre::TextureUnitState* tus = tusi.getNext(); if (Ogre::StringUtil::startsWith(tus->getName(), "Fairy/Projector", false)) { tus->setProjectiveTexturing(true, mProjectionCamera); } } } } } mProjectionMaterial->load(); }