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)
@ -529,13 +527,13 @@ Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds)
float min_x = 1.0f, max_x = 0.0f, min_y = 1.0f, max_y = 0.0f; float min_x = 1.0f, max_x = 0.0f, min_y = 1.0f, max_y = 0.0f;
// expand the screen-space bounding-box so that it completely encloses // expand the screen-space bounding-box so that it completely encloses
// the object's AABB // the object's AABB
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
{ {
Ogre::Vector3 corner = corners[i]; Ogre::Vector3 corner = corners[i];
// multiply the AABB corner vertex by the view matrix to // multiply the AABB corner vertex by the view matrix to
// get a camera-space vertex // get a camera-space vertex
corner = mat * corner; corner = mat * corner;
@ -544,20 +542,25 @@ Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds)
float x = corner.x / corner.z + 0.5; float x = corner.x / corner.z + 0.5;
float y = corner.y / corner.z + 0.5; float y = corner.y / corner.z + 0.5;
if (x < min_x) if (x < min_x)
min_x = x; min_x = x;
if (x > max_x) if (x > max_x)
max_x = x; max_x = x;
if (y < min_y) if (y < min_y)
min_y = y; min_y = y;
if (y > max_y) if (y > max_y)
max_y = y; max_y = y;
} }
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

@ -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
}
vertex_program_ref depth_shadow_caster_vs
{
}
fragment_program_ref depth_shadow_caster_ps_noalpha fragment_program_ref depth_shadow_caster_ps_noalpha
{ {
} }
} }
} }
} }

Loading…
Cancel
Save