//----------------------------------------------------------------------- void PrimitiveShapeSet::rotateTexture(Ogre::Real speed) { // Get the material and rotate it, assume the material is loaded already, otherwise skip. Ogre::MaterialPtr material = getMaterial(); if (material.isNull()) return; Ogre::TextureUnitState::EffectMap::const_iterator it; unsigned short numberOfTechniques = material->getNumTechniques(); for (unsigned short u = 0; u < numberOfTechniques; ++u) { Ogre::Technique* technique = material->getTechnique(u); unsigned short numberOfPasses = technique->getNumPasses(); for (unsigned short v = 0; v < numberOfPasses; ++v) { Ogre::Pass* pass = technique->getPass(v); unsigned short numberOfTextureUnitStates = pass->getNumTextureUnitStates(); for (unsigned short w = 0; w < numberOfTextureUnitStates; ++w) { // Set the rotation if not already available. // This can only be done once! Changing the rotationspeed or removing the rotation // and resetting it doesn´t seem to work. Ogre::TextureUnitState* textureUnitState = pass->getTextureUnitState(w); it = textureUnitState->getEffects().find(Ogre::TextureUnitState::ET_ROTATE); if (it == textureUnitState->getEffects().end()) { textureUnitState->setRotateAnimation(speed); } } } } }
//----------------------------------------------------------------------- void EntityRenderer::_rotateTexture(VisualParticle* particle, Ogre::Entity* entity) { Ogre::TextureUnitState::EffectMap::const_iterator it; // Get the material and rotate it unsigned int numberOfSubEntities = entity->getNumSubEntities(); for (unsigned short u = 0; u < numberOfSubEntities; ++u) { Ogre::MaterialPtr material = entity->getSubEntity(u)->getMaterial(); unsigned short numberOfTechniques = material->getNumTechniques(); for (unsigned short v = 0; v < numberOfTechniques; ++v) { Ogre::Technique* technique = material->getTechnique(v); unsigned short numberOfPasses = technique->getNumPasses(); for (unsigned short w = 0; w < numberOfPasses; ++w) { Ogre::Pass* pass = technique->getPass(w); unsigned short numberOfTextureUnitStates = pass->getNumTextureUnitStates(); for (unsigned short x = 0; x < numberOfTextureUnitStates; ++x) { // Set the rotation if not already available. // This can only be done once! Changing the rotationspeed or removing the rotation // and resetting it doesn´t seem to work. Ogre::TextureUnitState* textureUnitState = pass->getTextureUnitState(x); it = textureUnitState->getEffects().find(Ogre::TextureUnitState::ET_ROTATE); if (it == textureUnitState->getEffects().end()) { textureUnitState->setRotateAnimation((particle->zRotationSpeed.valueRadians())); } } } } } }
void DeferredLight::updateFromCamera(Ogre::Camera* camera) { 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); Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); 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); } } Ogre::Camera shadowCam("ShadowCameraSetupCam", 0); shadowCam._notifyViewport(camera->getViewport()); Ogre::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()); } } }
void RenderComponentBillboardSet::setChangeWorldFactor(double factor) { Ogre::Technique * technique; Ogre::GpuProgramParametersSharedPtr params; Ogre::Pass * pass; Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(mChangeWorldMaterial); if(material.get()) { technique= material->getTechnique(0); if(technique) { if(technique->getNumPasses()>0) { pass=technique->getPass(0); if(pass->hasFragmentProgram()) { params=pass->getFragmentProgramParameters(); if(params.get()) { params->setNamedConstant("mix_factor",Ogre::Real(factor)); } } } } } }
void BillboardObject::setColour(const ColourValue& pColour) { mColour = pColour; Ogre::MaterialPtr m = static_cast<sh::OgreMaterial*>(mMaterial->getMaterial ())->getOgreMaterial (); for (int i=0; i<m->getNumTechniques(); ++i) { Ogre::Technique* t = m->getTechnique(i); if (t->getNumPasses ()) t->getPass(0)->setSelfIllumination (pColour); } }
void BillboardObject::setVisibility(const float visibility) { mVisibility = visibility; Ogre::MaterialPtr m = static_cast<sh::OgreMaterial*>(mMaterial->getMaterial ())->getOgreMaterial (); for (int i=0; i<m->getNumTechniques(); ++i) { Ogre::Technique* t = m->getTechnique(i); if (t->getNumPasses ()) t->getPass(0)->setDiffuse (0,0,0, visibility); } }
void MainWindow::populateWorkSpaceTree(const QStringList &itemNames) { for(int count = 0; count < itemNames.size(); ++count) { QTreeWidgetItem *matItem = new QTreeWidgetItem(ui->workspaceTree); QString parentName = itemNames.at(count); matItem->setText(0, parentName); matItem->setText(1, "material"); Ogre::MaterialPtr parMat = Ogre::MaterialManager::getSingleton().getByName(parentName.toStdString()); unsigned short numTech = parMat.getPointer()->getNumTechniques(); for (int countTech = 0; countTech < numTech; ++countTech) { Ogre::Technique *parTech = parMat.getPointer()->getTechnique(countTech); int numPass = parTech->getNumPasses(); QTreeWidgetItem *techItem = new QTreeWidgetItem(matItem); techItem->setText(0, QString("technique(")+QString(Ogre::String(parTech->getName()).c_str())+QString(")")); for (int countPass = 0; countPass < numPass; ++countPass) { QTreeWidgetItem *passItem = new QTreeWidgetItem(techItem); Ogre::Pass* pass = parTech->getPass(countPass); passItem->setText(0, QString("pass(")+QString(Ogre::String(pass->getName()).c_str())+QString(")")); passItem->setText(1, QString("pass")); if(pass->hasVertexProgram()) { QTreeWidgetItem *vpItem = new QTreeWidgetItem(passItem); vpItem->setText(0,Ogre::String(pass->getVertexProgramName()).c_str()); vpItem->setText(1,QString("VertexProgram")); vpItem->setText(2,QString(parentName)); vpItem->setText(3,QString(countTech)); vpItem->setText(4,QString(countPass)); } if(pass->hasFragmentProgram()) { QTreeWidgetItem *fpItem = new QTreeWidgetItem(passItem); fpItem->setText(0,Ogre::String(pass->getFragmentProgramName()).c_str()); fpItem->setText(1,QString("FragmentProgram")); fpItem->setText(2,QString(parentName)); fpItem->setText(3,QString(countTech)); fpItem->setText(4,QString(countPass)); } if(pass->hasGeometryProgram()) { QTreeWidgetItem *gpItem = new QTreeWidgetItem(passItem); gpItem->setText(0,Ogre::String(pass->getGeometryProgramName()).c_str()); } } } } }
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); // fix texture extension to .dds if (textureOverride.size() > 4) { textureOverride[textureOverride.size()-3] = 'd'; textureOverride[textureOverride.size()-2] = 'd'; textureOverride[textureOverride.size()-1] = 's'; } NifOgre::ObjectScenePtr scene = NifOgre::Loader::createObjects(sceneNode, model); // TODO: turn off shadow casting MWRender::Animation::setRenderProperties(scene, RV_Misc, 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()) { 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("textures\\" + textureOverride); } } } } } mEffects.push_back(std::make_pair(sceneNode, scene)); }
//----------------------------------------------------------------------- void MaterialTab::selectMaterial(wxString& materialName) { Ogre::TextureUnitState* textureUnitState = 0; mTxtMaterialName->SetValue(materialName); if (isSelectedMaterialInUse()) { mTxtMaterialName->Disable(); } else { mTxtMaterialName->Enable(); } mLastSelectedMaterial = materialName; Ogre::String name = wx2ogre(materialName); Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(name); if (!material.isNull() && material->getNumTechniques() > 0) { material->load(); mTxtTextureLoad->SetValue(wxT("")); 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) { // Set pass properties mCheckLighting->SetValue(pass->getLightingEnabled()); mCheckDepthCheck->SetValue(pass->getDepthCheckEnabled()); mCheckDepthWrite->SetValue(pass->getDepthWriteEnabled()); mSceneBlendList->SetValue(getSceneBlending(pass)); if (pass->getNumTextureUnitStates() > 0) { textureUnitState = pass->getTextureUnitState(0); // Get the first if (textureUnitState) { // Set texture properties if (textureUnitState->getNumFrames() > 0) { wxString name = ogre2wx(textureUnitState->getFrameTextureName(0)); mTxtTextureLoad->SetValue(name); } mAddressingModeList->SetValue(getTextureAddressingMode(textureUnitState)); } } } } } // Display image viewTexture(textureUnitState); // Clear the old texture if no TextureUnitState }
//----------------------------------------------------------------------- Ogre::Pass* MaterialTab::getFirstPass(void) { wxString materialName = mMaterialListBox->GetStringSelection(); Ogre::String name = wx2ogre(materialName); Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(name); if (!material.isNull() && material->getNumTechniques() > 0) { Ogre::Technique* technique = 0; material->load(); technique = material->getBestTechnique(); // Get the best technique if (technique && technique->getNumPasses() > 0) { return technique->getPass(0); // Get the first } } return 0; }
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); } }
Ogre::Technique* GBufferSchemeHandler::handleSchemeNotFound(unsigned short schemeIndex, const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, const Ogre::Renderable* rend) { Ogre::MaterialManager& matMgr = Ogre::MaterialManager::getSingleton(); Ogre::String curSchemeName = matMgr.getActiveScheme(); matMgr.setActiveScheme(Ogre::MaterialManager::DEFAULT_SCHEME_NAME); Ogre::Technique* originalTechnique = originalMaterial->getBestTechnique(lodIndex, rend); matMgr.setActiveScheme(curSchemeName); Ogre::Technique* gBufferTech = originalMaterial->createTechnique(); gBufferTech->removeAllPasses(); gBufferTech->setSchemeName(schemeName); Ogre::Technique* noGBufferTech = originalMaterial->createTechnique(); noGBufferTech->removeAllPasses(); noGBufferTech->setSchemeName("NoGBuffer"); for (unsigned short i=0; i<originalTechnique->getNumPasses(); i++) { Ogre::Pass* originalPass = originalTechnique->getPass(i); PassProperties props = inspectPass(originalPass, lodIndex, rend); if (!props.isDeferred) { //Just copy the technique so it gets rendered regularly Ogre::Pass* clonePass = noGBufferTech->createPass(); *clonePass = *originalPass; continue; } Ogre::Pass* newPass = gBufferTech->createPass(); MaterialGenerator::Perm perm = getPermutation(props); const Ogre::MaterialPtr& templateMat = mMaterialGenerator.getMaterial(perm); //We assume that the GBuffer technique contains only one pass. But its true. *newPass = *(templateMat->getTechnique(0)->getPass(0)); fillPass(newPass, originalPass, props); } return gBufferTech; }
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 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); } } } } } } }
CFakeObjectEntityManager::FakeObjectMap::iterator CFakeObjectEntityManager::_GetFakeNode(LPCTSTR szNodeName, tEntityNode* pNode, LPCTSTR szCameraName, int nTexWidth, int nTexHeight, LPCTSTR szBackgroundName) { //缺省摄像机的位置 static const float s_fHeight = 0.8f; static const float s_fDistance = 3.2f; static const float s_fPitch = 0.21f; FakeObjectMap::iterator it = m_mapObject.find(szNodeName); if(it != m_mapObject.end()) return it; //不存在,创建 FakeObject newNode; newNode.strName = szNodeName; //-------------------------------------------------- //创建RenderTarget Ogre::TexturePtr ptrTex = Ogre::TextureManager::getSingleton().createManual( Ogre::String(szNodeName) + "_RenderTexture", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, nTexWidth, nTexHeight, 1, 0, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET, 0); //ptrTex->load(); newNode.ptrRenderTexture = ptrTex; Ogre::RenderTexture* pTexture = ptrTex->getBuffer()->getRenderTarget(); //缺省不刷新 pTexture->setAutoUpdated(false); pTexture->addListener(&g_theListener); //-------------------------------------------------- //放置摄像机 Ogre::SceneManager* pScnManager = CEngineInterface::GetMe()->GetFairySystem()->getSceneManager(); newNode.pCamera = pScnManager->createCamera(Ogre::String(szNodeName) + "_Camera"); //放缩系数 fVector3 fvScale = CEngineInterface::GetMe()->GetSacle(); newNode.fCameraHeight=s_fHeight; newNode.fCameraDistance=s_fDistance; newNode.fCameraPitch=s_fPitch; STRING szUserCameraValue; pNode->Actor_GetObjectProperty(szCameraName, szUserCameraValue); // if(szUserCameraValue.size() > 2 && szUserCameraValue.find(';') != STRING::npos) // { // sscanf(szUserCameraValue.c_str(), "%f;%f", &(newNode.fCameraHeight), &(newNode.fCameraDistance)); // } int Row_Index; Row_Index = atoi(szUserCameraValue.c_str()); const tDataBase* pDBC = g_pDataBase->GetDataBase(DBC_MODEL_PARAMETER); KLAssert(pDBC); const _DBC_MODEL_PARAMETER* pParameter = NULL; pParameter = (const _DBC_MODEL_PARAMETER*)((tDataBase*)pDBC)->Search_Index_EQU(Row_Index); if(pParameter) { newNode.fCameraHeight = pParameter->nHeight; newNode.fCameraDistance = pParameter->nDistance; } //设置摄像机 _UpdateCamera(newNode); newNode.pCamera->setNearClipDistance(10.f); newNode.pCamera->setAspectRatio((float)nTexWidth/nTexHeight); newNode.pCamera->setFOVy(Ogre::Degree(45.0f)); // 经验值 newNode.pCamera->setProjectionType(Ogre::PT_PERSPECTIVE); //透视投影 (平行投影 Ogre::PT_ORTHOGRAPHIC) //-------------------------------------------------- //创建ViewPort newNode.pViewPort = pTexture->addViewport(newNode.pCamera, 1); newNode.pViewPort->setClearEveryFrame(true); newNode.pViewPort->setBackgroundColour(Ogre::ColourValue(0,0,0,0)); newNode.pViewPort->setOverlaysEnabled(false); newNode.pViewPort->setSkiesEnabled(false); newNode.pViewPort->setShadowsEnabled(false); //-------------------------------------------------- //创建rectangle(如果纹理名称不为空并且所需的material template存在) Ogre::String backgroundTexName(szBackgroundName); Ogre::MaterialPtr originMat = Ogre::MaterialManager::getSingleton().getByName("UIModelBackground"); if (false == backgroundTexName.empty() && false == originMat.isNull()) { newNode.pRectange = new Ogre::Rectangle2D(true); newNode.pRectange->setCorners(-1.0f, 1.0f, 1.0f, -1.0f); Ogre::String cloneMatName = Ogre::String(szNodeName) + "_Rectangle"; Ogre::MaterialPtr cloneMat = Ogre::MaterialManager::getSingleton().getByName(cloneMatName); if (cloneMat.isNull()) { cloneMat = originMat->clone(cloneMatName); if (cloneMat->getNumTechniques()) { Ogre::Technique* tech = cloneMat->getTechnique(0); if (tech->getNumPasses()) { Ogre::Pass* pass = tech->getPass(0); if (pass->getNumTextureUnitStates()) { Ogre::TextureUnitState* tex = pass->getTextureUnitState(0); tex->setTextureName(szBackgroundName); } } } } newNode.pRectange->setMaterial(cloneMat->getName()); newNode.pRectange->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND); newNode.pRectange->setVisibilityFlags(Fairy::OVF_GUI_ELEMENTS); // 设置boundingbox为无限大,以防被camera剔除掉(默认的包围盒大小为-1,1) newNode.pRectange->setBoundingBox( Ogre::AxisAlignedBox( Ogre::Vector3(Ogre::Math::NEG_INFINITY, Ogre::Math::NEG_INFINITY, Ogre::Math::NEG_INFINITY), Ogre::Vector3(Ogre::Math::POS_INFINITY, Ogre::Math::POS_INFINITY, Ogre::Math::POS_INFINITY) ) ); Ogre::SceneNode* parentNode = CEngineInterface::GetMe()->GetFairySystem()->getBaseSceneNode()->createChildSceneNode(); parentNode->attachObject(newNode.pRectange); } //-------------------------------------------------- //加入Map m_mapObject.insert(std::make_pair(newNode.strName, newNode)); it = m_mapObject.find(newNode.strName); KLAssert(it != m_mapObject.end()); //加入索引Map m_mapIndexOfViewPort.insert(std::make_pair(newNode.pViewPort, &(it->second))); return it; }
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 Animation::addEffect(const std::string &model, int effectId, bool loop, const std::string &bonename, std::string texture) { // Early out if we already have this effect for (std::vector<EffectParams>::iterator it = mEffects.begin(); it != mEffects.end(); ++it) if (it->mLoop && loop && it->mEffectId == effectId && it->mBoneName == bonename) return; // fix texture extension to .dds if (texture.size() > 4) { texture[texture.size()-3] = 'd'; texture[texture.size()-2] = 'd'; texture[texture.size()-1] = 's'; } EffectParams params; params.mModelName = model; if (bonename.empty()) params.mObjects = NifOgre::Loader::createObjects(mInsert, model); else params.mObjects = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, model); // TODO: turn off shadow casting setRenderProperties(params.mObjects, RV_Misc, RQG_Main, RQG_Alpha, 0.f, false, NULL); params.mLoop = loop; params.mEffectId = effectId; params.mBoneName = bonename; for(size_t i = 0;i < params.mObjects->mControllers.size();i++) { if(params.mObjects->mControllers[i].getSource().isNull()) params.mObjects->mControllers[i].setSource(Ogre::SharedPtr<EffectAnimationTime> (new EffectAnimationTime())); } if (!texture.empty()) { for(size_t i = 0;i < params.mObjects->mParticles.size(); ++i) { Ogre::ParticleSystem* partSys = params.mObjects->mParticles[i]; Ogre::MaterialPtr mat = params.mObjects->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("textures\\" + texture); } } } } } mEffects.push_back(params); }