implemented weather transitions (currently only blends the clouds)

actorid
scrawl 13 years ago
parent 4efc5bc1f2
commit 41a8b22ebd

@ -64,6 +64,10 @@ RenderingManager::~RenderingManager ()
delete mSkyManager;
}
MWRender::SkyManager* RenderingManager::getSkyManager()
{
return mSkyManager;
}
MWRender::Objects& RenderingManager::getObjects(){
return mObjects;

@ -62,6 +62,8 @@ class RenderingManager: private RenderingInterface {
/// MWWorld::Player has been rewritten to not need access
/// to internal details of the rendering system anymore
SkyManager* getSkyManager();
void toggleLight();
bool toggleRenderMode(int mode);
@ -111,7 +113,9 @@ class RenderingManager: private RenderingInterface {
private:
void setAmbientMode();
SkyManager* mSkyManager;
OEngine::Render::OgreRenderer &mRendering;
MWRender::Objects mObjects;

@ -44,6 +44,11 @@ void CelestialBody::setPosition(const Vector3& pPosition)
mNode->setPosition(finalPosition);
}
void CelestialBody::setColour(const ColourValue& pColour)
{
mMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(pColour);
}
void CelestialBody::init(const String& textureName,
const unsigned int initialSize,
const Vector3& pInitialPosition,
@ -68,7 +73,7 @@ void CelestialBody::init(const String& textureName,
mNode->attachObject(bbSet);
bbSet->createBillboard(0,0,0);
mMaterial = MaterialManager::getSingleton().create("CelestialBody"+StringConverter::toString(bodyCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
mMaterial = MaterialManager::getSingleton().create("BillboardMaterial"+StringConverter::toString(bodyCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
mMaterial->removeAllTechniques();
Pass* p = mMaterial->createTechnique()->createPass();
p->setSceneBlending(SBT_TRANSPARENT_ALPHA);
@ -78,7 +83,7 @@ void CelestialBody::init(const String& textureName,
p->setDiffuse(0.0,0.0,0.0,1.0);
p->setAmbient(0.0,0.0,0.0);
p->createTextureUnitState(textureName);
bbSet->setMaterialName("CelestialBody"+StringConverter::toString(bodyCount));
bbSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
bodyCount++;
}
@ -152,6 +157,8 @@ void Moon::setType(const Moon::Type& type)
mType = type;
}
/// \todo the moon phase rendering is not correct - the dark part of the moon does not occlude the stars
void Moon::setPhase(const Moon::Phase& phase)
{
Ogre::String textureName = "textures\\tx_";
@ -199,12 +206,6 @@ void Moon::setVisibility(const float pVisibility)
mMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("visibilityFactor", Real(pVisibility));
}
void Moon::setColour(const ColourValue& pColour)
{
mMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(pColour);
}
void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType)
{
// Get the vertex colour buffer of this mesh
@ -367,14 +368,16 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
" out float4 oColor : COLOR, \n"
" in float4 color : TEXCOORD1, \n"
" uniform sampler2D texture : TEXUNIT0, \n"
" uniform sampler2D secondTexture : TEXUNIT1, \n"
" uniform float transitionFactor, \n"
" uniform float time, \n"
" uniform float opacity, \n"
" uniform float4 emissive \n"
") \n"
"{ \n"
" uv += float2(1,1) * time * "<<CLOUD_SPEED<<"; \n" // Scroll in x,y direction
" float4 tex = tex2D(texture, uv); \n"
" oColor = color * float4(emissive.xyz,1) * tex2D(texture, uv) * float4(1,1,1,opacity); \n"
" float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n"
" oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n"
"}";
mCloudFragmentShader->setSource(outStream2.str());
mCloudFragmentShader->load();
@ -400,6 +403,8 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mCloudMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("");
}
SkyManager::~SkyManager()
@ -437,6 +442,7 @@ void SkyManager::disable()
void SkyManager::setMoonColour (bool red)
{
/// \todo tweak these colors
mSecunda->setColour( red ? ColourValue(1.0, 0.0, 0.0)
: ColourValue(1.0, 1.0, 1.0));
}
@ -445,3 +451,31 @@ void SkyManager::setCloudsOpacity(float opacity)
{
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("opacity", Real(opacity));
}
void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
{
if (mClouds != weather.mCloudTexture)
{
mCloudMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("textures\\"+weather.mCloudTexture);
mClouds = weather.mCloudTexture;
}
if (mNextClouds != weather.mNextCloudTexture)
{
mCloudMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("textures\\"+weather.mNextCloudTexture);
mNextClouds = weather.mNextCloudTexture;
}
if (mCloudBlendFactor != weather.mCloudBlendFactor)
{
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("transitionFactor", Real(weather.mCloudBlendFactor));
mCloudBlendFactor = weather.mCloudBlendFactor;
}
if (mCloudOpacity != weather.mCloudOpacity)
{
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("opacity", Real(weather.mCloudOpacity));
mCloudOpacity = weather.mCloudOpacity;
}
}

@ -8,6 +8,7 @@
#include <OgreHighLevelGpuProgram.h>
#include "sky.hpp"
#include "../mwworld/weather.hpp"
namespace Ogre
{
@ -30,7 +31,8 @@ namespace MWRender
Ogre::SceneNode* pRootNode
);
CelestialBody();
void setColour(const Ogre::ColourValue& pColour);
void setPosition(const Ogre::Vector3& pPosition);
void setVisible(const bool visible);
@ -59,9 +61,7 @@ namespace MWRender
void setVisibility(const float pVisibility);
///< set the transparency factor for this moon
void setColour(const Ogre::ColourValue& pColour);
enum Phase
{
Phase_New = 0,
@ -123,6 +123,8 @@ namespace MWRender
void setCloudsOpacity(float opacity);
///< change opacity of the clouds
void setWeather(const MWWorld::WeatherResult& weather);
private:
CelestialBody* mSun;
Moon* mMasser;
@ -137,6 +139,14 @@ namespace MWRender
Ogre::HighLevelGpuProgramPtr mCloudFragmentShader;
// remember the cloud texture names used right now, so we don't have to set the texture names if they didnt change
Ogre::String mClouds;
Ogre::String mNextClouds;
float mCloudBlendFactor;
float mCloudOpacity;
float mRemainingTransitionTime;
void ModVertexAlpha(Ogre::Entity* ent, unsigned int meshType);
};
}

@ -2,9 +2,99 @@
#include "../mwrender/renderingmanager.hpp"
using namespace Ogre;
using namespace MWWorld;
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering)
#define TRANSITION_TIME 10
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering) :
mCurrentWeather("clear")
{
mRendering = rendering;
/// \todo read these from Morrowind.ini
Weather clear;
clear.mCloudTexture = "tx_sky_clear.dds";
clear.mCloudsMaximumPercent = 0.75;
mWeatherSettings["clear"] = clear;
Weather cloudy;
cloudy.mCloudTexture = "tx_sky_cloudy.dds";
cloudy.mCloudsMaximumPercent = 0.9;
mWeatherSettings["cloudy"] = cloudy;
Weather overcast;
overcast.mCloudTexture = "tx_sky_overcast.dds";
overcast.mCloudsMaximumPercent = 1.0;
mWeatherSettings["overcast"] = overcast;
setWeather("clear", true);
setWeather("cloudy", false);
}
void WeatherManager::setWeather(const String& weather, bool instant)
{
if (instant)
{
mNextWeather = "";
mCurrentWeather = weather;
}
else if (weather != mCurrentWeather)
{
mNextWeather = weather;
mRemainingTransitionTime = TRANSITION_TIME;
}
}
WeatherResult WeatherManager::getResult()
{
const Weather& current = mWeatherSettings[mCurrentWeather];
WeatherResult result;
result.mCloudTexture = current.mCloudTexture;
result.mCloudBlendFactor = 0;
result.mCloudOpacity = current.mCloudsMaximumPercent;
/// \todo
return result;
}
WeatherResult WeatherManager::transition(const Weather& other, float factor)
{
const Weather& current = mWeatherSettings[mCurrentWeather];
WeatherResult result;
result.mCloudTexture = current.mCloudTexture;
result.mNextCloudTexture = other.mCloudTexture;
result.mCloudBlendFactor = factor;
#define lerp(x, y) (x * (1-factor) + y * factor)
result.mCloudOpacity = lerp(current.mCloudsMaximumPercent, other.mCloudsMaximumPercent);
/// \todo
return result;
}
void WeatherManager::update(float duration)
{
WeatherResult result;
if (mNextWeather != "")
{
mRemainingTransitionTime -= duration;
if (mRemainingTransitionTime < 0)
{
mCurrentWeather = mNextWeather;
mNextWeather = "";
}
}
if (mNextWeather != "")
result = transition(mWeatherSettings[mNextWeather], 1-(mRemainingTransitionTime/TRANSITION_TIME));
else
result = getResult();
mRendering->getSkyManager()->setWeather(result);
}

@ -11,6 +11,35 @@ namespace MWRender
namespace MWWorld
{
/// Defines the actual weather that results from weather setting (see below), time of day and weather transition
struct WeatherResult
{
Ogre::String mCloudTexture;
Ogre::String mNextCloudTexture;
float mCloudBlendFactor;
Ogre::ColourValue mFogColor;
Ogre::ColourValue mAmbientColor;
Ogre::ColourValue mSunColor;
Ogre::ColourValue mSunDiscColor;
float mFogDepth;
float mWindSpeed;
float mCloudSpeed;
float mCloudOpacity;
float mGlareView;
Ogre::String mAmbientLoopSoundID;
};
/// Defines a single weather setting
struct Weather
{
@ -83,7 +112,7 @@ namespace MWWorld
* @param instant
* if true, the weather changes instantly. if false, it slowly starts transitioning.
*/
void setWeather(const Weather& weather, bool instant=false);
void setWeather(const Ogre::String& weather, bool instant=false);
/**
* Per-frame update
@ -93,6 +122,16 @@ namespace MWWorld
private:
MWRender::RenderingManager* mRendering;
std::map<Ogre::String, Weather> mWeatherSettings;
Ogre::String mCurrentWeather;
Ogre::String mNextWeather;
float mRemainingTransitionTime;
WeatherResult transition(const Weather& other, const float factor);
WeatherResult getResult();
};
}

@ -693,6 +693,8 @@ namespace MWWorld
void World::update (float duration)
{
mWorldScene->update (duration);
mWeatherManager->update (duration);
}
OEngine::Render::Fader* World::getFader()

Loading…
Cancel
Save