mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 19:56:42 +00:00 
			
		
		
		
	light improvements
This commit is contained in:
		
							parent
							
								
									fb0e649191
								
							
						
					
					
						commit
						c6da3872b4
					
				
					 6 changed files with 113 additions and 68 deletions
				
			
		|  | @ -8,20 +8,15 @@ | |||
| 
 | ||||
| using namespace MWRender; | ||||
| 
 | ||||
| bool Objects::lightConst = false; | ||||
| float Objects::lightConstValue = 0.0f; | ||||
| 
 | ||||
| bool Objects::lightLinear = true; | ||||
| int Objects::lightLinearMethod = 1; | ||||
| // These are the Morrowind.ini defaults
 | ||||
| float Objects::lightLinearValue = 3; | ||||
| float Objects::lightLinearRadiusMult = 1; | ||||
| 
 | ||||
| bool Objects::lightQuadratic = false; | ||||
| int Objects::lightQuadraticMethod = 2; | ||||
| float Objects::lightQuadraticValue = 16; | ||||
| float Objects::lightQuadraticRadiusMult = 1; | ||||
| 
 | ||||
| bool Objects::lightOutQuadInLin = false; | ||||
| bool Objects::lightOutQuadInLin = true; | ||||
| bool Objects::lightQuadratic = false; | ||||
| 
 | ||||
| int Objects::uniqueID = 0; | ||||
| 
 | ||||
|  | @ -132,7 +127,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects")) | ||||
|     if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent) | ||||
|     { | ||||
|         insert->attachObject(ent); | ||||
| 
 | ||||
|  | @ -144,18 +139,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) | |||
|     { | ||||
|         Ogre::StaticGeometry* sg = 0; | ||||
| 
 | ||||
| /*        if (transparent)
 | ||||
|         { | ||||
|             if( mStaticGeometryAlpha.find(ptr.getCell()) == mStaticGeometryAlpha.end()) | ||||
|             { | ||||
|                 uniqueID = uniqueID +1; | ||||
|                 sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); | ||||
|                 mStaticGeometryAlpha[ptr.getCell()] = sg; | ||||
|             } | ||||
|             else | ||||
|                 sg = mStaticGeometryAlpha[ptr.getCell()]; | ||||
|         } | ||||
|         else*/ if (small) | ||||
|         if (small) | ||||
|         { | ||||
|             if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) | ||||
|             { | ||||
|  | @ -207,34 +191,35 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f | |||
|     assert(insert); | ||||
|     Ogre::Light *light = mRenderer.getScene()->createLight(); | ||||
|     light->setDiffuseColour (r, g, b); | ||||
|     mLights.push_back(light->getName()); | ||||
| 
 | ||||
|     float cval=0.0f, lval=0.0f, qval=0.0f; | ||||
|     LightInfo info; | ||||
|     info.name = light->getName(); | ||||
|     info.radius = radius; | ||||
|     info.colour = Ogre::ColourValue(r, g, b); | ||||
|     mLights.push_back(info); | ||||
| 
 | ||||
|     if(lightConst) | ||||
|          cval = lightConstValue; | ||||
| 
 | ||||
|     if(!lightOutQuadInLin) | ||||
|     bool quadratic = false; | ||||
|     if (!lightOutQuadInLin) | ||||
|         quadratic = lightQuadratic; | ||||
|     else | ||||
|     { | ||||
|         if(lightLinear) | ||||
|             radius *= lightLinearRadiusMult; | ||||
|         if(lightQuadratic) | ||||
|             radius *= lightQuadraticRadiusMult; | ||||
|         quadratic = !mInterior; | ||||
|     } | ||||
| 
 | ||||
|         if(lightLinear) | ||||
|             lval = lightLinearValue / pow(radius, lightLinearMethod); | ||||
|         if(lightQuadratic) | ||||
|             qval = lightQuadraticValue / pow(radius, lightQuadraticMethod); | ||||
|     if (!quadratic) | ||||
|     { | ||||
|         float r = radius * lightLinearRadiusMult; | ||||
|         float attenuation = lightLinearValue / r; | ||||
|         light->setAttenuation(r*10, 0, attenuation, 0); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // FIXME:
 | ||||
|         // Do quadratic or linear, depending if we're in an exterior or interior
 | ||||
|         // cell, respectively. Ignore lightLinear and lightQuadratic.
 | ||||
|         float r = radius * lightQuadraticRadiusMult; | ||||
|         float attenuation = lightQuadraticValue / pow(r, 2); | ||||
|         light->setAttenuation(r*10, 0, 0, attenuation); | ||||
|     } | ||||
| 
 | ||||
|     light->setAttenuation(10*radius, cval, lval, qval); | ||||
| 
 | ||||
|     insert->attachObject(light); | ||||
| } | ||||
| 
 | ||||
|  | @ -290,13 +275,6 @@ void Objects::removeCell(MWWorld::Ptr::CellStore* store) | |||
|         mRenderer.getScene()->destroyStaticGeometry (sg); | ||||
|         sg = 0; | ||||
|     } | ||||
|     /*if(mStaticGeometryAlpha.find(store) != mStaticGeometryAlpha.end())
 | ||||
|     { | ||||
|         Ogre::StaticGeometry* sg = mStaticGeometryAlpha[store]; | ||||
|         mStaticGeometryAlpha.erase(store); | ||||
|         mRenderer.getScene()->destroyStaticGeometry (sg); | ||||
|         sg = 0; | ||||
|     }*/ | ||||
| 
 | ||||
