Merge remote branch 'scrawl/graphics'

Conflicts:
	apps/openmw/mwrender/renderingmanager.cpp
This commit is contained in:
Marc Zinnschlag 2012-05-21 11:24:36 +02:00
commit 7938566004
13 changed files with 207 additions and 87 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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;
}; };
} }

View file

@ -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 <<

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

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

View file

@ -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

View file

@ -1,67 +1,73 @@
vertex_program depth_shadow_caster_vs cg vertex_program depth_shadow_caster_vs cg
{ {
source depthshadowcaster.cg source depthshadowcaster.cg
profiles vs_1_1 arbvp1 profiles vs_1_1 arbvp1
entry_point main_vp entry_point main_vp
default_params default_params
{ {
param_named_auto wvpMat worldviewproj_matrix param_named_auto wvpMat worldviewproj_matrix
} }
} }
fragment_program depth_shadow_caster_ps cg fragment_program depth_shadow_caster_ps cg
{ {
source depthshadowcaster.cg source depthshadowcaster.cg
profiles ps_2_0 arbfp1 profiles ps_2_0 arbfp1
entry_point main_fp entry_point main_fp
default_params default_params
{ {
} }
} }
fragment_program depth_shadow_caster_ps_noalpha cg fragment_program depth_shadow_caster_ps_noalpha cg
{ {
source depthshadowcaster.cg source depthshadowcaster.cg
profiles ps_2_0 arbfp1 profiles ps_2_0 arbfp1
entry_point main_fp_noalpha entry_point main_fp_noalpha
default_params default_params
{ {
} }
} }
material depth_shadow_caster material depth_shadow_caster
{ {
technique technique
{ {
pass pass
{ {
vertex_program_ref depth_shadow_caster_vs // force-disable fog (relevant for DirectX profiles below SM3 that always apply fixed function fog)
{ fog_override true
}
fragment_program_ref depth_shadow_caster_ps vertex_program_ref depth_shadow_caster_vs
{ {
} }
}
} fragment_program_ref depth_shadow_caster_ps
{
}
}
}
} }
material depth_shadow_caster_noalpha material depth_shadow_caster_noalpha
{ {
technique technique
{ {
pass pass
{ {
vertex_program_ref depth_shadow_caster_vs // force-disable fog (relevant for DirectX profiles below SM3 that always apply fixed function fog)
{ fog_override true
}
fragment_program_ref depth_shadow_caster_ps_noalpha vertex_program_ref depth_shadow_caster_vs
{ {
} }
}
} fragment_program_ref depth_shadow_caster_ps_noalpha
{
}
}
}
} }