light improvements

actorid
scrawl 13 years ago
parent fb0e649191
commit c6da3872b4

@ -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;
bool quadratic = false;
if (!lightOutQuadInLin)
quadratic = lightQuadratic;
else
{
quadratic = !mInterior;
}
if(!lightOutQuadInLin)
if (!quadratic)
{
if(lightLinear)
radius *= lightLinearRadiusMult;
if(lightQuadratic)
radius *= lightQuadraticRadiusMult;
if(lightLinear)
lval = lightLinearValue / pow(radius, lightLinearMethod);
if(lightQuadratic)
qval = lightQuadraticValue / pow(radius, lightQuadraticMethod);
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…
Cancel
Save