From 6442d49e1630daaa9f5ef74f8dc2eaee1de68730 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 4 Apr 2012 18:53:40 +0200 Subject: [PATCH] render queue groups, sky fix --- apps/openmw/mwrender/creatureanimation.cpp | 21 +++++++++++++++++++++ apps/openmw/mwrender/npcanimation.cpp | 20 ++++++++++++++++++++ apps/openmw/mwrender/objects.cpp | 20 ++++++++++++++++++++ apps/openmw/mwrender/occlusionquery.cpp | 7 ++++--- apps/openmw/mwrender/renderconst.hpp | 13 ++++++++++++- apps/openmw/mwrender/sky.cpp | 16 ++++++++-------- apps/openmw/mwrender/terrain.cpp | 1 + apps/openmw/mwrender/water.cpp | 3 ++- 8 files changed, 88 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index 4c2ce8399..e0eb5ccc2 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -22,6 +22,27 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environme NifOgre::NIFLoader::load(meshNumbered); base = mRend.getScene()->createEntity(meshNumbered); base->setVisibilityFlags(RV_Actors); + + bool transparent = false; + for (unsigned int i=0; igetNumSubEntities(); ++i) + { + Ogre::MaterialPtr mat = base->getSubEntity(i)->getMaterial(); + Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); + while (techIt.hasMoreElements()) + { + Ogre::Technique* tech = techIt.getNext(); + Ogre::Technique::PassIterator passIt = tech->getPassIterator(); + while (passIt.hasMoreElements()) + { + Ogre::Pass* pass = passIt.getNext(); + + if (pass->getDepthWriteEnabled() == false) + transparent = true; + } + } + } + base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); + std::string meshZero = mesh + "0000>|"; if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){ diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 3a4d9300d..9de5705e3 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -67,6 +67,26 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O base = mRend.getScene()->createEntity(smodel); base->setVisibilityFlags(RV_Actors); + bool transparent = false; + for (unsigned int i=0; igetNumSubEntities(); ++i) + { + Ogre::MaterialPtr mat = base->getSubEntity(i)->getMaterial(); + Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); + while (techIt.hasMoreElements()) + { + Ogre::Technique* tech = techIt.getNext(); + Ogre::Technique::PassIterator passIt = tech->getPassIterator(); + while (passIt.hasMoreElements()) + { + Ogre::Pass* pass = passIt.getNext(); + + if (pass->getDepthWriteEnabled() == false) + transparent = true; + } + } + } + base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); + 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 bd39e1f5a..9d743fe90 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -113,6 +113,26 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) bounds.scale(insert->getScale()); mBounds[ptr.getCell()].merge(bounds); + bool transparent = false; + for (unsigned int i=0; igetNumSubEntities(); ++i) + { + Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial(); + Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); + while (techIt.hasMoreElements()) + { + Ogre::Technique* tech = techIt.getNext(); + Ogre::Technique::PassIterator passIt = tech->getPassIterator(); + while (passIt.hasMoreElements()) + { + Ogre::Pass* pass = passIt.getNext(); + + if (pass->getDepthWriteEnabled() == false) + transparent = true; + } + } + } + ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); + if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects")) { insert->attachObject(ent); diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index 781b522b6..ff1ce82e7 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -1,4 +1,5 @@ #include "occlusionquery.hpp" +#include "renderconst.hpp" #include #include @@ -39,8 +40,8 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod return; } - // This means that everything up to RENDER_QUEUE_MAIN can occlude the objects that are tested - const int queue = RENDER_QUEUE_MAIN+1; + // This means that everything up to RQG_Main can occlude the objects that are tested + const int queue = RQG_Main+1; MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting"); MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels"); @@ -152,7 +153,7 @@ void OcclusionQuery::renderQueueEnded(uint8 queueGroupId, const String& invocati * this can happen for example if the object that is tested is outside of the view frustum * to prevent this, check if the queries have been performed after everything has been rendered and if not, start them manually */ - if (queueGroupId == RENDER_QUEUE_SKIES_LATE) + if (queueGroupId == RQG_SkiesLate) { if (mWasVisible == false && mDoQuery) { diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp index 5e1c6c7bb..6eba8d92e 100644 --- a/apps/openmw/mwrender/renderconst.hpp +++ b/apps/openmw/mwrender/renderconst.hpp @@ -7,7 +7,18 @@ namespace MWRender { // Render queue groups -/// \todo +enum RenderQueueGroups +{ + // Sky early (atmosphere, clouds, moons) + RQG_SkiesEarly = Ogre::RENDER_QUEUE_SKIES_EARLY, + + RQG_Main = Ogre::RENDER_QUEUE_MAIN, + + RQG_Alpha = Ogre::RENDER_QUEUE_7, + + // Sky late (sun & sun flare) + RQG_SkiesLate = Ogre::RENDER_QUEUE_SKIES_LATE +}; // Visibility flags enum VisibilityFlags diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 8e774eb08..7ccbaf8e2 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -89,7 +89,6 @@ void BillboardObject::init(const String& textureName, /// \todo These billboards are not 100% correct, might want to revisit them later mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1); mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize); - mBBSet->setRenderQueueGroup(RENDER_QUEUE_MAIN+2); mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON); mBBSet->setCommonDirection( -position.normalisedCopy() ); mBBSet->setVisibilityFlags(RV_Sky); @@ -359,15 +358,16 @@ void SkyManager::create() mSecunda = new Moon("textures\\tx_secunda_full.dds", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode); mSecunda->setType(Moon::Type_Secunda); - mSecunda->setRenderQueue(RENDER_QUEUE_SKIES_EARLY+4); + mSecunda->setRenderQueue(RQG_SkiesEarly+4); mMasser = new Moon("textures\\tx_masser_full.dds", 0.75, Vector3(-0.4, 0.4, 0.5), mRootNode); - mMasser->setRenderQueue(RENDER_QUEUE_SKIES_EARLY+3); + mMasser->setRenderQueue(RQG_SkiesEarly+3); mMasser->setType(Moon::Type_Masser); mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, Vector3(0.4, 0.4, 0.4), mRootNode); + mSun->setRenderQueue(RQG_SkiesEarly+4); mSunGlare = new BillboardObject("textures\\tx_sun_flash_grey_05.dds", 3, Vector3(0.4, 0.4, 0.4), mRootNode); - mSunGlare->setRenderQueue(RENDER_QUEUE_SKIES_LATE); + mSunGlare->setRenderQueue(RQG_SkiesLate); HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); @@ -376,7 +376,7 @@ void SkyManager::create() /// \todo sky_night_02.nif (available in Bloodmoon) 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->setRenderQueueGroup(RQG_SkiesEarly+1); night1_ent->setVisibilityFlags(RV_Sky); mAtmosphereNight = mRootNode->createChildSceneNode(); @@ -450,7 +450,7 @@ void SkyManager::create() ModVertexAlpha(atmosphere_ent, 0); - atmosphere_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY); + atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly); atmosphere_ent->setVisibilityFlags(RV_Sky); mAtmosphereDay = mRootNode->createChildSceneNode(); mAtmosphereDay->attachObject(atmosphere_ent); @@ -489,7 +489,7 @@ void SkyManager::create() 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); + clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5); SceneNode* clouds_node = mRootNode->createChildSceneNode(); clouds_node->attachObject(clouds_ent); mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial(); @@ -738,7 +738,7 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather) strength = 1.f; mSunGlare->setVisibility(weather.mGlareView * mGlareFade * strength); - mSun->setVisibility(mGlareFade >= 0.5 ? weather.mGlareView * mGlareFade * strength : 0); + mSun->setVisibility(weather.mGlareView); mAtmosphereNight->setVisible(weather.mNight && mEnabled); } diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 6c11f7485..ed2c983dd 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -161,6 +161,7 @@ namespace MWRender numTextures, indexes); terrain->setVisibilityFlags(RV_Terrain); + terrain->setRenderQueueGroup(RQG_Main); if ( land && land->landData->usingColours ) { diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index df6d1a97a..1983616d6 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -26,10 +26,11 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : mWaterPlane = Plane(Vector3::UNIT_Y, 0); - 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); + MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Z); mWater = mSceneManager->createEntity("water"); mWater->setVisibilityFlags(RV_Water); + mWater->setRenderQueueGroup(RQG_Alpha); mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") + RV_Statics * Settings::Manager::getBool("reflect statics", "Water")