Crash fix, material fix

actorid
scrawl 12 years ago
parent 13afcc9324
commit 8c8653160d

@ -244,16 +244,6 @@ void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
mObjects.buildStaticGeometry (*store);
sh::Factory::getInstance().unloadUnreferencedMaterials();
mDebugging->cellAdded(store);
if (store->isExterior())
{
if (!mTerrain)
{
mTerrain = new Terrain::Terrain(mRendering.getScene(), new MWRender::TerrainStorage(), RV_Terrain,
Settings::Manager::getBool("distant land", "Terrain"),
Settings::Manager::getBool("shader", "Terrain"));
mTerrain->update(mRendering.getCamera()->getRealPosition());
}
}
waterAdded(store);
}
@ -848,7 +838,12 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
mWater->processChangedSettings(settings);
if (rebuild)
{
mObjects.rebuildStaticGeometry();
if (mTerrain)
mTerrain->applyMaterials(Settings::Manager::getBool("enabled", "Shadows"),
Settings::Manager::getBool("split", "Shadows"));
}
}
void RenderingManager::setMenuTransparency(float val)
@ -994,7 +989,7 @@ void RenderingManager::updateWaterRippleEmitterPtr (const MWWorld::Ptr& old, con
void RenderingManager::frameStarted(float dt, bool paused)
{
if (mTerrain)
if (mTerrain && mTerrain->getVisible())
mTerrain->update(mRendering.getCamera()->getRealPosition());
if (!paused)
@ -1012,4 +1007,24 @@ float RenderingManager::getTerrainHeightAt(Ogre::Vector3 worldPos)
return mTerrain->getHeightAt(worldPos);
}
void RenderingManager::enableTerrain(bool enable)
{
if (enable)
{
if (!mTerrain)
{
mTerrain = new Terrain::Terrain(mRendering.getScene(), new MWRender::TerrainStorage(), RV_Terrain,
Settings::Manager::getBool("distant land", "Terrain"),
Settings::Manager::getBool("shader", "Terrain"));
mTerrain->applyMaterials(Settings::Manager::getBool("enabled", "Shadows"),
Settings::Manager::getBool("split", "Shadows"));
mTerrain->update(mRendering.getCamera()->getRealPosition());
}
mTerrain->setVisible(true);
}
else
if (mTerrain)
mTerrain->setVisible(false);
}
} // namespace

@ -110,6 +110,8 @@ public:
void cellAdded (MWWorld::CellStore *store);
void waterAdded(MWWorld::CellStore *store);
void enableTerrain(bool enable);
void removeWater();
void preCellChange (MWWorld::CellStore* store);

@ -362,6 +362,8 @@ namespace MWWorld
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
mRendering.enableTerrain(false);
std::string loadingInteriorText;
loadingInteriorText = gmst.find ("sLoadingMessage2")->getString();
@ -440,6 +442,8 @@ namespace MWWorld
MWBase::Environment::get().getWorld()->positionToIndex (position.pos[0], position.pos[1], x, y);
mRendering.enableTerrain(true);
changeCell (x, y, position, true);
}

@ -34,6 +34,8 @@ namespace Terrain
MaterialGenerator::MaterialGenerator(bool shaders)
: mShaders(shaders)
, mShadows(false)
, mSplitShadows(false)
{
}
@ -46,6 +48,11 @@ namespace Terrain
// first layer doesn't need blendmap
--freeTextureUnits;
if (mSplitShadows)
freeTextureUnits -= 3;
else if (mShadows)
--freeTextureUnits;
// each layer needs 1.25 units (1xdiffusespec, 0.25xblend)
return static_cast<Ogre::uint8>(freeTextureUnits / (1.25f)) + 1;
}
@ -158,7 +165,6 @@ namespace Terrain
}
else
{
sh::MaterialInstance* material = sh::Factory::getInstance().createMaterialInstance (name.str());
material->setProperty ("allow_fixed_function", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(false)));
@ -179,12 +185,14 @@ namespace Terrain
tex->setProperty ("tex_address_mode", sh::makeProperty (new sh::StringValue("clamp")));
// shadow. TODO: repeated, put in function
for (Ogre::uint i = 0; i < 3; ++i)
if (mShadows)
{
sh::MaterialInstanceTextureUnit* shadowTex = p->createTextureUnit ("shadowMap" + Ogre::StringConverter::toString(i));
shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow")));
for (Ogre::uint 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))));
@ -272,12 +280,14 @@ namespace Terrain
}
// shadow
for (Ogre::uint i = 0; i < 3; ++i)
if (mShadows)
{
sh::MaterialInstanceTextureUnit* shadowTex = p->createTextureUnit ("shadowMap" + Ogre::StringConverter::toString(i));
shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow")));
for (Ogre::uint 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))));

@ -21,6 +21,9 @@ namespace Terrain
const std::vector<Ogre::TexturePtr>& getBlendmapList() { return mBlendmapList; }
void setCompositeMap (const std::string& name) { mCompositeMap = name; }
void enableShadows(bool shadows) { mShadows = shadows; }
void enableSplitShadows(bool splitShadows) { mSplitShadows = splitShadows; }
/// Creates a material suitable for displaying a chunk of terrain using alpha-blending.
/// @param mat Material that will be replaced by the generated material. May be empty as well, in which case
/// a new material is created.
@ -48,6 +51,8 @@ namespace Terrain
std::vector<Ogre::TexturePtr> mBlendmapList;
std::string mCompositeMap;
bool mShaders;
bool mShadows;
bool mSplitShadows;
};
}