|     if(mBounds.find(store) != mBounds.end()) | ||||
|         mBounds.erase(store); | ||||
|  | @ -314,11 +292,6 @@ void Objects::buildStaticGeometry(ESMS::CellStore<MWWorld::RefData>& cell) | |||
|         Ogre::StaticGeometry* sg = mStaticGeometrySmall[&cell]; | ||||
|         sg->build(); | ||||
|     } | ||||
|     /*if(mStaticGeometryAlpha.find(&cell) != mStaticGeometryAlpha.end())
 | ||||
|     { | ||||
|         Ogre::StaticGeometry* sg = mStaticGeometryAlpha[&cell]; | ||||
|         sg->build(); | ||||
|     }*/ | ||||
| } | ||||
| 
 | ||||
| Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell) | ||||
|  | @ -328,12 +301,12 @@ Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell) | |||
| 
 | ||||
| void Objects::enableLights() | ||||
| { | ||||
|     std::vector<std::string>::iterator it = mLights.begin(); | ||||
|     std::vector<LightInfo>::iterator it = mLights.begin(); | ||||
|     while (it != mLights.end()) | ||||
|     { | ||||
|         if (mMwRoot->getCreator()->hasLight(*it)) | ||||
|         if (mMwRoot->getCreator()->hasLight(it->name)) | ||||
|         { | ||||
|             mMwRoot->getCreator()->getLight(*it)->setVisible(true); | ||||
|             mMwRoot->getCreator()->getLight(it->name)->setVisible(true); | ||||
|             ++it; | ||||
|         } | ||||
|         else | ||||
|  | @ -343,12 +316,12 @@ void Objects::enableLights() | |||
| 
 | ||||
| void Objects::disableLights() | ||||
| { | ||||
|     std::vector<std::string>::iterator it = mLights.begin(); | ||||
|     std::vector<LightInfo>::iterator it = mLights.begin(); | ||||
|     while (it != mLights.end()) | ||||
|     { | ||||
|         if (mMwRoot->getCreator()->hasLight(*it)) | ||||
|         if (mMwRoot->getCreator()->hasLight(it->name)) | ||||
|         { | ||||
|             mMwRoot->getCreator()->getLight(*it)->setVisible(false); | ||||
|             mMwRoot->getCreator()->getLight(it->name)->setVisible(false); | ||||
|             ++it; | ||||
|         } | ||||
|         else | ||||
|  | @ -356,3 +329,48 @@ void Objects::disableLights() | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void Objects::setInterior(const bool interior) | ||||
| { | ||||
|     mInterior = interior; | ||||
| } | ||||
| 
 | ||||
| void Objects::update(const float dt) | ||||
| { | ||||
|     // adjust the lights depending if we're in an interior or exterior cell
 | ||||
|     // quadratic means the light intensity falls off quite fast, resulting in a
 | ||||
|     // dark, atmospheric environment (perfect for exteriors)
 | ||||
|     // for interiors, we want more "warm" lights, so use linear attenuation.
 | ||||
|     std::vector<LightInfo>::iterator it = mLights.begin(); | ||||
|     while (it != mLights.end()) | ||||
|     { | ||||
|         if (mMwRoot->getCreator()->hasLight(it->name)) | ||||
|         { | ||||
|             Ogre::Light* light = mMwRoot->getCreator()->getLight(it->name); | ||||
| 
 | ||||
|             bool quadratic = false; | ||||
|             if (!lightOutQuadInLin) | ||||
|                 quadratic = lightQuadratic; | ||||
|             else | ||||
|             { | ||||
|                 quadratic = !mInterior; | ||||
|             } | ||||
| 
 | ||||
|             if (!quadratic) | ||||
|             { | ||||
|                 float radius = it->radius * lightLinearRadiusMult; | ||||
|                 float attenuation = lightLinearValue / it->radius; | ||||
|                 light->setAttenuation(radius*10, 0, attenuation, 0); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 float radius = it->radius * lightQuadraticRadiusMult; | ||||
|                 float attenuation = lightQuadraticValue / pow(it->radius, 2); | ||||
|                 light->setAttenuation(radius*10, 0, 0, attenuation); | ||||
|             } | ||||
| 
 | ||||
|             ++it; | ||||
|         } | ||||
|         else | ||||
|             it = mLights.erase(it); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -10,37 +10,41 @@ | |||
| 
 | ||||
| namespace MWRender{ | ||||
| 
 | ||||
| /// information about light needed for rendering
 | ||||
| struct LightInfo | ||||
| { | ||||
|     std::string name; // ogre handle
 | ||||
|     Ogre::ColourValue colour; | ||||
|     float radius; | ||||
| }; | ||||
| 
 | ||||
| class Objects{ | ||||
|     OEngine::Render::OgreRenderer &mRenderer; | ||||
|     std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> mCellSceneNodes; | ||||
|     std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry; | ||||
|     std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall; | ||||
|     //std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometryAlpha;
 | ||||
|     std::map<MWWorld::Ptr::CellStore *, Ogre::AxisAlignedBox> mBounds; | ||||
|     std::vector<std::string> mLights; | ||||
|     std::vector<LightInfo> mLights; | ||||
|     Ogre::SceneNode* mMwRoot; | ||||
|     bool mIsStatic; | ||||
|     static int uniqueID; | ||||
|     static bool lightConst; | ||||
|     static float lightConstValue; | ||||
| 
 | ||||
|     static bool lightLinear; | ||||
|     static int lightLinearMethod; | ||||
|     static float lightLinearValue; | ||||
|     static float lightLinearRadiusMult; | ||||
| 
 | ||||
|     static bool lightQuadratic; | ||||
|     static int lightQuadraticMethod; | ||||
|     static float lightQuadraticValue; | ||||
|     static float lightQuadraticRadiusMult; | ||||
| 
 | ||||
|     static bool lightOutQuadInLin; | ||||
| 
 | ||||
|     bool mInterior; | ||||
| 
 | ||||
|     void clearSceneNode (Ogre::SceneNode *node); | ||||
|     ///< Remove all movable objects from \a node.
 | ||||
| 
 | ||||
| public: | ||||
|     Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer){} | ||||
|     Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer), mInterior(true) {} | ||||
|     ~Objects(){} | ||||
|     void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); | ||||
|     void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); | ||||
|  | @ -49,6 +53,12 @@ public: | |||
|     void enableLights(); | ||||
|     void disableLights(); | ||||
| 
 | ||||
|     void update (const float dt); | ||||
|     ///< per-frame update
 | ||||
| 
 | ||||
|     void setInterior(const bool interior); | ||||
|     ///< call this to switch from interior to exterior or vice versa
 | ||||
| 
 | ||||
|     Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*); | ||||
|     ///< get a bounding box that encloses all objects in the specified cell
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -213,6 +213,7 @@ void RenderingManager::moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Ve | |||
| void RenderingManager::update (float duration){ | ||||
| 
 | ||||
|     mActors.update (duration); | ||||
|     mObjects.update (duration); | ||||
| 
 | ||||
|     mOcclusionQuery->update(duration); | ||||
| 
 | ||||
|  | @ -508,4 +509,14 @@ Shadows* RenderingManager::getShadows() | |||
|     return mShadows; | ||||
| } | ||||
| 
 | ||||
| void RenderingManager::switchToInterior() | ||||
| { | ||||
|     mObjects.setInterior(true); | ||||
| } | ||||
| 
 | ||||
| void RenderingManager::switchToExterior() | ||||
| { | ||||
|     mObjects.setInterior(false); | ||||
| } | ||||
| 
 | ||||
| } // namespace
 | ||||
|  |  | |||
|  | @ -117,6 +117,9 @@ class RenderingManager: private RenderingInterface { | |||
| 
 | ||||
|     Shadows* getShadows(); | ||||
| 
 | ||||
|     void switchToInterior(); | ||||
|     void switchToExterior(); | ||||
| 
 | ||||
|     void setGlare(bool glare); | ||||
|     void skyEnable (); | ||||
|     void skyDisable (); | ||||
|  |  | |||
|  | @ -1149,8 +1149,8 @@ namespace Ogre | |||
| 				// simple per-pixel lighting with no normal mapping
 | ||||
|                                 for (int i=0; i<prof->getNumberOfLightsSupported(); ++i) | ||||
|                                 { | ||||
|                                         outStream << "	float3 halfAngle"<<i<<" = normalize(lightDir"<<i<<" + eyeDir);\n" | ||||
|                                                 "	float4 litRes"<<i<<" = lit(dot(normalize(lightDir"<<i<<"), normal), dot(halfAngle"<<i<<", normal), scaleBiasSpecular.z);\n"; | ||||
|                                         outStream << | ||||
|                                             "	float4 litRes"<<i<<" = lit(dot(normalize(lightDir"<<i<<"), normalize(normal)), 0, scaleBiasSpecular.z);\n"; | ||||
| 
 | ||||
|                                     if (i > 0) | ||||
|                                         outStream << | ||||
|  |  | |||
|  | @ -203,6 +203,8 @@ namespace MWWorld | |||
|         // Sky system
 | ||||
|         mWorld->adjustSky(); | ||||
| 
 | ||||
|         mRendering.switchToExterior(); | ||||
| 
 | ||||
|         mCellChanged = true; | ||||
|     } | ||||
| 
 | ||||
|  | @ -248,8 +250,9 @@ namespace MWWorld | |||
|         // adjust player
 | ||||
|         mCurrentCell = cell; | ||||
|         playerCellChange (cell, position); | ||||
|          | ||||
| 
 | ||||
|         // adjust fog
 | ||||
|         mRendering.switchToInterior(); | ||||
|         mRendering.configureFog(*cell); | ||||
| 
 | ||||
|         // Sky system
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue