//-------------------------------------------------------------------------------- static void setTextureAndTexAniFPS(const MaterialPtr& _material, const String& _texture, Real _texAniFPS) { Technique* technique = _material->getTechnique(0); Pass* pass = technique->getPass(0); if(_texture.empty()) { pass->removeAllTextureUnitStates(); } else { TextureManager& tmgr = TextureManager::getSingleton(); Ogre::TextureUnitState* tus = pass->getNumTextureUnitStates() ? pass->getTextureUnitState(0) : pass->createTextureUnitState(); if(_texAniFPS == 0) { TexturePtr ogreTexture = tmgr.createOrRetrieve(_texture).first; const String& ogreTexName = ogreTexture->getName(); tus->setTextureName(ogreTexName); } else { vector<String>::type ogreTexNames; TexturePtr ogreTexture = tmgr.createOrRetrieve(_texture).first; ogreTexNames.push_back(ogreTexture->getName()); size_t dotpos = _texture.rfind('.'); if(dotpos != String::npos && dotpos >= 1 && '0' <= _texture[dotpos-1] && _texture[dotpos-1] < '9') { String tmpname = _texture; char& dig0 = tmpname[dotpos - 1]; ++dig0; while(!tmgr.getByName(tmpname).isNull() || tmgr.canLoadResource(tmpname, TextureManager::GROUP_NAME)) { TexturePtr ogreTexture = tmgr.createOrRetrieve(tmpname).first; ogreTexNames.push_back(ogreTexture->getName()); ++dig0; if(dig0 > '9') { if(dotpos >= 2 && '0' <= _texture[dotpos-2] && _texture[dotpos-2] < '9') { char& dig1 = tmpname[dotpos-2]; ++dig1; dig0 = '0'; } else break; } } } Real duration = ogreTexNames.size() / _texAniFPS; tus->setAnimatedTextureName(&ogreTexNames[0], ogreTexNames.size(), duration); } } }
bool Filter::unlinkFrom(std::shared_ptr<BaseObject> obj) { if (dynamic_pointer_cast<Texture>(obj).get() != nullptr) { if (_inTexture.expired()) return false; auto inTex = _inTexture.lock(); TexturePtr tex = dynamic_pointer_cast<Texture>(obj); _screen->removeTexture(tex); if (tex->getName() == inTex->getName()) _inTexture.reset(); return true; } else if (dynamic_pointer_cast<Image>(obj).get() != nullptr) { auto textureName = getName() + "_" + obj->getName() + "_tex"; auto tex = _root.lock()->unregisterObject(textureName); if (!tex) return false; tex->unlinkFrom(obj); return unlinkFrom(tex); } return Texture::unlinkFrom(obj); }
void MaterialFactory::setSoftParticleDepth(TexturePtr depthtexture) { if(MaterialGenerator::MRTSupported()) { for (std::vector<std::string>::iterator it=softMtrs.begin(); it != softMtrs.end(); ++it) { MaterialPtr mat = MaterialManager::getSingleton().getByName( (*it) ); TextureUnitState* tus =mat->getTechnique(0)->getPass(0)->getTextureUnitState("depthMap"); tus->setTextureName(depthtexture->getName()); } } }
ProceduralManualObject* createProceduralParticleSystem() { particleSystem = static_cast<ProceduralManualObject*> (mSceneMgr->createMovableObject("ParticleGSEntity", ProceduralManualObjectFactory::FACTORY_TYPE_NAME)); particleSystem->setMaterial("Ogre/ParticleGS/Display"); //Generate the geometry that will seed the particle system ManualObject* particleSystemSeed = mSceneMgr->createManualObject("ParticleSeed"); //This needs to be the initial launcher particle particleSystemSeed->begin("Ogre/ParticleGS/Display", RenderOperation::OT_POINT_LIST); particleSystemSeed->position(0,0,0); //Position particleSystemSeed->textureCoord(1); //Timer particleSystemSeed->textureCoord(0); //Type particleSystemSeed->textureCoord(0,0,0); //Velocity particleSystemSeed->end(); //Generate the RenderToBufferObject RenderToVertexBufferSharedPtr r2vbObject = HardwareBufferManager::getSingleton().createRenderToVertexBuffer(); r2vbObject->setRenderToBufferMaterialName("Ogre/ParticleGS/Generate"); //Apply the random texture TexturePtr randomTexture = RandomTools::generateRandomVelocityTexture(); r2vbObject->getRenderToBufferMaterial()->getTechnique(0)->getPass(0)-> getTextureUnitState("RandomTexture")->setTextureName( randomTexture->getName(), randomTexture->getTextureType()); r2vbObject->setOperationType(RenderOperation::OT_POINT_LIST); r2vbObject->setMaxVertexCount(16000); r2vbObject->setResetsEveryUpdate(false); VertexDeclaration* vertexDecl = r2vbObject->getVertexDeclaration(); size_t offset = 0; offset += vertexDecl->addElement(0, offset, VET_FLOAT3, VES_POSITION).getSize(); //Position offset += vertexDecl->addElement(0, offset, VET_FLOAT1, VES_TEXTURE_COORDINATES, 0).getSize(); //Timer offset += vertexDecl->addElement(0, offset, VET_FLOAT1, VES_TEXTURE_COORDINATES, 1).getSize(); //Type offset += vertexDecl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES, 2).getSize(); //Velocity //Bind the two together particleSystem->setRenderToVertexBuffer(r2vbObject); particleSystem->setManualObject(particleSystemSeed); //Set bounds AxisAlignedBox aabb; aabb.setMinimum(-100,-100,-100); aabb.setMaximum(100,100,100); particleSystem->setBoundingBox(aabb); return particleSystem; }
//----------------------------------------------------------------------- void TextureUnitState::setTexture( const TexturePtr& texPtr) { if (texPtr.isNull()) { OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texture Pointer is empty.", "TextureUnitState::setTexture"); } setContentType(CONTENT_NAMED); mTextureLoadFailed = false; if (texPtr->getTextureType() == TEX_TYPE_CUBE_MAP) { // delegate to cubic texture implementation setCubicTexture(&texPtr, true); } else { mFrames.resize(1); mFramePtrs.resize(1); mFrames[0] = texPtr->getName(); mFramePtrs[0] = texPtr; // defer load until used, so don't grab pointer yet mCurrentFrame = 0; mCubic = false; mTextureType = texPtr->getTextureType(); // Load immediately ? if (isLoaded()) { _load(); // reload } // Tell parent to recalculate hash if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) { mParent->_dirtyHash(); } } }
void kore:: TexturesComponent::addTexture(TexturePtr tex, const bool useMipMaps /*=true*/, const TextureSampler* sampler /*= NULL*/ ) { if (std::find(_vTextures.begin(), _vTextures.end(), tex) != _vTextures.end()) { return; } STextureInfo* texInfo = new STextureInfo; texInfo->texLocation = tex->getHandle(); texInfo->texTarget = tex->getProperties().targetType; _vTextureInfos.push_back(texInfo); ShaderData shaderdata; shaderdata.type = GL_TEXTURE; shaderdata.name = tex->getName(); shaderdata.data = texInfo; shaderdata.component = this; _shaderData.push_back(shaderdata); // Tex unit is defined by shader }
void ImpostorTexture::renderTextures(bool force) { #ifdef IMPOSTOR_FILE_SAVE TexturePtr renderTexture; #else TexturePtr renderTexture(texture); //if we're not using a file image we need to set up a resource loader, so that the texture is regenerated if it's ever unloaded (such as switching between fullscreen and the desktop in win32) loader = std::auto_ptr<ImpostorTextureResourceLoader>(new ImpostorTextureResourceLoader(*this)); #endif RenderTexture *renderTarget; Camera *renderCamera; Viewport *renderViewport; SceneNode *camNode; //Set up RTT texture uint32 textureSize = ImpostorPage::impostorResolution; if (renderTexture.isNull()) { renderTexture = TextureManager::getSingleton().createManual(getUniqueID("ImpostorTexture"), "Impostors", TEX_TYPE_2D, textureSize * IMPOSTOR_YAW_ANGLES, textureSize * IMPOSTOR_PITCH_ANGLES, 0, PF_A8R8G8B8, TU_RENDERTARGET, loader.get()); } renderTexture->setNumMipmaps(MIP_UNLIMITED); //Set up render target renderTarget = renderTexture->getBuffer()->getRenderTarget(); renderTarget->setAutoUpdated(false); //Set up camera camNode = sceneMgr->getSceneNode("ImpostorPage::cameraNode"); renderCamera = sceneMgr->createCamera(getUniqueID("ImpostorCam")); camNode->attachObject(renderCamera); renderCamera->setLodBias(1000.0f); renderViewport = renderTarget->addViewport(renderCamera); renderViewport->setOverlaysEnabled(false); renderViewport->setClearEveryFrame(true); renderViewport->setShadowsEnabled(false); renderViewport->setBackgroundColour(ImpostorPage::impostorBackgroundColor); //Set up scene node SceneNode* node = sceneMgr->getSceneNode("ImpostorPage::renderNode"); Ogre::SceneNode* oldSceneNode = entity->getParentSceneNode(); if (oldSceneNode) { oldSceneNode->detachObject(entity); } node->attachObject(entity); node->setPosition(-entityCenter); //Set up camera FOV const Real objDist = entityRadius * 100; const Real nearDist = objDist - (entityRadius + 1); const Real farDist = objDist + (entityRadius + 1); renderCamera->setAspectRatio(1.0f); renderCamera->setFOVy(Math::ATan(entityDiameter / objDist)); renderCamera->setNearClipDistance(nearDist); renderCamera->setFarClipDistance(farDist); //Disable mipmapping (without this, masked textures look bad) MaterialManager *mm = MaterialManager::getSingletonPtr(); FilterOptions oldMinFilter = mm->getDefaultTextureFiltering(FT_MIN); FilterOptions oldMagFilter = mm->getDefaultTextureFiltering(FT_MAG); FilterOptions oldMipFilter = mm->getDefaultTextureFiltering(FT_MIP); mm->setDefaultTextureFiltering(FO_POINT, FO_LINEAR, FO_NONE); //Disable fog FogMode oldFogMode = sceneMgr->getFogMode(); ColourValue oldFogColor = sceneMgr->getFogColour(); Real oldFogDensity = sceneMgr->getFogDensity(); Real oldFogStart = sceneMgr->getFogStart(); Real oldFogEnd = sceneMgr->getFogEnd(); sceneMgr->setFog(Ogre::FOG_EXP2, Ogre::ColourValue(0,0,0,0), 0.0f, 0.0f, 0.0f); //Ember change //We need to disable all lightning and render it full bright Ogre::ColourValue oldAmbientColour = sceneMgr->getAmbientLight(); sceneMgr->setAmbientLight(ColourValue::White); std::vector<Ogre::MovableObject*> lightStore; Ogre::SceneManager::MovableObjectIterator lightIterator = sceneMgr->getMovableObjectIterator(Ogre::LightFactory::FACTORY_TYPE_NAME); while (lightIterator.hasMoreElements()) { Ogre::MovableObject* light = lightIterator.getNext(); if (light) { if (light->getVisible()) { lightStore.push_back(light); light->setVisible(false); } } } // Get current status of the queue mode Ogre::SceneManager::SpecialCaseRenderQueueMode OldSpecialCaseRenderQueueMode = sceneMgr->getSpecialCaseRenderQueueMode(); //Only render the entity sceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_INCLUDE); sceneMgr->addSpecialCaseRenderQueue(group->geom->getRenderQueue() + 1); uint8 oldRenderQueueGroup = entity->getRenderQueueGroup(); entity->setRenderQueueGroup(group->geom->getRenderQueue() + 1); bool oldVisible = entity->getVisible(); entity->setVisible(true); float oldMaxDistance = entity->getRenderingDistance(); entity->setRenderingDistance(0); bool needsRegen = true; #ifdef IMPOSTOR_FILE_SAVE //Calculate the filename hash used to uniquely identity this render String strKey = entityKey; char key[32] = {0}; uint32 i = 0; for (String::const_iterator it = entityKey.begin(); it != entityKey.end(); ++it) { key[i] ^= *it; i = (i+1) % sizeof(key); } for (i = 0; i < sizeof(key); ++i) key[i] = (key[i] % 26) + 'A'; String tempdir = this->group->geom->getTempdir(); ResourceGroupManager::getSingleton().addResourceLocation(tempdir, "FileSystem", "BinFolder"); String fileNamePNG = "Impostor." + String(key, sizeof(key)) + '.' + StringConverter::toString(textureSize) + ".png"; String fileNameDDS = "Impostor." + String(key, sizeof(key)) + '.' + StringConverter::toString(textureSize) + ".dds"; //Attempt to load the pre-render file if allowed needsRegen = force; if (!needsRegen){ try{ texture = TextureManager::getSingleton().load(fileNameDDS, "BinFolder", TEX_TYPE_2D, MIP_UNLIMITED); } catch (...){ try{ texture = TextureManager::getSingleton().load(fileNamePNG, "BinFolder", TEX_TYPE_2D, MIP_UNLIMITED); } catch (...){ needsRegen = true; } } } #endif if (needsRegen){ //If this has not been pre-rendered, do so now const float xDivFactor = 1.0f / IMPOSTOR_YAW_ANGLES; const float yDivFactor = 1.0f / IMPOSTOR_PITCH_ANGLES; for (int o = 0; o < IMPOSTOR_PITCH_ANGLES; ++o){ //4 pitch angle renders #ifdef IMPOSTOR_RENDER_ABOVE_ONLY Radian pitch = Degree((90.0f * o) * yDivFactor); //0, 22.5, 45, 67.5 #else Radian pitch = Degree((180.0f * o) * yDivFactor - 90.0f); #endif for (int i = 0; i < IMPOSTOR_YAW_ANGLES; ++i){ //8 yaw angle renders Radian yaw = Degree((360.0f * i) * xDivFactor); //0, 45, 90, 135, 180, 225, 270, 315 //Position camera camNode->setPosition(0, 0, 0); camNode->setOrientation(Quaternion(yaw, Vector3::UNIT_Y) * Quaternion(-pitch, Vector3::UNIT_X)); camNode->translate(Vector3(0, 0, objDist), Node::TS_LOCAL); //Render the impostor renderViewport->setDimensions((float)(i) * xDivFactor, (float)(o) * yDivFactor, xDivFactor, yDivFactor); renderTarget->update(); } } #ifdef IMPOSTOR_FILE_SAVE //Save RTT to file with respecting the temp dir renderTarget->writeContentsToFile(tempdir + fileNamePNG); //Load the render into the appropriate texture view texture = TextureManager::getSingleton().load(fileNamePNG, "BinFolder", TEX_TYPE_2D, MIP_UNLIMITED); #else texture = renderTexture; #endif } entity->setVisible(oldVisible); entity->setRenderQueueGroup(oldRenderQueueGroup); entity->setRenderingDistance(oldMaxDistance); sceneMgr->removeSpecialCaseRenderQueue(group->geom->getRenderQueue() + 1); // Restore original state sceneMgr->setSpecialCaseRenderQueueMode(OldSpecialCaseRenderQueueMode); //Re-enable mipmapping mm->setDefaultTextureFiltering(oldMinFilter, oldMagFilter, oldMipFilter); //Re-enable fog sceneMgr->setFog(oldFogMode, oldFogColor, oldFogDensity, oldFogStart, oldFogEnd); //Re-enable both scene lightning and disabled individual lights sceneMgr->setAmbientLight(oldAmbientColour); for (std::vector<Ogre::MovableObject*>::const_iterator I = lightStore.begin(); I != lightStore.end(); ++I) { (*I)->setVisible(true); } //Delete camera renderTarget->removeViewport(0); renderCamera->getSceneManager()->destroyCamera(renderCamera); //Delete scene node node->detachAllObjects(); if (oldSceneNode) { oldSceneNode->attachObject(entity); } #ifdef IMPOSTOR_FILE_SAVE //Delete RTT texture assert(!renderTexture.isNull()); String texName2(renderTexture->getName()); renderTexture.setNull(); if (TextureManager::getSingletonPtr()) TextureManager::getSingleton().remove(texName2); #endif }
void addTextureDebugOverlay( TrayLocation loc, TexturePtr tex, size_t i ) { addTextureDebugOverlay( loc, tex->getName(), i ); }
int ShadowManager::updateShadowTechnique() { float shadowFarDistance = FSETTING("SightRange", 2000); float scoef = 0.12; gEnv->sceneManager->setShadowColour(Ogre::ColourValue(0.563 + scoef, 0.578 + scoef, 0.625 + scoef)); gEnv->sceneManager->setShowDebugShadows(false); if (ShadowsType == SHADOWS_TEXTURE) { gEnv->sceneManager->setShadowFarDistance(shadowFarDistance); processTextureShadows(); } else if (ShadowsType == SHADOWS_PSSM) { processPSSM(); if (gEnv->sceneManager->getShowDebugShadows()) { // add the overlay elements to show the shadow maps: // init overlay elements OverlayManager& mgr = Ogre::OverlayManager::getSingleton(); Overlay* overlay = mgr.create("DebugOverlay"); for (int i = 0; i < PSSM_Shadows.ShadowsTextureNum; ++i) { TexturePtr tex = gEnv->sceneManager->getShadowTexture(i); // Set up a debug panel to display the shadow MaterialPtr debugMat = MaterialManager::getSingleton().create("Ogre/DebugTexture" + StringConverter::toString(i), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName()); t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); OverlayContainer* debugPanel = (OverlayContainer*)(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i))); debugPanel->_setPosition(0.8, i*0.25); debugPanel->_setDimensions(0.2, 0.24); debugPanel->setMaterialName(debugMat->getName()); debugPanel->setEnabled(true); overlay->add2D(debugPanel); overlay->show(); } } } return 0; }
const String& CoverageMap::getName() const { return mTexture->getName(); }
/// Shadows config //--------------------------------------------------------------------------------------------------- void App::changeShadows() { QTimer ti; ti.update(); /// time // get settings bool enabled = pSet->shadow_type != 0; bool bDepth = pSet->shadow_type >= 2; bool bSoft = pSet->shadow_type == 3; pSet->shadow_size = std::max(0,std::min(ciShadowNumSizes-1, pSet->shadow_size)); int fTex = /*2048*/ ciShadowSizesA[pSet->shadow_size], fTex2 = fTex/2; int num = /*3*/ pSet->shadow_count; // disable 4 shadow textures (does not work because no texcoord's left in shader) if (num == 4) num = 3; TerrainMaterialGeneratorB::SM2Profile* matProfile = 0; if (mTerrainGlobals) { matProfile = (TerrainMaterialGeneratorB::SM2Profile*) mTerrainGlobals->getDefaultMaterialGenerator()->getActiveProfile(); if (matProfile) { matProfile->setReceiveDynamicShadowsEnabled(enabled); matProfile->setReceiveDynamicShadowsLowLod(true); matProfile->setGlobalColourMapEnabled(false); matProfile->setLayerSpecularMappingEnabled(pSet->ter_mtr >= 1); // ter mtr matProfile->setLayerNormalMappingEnabled( pSet->ter_mtr >= 2); matProfile->setLayerParallaxMappingEnabled(pSet->ter_mtr >= 3); } } if (!enabled) { mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); /*return;*/ } else { // General scene setup //mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED); mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED); mSceneMgr->setShadowFarDistance(pSet->shadow_dist); // 3000 mSceneMgr->setShadowTextureCountPerLightType(Light::LT_DIRECTIONAL, num); if (mPSSMSetup.isNull()) { // shadow camera setup PSSMShadowCameraSetup* pssmSetup = new PSSMShadowCameraSetup(); #ifndef ROAD_EDITOR pssmSetup->setSplitPadding(mSplitMgr->mCameras.front()->getNearClipDistance()); //pssmSetup->setSplitPadding(10); pssmSetup->calculateSplitPoints(num, mSplitMgr->mCameras.front()->getNearClipDistance(), mSceneMgr->getShadowFarDistance()); #else pssmSetup->setSplitPadding(mCamera->getNearClipDistance()); //pssmSetup->setSplitPadding(10); pssmSetup->calculateSplitPoints(num, mCamera->getNearClipDistance(), mSceneMgr->getShadowFarDistance()); #endif for (int i=0; i < num; ++i) { //int size = i==0 ? fTex : fTex2; const Real cAdjfA[5] = {2, 1, 0.5, 0.25, 0.125}; pssmSetup->setOptimalAdjustFactor(i, cAdjfA[std::min(i, 4)]); } materialFactory->setPSSMCameraSetup(pssmSetup); mPSSMSetup.bind(pssmSetup); } mSceneMgr->setShadowCameraSetup(mPSSMSetup); mSceneMgr->setShadowTextureCount(num); for (int i=0; i < num; ++i) { int size = i==0 ? fTex : fTex2; PixelFormat pf; if (bDepth && !bSoft) pf = PF_FLOAT32_R; else if (bSoft) pf = PF_FLOAT16_RGB; else pf = PF_X8B8G8R8; mSceneMgr->setShadowTextureConfig(i, size, size, pf); } mSceneMgr->setShadowTextureSelfShadow(bDepth ? true : false); //-? mSceneMgr->setShadowCasterRenderBackFaces((bDepth && !bSoft) ? true : false); String shadowCasterMat; if (bDepth && !bSoft) shadowCasterMat = "PSSM/shadow_caster"; else if (bSoft) shadowCasterMat = "PSVSM/shadow_caster"; else shadowCasterMat = StringUtil::BLANK; mSceneMgr->setShadowTextureCasterMaterial(shadowCasterMat); if (matProfile && terrain) { matProfile->setReceiveDynamicShadowsDepth(bDepth); matProfile->setReceiveDynamicShadowsPSSM(static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get())); MaterialPtr mtr = matProfile->generateForCompositeMap(terrain); //LogO(mtr->getBestTechnique()->getPass(0)->getTextureUnitState(0)->getName()); //LogO(String("Ter mtr: ") + mtr->getName()); } } materialFactory->setTerrain(terrain); materialFactory->setNumShadowTex(num); materialFactory->setShadows(pSet->shadow_type != 0); materialFactory->setShadowsDepth(bDepth); materialFactory->setShadowsSoft(bSoft); materialFactory->generate(); #if 0 // shadow tex overlay // add the overlay elements to show the shadow maps: // init overlay elements OverlayManager& mgr = OverlayManager::getSingleton(); Overlay* overlay; // destroy if already exists if (overlay = mgr.getByName("DebugOverlay")) mgr.destroy(overlay); overlay = mgr.create("DebugOverlay"); TexturePtr tex; for (size_t i = 0; i < 2; ++i) { //TexturePtr tex = mSceneMgr->getShadowTexture(i); if (i == 0) tex = TextureManager::getSingleton().getByName("PlaneReflection"); else tex = TextureManager::getSingleton().getByName("PlaneRefraction"); // Set up a debug panel to display the shadow if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + toStr(i))) MaterialManager::getSingleton().remove("Ogre/DebugTexture" + toStr(i)); MaterialPtr debugMat = MaterialManager::getSingleton().create( "Ogre/DebugTexture" + toStr(i), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName()); t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); OverlayContainer* debugPanel; // destroy container if exists try { if (debugPanel = static_cast<OverlayContainer*>( mgr.getOverlayElement("Ogre/DebugTexPanel" + toStr(i) ))) mgr.destroyOverlayElement(debugPanel); } catch (Ogre::Exception&) {} debugPanel = (OverlayContainer*) (OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i))); debugPanel->_setPosition(0.8, i*0.25); debugPanel->_setDimensions(0.2, 0.24); debugPanel->setMaterialName(debugMat->getName()); debugPanel->show(); overlay->add2D(debugPanel); overlay->show(); } #endif // ------------------- update the paged-geom materials // grass is not cloned, just need to set new shader parameters if (grass) { GrassLoader *grassLoader = static_cast<GrassLoader*>(grass->getPageLoader()); for (std::list<GrassLayer*>::iterator it= grassLoader->getLayerList().begin(); it != grassLoader->getLayerList().end(); ++it) { GrassLayer* layer = (*it); layer->applyShader(); } } // trees are more complicated since they are cloned //!todo this doesn't work (tree material does not update immediately) if(trees) { trees->reloadGeometry(); std::vector<ResourcePtr> reosurceToDelete; ResourceManager::ResourceMapIterator it = MaterialManager::getSingleton().getResourceIterator(); while (it.hasMoreElements()) { ResourcePtr material = it.getNext(); String materialName = material->getName(); std::string::size_type pos =materialName.find("BatchMat|"); if( pos != std::string::npos ) { reosurceToDelete.push_back(material); } } for(int i=0;i<reosurceToDelete.size();i++) { MaterialManager::getSingleton().remove(reosurceToDelete[i]); } } UpdPSSMMaterials(); ti.update(); /// time float dt = ti.dt * 1000.f; LogO(String("::: Time Shadows: ") + toStr(dt) + " ms"); }
/// Shadows config //--------------------------------------------------------------------------------------------------- void CScene::changeShadows() { Ogre::Timer ti; // get settings SETTINGS* pSet = app->pSet; bool enabled = pSet->shadow_type != Sh_None; bool bDepth = pSet->shadow_type >= Sh_Depth; bool bSoft = pSet->shadow_type == Sh_Soft; pSet->shadow_size = std::max(0,std::min(ciShadowSizesNum-1, pSet->shadow_size)); int fTex = ciShadowSizesA[pSet->shadow_size], fTex2 = fTex/2; int num = pSet->shadow_count; sh::Vector4* fade = new sh::Vector4( pSet->shadow_dist, pSet->shadow_dist * 0.6, // fade start 0, 0); sh::Factory* mFactory = app->mFactory; SceneManager* mSceneMgr = app->mSceneMgr; if (terrain) mFactory->setTextureAlias("TerrainLightMap", terrain->getLightmap()->getName()); // disable 4 shadow textures (does not work because no texcoord's left in shader) if (num == 4) num = 3; if (!enabled) mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); else { // General scene setup //mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED); mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED); mSceneMgr->setShadowFarDistance(pSet->shadow_dist); // 3000 mSceneMgr->setShadowTextureCountPerLightType(Light::LT_DIRECTIONAL, num); if (num == 1) // 1 tex, fast { ShadowCameraSetupPtr mShadowCameraSetup = ShadowCameraSetupPtr(new LiSPSMShadowCameraSetup()); mSceneMgr->setShadowCameraSetup(mShadowCameraSetup); }else { if (mPSSMSetup.isNull()) // pssm { PSSMShadowCameraSetup* pssmSetup = new PSSMShadowCameraSetup(); #ifndef SR_EDITOR pssmSetup->setSplitPadding(app->mSplitMgr->mCameras.front()->getNearClipDistance()); pssmSetup->calculateSplitPoints(num, app->mSplitMgr->mCameras.front()->getNearClipDistance(), mSceneMgr->getShadowFarDistance()); #else pssmSetup->setSplitPadding(app->mCamera->getNearClipDistance()); pssmSetup->calculateSplitPoints(num, app->mCamera->getNearClipDistance(), app->mSceneMgr->getShadowFarDistance()); #endif for (int i=0; i < num; ++i) { //int size = i==0 ? fTex : fTex2; const Real cAdjfA[5] = {2, 1, 0.5, 0.25, 0.125}; pssmSetup->setOptimalAdjustFactor(i, cAdjfA[std::min(i, 4)]); } mPSSMSetup.bind(pssmSetup); } mSceneMgr->setShadowCameraSetup(mPSSMSetup); } mSceneMgr->setShadowTextureCount(num); for (int i=0; i < num; ++i) { int size = i==0 ? fTex : fTex2; PixelFormat pf; if (bDepth && !bSoft) pf = PF_FLOAT32_R; else if (bSoft) pf = PF_FLOAT16_RGB; else pf = PF_X8B8G8R8; mSceneMgr->setShadowTextureConfig(i, size, size, pf); } mSceneMgr->setShadowTextureSelfShadow(bDepth ? true : false); //-? mSceneMgr->setShadowCasterRenderBackFaces((bDepth && !bSoft) ? true : false); mSceneMgr->setShadowTextureCasterMaterial(bDepth ? "shadowcaster_default" : ""); } mSceneMgr->setShadowColour(Ogre::ColourValue(0,0,0,1)); #if 0 /// TEST overlays // add overlay elements to show shadow or terrain maps OverlayManager& mgr = OverlayManager::getSingleton(); Overlay* overlay = mgr.getByName("DebugOverlay"); if (overlay) mgr.destroy(overlay); overlay = mgr.create("DebugOverlay"); TexturePtr tex; #if 0 /// shadow for (int i = 0; i < pSet->shadow_count; ++i) { TexturePtr tex = mSceneMgr->getShadowTexture(i); #else /// terrain for (int i = 0; i < 2/*pSet->shadow_count*/; ++i) { TexturePtr tex = !terrain ? mSceneMgr->getShadowTexture(i) : i==0 ? terrain->getCompositeMap() : terrain->getLightmap(); #endif // Set up a debug panel to display the shadow if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + toStr(i))) MaterialManager::getSingleton().remove("Ogre/DebugTexture" + toStr(i)); MaterialPtr debugMat = MaterialManager::getSingleton().create( "Ogre/DebugTexture" + toStr(i), rgDef); debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName()); t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); OverlayContainer* debugPanel; // destroy container if exists try { if (debugPanel = static_cast<OverlayContainer*>(mgr.getOverlayElement("Ogre/DebugTexPanel" + toStr(i)))) mgr.destroyOverlayElement(debugPanel); } catch (Ogre::Exception&) {} debugPanel = (OverlayContainer*) (OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i))); debugPanel->_setPosition(0.8, i*0.31); //aspect.. 0.25 0.24 debugPanel->_setDimensions(0.2, 0.3); debugPanel->setMaterialName(debugMat->getName()); debugPanel->show(); overlay->add2D(debugPanel); overlay->show(); } #endif UpdPSSMMaterials(); // rebuild static geom after materials change if (vdrTrack) { vdrTrack->destroy(); vdrTrack->build(); } LogO(String("::: Time Shadows: ") + fToStr(ti.getMilliseconds(),0,3) + " ms"); } /// . . . . . . . . void CScene::UpdPSSMMaterials() { if (app->pSet->shadow_type == Sh_None) return; if (app->pSet->shadow_count == 1) // 1 tex { float dist = app->pSet->shadow_dist; sh::Vector3* splits = new sh::Vector3(dist, 0,0); //dist*2, dist*3); sh::Factory::getInstance().setSharedParameter("pssmSplitPoints", sh::makeProperty<sh::Vector3>(splits)); return; } if (!mPSSMSetup.get()) return; //-- pssm params PSSMShadowCameraSetup* pssmSetup = static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get()); const PSSMShadowCameraSetup::SplitPointList& sp = pssmSetup->getSplitPoints(); const int last = sp.size()-1; sh::Vector3* splits = new sh::Vector3( sp[std::min(1,last)], sp[std::min(2,last)], sp[std::min(3,last)] ); sh::Factory::getInstance().setSharedParameter("pssmSplitPoints", sh::makeProperty<sh::Vector3>(splits)); }
void TerrainManager::cellAdded(MWWorld::Ptr::CellStore *store) { const int cellX = store->mCell->getGridX(); const int cellY = store->mCell->getGridY(); ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().get<ESM::Land>().search(cellX, cellY); if (land == NULL) // no land data means we're not going to create any terrain. return; int dataRequired = ESM::Land::DATA_VHGT | ESM::Land::DATA_VCLR; if (!land->isDataLoaded(dataRequired)) { land->loadData(dataRequired); } //split the cell terrain into four segments const int numTextures = ESM::Land::LAND_TEXTURE_SIZE/2; for ( int x = 0; x < 2; x++ ) { for ( int y = 0; y < 2; y++ ) { Terrain::ImportData terrainData = mTerrainGroup.getDefaultImportSettings(); const int terrainX = cellX * 2 + x; const int terrainY = cellY * 2 + y; //it makes far more sense to reallocate the memory here, //and let Ogre deal with it due to the issues with deleting //it at the wrong time if using threads (Which Terrain does) terrainData.inputFloat = OGRE_ALLOC_T(float, mLandSize*mLandSize, MEMCATEGORY_GEOMETRY); //copy the height data row by row for ( int terrainCopyY = 0; terrainCopyY < mLandSize; terrainCopyY++ ) { //the offset of the current segment const size_t yOffset = y * (mLandSize-1) * ESM::Land::LAND_SIZE + //offset of the row terrainCopyY * ESM::Land::LAND_SIZE; const size_t xOffset = x * (mLandSize-1); memcpy(&terrainData.inputFloat[terrainCopyY*mLandSize], &land->mLandData->mHeights[yOffset + xOffset], mLandSize*sizeof(float)); } std::map<uint16_t, int> indexes; initTerrainTextures(&terrainData, cellX, cellY, x * numTextures, y * numTextures, numTextures, indexes, land->mPlugin); if (mTerrainGroup.getTerrain(terrainX, terrainY) == NULL) { mTerrainGroup.defineTerrain(terrainX, terrainY, &terrainData); mTerrainGroup.loadTerrain(terrainX, terrainY, true); Terrain* terrain = mTerrainGroup.getTerrain(terrainX, terrainY); initTerrainBlendMaps(terrain, cellX, cellY, x * numTextures, y * numTextures, numTextures, indexes); terrain->setVisibilityFlags(RV_Terrain); terrain->setRenderQueueGroup(RQG_Main); // disable or enable global colour map (depends on available vertex colours) if ( land->mLandData->mUsingColours ) { TexturePtr vertex = getVertexColours(land, cellX, cellY, x*(mLandSize-1), y*(mLandSize-1), mLandSize); mActiveProfile->setGlobalColourMapEnabled(true); mActiveProfile->setGlobalColourMap (terrain, vertex->getName()); } else mActiveProfile->setGlobalColourMapEnabled (false); } } } // when loading from a heightmap, Ogre::Terrain does not update the derived data (normal map, LOD) // synchronously, even if we supply synchronous = true parameter to loadTerrain. // the following to be the only way to make sure derived data is ready when rendering the next frame. while (mTerrainGroup.isDerivedDataUpdateInProgress()) { // we need to wait for this to finish OGRE_THREAD_SLEEP(5); Root::getSingleton().getWorkQueue()->processResponses(); } mTerrainGroup.freeTemporaryResources(); }