mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:59:54 +00:00
Crash fix, material fix
This commit is contained in:
parent
13afcc9324
commit
8c8653160d
11 changed files with 123 additions and 25 deletions
|
@ -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…
Reference in a new issue