diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index a9216a1a3..448050240 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -37,6 +37,16 @@ void BillboardObject::setVisible(const bool visible) mNode->setVisible(visible); } +void BillboardObject::setSize(const float size) +{ + mNode->setScale(size, size, size); +} + +void BillboardObject::setVisibility(const float visibility) +{ + mMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, visibility); +} + void BillboardObject::setPosition(const Vector3& pPosition) { Vector3 normalised = pPosition.normalisedCopy(); @@ -47,6 +57,11 @@ void BillboardObject::setPosition(const Vector3& pPosition) mNode->setPosition(finalPosition); } +Vector3 BillboardObject::getPosition() const +{ + return mNode->getPosition(); +} + void BillboardObject::setColour(const ColourValue& pColour) { mMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(pColour); @@ -146,15 +161,16 @@ Moon::Moon( const String& textureName, " in float2 uv : TEXCOORD0, \n" " out float4 oColor : COLOR, \n" " uniform sampler2D texture : TEXUNIT0, \n" - " uniform float visibilityFactor, \n" + " uniform float4 diffuse, \n" " uniform float4 emissive \n" ") \n" "{ \n" " float4 tex = tex2D(texture, uv); \n" - " oColor = float4(emissive.xyz,1) * tex2D(texture, uv) * float4(1,1,1,visibilityFactor); \n" + " oColor = float4(emissive.xyz,1) * tex2D(texture, uv) * float4(1,1,1,diffuse.a); \n" "}"; fshader->setSource(outStream2.str()); fshader->load(); + fshader->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR); fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR); mMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName()); @@ -212,15 +228,6 @@ unsigned int Moon::getPhaseInt() const return 0; } -void Moon::setVisibility(const float visibility) -{ - if (mVisibility != visibility) - { - mMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("visibilityFactor", Real(visibility)); - mVisibility = visibility; - } -} - void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType) { // Get the vertex colour buffer of this mesh @@ -277,7 +284,7 @@ void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType) } SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) : - mGlareEnabled(false) + mGlareFade(0), mGlareEnabled(false) { mViewport = pCamera->getViewport(); mSceneMgr = pMwRoot->getCreator(); @@ -541,10 +548,36 @@ void SkyManager::update(float duration) // UV Scroll the clouds mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", 1); + /// \todo improve this mMasser->setPhase( static_cast( (int) ((mDay % 32)/4.f)) ); mSecunda->setPhase ( static_cast( (int) ((mDay % 32)/4.f)) ); - mSunGlare->setVisible(mGlareEnabled && mSunEnabled); + // increase the strength of the sun glare effect depending + // on how directly the player is looking at the sun + if (mSunEnabled) + { + Vector3 sun = mSunGlare->getPosition(); + sun = Vector3(sun.x, sun.z, -sun.y); + Vector3 cam = mViewport->getCamera()->getRealDirection(); + const Degree angle = sun.angleBetween( cam ); + float val = 1- (angle.valueDegrees() / 180.f); + val = (val*val*val*val)*2; + + if (mGlareEnabled) + { + mGlareFade += duration*3; + if (mGlareFade > 1) mGlareFade = 1; + } + else + { + mGlareFade -= duration*3; + if (mGlareFade < 0.3) mGlareFade = 0; + } + + mSunGlare->setSize(val * (mGlareFade)); + } + + mSunGlare->setVisible(mGlareFade>0 && mSunEnabled); mSun->setVisible(mSunEnabled); mMasser->setVisible(mMasserEnabled); mSecunda->setVisible(mSecundaEnabled); @@ -627,6 +660,15 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather) mStarsMaterials[i]->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, weather.mNightFade); mStarsOpacity = weather.mNightFade; } + + float strength; + float timeofday_angle = std::abs(mSunGlare->getPosition().z/mSunGlare->getPosition().length()); + if (timeofday_angle <= 0.44) + strength = timeofday_angle/0.44f; + else + strength = 1.f; + + mSunGlare->setVisibility(weather.mGlareView * strength); mAtmosphereNight->setVisible(weather.mNight && mEnabled); } diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 0d5935dd0..2678165e3 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -39,6 +39,10 @@ namespace MWRender void setPosition(const Ogre::Vector3& pPosition); void setVisible(const bool visible); void setRenderQueue(unsigned int id); + void setSize(const float size); + Ogre::Vector3 getPosition() const; + + void setVisibility(const float visibility); Ogre::SceneNode* getNode(); @@ -65,9 +69,6 @@ namespace MWRender const Ogre::Vector3& position, Ogre::SceneNode* rootNode ); - - void setVisibility(const float visibility); - ///< set the transparency factor for this moon enum Phase { @@ -94,7 +95,6 @@ namespace MWRender unsigned int getPhaseInt() const; private: - float mVisibility; Type mType; Phase mPhase; }; @@ -197,6 +197,8 @@ namespace MWRender float mRemainingTransitionTime; + float mGlareFade; + void ModVertexAlpha(Ogre::Entity* ent, unsigned int meshType); bool mEnabled; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index c88dad0f2..3d97acb04 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -349,6 +349,7 @@ WeatherResult WeatherManager::getResult(const String& weather) result.mCloudSpeed = current.mCloudSpeed; result.mGlareView = current.mGlareView; result.mAmbientLoopSoundID = current.mAmbientLoopSoundID; + result.mSunColor = current.mSunDiscSunsetColor; const float fade_duration = current.mTransitionDelta * 24.f;