diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index 4de6453aa..4c2ce8399 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -1,4 +1,5 @@ #include "creatureanimation.hpp" +#include "renderconst.hpp" #include "../mwworld/world.hpp" @@ -20,6 +21,7 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environme std::string meshNumbered = mesh + getUniqueID(mesh) + ">|"; NifOgre::NIFLoader::load(meshNumbered); base = mRend.getScene()->createEntity(meshNumbered); + base->setVisibilityFlags(RV_Actors); std::string meshZero = mesh + "0000>|"; if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){ diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index e88557f20..cf9cfab4c 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -4,6 +4,7 @@ #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" #include "../mwgui/window_manager.hpp" +#include "renderconst.hpp" #include #include @@ -211,7 +212,7 @@ void LocalMap::render(const float x, const float y, vp->setOverlaysEnabled(false); vp->setShadowsEnabled(false); vp->setBackgroundColour(ColourValue(0, 0, 0)); - //vp->setVisibilityMask( ... ); + vp->setVisibilityMask(RV_Map); rtt->update(); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index c6fe023d6..3a4d9300d 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -1,5 +1,6 @@ #include "npcanimation.hpp" #include "../mwworld/world.hpp" +#include "renderconst.hpp" using namespace Ogre; @@ -65,6 +66,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O NifOgre::NIFLoader::load(smodel); base = mRend.getScene()->createEntity(smodel); + base->setVisibilityFlags(RV_Actors); base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones //stay in the same place when we skipanim, or open a gui window diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 39ab0b089..bd39e1f5a 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -4,6 +4,7 @@ #include #include +#include "renderconst.hpp" using namespace MWRender; @@ -116,7 +117,8 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) { insert->attachObject(ent); - ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); /// \todo config value + ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); + ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } else { @@ -158,6 +160,8 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale()); + sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); + mRenderer.getScene()->destroyEntity(ent); } } diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp new file mode 100644 index 000000000..5e1c6c7bb --- /dev/null +++ b/apps/openmw/mwrender/renderconst.hpp @@ -0,0 +1,44 @@ +#ifndef GAME_RENDER_CONST_H +#define GAME_RENDER_CONST_H + +#include + +namespace MWRender +{ + +// Render queue groups +/// \todo + +// Visibility flags +enum VisibilityFlags +{ + // Terrain + RV_Terrain = 1, + + // Statics (e.g. trees, houses) + RV_Statics = 2, + + // Small statics + RV_StaticsSmall = 4, + + // Water + RV_Water = 8, + + // Actors (player, npcs, creatures) + RV_Actors = 16, + + // Misc objects (containers, dynamic objects) + RV_Misc = 32, + + RV_Sky = 64, + + RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water, + + /// \todo markers (normally hidden) + + RV_All = 255 +}; + +} + +#endif diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 5dc41dc4b..608ae441b 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -112,8 +112,7 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store) void RenderingManager::removeWater () { if(mWater){ - delete mWater; - mWater = 0; + mWater->setActive(false); } } @@ -188,8 +187,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ mWater = new MWRender::Water(mRendering.getCamera(), store->cell); else mWater->changeCell(store->cell); - //else - + mWater->setActive(true); } else removeWater(); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 781f7abd5..8e774eb08 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -12,7 +12,7 @@ #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" -#include "occlusionquery.hpp" +#include "renderconst.hpp" using namespace MWRender; using namespace Ogre; @@ -92,6 +92,7 @@ void BillboardObject::init(const String& textureName, mBBSet->setRenderQueueGroup(RENDER_QUEUE_MAIN+2); mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON); mBBSet->setCommonDirection( -position.normalisedCopy() ); + mBBSet->setVisibilityFlags(RV_Sky); mNode = rootNode->createChildSceneNode(); mNode->setPosition(finalPosition); mNode->attachObject(mBBSet); @@ -376,6 +377,7 @@ void SkyManager::create() MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif"); Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif"); night1_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+1); + night1_ent->setVisibilityFlags(RV_Sky); mAtmosphereNight = mRootNode->createChildSceneNode(); mAtmosphereNight->attachObject(night1_ent); @@ -449,6 +451,7 @@ void SkyManager::create() ModVertexAlpha(atmosphere_ent, 0); atmosphere_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY); + atmosphere_ent->setVisibilityFlags(RV_Sky); mAtmosphereDay = mRootNode->createChildSceneNode(); mAtmosphereDay->attachObject(atmosphere_ent); mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial(); @@ -485,6 +488,7 @@ void SkyManager::create() // Clouds NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif"); Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif"); + clouds_ent->setVisibilityFlags(RV_Sky); clouds_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+5); SceneNode* clouds_node = mRootNode->createChildSceneNode(); clouds_node->attachObject(clouds_ent); diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 887721565..6c11f7485 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -6,6 +6,7 @@ #include "terrainmaterial.hpp" #include "terrain.hpp" +#include "renderconst.hpp" using namespace Ogre; @@ -159,6 +160,7 @@ namespace MWRender x * numTextures, y * numTextures, numTextures, indexes); + terrain->setVisibilityFlags(RV_Terrain); if ( land && land->landData->usingColours ) { diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index c19a487ab..0ef914210 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -8,7 +8,8 @@ namespace MWRender Water::Water (Ogre::Camera *camera, const ESM::Cell* cell) : mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()), - mIsUnderwater(false) + mIsUnderwater(false), mReflectDistance(0), mVisibilityFlags(0), mOldCameraFarClip(0), + mReflectionTarget(0), mRefractionTarget(0), mActive(1) { try { @@ -25,9 +26,16 @@ Water::Water (Ogre::Camera *camera, const ESM::Cell* cell) : MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,5, Vector3::UNIT_Z); mWater = mSceneManager->createEntity("water"); - + mWater->setVisibilityFlags(RV_Water); mWater->setMaterialName("Examples/Water0"); + mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") + + RV_Statics * Settings::Manager::getBool("reflect statics", "Water") + + RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water") + + RV_Actors * Settings::Manager::getBool("reflect actors", "Water") + + RV_Misc * Settings::Manager::getBool("reflect misc", "Water"); + mReflectDistance = Settings::Manager::getInt("reflect distance", "Water"); + mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); mWaterNode->setPosition(0, mTop, 0); @@ -43,7 +51,7 @@ Water::Water (Ogre::Camera *camera, const ESM::Cell* cell) : { if (i==0 && !Settings::Manager::getBool("reflection", "Water")) continue; if (i==1 && !Settings::Manager::getBool("refraction", "Water")) continue; - + TexturePtr tex = TextureManager::getSingleton().createManual(i == 0 ? "WaterReflection" : "WaterRefraction", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_R8G8B8, TU_RENDERTARGET); @@ -52,7 +60,7 @@ Water::Water (Ogre::Camera *camera, const ESM::Cell* cell) : vp->setOverlaysEnabled(false); vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f)); vp->setShadowsEnabled(false); - //vp->setVisibilityMask( ... ); + vp->setVisibilityMask( (i == 0) ? mVisibilityFlags : RV_All); rtt->addListener(this); rtt->setActive(true); @@ -61,6 +69,13 @@ Water::Water (Ogre::Camera *camera, const ESM::Cell* cell) : } } +void Water::setActive(bool active) +{ + mActive = active; + if (mReflectionTarget) mReflectionTarget->setActive(active); + if (mRefractionTarget) mRefractionTarget->setActive(active); + mWater->setVisible(active); +} Water::~Water() { @@ -91,11 +106,13 @@ void Water::setHeight(const float height) void Water::toggle() { - mWater->setVisible(!mWater->getVisible()); + if (mActive) + mWater->setVisible(!mWater->getVisible()); } void Water::checkUnderwater(float y) { + if (!mActive) return; if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID) { try { @@ -122,6 +139,10 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) { mWater->setVisible(false); + mOldCameraFarClip = mCamera->getFarClipDistance(); + if (mReflectDistance != 0) + mCamera->setFarClipDistance(mReflectDistance); + if (evt.source == mReflectionTarget) { mCamera->enableCustomNearClipPlane(mWaterPlane); @@ -133,6 +154,8 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) { mWater->setVisible(true); + mCamera->setFarClipDistance(mOldCameraFarClip); + if (evt.source == mReflectionTarget) { mCamera->disableReflection(); diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 6f3c4a6c3..44f765a94 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -4,6 +4,8 @@ #include #include +#include "renderconst.hpp" + namespace MWRender { /// Water rendering @@ -19,6 +21,7 @@ namespace MWRender { Ogre::Entity *mWater; bool mIsUnderwater; + bool mActive; int mTop; Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY); @@ -30,10 +33,16 @@ namespace MWRender { Ogre::RenderTarget* mReflectionTarget; Ogre::RenderTarget* mRefractionTarget; + int mVisibilityFlags; + int mReflectDistance; + int mOldCameraFarClip; + public: Water (Ogre::Camera *camera, const ESM::Cell* cell); ~Water(); + void setActive(bool active); + void toggle(); void checkUnderwater(float y); diff --git a/files/settings-default.cfg b/files/settings-default.cfg index ec105c8f3..d9c908883 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -49,3 +49,16 @@ reflection = false refraction = false rtt size = 256 + +# 0 unlimited +reflect distance = 0 + +reflect terrain = true + +reflect statics = true + +reflect small statics = false + +reflect actors = true + +reflect misc = false