void AmbientLight::updateFromCamera(Ogre::Camera* camera) { Ogre::Technique* tech = getMaterial()->getBestTechnique(); Ogre::Vector3 farCorner = camera->getViewMatrix(true) * camera->getWorldSpaceCorners()[4]; for (unsigned short i=0; i<tech->getNumPasses(); i++) { Ogre::Pass* pass = tech->getPass(i); // get the vertex shader parameters Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); // set the camera's far-top-right corner if (params->_findNamedConstantDefinition("farCorner")) params->setNamedConstant("farCorner", farCorner); params = pass->getFragmentProgramParameters(); if (params->_findNamedConstantDefinition("farCorner")) params->setNamedConstant("farCorner", farCorner); } }
void EffectManager::addEffect(const std::string &model, std::string textureOverride, const Ogre::Vector3 &worldPosition, float scale) { Ogre::SceneNode* sceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(worldPosition); sceneNode->setScale(scale,scale,scale); NifOgre::ObjectScenePtr scene = NifOgre::Loader::createObjects(sceneNode, model); MWRender::Animation::setRenderProperties(scene, RV_Effects, RQG_Main, RQG_Alpha, 0.f, false, NULL); for(size_t i = 0;i < scene->mControllers.size();i++) { if(scene->mControllers[i].getSource().isNull()) scene->mControllers[i].setSource(Ogre::SharedPtr<EffectAnimationTime> (new EffectAnimationTime())); } if (!textureOverride.empty()) { std::string correctedTexture = Misc::ResourceHelpers::correctTexturePath(textureOverride); for(size_t i = 0;i < scene->mParticles.size(); ++i) { Ogre::ParticleSystem* partSys = scene->mParticles[i]; Ogre::MaterialPtr mat = scene->mMaterialControllerMgr.getWritableMaterial(partSys); for (int t=0; t<mat->getNumTechniques(); ++t) { Ogre::Technique* tech = mat->getTechnique(t); for (int p=0; p<tech->getNumPasses(); ++p) { Ogre::Pass* pass = tech->getPass(p); for (int tex=0; tex<pass->getNumTextureUnitStates(); ++tex) { Ogre::TextureUnitState* tus = pass->getTextureUnitState(tex); tus->setTextureName(correctedTexture); } } } } } mEffects.push_back(std::make_pair(sceneNode, scene)); }
void Water::createdConfiguration (sh::MaterialInstance* m, const std::string& configuration) { if (configuration == "local_map" || !Settings::Manager::getBool("shader", "Water")) { // for simple water, set animated texture names // these have to be set in code std::string textureNames[32]; for (int i=0; i<32; ++i) { textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds"; } Ogre::Technique* t = static_cast<sh::OgreMaterial*>(m->getMaterial())->getOgreTechniqueForConfiguration(configuration); if (t->getPass(0)->getNumTextureUnitStates () == 0) return; t->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2); t->getPass(0)->setDepthWriteEnabled (false); t->getPass(0)->setSceneBlending (Ogre::SBT_TRANSPARENT_ALPHA); } }
//----------------------------------------------------------------------- Ogre::TextureUnitState* MaterialTab::getFirstTexture(void) { wxString materialName = mMaterialListBox->GetStringSelection(); Ogre::String name = wx2ogre(materialName); Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(name); if (!material.isNull() && material->getNumTechniques() > 0) { material->load(); Ogre::Technique* technique = material->getBestTechnique(); // Get the best technique if (technique && technique->getNumPasses() > 0) { Ogre::Pass* pass = technique->getPass(0); // Get the first if (pass->getNumTextureUnitStates() > 0) { return pass->getTextureUnitState(0); // Get the first } } } return 0; }
void MaterialEditor::OnDeleteMaterialObject(wxCommandEvent &e) { if(mMaterial.isNull()) return; if(m_MaterialTree->getSelecteTextureUnit()) { Ogre::TextureUnitState* pTexture = m_MaterialTree->getSelecteTextureUnit(); Ogre::Pass* pPass = pTexture->getParent(); if(pPass) { pPass->removeTextureUnitState(pPass->getTextureUnitStateIndex(pTexture)); } } else if(m_MaterialTree->getSelectePass()) { Ogre::Pass* pPass = m_MaterialTree->getSelectePass(); Ogre::Technique* pTechnique = pPass->getParent(); if(pTechnique) { pTechnique->removePass(pPass->getIndex()); } } else if(m_MaterialTree->getSelecteTechnique()) { Ogre::Technique* pTechnique = m_MaterialTree->getSelecteTechnique(); for(int i= 0;i<mMaterial->getNumTechniques();i++) { if(pTechnique == mMaterial->getTechnique(i)) { mMaterial->removeTechnique(i); break; } } } else return; m_Frame->GetEffectObjectProperty()->InitMaterialEditor(mMaterial,mMaterialName); m_MaterialTree->DeleteAllItems(); m_MaterialTree->AddMaterialToTree(mMaterial,mMaterialName); }
/** This class demonstrates basic usage of the RTShader system. It sub class the material manager listener class and when a target scheme callback is invoked with the shader generator scheme it tries to create an equivalent shader based technique based on the default technique of the given material. */ Ogre::Technique* MaterialMgrListener::handleSchemeNotFound(unsigned short schemeIndex, const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, const Ogre::Renderable* rend) { Ogre::Technique* generatedTech = NULL; // Case this is the default shader generator scheme. if (schemeName == Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) { bool techniqueCreated; // Create shader generated technique for this material. techniqueCreated = mShaderGenerator->createShaderBasedTechnique( originalMaterial->getName(), Ogre::MaterialManager::DEFAULT_SCHEME_NAME, schemeName); // Case technique registration succeeded. if (techniqueCreated) { // Force creating the shaders for the generated technique. mShaderGenerator->validateMaterial(schemeName, originalMaterial->getName()); // Grab the generated technique. Ogre::Material::TechniqueIterator itTech = originalMaterial->getTechniqueIterator(); while (itTech.hasMoreElements()) { Ogre::Technique* curTech = itTech.getNext(); if (curTech->getSchemeName() == schemeName) { generatedTech = curTech; break; } } } } return generatedTech; }
void MeshPersonVisual::setColor(const Ogre::ColourValue& c) { Ogre::SceneBlendType blending; bool depth_write; if ( c.a < 0.9998 ) { blending = Ogre::SBT_TRANSPARENT_ALPHA; depth_write = false; } else { blending = Ogre::SBT_REPLACE; depth_write = true; } std::set<Ogre::MaterialPtr>::iterator it; for( it = materials_.begin(); it != materials_.end(); it++ ) { Ogre::Technique* technique = (*it)->getTechnique( 0 ); technique->setAmbient( c.r*0.5, c.g*0.5, c.b*0.5 ); technique->setDiffuse( c.r, c.g, c.b, c.a ); technique->setSceneBlending( blending ); technique->setDepthWriteEnabled( depth_write ); technique->setLightingEnabled( true ); } }
void GetTextureNamesFromMaterial(Ogre::MaterialPtr material, StringVector& textures) { textures.clear(); if (material.isNull()) return; // Use a set internally to avoid duplicates std::set<std::string> textures_set; Ogre::Material::TechniqueIterator iter = material->getTechniqueIterator(); while(iter.hasMoreElements()) { Ogre::Technique *tech = iter.getNext(); assert(tech); Ogre::Technique::PassIterator passIter = tech->getPassIterator(); while(passIter.hasMoreElements()) { Ogre::Pass *pass = passIter.getNext(); Ogre::Pass::TextureUnitStateIterator texIter = pass->getTextureUnitStateIterator(); while(texIter.hasMoreElements()) { Ogre::TextureUnitState *texUnit = texIter.getNext(); const std::string& texname = texUnit->getTextureName(); if (!texname.empty()) textures_set.insert(texname); } } } std::set<std::string>::iterator i = textures_set.begin(); while (i != textures_set.end()) { textures.push_back(*i); ++i; } }
ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr) : Animation(ptr) { MWWorld::LiveCellRef<ESM::Activator> *ref = mPtr.get<ESM::Activator>(); assert (ref->mBase != NULL); if(!ref->mBase->mModel.empty()) { std::string mesh = "meshes\\" + ref->mBase->mModel; createEntityList(mPtr.getRefData().getBaseNode(), mesh); for(size_t i = 0;i < mEntityList.mEntities.size();i++) { Ogre::Entity *ent = mEntityList.mEntities[i]; bool transparent = false; for (unsigned int j=0;j < ent->getNumSubEntities() && !transparent; ++j) { Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); while (techIt.hasMoreElements() && !transparent) { Ogre::Technique* tech = techIt.getNext(); Ogre::Technique::PassIterator passIt = tech->getPassIterator(); while (passIt.hasMoreElements() && !transparent) { Ogre::Pass* pass = passIt.getNext(); if (pass->getDepthWriteEnabled() == false) transparent = true; } } } ent->setVisibilityFlags(RV_Misc); ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); } setAnimationSource(mesh); } }
void RoR::SkinManager::ReplaceMaterialTextures(SkinDef* skin_def, std::string materialName) // Static { const auto not_found = skin_def->replace_textures.end(); Ogre::MaterialPtr mat = RoR::OgreSubsystem::GetMaterialByName(materialName); if (!mat.isNull()) { for (int t = 0; t < mat->getNumTechniques(); t++) { Ogre::Technique* tech = mat->getTechnique(0); if (!tech) continue; for (int p = 0; p < tech->getNumPasses(); p++) { Ogre::Pass* pass = tech->getPass(p); if (!pass) continue; for (int tu = 0; tu < pass->getNumTextureUnitStates(); tu++) { Ogre::TextureUnitState* tus = pass->getTextureUnitState(tu); if (!tus) continue; //if (tus->getTextureType() != TEX_TYPE_2D) continue; // only replace 2d images // walk the frames, usually there is only one for (unsigned int fr = 0; fr < tus->getNumFrames(); fr++) { Ogre::String textureName = tus->getFrameTextureName(fr); std::map<Ogre::String, Ogre::String>::iterator it = skin_def->replace_textures.find(textureName); if (it != not_found) { textureName = it->second; //getReplacementForTexture(textureName); tus->setFrameTextureName(textureName, fr); } } } } } } }
void CubeWorld::createSkyTexture(const TCHAR* pName) { Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(pName, "General", true); Ogre::Technique* tech = mat->getTechnique(0); Ogre::Pass* pass = tech->getPass(0); Ogre::TextureUnitState* tex = pass->createTextureUnitState(); pass->setLightingEnabled(false); pass->setDepthCheckEnabled(false); pass->setDepthWriteEnabled(false); pass->setFog(true); tex->setTextureName("clouds.jpg"); tex->setScrollAnimation(0.05, 0); // This is a new texture state to simulate lightning tex = pass->createTextureUnitState(); tex->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, Ogre::ColourValue(1, 1, 1)); m_SkyMaterial = mat; updateSkyTextureLight(); }
void CompositionHandler::SetMaterialParameters(const Ogre::MaterialPtr &material, const QList< std::pair<std::string, Ogre::Vector4> > &source) const { assert (material.get()); material->load(); for(ushort t=0 ; t<material->getNumTechniques() ; ++t) { Ogre::Technique *technique = material->getTechnique(t); if (technique) { for(ushort p=0 ; p<technique->getNumPasses() ; ++p) { Ogre::Pass *pass = technique->getPass(p); if (pass) { if (pass->hasVertexProgram()) { Ogre::GpuProgramParametersSharedPtr destination = pass->getVertexProgramParameters(); for(int i=0 ; i<source.size() ; ++i) { if (destination->_findNamedConstantDefinition(source[i].first, false)) destination->setNamedConstant(source[i].first, source[i].second); } } if (pass->hasFragmentProgram()) { Ogre::GpuProgramParametersSharedPtr destination = pass->getFragmentProgramParameters(); for(int i=0 ; i<source.size() ; ++i) { if (destination->_findNamedConstantDefinition(source[i].first, false)) destination->setNamedConstant(source[i].first, source[i].second); } } } } } } }
// unload all about this mesh. The mesh itself and the textures. // BETWEEN FRAME OPERATION void VisCalcFrustDist::unloadTheMesh(Ogre::MeshPtr meshP) { if (m_shouldCullTextures) { Ogre::Mesh::SubMeshIterator smi = meshP->getSubMeshIterator(); while (smi.hasMoreElements()) { Ogre::SubMesh* oneSubMesh = smi.getNext(); Ogre::String subMeshMaterialName = oneSubMesh->getMaterialName(); Ogre::MaterialPtr subMeshMaterial = (Ogre::MaterialPtr)Ogre::MaterialManager::getSingleton().getByName(subMeshMaterialName); if (!subMeshMaterial.isNull()) { Ogre::Material::TechniqueIterator techIter = subMeshMaterial->getTechniqueIterator(); while (techIter.hasMoreElements()) { Ogre::Technique* oneTech = techIter.getNext(); Ogre::Technique::PassIterator passIter = oneTech->getPassIterator(); while (passIter.hasMoreElements()) { Ogre::Pass* onePass = passIter.getNext(); Ogre::Pass::TextureUnitStateIterator tusIter = onePass->getTextureUnitStateIterator(); while (tusIter.hasMoreElements()) { Ogre::TextureUnitState* oneTus = tusIter.getNext(); Ogre::String texName = oneTus->getTextureName(); Ogre::TexturePtr texP = (Ogre::TexturePtr)Ogre::TextureManager::getSingleton().getByName(texName); if (!texP.isNull()) { // if (texP.useCount() <= 1) { texP->unload(); LG::IncStat(LG::StatCullTexturesUnloaded); // LG::Log("unloadTheMesh: unloading texture %s", texName.c_str()); // } } } } } } } } if (m_shouldCullMeshes) { LG::OLMeshTracker::Instance()->MakeUnLoaded(meshP->getName(), Ogre::String(), NULL); LG::IncStat(LG::StatCullMeshesUnloaded); // LG::Log("unloadTheMesh: unloading mesh %s", mshName.c_str()); } }
void GroundFog::findFogPassesByName (const Ogre::String& passName) { Ogre::MaterialManager *matManager = Ogre::MaterialManager::getSingletonPtr(); Ogre::MaterialManager::ResourceMapIterator matIt = matManager->getResourceIterator(); while (matIt.hasMoreElements()) { #if (OGRE_VERSION < ((1 << 16) | (9 << 8) | 0)) Ogre::MaterialPtr mat = matIt.getNext(); #else Ogre::MaterialPtr mat = matIt.getNext().staticCast<Ogre::Material>(); #endif Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); while (techIt.hasMoreElements()) { Ogre::Technique *tech = techIt.getNext(); Ogre::Technique::PassIterator passIt = tech->getPassIterator(); while (passIt.hasMoreElements()) { Ogre::Pass *pass = passIt.getNext(); if (pass->getName() == passName) { mPasses.insert(pass); } } } } forceUpdate(); }
void SetTextureUnitOnMaterial(Ogre::MaterialPtr material, const std::string& texture_name, uint index) { if (material.isNull()) return; Ogre::TextureManager &tm = Ogre::TextureManager::getSingleton(); Ogre::TexturePtr tex = tm.getByName(texture_name); Ogre::Material::TechniqueIterator iter = material->getTechniqueIterator(); while(iter.hasMoreElements()) { Ogre::Technique *tech = iter.getNext(); assert(tech); Ogre::Technique::PassIterator passIter = tech->getPassIterator(); while(passIter.hasMoreElements()) { Ogre::Pass *pass = passIter.getNext(); Ogre::Pass::TextureUnitStateIterator texIter = pass->getTextureUnitStateIterator(); uint cmp_index = 0; while(texIter.hasMoreElements()) { Ogre::TextureUnitState *texUnit = texIter.getNext(); if (index == cmp_index) { if (tex.get()) texUnit->setTextureName(texture_name); else texUnit->setTextureName("TextureMissing.png"); } cmp_index++; } } } }
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); } } } } }
//----------------------------------------------------------------------- void DLight::updateFromCamera(Ogre::Camera* camera) { //Set shader params const Ogre::MaterialPtr& mat = getMaterial(); if (!mat->isLoaded()) { mat->load(); } Ogre::Technique* tech = mat->getBestTechnique(); Ogre::Vector3 farCorner = camera->getViewMatrix(true) * camera->getWorldSpaceCorners()[4]; for (unsigned short i=0; i<tech->getNumPasses(); i++) { Ogre::Pass* pass = tech->getPass(i); // get the vertex shader parameters Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); // set the camera's far-top-right corner if (params->_findNamedConstantDefinition("farCorner")) params->setNamedConstant("farCorner", farCorner); params = pass->getFragmentProgramParameters(); if (params->_findNamedConstantDefinition("farCorner")) params->setNamedConstant("farCorner", farCorner); //If inside light geometry, render back faces with CMPF_GREATER, otherwise normally if (mParentLight->getType() == Ogre::Light::LT_DIRECTIONAL) { pass->setCullingMode(Ogre::CULL_CLOCKWISE); pass->setDepthCheckEnabled(false); } else { pass->setDepthCheckEnabled(true); if (isCameraInsideLight(camera)) { pass->setCullingMode(Ogre::CULL_ANTICLOCKWISE); pass->setDepthFunction(Ogre::CMPF_GREATER_EQUAL); } else { pass->setCullingMode(Ogre::CULL_CLOCKWISE); pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL); } } Camera shadowCam("ShadowCameraSetupCam", 0); shadowCam._notifyViewport(camera->getViewport()); SceneManager* sm = mParentLight->_getManager(); sm->getShadowCameraSetup()->getShadowCamera(sm, camera, camera->getViewport(), mParentLight, &shadowCam, 0); //Get the shadow camera position if (params->_findNamedConstantDefinition("shadowCamPos")) { params->setNamedConstant("shadowCamPos", shadowCam.getPosition()); } if (params->_findNamedConstantDefinition("shadowFarClip")) { params->setNamedConstant("shadowFarClip", shadowCam.getFarClipDistance()); } } }
Ogre::MaterialPtr MaterialGenerator::create(bool renderCompositeMap, bool displayCompositeMap) { assert(!renderCompositeMap || !displayCompositeMap); static int count = 0; std::stringstream name; name << "terrain/mat" << count++; if (!mShaders) { Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(name.str(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); Ogre::Technique* technique = mat->getTechnique(0); technique->removeAllPasses(); if (displayCompositeMap) { Ogre::Pass* pass = technique->createPass(); pass->setVertexColourTracking(Ogre::TVC_AMBIENT|Ogre::TVC_DIFFUSE); pass->createTextureUnitState(mCompositeMap)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP); } else { assert(mLayerList.size() == mBlendmapList.size()+1); std::vector<Ogre::TexturePtr>::iterator blend = mBlendmapList.begin(); for (std::vector<LayerInfo>::iterator layer = mLayerList.begin(); layer != mLayerList.end(); ++layer) { Ogre::Pass* pass = technique->createPass(); pass->setLightingEnabled(false); pass->setVertexColourTracking(Ogre::TVC_NONE); // TODO: How to handle fog? pass->setFog(true, Ogre::FOG_NONE); bool first = (layer == mLayerList.begin()); Ogre::TextureUnitState* tus; if (!first) { pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); pass->setDepthFunction(Ogre::CMPF_EQUAL); tus = pass->createTextureUnitState((*blend)->getName()); tus->setAlphaOperation(Ogre::LBX_BLEND_TEXTURE_ALPHA, Ogre::LBS_TEXTURE, Ogre::LBS_TEXTURE); tus->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA, Ogre::LBS_TEXTURE, Ogre::LBS_TEXTURE); tus->setIsAlpha(true); tus->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP); float scale = (16/(16.f+1.f)); tus->setTextureScale(1.f/scale,1.f/scale); } // Add the actual layer texture on top of the alpha map. tus = pass->createTextureUnitState(layer->mDiffuseMap); if (!first) tus->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA, Ogre::LBS_TEXTURE, Ogre::LBS_CURRENT); tus->setTextureScale(1/16.f,1/16.f); if (!first) ++blend; } if (!renderCompositeMap) { Ogre::Pass* lightingPass = technique->createPass(); lightingPass->setSceneBlending(Ogre::SBT_MODULATE); lightingPass->setVertexColourTracking(Ogre::TVC_AMBIENT|Ogre::TVC_DIFFUSE); lightingPass->setFog(true, Ogre::FOG_NONE); } } return mat; } #if TERRAIN_USE_SHADER else { sh::MaterialInstance* material = sh::Factory::getInstance().createMaterialInstance (name.str()); material->setProperty ("allow_fixed_function", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(false))); if (displayCompositeMap) { sh::MaterialInstancePass* p = material->createPass (); p->setProperty ("vertex_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_vertex"))); p->setProperty ("fragment_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_fragment"))); p->mShaderProperties.setProperty ("is_first_pass", sh::makeProperty(new sh::BooleanValue(true))); p->mShaderProperties.setProperty ("render_composite_map", sh::makeProperty(new sh::BooleanValue(false))); p->mShaderProperties.setProperty ("display_composite_map", sh::makeProperty(new sh::BooleanValue(true))); p->mShaderProperties.setProperty ("num_layers", sh::makeProperty (new sh::StringValue("0"))); p->mShaderProperties.setProperty ("num_blendmaps", sh::makeProperty (new sh::StringValue("0"))); p->mShaderProperties.setProperty ("normal_map_enabled", sh::makeProperty (new sh::BooleanValue(false))); p->mShaderProperties.setProperty ("parallax_enabled", sh::makeProperty (new sh::BooleanValue(false))); p->mShaderProperties.setProperty ("normal_maps", sh::makeProperty (new sh::IntValue(0))); sh::MaterialInstanceTextureUnit* tex = p->createTextureUnit ("compositeMap"); tex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(mCompositeMap))); tex->setProperty ("tex_address_mode", sh::makeProperty (new sh::StringValue("clamp"))); // shadow. TODO: repeated, put in function if (mShadows) { for (int i = 0; i < (mSplitShadows ? 3 : 1); ++i) { sh::MaterialInstanceTextureUnit* shadowTex = p->createTextureUnit ("shadowMap" + Ogre::StringConverter::toString(i)); shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow"))); } } p->mShaderProperties.setProperty ("shadowtexture_offset", sh::makeProperty (new sh::StringValue( Ogre::StringConverter::toString(1)))); p->mShaderProperties.setProperty ("pass_index", sh::makeProperty(new sh::IntValue(0))); } else { bool shadows = mShadows && !renderCompositeMap; int layerOffset = 0; while (layerOffset < (int)mLayerList.size()) { int blendmapOffset = (layerOffset == 0) ? 1 : 0; // the first layer of the first pass is the base layer and does not need a blend map // Check how many layers we can fit in this pass int numLayersInThisPass = 0; int numBlendTextures = 0; std::vector<std::string> blendTextures; int remainingTextureUnits = OGRE_MAX_TEXTURE_LAYERS; if (shadows) remainingTextureUnits -= (mSplitShadows ? 3 : 1); while (remainingTextureUnits && layerOffset + numLayersInThisPass < (int)mLayerList.size()) { int layerIndex = numLayersInThisPass + layerOffset; int neededTextureUnits=0; int neededBlendTextures=0; if (layerIndex != 0) { std::string blendTextureName = mBlendmapList[getBlendmapIndexForLayer(layerIndex)]->getName(); if (std::find(blendTextures.begin(), blendTextures.end(), blendTextureName) == blendTextures.end()) { blendTextures.push_back(blendTextureName); ++neededBlendTextures; ++neededTextureUnits; // blend texture } } ++neededTextureUnits; // layer texture // Check if this layer has a normal map if (mNormalMapping && !mLayerList[layerIndex].mNormalMap.empty() && !renderCompositeMap) ++neededTextureUnits; // normal map if (neededTextureUnits <= remainingTextureUnits) { // We can fit another! remainingTextureUnits -= neededTextureUnits; numBlendTextures += neededBlendTextures; ++numLayersInThisPass; } else break; // We're full } sh::MaterialInstancePass* p = material->createPass (); p->setProperty ("vertex_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_vertex"))); p->setProperty ("fragment_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_fragment"))); if (layerOffset != 0) { p->setProperty ("scene_blend", sh::makeProperty(new sh::StringValue("alpha_blend"))); // Only write if depth is equal to the depth value written by the previous pass. p->setProperty ("depth_func", sh::makeProperty(new sh::StringValue("equal"))); } p->mShaderProperties.setProperty ("render_composite_map", sh::makeProperty(new sh::BooleanValue(renderCompositeMap))); p->mShaderProperties.setProperty ("display_composite_map", sh::makeProperty(new sh::BooleanValue(displayCompositeMap))); p->mShaderProperties.setProperty ("num_layers", sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(numLayersInThisPass)))); p->mShaderProperties.setProperty ("num_blendmaps", sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(numBlendTextures)))); p->mShaderProperties.setProperty ("normal_map_enabled", sh::makeProperty (new sh::BooleanValue(false))); // blend maps // the index of the first blend map used in this pass int blendmapStart; if (mLayerList.size() == 1) // special case. if there's only one layer, we don't need blend maps at all blendmapStart = 0; else blendmapStart = getBlendmapIndexForLayer(layerOffset+blendmapOffset); for (int i = 0; i < numBlendTextures; ++i) { sh::MaterialInstanceTextureUnit* blendTex = p->createTextureUnit ("blendMap" + Ogre::StringConverter::toString(i)); blendTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(mBlendmapList[blendmapStart+i]->getName()))); blendTex->setProperty ("tex_address_mode", sh::makeProperty (new sh::StringValue("clamp"))); } // layer maps bool anyNormalMaps = false; bool anyParallax = false; size_t normalMaps = 0; for (int i = 0; i < numLayersInThisPass; ++i) { const LayerInfo& layer = mLayerList[layerOffset+i]; // diffuse map sh::MaterialInstanceTextureUnit* diffuseTex = p->createTextureUnit ("diffuseMap" + Ogre::StringConverter::toString(i)); diffuseTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(layer.mDiffuseMap))); // normal map (optional) bool useNormalMap = mNormalMapping && !mLayerList[layerOffset+i].mNormalMap.empty() && !renderCompositeMap; bool useParallax = useNormalMap && mParallaxMapping && layer.mParallax; bool useSpecular = layer.mSpecular; if (useNormalMap) { anyNormalMaps = true; anyParallax = anyParallax || useParallax; sh::MaterialInstanceTextureUnit* normalTex = p->createTextureUnit ("normalMap" + Ogre::StringConverter::toString(i)); normalTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(layer.mNormalMap))); } p->mShaderProperties.setProperty ("use_normal_map_" + Ogre::StringConverter::toString(i), sh::makeProperty (new sh::BooleanValue(useNormalMap))); p->mShaderProperties.setProperty ("use_parallax_" + Ogre::StringConverter::toString(i), sh::makeProperty (new sh::BooleanValue(useParallax))); p->mShaderProperties.setProperty ("use_specular_" + Ogre::StringConverter::toString(i), sh::makeProperty (new sh::BooleanValue(useSpecular))); boost::hash_combine(normalMaps, useNormalMap); boost::hash_combine(normalMaps, useNormalMap && layer.mParallax); boost::hash_combine(normalMaps, useSpecular); if (i+layerOffset > 0) { int blendTextureIndex = getBlendmapIndexForLayer(layerOffset+i); std::string blendTextureComponent = getBlendmapComponentForLayer(layerOffset+i); p->mShaderProperties.setProperty ("blendmap_component_" + Ogre::StringConverter::toString(i), sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(blendTextureIndex-blendmapStart) + "." + blendTextureComponent))); } else { // just to make it shut up about blendmap_component_0 not existing in the first pass. // it might be retrieved, but will never survive the preprocessing step. p->mShaderProperties.setProperty ("blendmap_component_" + Ogre::StringConverter::toString(i), sh::makeProperty (new sh::StringValue(""))); } } p->mShaderProperties.setProperty ("normal_map_enabled", sh::makeProperty (new sh::BooleanValue(anyNormalMaps))); p->mShaderProperties.setProperty ("parallax_enabled", sh::makeProperty (new sh::BooleanValue(anyParallax))); // Since the permutation handler can't handle dynamic property names, // combine normal map settings for all layers into one value p->mShaderProperties.setProperty ("normal_maps", sh::makeProperty (new sh::IntValue(normalMaps))); // shadow if (shadows) { for (int i = 0; i < (mSplitShadows ? 3 : 1); ++i) { sh::MaterialInstanceTextureUnit* shadowTex = p->createTextureUnit ("shadowMap" + Ogre::StringConverter::toString(i)); shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow"))); } } p->mShaderProperties.setProperty ("shadowtexture_offset", sh::makeProperty (new sh::StringValue( Ogre::StringConverter::toString(numBlendTextures + numLayersInThisPass)))); // Make sure the pass index is fed to the permutation handler, because blendmap components may be different p->mShaderProperties.setProperty ("pass_index", sh::makeProperty(new sh::IntValue(layerOffset))); assert ((int)p->mTexUnits.size() == OGRE_MAX_TEXTURE_LAYERS - remainingTextureUnits); layerOffset += numLayersInThisPass; } } } #endif return Ogre::MaterialManager::getSingleton().getByName(name.str()); }
OgrePass::OgrePass (OgreMaterial* parent, const std::string& configuration, unsigned short lodIndex) : Pass() { Ogre::Technique* t = parent->getOgreTechniqueForConfiguration(configuration, lodIndex); mPass = t->createPass(); }
bool ModelBackgroundLoader::poll(const TimeFrame& timeFrame) { #if OGRE_THREAD_SUPPORT if (mState == LS_UNINITIALIZED) { //Start to load the meshes for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) { Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName())); if (meshPtr.isNull() || !meshPtr->isPrepared()) { try { Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MeshManager::getSingleton().getResourceType(), (*I_subModels)->getMeshName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { addTicket(ticket); } } catch (const std::exception& ex) { S_LOG_FAILURE("Could not load the mesh " << (*I_subModels)->getMeshName() << " when loading model " << mModel.getName() << "." << ex); continue; } } } mState = LS_MESH_PREPARING; return poll(timeFrame); } else if (mState == LS_MESH_PREPARING) { if (areAllTicketsProcessed()) { mState = LS_MESH_PREPARED; return poll(timeFrame); } } else if (mState == LS_MESH_PREPARED) { for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) { Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName())); if (!meshPtr.isNull()) { if (!meshPtr->isLoaded()) { #if OGRE_THREAD_SUPPORT == 1 Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MeshManager::getSingleton().getResourceType(), meshPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { // meshPtr->setBackgroundLoaded(true); addTicket(ticket); } #else if (!timeFrame.isTimeLeft()) { return false; } try { meshPtr->load(); } catch (const std::exception& ex) { S_LOG_FAILURE("Could not load the mesh " << meshPtr->getName() << " when loading model " << mModel.getName() << "." << ex); continue; } #endif } } } mState = LS_MESH_LOADING; return poll(timeFrame); } else if (mState == LS_MESH_LOADING) { if (areAllTicketsProcessed()) { mState = LS_MESH_LOADED; return poll(timeFrame); } } else if (mState == LS_MESH_LOADED) { for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) { Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName())); if (!meshPtr.isNull()) { if (meshPtr->isLoaded()) { Ogre::Mesh::SubMeshIterator subMeshI = meshPtr->getSubMeshIterator(); while (subMeshI.hasMoreElements()) { Ogre::SubMesh* submesh(subMeshI.getNext()); Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(submesh->getMaterialName())); if (materialPtr.isNull() || !materialPtr->isPrepared()) { // S_LOG_VERBOSE("Preparing material " << materialPtr->getName()); Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MaterialManager::getSingleton().getResourceType(),submesh->getMaterialName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { addTicket(ticket); } } } } } for (PartDefinitionsStore::const_iterator I_parts = (*I_subModels)->getPartDefinitions().begin(); I_parts != (*I_subModels)->getPartDefinitions().end(); ++I_parts) { if ((*I_parts)->getSubEntityDefinitions().size() > 0) { for (SubEntityDefinitionsStore::const_iterator I_subEntities = (*I_parts)->getSubEntityDefinitions().begin(); I_subEntities != (*I_parts)->getSubEntityDefinitions().end(); ++I_subEntities) { const std::string& materialName = (*I_subEntities)->getMaterialName(); if (materialName != "") { Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(materialName)); if (materialPtr.isNull() || !materialPtr->isPrepared()) { // S_LOG_VERBOSE("Preparing material " << materialName); Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MaterialManager::getSingleton().getResourceType(), materialName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { addTicket(ticket); } } } } } } } mState = LS_MATERIAL_PREPARING; return poll(timeFrame); } else if (mState == LS_MATERIAL_PREPARING) { if (areAllTicketsProcessed()) { mState = LS_MATERIAL_PREPARED; return poll(timeFrame); } } else if (mState == LS_MATERIAL_PREPARED) { for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) { Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName())); Ogre::Mesh::SubMeshIterator subMeshI = meshPtr->getSubMeshIterator(); while (subMeshI.hasMoreElements()) { Ogre::SubMesh* submesh(subMeshI.getNext()); Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(submesh->getMaterialName())); if (!materialPtr.isNull() && !materialPtr->isLoaded()) { #if OGRE_THREAD_SUPPORT == 1 Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MaterialManager::getSingleton().getResourceType(), materialPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { // materialPtr->setBackgroundLoaded(true); addTicket(ticket); } #else Ogre::Material::TechniqueIterator techIter = materialPtr->getSupportedTechniqueIterator(); while (techIter.hasMoreElements()) { Ogre::Technique* tech = techIter.getNext(); Ogre::Technique::PassIterator passIter = tech->getPassIterator(); while (passIter.hasMoreElements()) { Ogre::Pass* pass = passIter.getNext(); Ogre::Pass::TextureUnitStateIterator tusIter = pass->getTextureUnitStateIterator(); while (tusIter.hasMoreElements()) { Ogre::TextureUnitState* tus = tusIter.getNext(); unsigned int frames = tus->getNumFrames(); for (unsigned int i = 0; i < frames; ++i) { if (!timeFrame.isTimeLeft()) { return false; } //This will automatically load the texture. // S_LOG_VERBOSE("Loading texture " << tus->getTextureName()); Ogre::TexturePtr texturePtr = tus->_getTexturePtr(i); } } } } if (!timeFrame.isTimeLeft()) { return false; } // S_LOG_VERBOSE("Loading material " << materialPtr->getName()); materialPtr->load(); #endif } } for (PartDefinitionsStore::const_iterator I_parts = (*I_subModels)->getPartDefinitions().begin(); I_parts != (*I_subModels)->getPartDefinitions().end(); ++I_parts) { if ((*I_parts)->getSubEntityDefinitions().size() > 0) { for (SubEntityDefinitionsStore::const_iterator I_subEntities = (*I_parts)->getSubEntityDefinitions().begin(); I_subEntities != (*I_parts)->getSubEntityDefinitions().end(); ++I_subEntities) { const std::string& materialName = (*I_subEntities)->getMaterialName(); if (materialName != "") { Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(materialName)); if (!materialPtr.isNull() && !materialPtr->isLoaded()) { #if OGRE_THREAD_SUPPORT == 1 Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MaterialManager::getSingleton().getResourceType(), materialPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { addTicket(ticket); } #else Ogre::Material::TechniqueIterator techIter = materialPtr->getSupportedTechniqueIterator(); while (techIter.hasMoreElements()) { Ogre::Technique* tech = techIter.getNext(); Ogre::Technique::PassIterator passIter = tech->getPassIterator(); while (passIter.hasMoreElements()) { Ogre::Pass* pass = passIter.getNext(); Ogre::Pass::TextureUnitStateIterator tusIter = pass->getTextureUnitStateIterator(); while (tusIter.hasMoreElements()) { Ogre::TextureUnitState* tus = tusIter.getNext(); unsigned int frames = tus->getNumFrames(); for (unsigned int i = 0; i < frames; ++i) { if (!timeFrame.isTimeLeft()) { return false; } //This will automatically load the texture. // S_LOG_VERBOSE("Loading texture " << tus->getTextureName()); Ogre::TexturePtr texturePtr = tus->_getTexturePtr(i); } } } } if (!timeFrame.isTimeLeft()) { return false; } // S_LOG_VERBOSE("Loading material " << materialPtr->getName()); materialPtr->load(); #endif } } } } } } mState = LS_MATERIAL_LOADING; return poll(timeFrame); } else if (mState == LS_MATERIAL_LOADING) { if (areAllTicketsProcessed()) { mState = LS_DONE; return true; } } else { return true; } return false; #else //If there's no threading support, just return here. return true; #endif }
void MaterialEditor::runCommand(const std::string &command, const std::string &args) { if (AlterMaterial == command) { try { Tokeniser tokeniser; tokeniser.initTokens(args); std::vector<std::string> tokens; std::string token; while ((token = tokeniser.nextToken()) != "") { tokens.push_back(token); } std::string materialName = tokens[0]; Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().getByName( materialName)); if (!materialPtr.isNull()) { std::string techniqueIndexString = tokens[1]; if (techniqueIndexString != "") { int techniqueIndex = Ogre::StringConverter::parseInt( techniqueIndexString); Ogre::Technique* technique = materialPtr->getTechnique( techniqueIndex); if (technique) { std::string passIndexString = tokens[2]; if (passIndexString != "") { int passIndex = Ogre::StringConverter::parseInt( passIndexString); Ogre::Pass* pass = technique->getPass( passIndex); //is texture unit specified if (tokens.size() == 6) { std::string textureUnitIndexString = tokens[3]; std::string property = tokens[4]; std::string value = tokens[5]; int textureUnitIndex = Ogre::StringConverter::parseInt( textureUnitIndexString); Ogre::TextureUnitState* textureUnit = pass->getTextureUnitState( textureUnitIndex); if (textureUnit) { } } else { std::string property = tokens[3]; std::string value = tokens[4]; if (property == "alpha_rejection") { pass->setAlphaRejectValue( Ogre::StringConverter::parseInt( value)); } } } } } } } catch (const std::exception& ex) { S_LOG_WARNING("Error when altering material." << ex); } catch (...) { S_LOG_WARNING("Error when altering material."); } } }
const Ogre::MaterialPtr& Terrain::_getGridMaterial(const TerrainData::GridInfo &gridInfo, ushort depthBias, int nTileX, int nTileZ) { assert(mData != NULL); size_t textureIds[TerrainData::NumLayers] = { 0 }; for (size_t i = 0; i < TerrainData::NumLayers; ++i) { if (gridInfo.layers[i].pixmapId) { textureIds[i] = _getPixmapAtlasId(gridInfo.layers[i].pixmapId - 1) + 1; } } assert(textureIds[0] && "Internal fault while create grid material"); bool lightmapped = mData->mLightmapImage && getLightmapQuality() != LMQ_NONE; Ogre::ulong lightmapId = lightmapped ? (nTileZ << 16) | nTileX : ~0; MaterialId id(textureIds[0], textureIds[1], lightmapId, depthBias); // find the material that already created MaterialMap::const_iterator it = mMaterials.find(id); if (it != mMaterials.end()) return it->second; Ogre::String name = "Terrain/"; if (!mData->mName.empty()) name += mData->mName + "/"; name += Ogre::StringConverter::toString(textureIds[0]) + "." + Ogre::StringConverter::toString(textureIds[1]); if (depthBias) name += "_" + Ogre::StringConverter::toString(depthBias); Ogre::String lightmapName = "<Lightmap>(" + Ogre::StringConverter::toString(nTileX / mData->mTileSize) + "," + Ogre::StringConverter::toString(nTileZ / mData->mTileSize) + ")"; if (lightmapped) name += "_" + lightmapName; Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(name); if (material.isNull()) { // get user supplied material Ogre::String templateName = textureIds[1] ? "TwoLayer" : "OneLayer"; if (lightmapped) templateName += "Lightmap"; TerrainData::MaterialTemplates::const_iterator it = mData->mMaterialTemplates.find(templateName); if (it == mData->mMaterialTemplates.end()) OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Can't found grid material template for '" + templateName + "'!", "Terrain::_getGridMaterial"); const Ogre::String& baseName = it->second; Ogre::MaterialPtr templateMaterial = Ogre::MaterialManager::getSingleton().getByName(baseName); if (templateMaterial.isNull()) OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Can't load grid material template '" + baseName + "'!", "Terrain::_getGridMaterial"); // clone the material material = templateMaterial->clone(name, true, BRUSH_RESOURCE_GROUP_NAME); // Setup texture alias list Ogre::AliasTextureNamePairList aliasList; aliasList["<layer0>"] = mAtlases[textureIds[0]-1].texture->getName(); if (textureIds[1]) aliasList["<layer1>"] = mAtlases[textureIds[1]-1].texture->getName(); if (lightmapped) aliasList["<lightmap>"] = lightmapName; // Applies texture names material->applyTextureAliases(aliasList); // Applies surface params _applySurfaceParams(material); // Applies fog _applyFogMode(material, Ogre::FOG_NONE, mCurrentFogMode); // Adjust other material attributes 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(); if (depthBias) { #if OGRE_VERSION >= 0x010300 pass->setDepthBias(depthBias + pass->getDepthBiasConstant(), pass->getDepthBiasSlopeScale()); #else pass->setDepthBias(depthBias + pass->getDepthBias()); #endif } } } } // The material will load on demand std::pair<MaterialMap::iterator, bool> inserted = mMaterials.insert(MaterialMap::value_type(id, material)); assert(inserted.second && "Internal fault while create grid material"); return inserted.first->second; }
void MeshResourceMarker::onNewMessage(const MarkerConstPtr& old_message, const MarkerConstPtr& new_message) { ROS_ASSERT(new_message->type == visualization_msgs::Marker::MESH_RESOURCE); // flag indicating if the mesh material color needs to be updated bool update_color = false; scene_node_->setVisible(false); if (!entity_ || old_message->mesh_resource != new_message->mesh_resource || old_message->mesh_use_embedded_materials != new_message->mesh_use_embedded_materials) { reset(); if (new_message->mesh_resource.empty()) { return; } if (loadMeshFromResource(new_message->mesh_resource).isNull()) { std::stringstream ss; ss << "Mesh resource marker [" << getStringID() << "] could not load [" << new_message->mesh_resource << "]"; if (owner_) { owner_->setMarkerStatus(getID(), StatusProperty::Error, ss.str()); } ROS_DEBUG("%s", ss.str().c_str()); return; } static uint32_t count = 0; std::stringstream ss; ss << "mesh_resource_marker_" << count++; std::string id = ss.str(); entity_ = context_->getSceneManager()->createEntity(id, new_message->mesh_resource); scene_node_->attachObject(entity_); // create a default material for any sub-entities which don't have their own. ss << "Material"; Ogre::MaterialPtr default_material = Ogre::MaterialManager::getSingleton().create(ss.str(), ROS_PACKAGE_NAME); default_material->setReceiveShadows(false); default_material->getTechnique(0)->setLightingEnabled(true); default_material->getTechnique(0)->setAmbient(0.5, 0.5, 0.5); materials_.insert(default_material); if (new_message->mesh_use_embedded_materials) { // make clones of all embedded materials so selection works correctly S_MaterialPtr materials = getMaterials(); S_MaterialPtr::iterator it; for (it = materials.begin(); it != materials.end(); it++) { if ((*it)->getName() != "BaseWhiteNoLighting") { Ogre::MaterialPtr new_material = (*it)->clone(id + (*it)->getName()); materials_.insert(new_material); } } // make sub-entities use cloned materials for (uint32_t i = 0; i < entity_->getNumSubEntities(); ++i) { std::string mat_name = entity_->getSubEntity(i)->getMaterialName(); if (mat_name != "BaseWhiteNoLighting") { entity_->getSubEntity(i)->setMaterialName(id + mat_name); } else { // BaseWhiteNoLighting is the default material Ogre uses // when it sees a mesh with no material. Here we replace // that with our default_material which gets colored with // new_message->color. entity_->getSubEntity(i)->setMaterial(default_material); } } } else { entity_->setMaterial(default_material); } // add a pass to every material to perform the color tinting S_MaterialPtr::iterator material_it; for (material_it = materials_.begin(); material_it != materials_.end(); material_it++) { Ogre::Technique* technique = (*material_it)->getTechnique(0); color_tint_passes_.push_back(technique->createPass()); } // always update color on resource change update_color = true; handler_.reset(new MarkerSelectionHandler(this, MarkerID(new_message->ns, new_message->id), context_)); handler_->addTrackedObject(entity_); } else { // underlying mesh resource has not changed but if the color has // then we need to update the materials color if (!old_message || old_message->color.r != new_message->color.r || old_message->color.g != new_message->color.g || old_message->color.b != new_message->color.b || old_message->color.a != new_message->color.a) { update_color = true; } } // update material color // if the mesh_use_embedded_materials is true and color is non-zero // then the color will be used to tint the embedded materials if (update_color) { float r = new_message->color.r; float g = new_message->color.g; float b = new_message->color.b; float a = new_message->color.a; Ogre::SceneBlendType blending; bool depth_write; if (a < 0.9998) { blending = Ogre::SBT_TRANSPARENT_ALPHA; depth_write = false; } else { blending = Ogre::SBT_REPLACE; depth_write = true; } for (std::vector<Ogre::Pass*>::iterator it = color_tint_passes_.begin(); it != color_tint_passes_.end(); ++it) { (*it)->setAmbient(0.5 * r, 0.5 * g, 0.5 * b); (*it)->setDiffuse(r, g, b, a); (*it)->setSceneBlending(blending); (*it)->setDepthWriteEnabled(depth_write); (*it)->setLightingEnabled(true); } } Ogre::Vector3 pos, scale; Ogre::Quaternion orient; transform(new_message, pos, orient, scale); scene_node_->setVisible(true); setPosition(pos); setOrientation(orient); scene_node_->setScale(scale); }
CRosRttTexture::CRosRttTexture(unsigned width, unsigned height, Ogre::Camera * camera, bool isDepth /*= false*/ ) : m_materialName("MyRttMaterial") , width_(width) , height_(height) , frame_("/map") , m_bIsDepth( isDepth ) { assert( height > 0 && width > 0 ); { // Set encoding current_image_.encoding = ROS_IMAGE_FORMAT; // Set image size current_image_.width = width; current_image_.height = height; // Set image row length in bytes (row length * 3 bytes for a color) current_image_.step = width * BPP; #if OGRE_ENDIAN == ENDIAN_BIG current_image_.is_bigendian = true; #else current_image_.is_bigendian = false; #endif // Resize data current_image_.data.resize( width_ * height_ * BPP); } Ogre::TextureManager & lTextureManager( Ogre::TextureManager::getSingleton() ); Ogre::String textureName("RVIZ_CamCast_Texture"); bool lGammaCorrection( false ); unsigned int lAntiAliasing( 0 ); unsigned int lNumMipmaps( 0 ); if( isDepth ) { texture_ = lTextureManager.createManual(textureName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, width, height, lNumMipmaps, OGRE_DEPTH_TEXTURE_FORMAT, Ogre::TU_RENDERTARGET, 0, lGammaCorrection, lAntiAliasing); } else { texture_ = lTextureManager.createManual(textureName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, width, height, lNumMipmaps, OGRE_TEXTURE_FORMAT, Ogre::TU_RENDERTARGET, 0, lGammaCorrection, lAntiAliasing); } // Create render target Ogre::RenderTexture* lRenderTarget = NULL; Ogre::HardwarePixelBufferSharedPtr lRttBuffer = texture_->getBuffer(); lRenderTarget = lRttBuffer->getRenderTarget(); lRenderTarget->setAutoUpdated(true); // Create and attach viewport Ogre::Viewport* lRttViewport1 = lRenderTarget->addViewport(camera, 50, 0.00f, 0.00f, 1.0f, 1.0f); lRttViewport1->setAutoUpdated(true); Ogre::ColourValue lBgColor1(0.0,0.0,0.0,1.0); lRttViewport1->setBackgroundColour(lBgColor1); // create a material using this texture. //Get a reference on the material manager, which is a singleton. Ogre::MaterialManager& lMaterialManager = Ogre::MaterialManager::getSingleton(); Ogre::MaterialPtr lMaterial = lMaterialManager.create(m_materialName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); Ogre::Technique * lTechnique = lMaterial->getTechnique(0); Ogre::Pass* lPass = lTechnique->getPass(0); if( isDepth ) { lPass->setLightingEnabled(false); } Ogre::TextureUnitState* lTextureUnit = lPass->createTextureUnitState(); lTextureUnit->setTextureName(textureName); lTextureUnit->setNumMipmaps(0); lTextureUnit->setTextureFiltering(Ogre::TFO_BILINEAR); update(); }
void MeshResourceMarker::onNewMessage(const MarkerConstPtr& old_message, const MarkerConstPtr& new_message) { ROS_ASSERT(new_message->type == visualization_msgs::Marker::MESH_RESOURCE); bool need_color = false; scene_node_->setVisible(false); if( !entity_ || old_message->mesh_resource != new_message->mesh_resource || old_message->mesh_use_embedded_materials != new_message->mesh_use_embedded_materials ) { reset(); if (new_message->mesh_resource.empty()) { return; } if (loadMeshFromResource(new_message->mesh_resource).isNull()) { std::stringstream ss; ss << "Mesh resource marker [" << getStringID() << "] could not load [" << new_message->mesh_resource << "]"; if ( owner_ ) { owner_->setMarkerStatus(getID(), StatusProperty::Error, ss.str()); } ROS_DEBUG("%s", ss.str().c_str()); return; } static uint32_t count = 0; std::stringstream ss; ss << "mesh_resource_marker_" << count++; std::string id = ss.str(); entity_ = context_->getSceneManager()->createEntity(id, new_message->mesh_resource); scene_node_->attachObject(entity_); need_color = true; // create a default material for any sub-entities which don't have their own. ss << "Material"; Ogre::MaterialPtr default_material = Ogre::MaterialManager::getSingleton().create( ss.str(), ROS_PACKAGE_NAME ); default_material->setReceiveShadows(false); default_material->getTechnique(0)->setLightingEnabled(true); default_material->getTechnique(0)->setAmbient( 0.5, 0.5, 0.5 ); materials_.insert( default_material ); if ( new_message->mesh_use_embedded_materials ) { // make clones of all embedded materials so selection works correctly S_MaterialPtr materials = getMaterials(); S_MaterialPtr::iterator it; for ( it = materials.begin(); it!=materials.end(); it++ ) { if( (*it)->getName() != "BaseWhiteNoLighting" ) { Ogre::MaterialPtr new_material = (*it)->clone( id + (*it)->getName() ); materials_.insert( new_material ); } } // make sub-entities use cloned materials for (uint32_t i = 0; i < entity_->getNumSubEntities(); ++i) { std::string mat_name = entity_->getSubEntity(i)->getMaterialName(); if( mat_name != "BaseWhiteNoLighting" ) { entity_->getSubEntity(i)->setMaterialName( id + mat_name ); } else { // BaseWhiteNoLighting is the default material Ogre uses // when it sees a mesh with no material. Here we replace // that with our default_material which gets colored with // new_message->color. entity_->getSubEntity(i)->setMaterial( default_material ); } } } else { entity_->setMaterial( default_material ); } context_->getSelectionManager()->removeObject(coll_); coll_ = context_->getSelectionManager()->createCollisionForEntity(entity_, SelectionHandlerPtr(new MarkerSelectionHandler(this, MarkerID(new_message->ns, new_message->id))), coll_); } if( need_color || old_message->color.r != new_message->color.r || old_message->color.g != new_message->color.g || old_message->color.b != new_message->color.b || old_message->color.a != new_message->color.a ) { float r = new_message->color.r; float g = new_message->color.g; float b = new_message->color.b; float a = new_message->color.a; // Old way was to ignore the color and alpha when using embedded // materials, which meant you could leave them unset, which means // 0. Since we now USE the color and alpha values, leaving them // all 0 will mean the object will be invisible. Therefore detect // the situation where RGBA are all 0 and treat that the same as // all 1 (full white). if( new_message->mesh_use_embedded_materials && r == 0 && g == 0 && b == 0 && a == 0 ) { r = 1; g = 1; b = 1; a = 1; } Ogre::SceneBlendType blending; bool depth_write; if ( a < 0.9998 ) { blending = Ogre::SBT_TRANSPARENT_ALPHA; depth_write = false; } else { blending = Ogre::SBT_REPLACE; depth_write = true; } S_MaterialPtr::iterator it; for( it = materials_.begin(); it != materials_.end(); it++ ) { Ogre::Technique* technique = (*it)->getTechnique( 0 ); technique->setAmbient( r*0.5, g*0.5, b*0.5 ); technique->setDiffuse( r, g, b, a ); technique->setSceneBlending( blending ); technique->setDepthWriteEnabled( depth_write ); } } Ogre::Vector3 pos, scale; Ogre::Quaternion orient; transform(new_message, pos, orient, scale); scene_node_->setVisible(true); setPosition(pos); setOrientation(orient); // In Ogre, mesh surface normals are not normalized if object is not // scaled. This forces the surface normals to be renormalized by // invisibly tweaking the scale. if( scale.x == 1.0 && scale.y == 1.0 && scale.z == 1.0 ) { scale.z = 1.0001; } scene_node_->setScale(scale); }
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; }
Camera::Camera(Event::Lane& lane, GameHandle cameraHandle, Ogre::SceneNode* camNode, Ogre::RenderTarget* renderTarget, u32 width, u32 height, const v3& position, const qv4& orientation, GameHandle parent) : mSubLane(lane.createSubLane()), mCameraNode(camNode), mRenderTarget(renderTarget), mHandle(cameraHandle), mNodeCreated(false), mRenderTargetCreated(false) { Ogre::SceneManager* sceneMgr = Ogre::Root::getSingleton().getSceneManager(BFG_SCENEMANAGER); if (mCameraNode == NULL) // Create SceneNode { if (sceneMgr->hasSceneNode(stringify(mHandle))) { mCameraNode = sceneMgr->getSceneNode(stringify(mHandle)); } else { mCameraNode = sceneMgr->getRootSceneNode()->createChildSceneNode(stringify(mHandle)); mNodeCreated = true; } } mCameraNode->setOrientation(toOgre(orientation)); mCameraNode->setPosition(toOgre(position)); v3 target = toBFG(mCameraNode->getOrientation().zAxis()); norm(target); Ogre::Camera* cam; cam = sceneMgr->createCamera(stringify(mHandle)); cam->setFOVy(Ogre::Degree(60.0f)); cam->setNearClipDistance(0.1f); cam->setFarClipDistance(250000.0f); cam->lookAt(toOgre(target)*10); mCameraNode->attachObject(cam); infolog << "Camera: " << stringify(mHandle) << " created."; if (mRenderTarget == NULL) { // Create renderToTexture RenderTarget if (width == 0 || height == 0) { throw std::logic_error("Too few information to create a render target."); } cam->setAspectRatio((f32)width / (f32)height); Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual ( stringify(mHandle), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, width, height, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET ); mRenderTarget = texture->getBuffer()->getRenderTarget(); prepareRenderTarget(); mRenderTarget->addViewport(cam); mRenderTarget->getViewport(0)->setClearEveryFrame(true); mRenderTarget->getViewport(0)->setBackgroundColour(Ogre::ColourValue::Black); mRenderTarget->getViewport(0)->setOverlaysEnabled(false); Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName(stringify(mHandle)); if (mat.isNull()) { mat = Ogre::MaterialManager::getSingleton().create( stringify(mHandle), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); } Ogre::Technique* tech = mat->getTechnique(0); if (!tech) { tech = mat->createTechnique(); } Ogre::Pass* pass = tech->getPass(0); if (!pass) { pass = tech->createPass(); } pass->setLightingEnabled(false); if (pass->getNumTextureUnitStates() > 0) { Ogre::TextureUnitState* txState = NULL; txState = pass->getTextureUnitState(0); txState->setTextureName(stringify(mHandle)); } else { pass->createTextureUnitState(stringify(mHandle)); } mRenderTarget->setAutoUpdated(true); mRenderTargetCreated = true; infolog << "Rendertarget: " << stringify(mHandle) << " created."; } else { prepareRenderTarget(); f32 width = static_cast<f32>(mRenderTarget->getWidth()); f32 height = static_cast<f32>(mRenderTarget->getHeight()); cam->setAspectRatio(width / height); mRenderTarget->addViewport(cam); } // mSubLane->connect(ID::VE_UPDATE_POSITION, this, &Camera::updatePosition, mHandle); // mSubLane->connect(ID::VE_UPDATE_ORIENTATION, this, &Camera::updateOrientation, mHandle); mSubLane->connect(ID::VE_SET_CAMERA_TARGET, this, &Camera::onSetTarget, mHandle); if (parent != NULL_HANDLE) { onSetTarget(parent); } }
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; }
// 设置选中的外观颜色. void CEditDobject_NT::SetSelectLook(Ogre::ColourValue color) { if(0 == m_materialSelVector.size()) { // 选中材质的名字. Ogre::String strCloneName; int iCount = m_EntityList.size(); Ogre::Entity* pEntity = NULL; for(int i = 0; i < iCount; i++) { pEntity = m_EntityList[i].pEntity; if(pEntity) { Ogre::SubEntity* pSubEntiy = pEntity->getSubEntity(0); if(pSubEntiy) { Ogre::MaterialPtr pMaterial = pSubEntiy->getMaterial(); if(pMaterial.isNull()) { return; }// const Ogre::String& strName = pMaterial->getName(); if("BaseWhite" == strName) { continue; } strCloneName = strName; strCloneName += "_select"; Ogre::MaterialManager* pMaterialManager = (Ogre::MaterialManager*)(pMaterial->getCreator()); if(NULL == pMaterialManager) { return; } Ogre::MaterialPtr pMaterialClone = pMaterialManager->getByName(strCloneName); if(pMaterialClone.isNull()) { pMaterialClone = pMaterial->clone(strCloneName); } //if(!pMaterialClone) //{ // return; //}// Ogre::Technique* pTechnique = pMaterialClone->getBestTechnique(); Ogre::Pass* pPass = pTechnique->getPass(0); //pPass->setSceneBlending(SBT_ADD); //pPass->setSceneBlending(SBF_SOURCE_ALPHA , SBF_ONE_MINUS_SOURCE_ALPHA ); //pTextureState->setAlphaOperation(LBX_MODULATE, LBS_TEXTURE, LBS_MANUAL, 1, Transparence, 1);// Ogre::TextureUnitState* pTextureState = pPass->getTextureUnitState(0); pTextureState->setColourOperationEx(Ogre::LBX_ADD , Ogre::LBS_TEXTURE , Ogre::LBS_MANUAL, color, color ); pSubEntiy->setMaterialName(strCloneName); m_materialSelVector.push_back(pMaterialClone); m_materilaOldVector.push_back(pMaterial); } } } } else { int iIndex = 0; int iCount = m_EntityList.size(); Ogre::Entity* pEntity = NULL; for(int i = 0; i < iCount; i++) { pEntity = m_EntityList[i].pEntity; if(pEntity) { Ogre::SubEntity* pSubEntiy = pEntity->getSubEntity(0); if(pSubEntiy) { if(iIndex >= (int)m_materialSelVector.size()) { continue; } std::string strMaterialName = m_materialSelVector[iIndex]->getName(); pSubEntiy->setMaterialName(strMaterialName); iIndex++; } } } } }
void Selection3DDisplayCustom::load() { Ogre::MaterialManager& lMaterialManager = Ogre::MaterialManager::getSingleton(); Ogre::String lNameOfResourceGroup = "SelectionMaterials"; Ogre::ResourceGroupManager& lRgMgr = Ogre::ResourceGroupManager::getSingleton(); Ogre::String lMaterialName = lNameOfResourceGroup+"MarkerMaterial"; if(!lRgMgr.resourceGroupExists(lNameOfResourceGroup)) { lRgMgr.createResourceGroup(lNameOfResourceGroup); Ogre::MaterialPtr lMaterial = lMaterialManager.create(lMaterialName,lNameOfResourceGroup); Ogre::Technique* lFirstTechnique = lMaterial->getTechnique(0); Ogre::Pass* lFirstPass = lFirstTechnique->getPass(0); float transparency = 0.6f; Ogre::ColourValue lSelfIllumnationColour(0.0f, 0.0f, 0.0f, transparency); lFirstPass->setSelfIllumination(lSelfIllumnationColour); Ogre::ColourValue lDiffuseColour(1.0f, 1.0f, 0.0f, transparency); lFirstPass->setDiffuse(lDiffuseColour); Ogre::ColourValue lAmbientColour(0.4f, 0.4f, 0.1f, transparency); lFirstPass->setAmbient(lAmbientColour); Ogre::ColourValue lSpecularColour(1.0f, 1.0f, 1.0f, 1.0f); lFirstPass->setSpecular(lSpecularColour); Ogre::Real lShininess = 64.0f; lFirstPass->setShininess(lShininess); lFirstPass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); lFirstPass->setDepthWriteEnabled(false); } // Create spheres to be used as markers Ogre::Entity* lEntity = this->scene_manager_->createEntity("selection marker", Ogre::SceneManager::PT_SPHERE); //lEntity->setMaterialName(lMaterialName); selection_marker_ = this->scene_node_->createChildSceneNode(); selection_marker_->attachObject(lEntity); // Change position and scale selection_marker_->setPosition(0.0f, 0.0f, 0.0f); selection_marker_->scale(0.001f,0.001f,0.001f); selection_marker_->setVisible( false ); lEntity->setMaterialName(lMaterialName); // lEntity = this->scene_manager_->createEntity("ROI selection marker final", Ogre::SceneManager::PT_SPHERE); // //lEntity->setMaterialName(lMaterialName); // roi_marker_final_ = this->scene_node_->createChildSceneNode(); // roi_marker_final_->attachObject(lEntity); // // Change position and scale // roi_marker_final_->setPosition(0.0f, 0.0f, 0.0f); // roi_marker_final_->scale(0.001f,0.001f,0.001f); // roi_marker_final_->setVisible( false ); // lEntity->setMaterialName(lMaterialName); // lMaterialName = lNameOfResourceGroup+"MarkerBoxMaterial"; // if(!lRgMgr.resourceGroupExists(lNameOfResourceGroup)) // { // lRgMgr.createResourceGroup(lNameOfResourceGroup); // Ogre::MaterialPtr lMaterial = lMaterialManager.create(lMaterialName,lNameOfResourceGroup); // Ogre::Technique* lFirstTechnique = lMaterial->getTechnique(0); // Ogre::Pass* lFirstPass = lFirstTechnique->getPass(0); // float transparency = 0.3f; // Ogre::ColourValue lSelfIllumnationColour(0.1f, 0.0f, 0.0f, transparency); // lFirstPass->setSelfIllumination(lSelfIllumnationColour); // Ogre::ColourValue lDiffuseColour(1.0f, 0.4f, 0.4f, transparency); // lFirstPass->setDiffuse(lDiffuseColour); // Ogre::ColourValue lAmbientColour(0.4f, 0.1f, 0.1f, transparency); // lFirstPass->setAmbient(lAmbientColour); // Ogre::ColourValue lSpecularColour(1.0f, 1.0f, 1.0f, 1.0f); // lFirstPass->setSpecular(lSpecularColour); // Ogre::Real lShininess = 64.0f; // lFirstPass->setShininess(lShininess); // lFirstPass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); // lFirstPass->setDepthWriteEnabled(false); // } // lEntity = this->scene_manager_->createEntity("ROI selection marker box", Ogre::SceneManager::PT_CUBE); // lEntity->setMaterialName(lMaterialName); // roi_marker_box_ = this->scene_node_->createChildSceneNode(); // roi_marker_box_->attachObject(lEntity); // // Change position and scale // roi_marker_box_->setPosition(100000.0f, 100000.0f, 100000.0f); // roi_marker_box_->scale(0.001f,0.001f,0.001f); // roi_marker_box_->setVisible( false ); // lEntity->setMaterialName(lMaterialName); // Create ground plane to be able to perform raycasting anywhere lEntity = this->scene_manager_->createEntity("ground plane", Ogre::SceneManager::PT_CUBE); //lEntity->setMaterialName(lMaterialName); ground_ = this->scene_node_->createChildSceneNode(); ground_->attachObject(lEntity); // Change position and scale ground_->setPosition(0.0f, 0.0f, 0.0f); ground_->scale(10000.0f,10000.0f,0.00001f); ground_->setVisible( false ); }