@ -256,6 +256,10 @@ void QuadTreeNode::update(const Ogre::Vector3 &cameraPos)
mChunk->setVisibilityFlags(mTerrain->getVisiblityFlags());
mChunk->setCastShadows(true);
mSceneNode->attachObject(mChunk);
mMaterialGenerator->enableShadows(mTerrain->getShadowsEnabled());
mMaterialGenerator->enableSplitShadows(mTerrain->getSplitShadowsEnabled());
if (mSize == 1)
{
ensureLayerInfo();
@ -338,8 +342,11 @@ void QuadTreeNode::destroyChunks()
mMaterialGenerator->setCompositeMap("");
}
Ogre::TextureManager::getSingleton().remove(mCompositeMap->getName());
mCompositeMap.setNull();
if (!mCompositeMap.isNull())
{
Ogre::TextureManager::getSingleton().remove(mCompositeMap->getName());
mCompositeMap.setNull();
}
}
else if (hasChildren())
for (int i=0; i<4; ++i)
@ -444,3 +451,29 @@ void QuadTreeNode::ensureCompositeMap()
mTerrain->clearCompositeMapSceneManager();
}
void QuadTreeNode::applyMaterials()
{
if (mChunk)
{
mMaterialGenerator->enableShadows(mTerrain->getShadowsEnabled());
mMaterialGenerator->enableSplitShadows(mTerrain->getSplitShadowsEnabled());
if (mSize <= 1)
mChunk->setMaterial(mMaterialGenerator->generate(Ogre::MaterialPtr()));
else
mChunk->setMaterial(mMaterialGenerator->generateForCompositeMap(Ogre::MaterialPtr()));
}
if (hasChildren())
for (int i=0; i<4; ++i)
mChildren[i]->applyMaterials();
}
void QuadTreeNode::setVisible(bool visible)
{
if (!visible && mChunk)
mChunk->setVisible(false);
if (hasChildren())
for (int i=0; i<4; ++i)
mChildren[i]->setVisible(visible);
}

@ -49,6 +49,11 @@ namespace Terrain
QuadTreeNode (Terrain* terrain, ChildDirection dir, float size, const Ogre::Vector2& center, QuadTreeNode* parent);
~QuadTreeNode();
void setVisible(bool visible);
/// Rebuild all materials
void applyMaterials();
/// Initialize neighbours - do this after the quadtree is built
void initNeighbours();
/// Initialize bounding boxes of non-leafs by merging children bounding boxes.

@ -425,7 +425,7 @@ namespace Terrain
0---1 0---1
*/
// Build all 4 positions in terrain space, using point-sampled height
// Build all 4 positions in normalized cell space, using point-sampled height
Ogre::Vector3 v0 (startXTS, startYTS, getVertexHeight(land, startX, startY) / 8192.f);
Ogre::Vector3 v1 (endXTS, startYTS, getVertexHeight(land, endX, startY) / 8192.f);
Ogre::Vector3 v2 (endXTS, endYTS, getVertexHeight(land, endX, endY) / 8192.f);

@ -370,5 +370,23 @@ namespace Terrain
return mStorage->getHeightAt(worldPos);
}
void Terrain::applyMaterials(bool shadows, bool splitShadows)
{
mShadows = shadows;
mSplitShadows = splitShadows;
mRootNode->applyMaterials();
}
void Terrain::setVisible(bool visible)
{
mVisible = visible;
mRootNode->setVisible(visible);
}
bool Terrain::getVisible()
{
return mVisible;
}
}

@ -40,6 +40,8 @@ namespace Terrain
bool getDistantLandEnabled() { return mDistantLand; }
bool getShadersEnabled() { return mShaders; }
bool getShadowsEnabled() { return mShadows; }
bool getSplitShadowsEnabled() { return mSplitShadows; }
float getHeightAt (const Ogre::Vector3& worldPos);
@ -56,14 +58,16 @@ namespace Terrain
Storage* getStorage() { return mStorage; }
/// Show or hide the whole terrain
/// @note this setting will be invalidated once you call Terrain::update, so do not call it while the terrain should be hidden
void setVisible(bool visible);
bool getVisible();
/// Recreate materials used by terrain chunks. This should be called whenever settings of
/// the material factory are changed. (Relying on the factory to update those materials is not
/// enough, since turning a feature on/off can change the number of texture units available for layer/blend
/// textures, and to properly respond to this we may need to change the structure of the material, such as
/// adding or removing passes. This can only be achieved by a full rebuild.)
void applyMaterials();
void applyMaterials(bool shadows, bool splitShadows);
int getVisiblityFlags() { return mVisibilityFlags; }
@ -74,6 +78,9 @@ namespace Terrain
private:
bool mDistantLand;
bool mShaders;
bool mShadows;
bool mSplitShadows;
bool mVisible;
QuadTreeNode* mRootNode;
Storage* mStorage;

@ -348,7 +348,6 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5;
#else
shOutputColour(0).a = 1.f-previousAlpha;
#endif
}
#endif

Loading…
Cancel
Save