Merge remote branch 'scrawl/graphics'

Conflicts:
	apps/openmw/mwrender/renderingmanager.cpp
actorid
Marc Zinnschlag 13 years ago
commit 7938566004

@ -16,6 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender add_openmw_dir (mwrender
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows shaderhelper renderinginterface localmap occlusionquery terrain terrainmaterial water shadows shaderhelper
compositors
) )
add_openmw_dir (mwinput add_openmw_dir (mwinput

@ -0,0 +1,49 @@
#include "compositors.hpp"
#include <OgreViewport.h>
#include <OgreCompositorManager.h>
using namespace MWRender;
Compositors::Compositors(Ogre::Viewport* vp) :
mViewport(vp)
, mEnabled(true)
{
}
Compositors::~Compositors()
{
Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport);
}
void Compositors::setEnabled (const bool enabled)
{
for (CompositorMap::iterator it=mCompositors.begin();
it != mCompositors.end(); ++it)
{
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, it->first, enabled && it->second.first);
}
mEnabled = enabled;
}
void Compositors::addCompositor (const std::string& name, const int priority)
{
int id = 0;
for (CompositorMap::iterator it=mCompositors.begin();
it != mCompositors.end(); ++it)
{
if (it->second.second > priority)
break;
++id;
}
Ogre::CompositorManager::getSingleton().addCompositor (mViewport, name, id);
mCompositors[name] = std::make_pair(false, priority);
}
void Compositors::setCompositorEnabled (const std::string& name, const bool enabled)
{
mCompositors[name].first = enabled;
Ogre::CompositorManager::getSingleton().setCompositorEnabled (mViewport, name, enabled && mEnabled);
}

@ -0,0 +1,53 @@
#ifndef GAME_MWRENDER_COMPOSITORS_H
#define GAME_MWRENDER_COMPOSITORS_H
#include <map>
#include <string>
namespace Ogre
{
class Viewport;
}
namespace MWRender
{
typedef std::map < std::string, std::pair<bool, int> > CompositorMap;
/// \brief Manages a set of compositors for one viewport
class Compositors
{
public:
Compositors(Ogre::Viewport* vp);
virtual ~Compositors();
/**
* enable or disable all compositors globally
*/
void setEnabled (const bool enabled);
bool toggle() { setEnabled(!mEnabled); return mEnabled; }
/**
* enable or disable a specific compositor
* @note enable has no effect if all compositors are globally disabled
*/
void setCompositorEnabled (const std::string& name, const bool enabled);
/**
* @param name of compositor
* @param priority, lower number will be first in the chain
*/
void addCompositor (const std::string& name, const int priority);
protected:
/// maps compositor name to its "enabled" state
CompositorMap mCompositors;
bool mEnabled;
Ogre::Viewport* mViewport;
};
}
#endif

@ -19,6 +19,7 @@
#include "shaderhelper.hpp" #include "shaderhelper.hpp"
#include "localmap.hpp" #include "localmap.hpp"
#include "water.hpp" #include "water.hpp"
#include "compositors.hpp"
using namespace MWRender; using namespace MWRender;
using namespace Ogre; using namespace Ogre;
@ -30,6 +31,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
{ {
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
mCompositors = new Compositors(mRendering.getViewport());
mWater = 0; mWater = 0;
//The fog type must be set before any terrain objects are created as if the //The fog type must be set before any terrain objects are created as if the
@ -68,15 +71,15 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
// note that the order is important here // note that the order is important here
if (useMRT()) if (useMRT())
{ {
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbuffer"); mCompositors->addCompositor("gbuffer", 0);
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true); mCompositors->setCompositorEnabled("gbuffer", true);
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "Underwater"); mCompositors->addCompositor("Underwater", 1);
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbufferFinalizer"); mCompositors->addCompositor("gbufferFinalizer", 2);
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true); mCompositors->setCompositorEnabled("gbufferFinalizer", true);
} }
else else
{ {
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "UnderwaterNoMRT"); mCompositors->addCompositor("UnderwaterNoMRT", 0);
} }
// Turn the entire scene (represented by the 'root' node) -90 // Turn the entire scene (represented by the 'root' node) -90
@ -121,6 +124,7 @@ RenderingManager::~RenderingManager ()
delete mTerrainManager; delete mTerrainManager;
delete mLocalMap; delete mLocalMap;
delete mOcclusionQuery; delete mOcclusionQuery;
delete mCompositors;
} }
MWRender::SkyManager* RenderingManager::getSkyManager() MWRender::SkyManager* RenderingManager::getSkyManager()
@ -235,7 +239,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){
&& !MWBase::Environment::get().getWorld()->getStore().lands.search(store->cell->data.gridX,store->cell->data.gridY) )) // always use water, if the cell does not have land. && !MWBase::Environment::get().getWorld()->getStore().lands.search(store->cell->data.gridX,store->cell->data.gridY) )) // always use water, if the cell does not have land.
{ {
if(mWater == 0) if(mWater == 0)
mWater = new MWRender::Water(mRendering.getCamera(), mSkyManager, store->cell); mWater = new MWRender::Water(mRendering.getCamera(), this, store->cell);
else else
mWater->changeCell(store->cell); mWater->changeCell(store->cell);
mWater->setActive(true); mWater->setActive(true);
@ -295,35 +299,29 @@ void RenderingManager::skySetMoonColour (bool red){
bool RenderingManager::toggleRenderMode(int mode) bool RenderingManager::toggleRenderMode(int mode)
{ {
if (mode != MWWorld::World::Render_Wireframe) if (mode == MWWorld::World::Render_CollisionDebug || mode == MWWorld::World::Render_Pathgrid)
return mDebugging->toggleRenderMode(mode); return mDebugging->toggleRenderMode(mode);
else // if (mode == MWWorld::World::Render_Wireframe) else if (mode == MWWorld::World::Render_Wireframe)
{ {
if (mRendering.getCamera()->getPolygonMode() == PM_SOLID) if (mRendering.getCamera()->getPolygonMode() == PM_SOLID)
{ {
// disable compositors mCompositors->setEnabled(false);
if (useMRT())
{
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", false);
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", false);
}
mRendering.getCamera()->setPolygonMode(PM_WIREFRAME); mRendering.getCamera()->setPolygonMode(PM_WIREFRAME);
return true; return true;
} }
else else
{ {
// re-enable compositors mCompositors->setEnabled(true);
if (useMRT())
{
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true);
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true);
}
mRendering.getCamera()->setPolygonMode(PM_SOLID); mRendering.getCamera()->setPolygonMode(PM_SOLID);
return false; return false;
} }
} }
else //if (mode == MWWorld::World::Render_Compositors)
{
return mCompositors->toggle();
}
} }
void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell) void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
@ -560,4 +558,9 @@ Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds)
return Vector4(min_x, min_y, max_x, max_y); return Vector4(min_x, min_y, max_x, max_y);
} }
Compositors* RenderingManager::getCompositors()
{
return mCompositors;
}
} // namespace } // namespace

@ -47,6 +47,7 @@ namespace MWRender
class ShaderHelper; class ShaderHelper;
class LocalMap; class LocalMap;
class Water; class Water;
class Compositors;
class RenderingManager: private RenderingInterface { class RenderingManager: private RenderingInterface {
@ -67,6 +68,7 @@ class RenderingManager: private RenderingInterface {
/// to internal details of the rendering system anymore /// to internal details of the rendering system anymore
SkyManager* getSkyManager(); SkyManager* getSkyManager();
Compositors* getCompositors();
void toggleLight(); void toggleLight();
bool toggleRenderMode(int mode); bool toggleRenderMode(int mode);
@ -196,6 +198,8 @@ class RenderingManager: private RenderingInterface {
MWRender::Shadows* mShadows; MWRender::Shadows* mShadows;
MWRender::ShaderHelper* mShaderHelper; MWRender::ShaderHelper* mShaderHelper;
MWRender::Compositors* mCompositors;
}; };
} }

@ -258,7 +258,7 @@ void ShaderHelper::createShader(const bool mrt, const bool shadows, const bool s
outStream << outStream <<
" float3 lightingFinal = lightColour.xyz * diffuse.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n" " float3 lightingFinal = lightColour.xyz * diffuse.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
" float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); \n" " float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); \n"
" oColor.xyz = lerp(lightingFinal * tex.xyz * vertexColour.xyz, fogColour.xyz, fogValue); \n" " oColor.xyz = saturate(lerp(lightingFinal * tex.xyz * vertexColour.xyz, fogColour.xyz, fogValue)); \n" // saturate output to prevent negative output colors - TODO: replace this once there is HDR-rendering
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n"; " oColor.a = tex.a * diffuse.a * vertexColour.a; \n";
if (mrt) outStream << if (mrt) outStream <<

@ -113,6 +113,7 @@ void BillboardObject::init(const String& textureName,
p->setSelfIllumination(1.0,1.0,1.0); p->setSelfIllumination(1.0,1.0,1.0);
p->setDiffuse(0.0,0.0,0.0,1.0); p->setDiffuse(0.0,0.0,0.0,1.0);
p->setAmbient(0.0,0.0,0.0); p->setAmbient(0.0,0.0,0.0);
p->setPolygonModeOverrideable(false);
p->createTextureUnitState(textureName); p->createTextureUnitState(textureName);
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount)); mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
@ -520,6 +521,7 @@ void SkyManager::create()
mp->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); mp->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mp->getTechnique(0)->getPass(0)->setVertexProgram(stars_vp->getName()); mp->getTechnique(0)->getPass(0)->setVertexProgram(stars_vp->getName());
mp->getTechnique(0)->getPass(0)->setFragmentProgram(stars_fp->getName()); mp->getTechnique(0)->getPass(0)->setFragmentProgram(stars_fp->getName());
mp->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
mStarsMaterials[i] = mp; mStarsMaterials[i] = mp;
} }
@ -535,6 +537,7 @@ void SkyManager::create()
mAtmosphereDay = mRootNode->createChildSceneNode(); mAtmosphereDay = mRootNode->createChildSceneNode();
mAtmosphereDay->attachObject(atmosphere_ent); mAtmosphereDay->attachObject(atmosphere_ent);
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial(); mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
// Atmosphere shader // Atmosphere shader
HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
@ -598,6 +601,7 @@ void SkyManager::create()
SceneNode* clouds_node = mRootNode->createChildSceneNode(); SceneNode* clouds_node = mRootNode->createChildSceneNode();
clouds_node->attachObject(clouds_ent); clouds_node->attachObject(clouds_ent);
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial(); mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
mCloudMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
clouds_ent->setCastShadows(false); clouds_ent->setCastShadows(false);
// Clouds vertex shader // Clouds vertex shader

@ -2,24 +2,20 @@
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include "sky.hpp" #include "sky.hpp"
#include "renderingmanager.hpp" #include "renderingmanager.hpp"
#include "compositors.hpp"
using namespace Ogre; using namespace Ogre;
namespace MWRender namespace MWRender
{ {
Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) :
mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()), mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()),
mIsUnderwater(false), mVisibilityFlags(0), mIsUnderwater(false), mVisibilityFlags(0),
mReflectionTarget(0), mActive(1), mToggled(1), mReflectionTarget(0), mActive(1), mToggled(1),
mReflectionRenderActive(false) mReflectionRenderActive(false), mRendering(rend)
{ {
mSky = sky; mSky = rend->getSkyManager();
try
{
CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false);
} catch(...) {}
mTop = cell->water; mTop = cell->water;
@ -147,8 +143,6 @@ Water::~Water()
mWaterNode->detachObject(mWater); mWaterNode->detachObject(mWater);
mSceneManager->destroyEntity(mWater); mSceneManager->destroyEntity(mWater);
mSceneManager->destroySceneNode(mWaterNode); mSceneManager->destroySceneNode(mWaterNode);
CompositorManager::getSingleton().removeCompositorChain(mViewport);
} }
void Water::changeCell(const ESM::Cell* cell) void Water::changeCell(const ESM::Cell* cell)
@ -178,13 +172,13 @@ void Water::checkUnderwater(float y)
{ {
if (!mActive) if (!mActive)
{ {
CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, false); mRendering->getCompositors()->setCompositorEnabled(mCompositorName, false);
return; return;
} }
if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID) if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID)
{ {
CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, false); mRendering->getCompositors()->setCompositorEnabled(mCompositorName, false);
// tell the shader we are not underwater // tell the shader we are not underwater
Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0); Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0);
@ -199,7 +193,7 @@ void Water::checkUnderwater(float y)
if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID) if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID)
{ {
if (mUnderwaterEffect) if (mUnderwaterEffect)
CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, true); mRendering->getCompositors()->setCompositorEnabled(mCompositorName, true);
// tell the shader we are underwater // tell the shader we are underwater
Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0); Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0);

