mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 18:09:39 +00:00
re-use bzzts waterplane overlay for debug; makes it easier to test. To use this, set the env OPENMW_WATER_CULLING_DEBUG=1; You will see blue rectangles corresponding to water outlines. Once there are no more outlines, water is culled. You can further see this by pressing F3 3 times to check the the amount of quads. Before culling it should be around 1600, after culling it should drop to 0.
This commit is contained in:
parent
407fbe320e
commit
48713915cb
4 changed files with 66 additions and 7 deletions
|
@ -227,6 +227,8 @@ osg::ref_ptr<osg::Node> ChunkManager::createChunk(float chunkSize, const osg::Ve
|
||||||
transform->addChild(geometry);
|
transform->addChild(geometry);
|
||||||
transform->getBound();
|
transform->getBound();
|
||||||
|
|
||||||
|
geometry->setupWaterBoundingBox(-1, chunkSize * mStorage->getCellWorldSize() / numVerts);
|
||||||
|
|
||||||
if (mSceneManager->getIncrementalCompileOperation())
|
if (mSceneManager->getIncrementalCompileOperation())
|
||||||
{
|
{
|
||||||
mSceneManager->getIncrementalCompileOperation()->add(geometry);
|
mSceneManager->getIncrementalCompileOperation()->add(geometry);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "quadtreeworld.hpp"
|
#include "quadtreeworld.hpp"
|
||||||
|
|
||||||
#include <osgUtil/CullVisitor>
|
#include <osgUtil/CullVisitor>
|
||||||
|
#include <osg/ShapeDrawable>
|
||||||
|
#include <osg/PolygonMode>
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -13,6 +15,7 @@
|
||||||
#include "viewdata.hpp"
|
#include "viewdata.hpp"
|
||||||
#include "chunkmanager.hpp"
|
#include "chunkmanager.hpp"
|
||||||
#include "compositemaprenderer.hpp"
|
#include "compositemaprenderer.hpp"
|
||||||
|
#include "terraindrawable.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -323,9 +326,8 @@ void updateWaterCullingView(HeightCullCallback* callback, ViewData* vd, osgUtil:
|
||||||
for (unsigned int i=0; i<vd->getNumEntries(); ++i)
|
for (unsigned int i=0; i<vd->getNumEntries(); ++i)
|
||||||
{
|
{
|
||||||
ViewData::Entry& entry = vd->getEntry(i);
|
ViewData::Entry& entry = vd->getEntry(i);
|
||||||
osg::BoundingBox bb = static_cast<osg::Drawable*>(entry.mRenderingNode->asGroup()->getChild(0))->getBoundingBox();
|
osg::BoundingBox bb = static_cast<TerrainDrawable*>(entry.mRenderingNode->asGroup()->getChild(0))->getWaterBoundingBox();
|
||||||
float minZ = bb._min.z();
|
if (!bb.valid())
|
||||||
if (minZ > highZ)
|
|
||||||
continue;
|
continue;
|
||||||
osg::Vec3f ofs (entry.mNode->getCenter().x()*cellworldsize, entry.mNode->getCenter().y()*cellworldsize, 0.f);
|
osg::Vec3f ofs (entry.mNode->getCenter().x()*cellworldsize, entry.mNode->getCenter().y()*cellworldsize, 0.f);
|
||||||
bb._min += ofs; bb._max += ofs;
|
bb._min += ofs; bb._max += ofs;
|
||||||
|
@ -333,8 +335,30 @@ void updateWaterCullingView(HeightCullCallback* callback, ViewData* vd, osgUtil:
|
||||||
bb._max.z() = highZ;
|
bb._max.z() = highZ;
|
||||||
if (cv->isCulled(bb))
|
if (cv->isCulled(bb))
|
||||||
continue;
|
continue;
|
||||||
lowZ = minZ;
|
lowZ = bb._min.z();
|
||||||
break;
|
|
||||||
|
static bool debug = getenv("OPENMW_WATER_CULLING_DEBUG") != nullptr;
|
||||||
|
if (!debug)
|
||||||
|
break;
|
||||||
|
osg::Box* b = new osg::Box;
|
||||||
|
b->set(bb.center(), bb._max - bb.center());
|
||||||
|
osg::ShapeDrawable* drw = new osg::ShapeDrawable(b);
|
||||||
|
static osg::ref_ptr<osg::StateSet> stateset = nullptr;
|
||||||
|
if (!stateset)
|
||||||
|
{
|
||||||
|
stateset = new osg::StateSet;
|
||||||
|
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
|
||||||
|
stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
||||||
|
stateset->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE), osg::StateAttribute::ON);
|
||||||
|
osg::Material* m = new osg::Material;
|
||||||
|
m->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(0,0,1,1));
|
||||||
|
m->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0,0,0,1));
|
||||||
|
m->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(0,0,0,1));
|
||||||
|
stateset->setAttributeAndModes(m, osg::StateAttribute::ON);
|
||||||
|
stateset->setRenderBinDetails(100,"RenderBin");
|
||||||
|
}
|
||||||
|
drw->setStateSet(stateset);
|
||||||
|
drw->accept(*cv);
|
||||||
}
|
}
|
||||||
callback->setLowZ(lowZ);
|
callback->setLowZ(lowZ);
|
||||||
cv->popCurrentMask();
|
cv->popCurrentMask();
|
||||||
|
|
|
@ -10,6 +10,16 @@
|
||||||
namespace Terrain
|
namespace Terrain
|
||||||
{
|
{
|
||||||
|
|
||||||
|
TerrainDrawable::TerrainDrawable()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TerrainDrawable::~TerrainDrawable()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
TerrainDrawable::TerrainDrawable(const TerrainDrawable ©, const osg::CopyOp ©op)
|
TerrainDrawable::TerrainDrawable(const TerrainDrawable ©, const osg::CopyOp ©op)
|
||||||
: osg::Geometry(copy, copyop)
|
: osg::Geometry(copy, copyop)
|
||||||
, mPasses(copy.mPasses)
|
, mPasses(copy.mPasses)
|
||||||
|
@ -118,6 +128,25 @@ void TerrainDrawable::setLightListCallback(SceneUtil::LightListCallback *lightLi
|
||||||
mLightListCallback = lightListCallback;
|
mLightListCallback = lightListCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerrainDrawable::setupWaterBoundingBox(float waterheight, float margin)
|
||||||
|
{
|
||||||
|
osg::Vec3Array* vertices = static_cast<osg::Vec3Array*>(getVertexArray());
|
||||||
|
for (unsigned int i=0; i<vertices->size(); ++i)
|
||||||
|
{
|
||||||
|
const osg::Vec3f& vertex = (*vertices)[i];
|
||||||
|
if (vertex.z() <= waterheight)
|
||||||
|
mWaterBoundingBox.expandBy(vertex);
|
||||||
|
}
|
||||||
|
if (mWaterBoundingBox.valid())
|
||||||
|
{
|
||||||
|
const osg::BoundingBox& bb = getBoundingBox();
|
||||||
|
mWaterBoundingBox.xMin() = std::max(bb.xMin(), mWaterBoundingBox.xMin() - margin);
|
||||||
|
mWaterBoundingBox.yMin() = std::max(bb.yMin(), mWaterBoundingBox.yMin() - margin);
|
||||||
|
mWaterBoundingBox.xMax() = std::min(bb.xMax(), mWaterBoundingBox.xMax() + margin);
|
||||||
|
mWaterBoundingBox.xMax() = std::min(bb.xMax(), mWaterBoundingBox.xMax() + margin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TerrainDrawable::compileGLObjects(osg::RenderInfo &renderInfo) const
|
void TerrainDrawable::compileGLObjects(osg::RenderInfo &renderInfo) const
|
||||||
{
|
{
|
||||||
for (PassVector::const_iterator it = mPasses.begin(); it != mPasses.end(); ++it)
|
for (PassVector::const_iterator it = mPasses.begin(); it != mPasses.end(); ++it)
|
||||||
|
|
|
@ -36,8 +36,8 @@ namespace Terrain
|
||||||
virtual const char* className() const { return "TerrainDrawable"; }
|
virtual const char* className() const { return "TerrainDrawable"; }
|
||||||
virtual const char* libraryName() const { return "Terrain"; }
|
virtual const char* libraryName() const { return "Terrain"; }
|
||||||
|
|
||||||
TerrainDrawable() = default;
|
TerrainDrawable();
|
||||||
~TerrainDrawable() = default;
|
~TerrainDrawable(); // has to be defined in the cpp file because we only forward declared some members.
|
||||||
TerrainDrawable(const TerrainDrawable& copy, const osg::CopyOp& copyop);
|
TerrainDrawable(const TerrainDrawable& copy, const osg::CopyOp& copyop);
|
||||||
|
|
||||||
virtual void accept(osg::NodeVisitor &nv);
|
virtual void accept(osg::NodeVisitor &nv);
|
||||||
|
@ -52,10 +52,14 @@ namespace Terrain
|
||||||
|
|
||||||
virtual void compileGLObjects(osg::RenderInfo& renderInfo) const;
|
virtual void compileGLObjects(osg::RenderInfo& renderInfo) const;
|
||||||
|
|
||||||
|
void setupWaterBoundingBox(float waterheight, float margin);
|
||||||
|
const osg::BoundingBox& getWaterBoundingBox() const { return mWaterBoundingBox; }
|
||||||
|
|
||||||
void setCompositeMap(CompositeMap* map) { mCompositeMap = map; }
|
void setCompositeMap(CompositeMap* map) { mCompositeMap = map; }
|
||||||
void setCompositeMapRenderer(CompositeMapRenderer* renderer) { mCompositeMapRenderer = renderer; }
|
void setCompositeMapRenderer(CompositeMapRenderer* renderer) { mCompositeMapRenderer = renderer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
osg::BoundingBox mWaterBoundingBox;
|
||||||
PassVector mPasses;
|
PassVector mPasses;
|
||||||
|
|
||||||
osg::ref_ptr<osg::ClusterCullingCallback> mClusterCullingCallback;
|
osg::ref_ptr<osg::ClusterCullingCallback> mClusterCullingCallback;
|
||||||
|
|
Loading…
Reference in a new issue