mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 12:23:51 +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