@ -9,6 +9,7 @@
namespace MWRender { namespace MWRender {
class SkyManager; class SkyManager;
class RenderingManager;
/// Water rendering /// Water rendering
class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener
@ -40,6 +41,7 @@ namespace MWRender {
void updateVisible(); void updateVisible();
RenderingManager* mRendering;
SkyManager* mSky; SkyManager* mSky;
std::string mCompositorName; std::string mCompositorName;
@ -55,7 +57,7 @@ namespace MWRender {
int mVisibilityFlags; int mVisibilityFlags;
public: public:
Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell); Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell);
~Water(); ~Water();
void setActive(bool active); void setActive(bool active);

@ -146,4 +146,4 @@ op 0x200014f: ForceGreeting
op 0x2000150: ForceGreeting, explicit reference op 0x2000150: ForceGreeting, explicit reference
op 0x2000151: ToggleFullHelp op 0x2000151: ToggleFullHelp
op 0x2000152: Goodbye op 0x2000152: Goodbye
opcodes 0x2000153-0x3ffffff unused opcodes 0x2000154-0x3ffffff unused

@ -66,7 +66,8 @@ namespace MWWorld
{ {
Render_CollisionDebug, Render_CollisionDebug,
Render_Wireframe, Render_Wireframe,
Render_Pathgrid Render_Pathgrid,
Render_Compositors
}; };
private: private:

@ -326,6 +326,8 @@ void NIFLoader::createMaterial(const String &name,
{ {
material->getTechnique(0)->getPass(0)->setVertexProgram("main_vp"); material->getTechnique(0)->getPass(0)->setVertexProgram("main_vp");
material->getTechnique(0)->getPass(0)->setFragmentProgram("main_fp"); material->getTechnique(0)->getPass(0)->setFragmentProgram("main_fp");
material->getTechnique(0)->getPass(0)->setFog(true); // force-disable fixed function fog, it is calculated in shader
} }
// Create a fallback technique without shadows and without mrt // Create a fallback technique without shadows and without mrt
@ -338,6 +340,7 @@ void NIFLoader::createMaterial(const String &name,
{ {
pass2->setVertexProgram("main_fallback_vp"); pass2->setVertexProgram("main_fallback_vp");
pass2->setFragmentProgram("main_fallback_fp"); pass2->setFragmentProgram("main_fallback_fp");
pass2->setFog(true); // force-disable fixed function fog, it is calculated in shader
} }
// Add material bells and whistles // Add material bells and whistles

@ -38,6 +38,9 @@ material depth_shadow_caster
{ {
pass pass
{ {
// force-disable fog (relevant for DirectX profiles below SM3 that always apply fixed function fog)
fog_override true
vertex_program_ref depth_shadow_caster_vs vertex_program_ref depth_shadow_caster_vs
{ {
} }
@ -55,6 +58,9 @@ material depth_shadow_caster_noalpha
{ {
pass pass
{ {
// force-disable fog (relevant for DirectX profiles below SM3 that always apply fixed function fog)
fog_override true
vertex_program_ref depth_shadow_caster_vs vertex_program_ref depth_shadow_caster_vs
{ {
} }

Loading…
Cancel
Save