1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-20 19:39:41 +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:
Bret Curtis 2020-04-23 11:12:10 +02:00
parent 407fbe320e
commit 48713915cb
4 changed files with 66 additions and 7 deletions

View file

@ -227,6 +227,8 @@ osg::ref_ptr<osg::Node> ChunkManager::createChunk(float chunkSize, const osg::Ve
transform->addChild(geometry);
transform->getBound();
geometry->setupWaterBoundingBox(-1, chunkSize * mStorage->getCellWorldSize() / numVerts);
if (mSceneManager->getIncrementalCompileOperation())
{
mSceneManager->getIncrementalCompileOperation()->add(geometry);

View file

@ -1,6 +1,8 @@
#include "quadtreeworld.hpp"
#include <osgUtil/CullVisitor>
#include <osg/ShapeDrawable>
#include <osg/PolygonMode>
#include <limits>
#include <sstream>
@ -13,6 +15,7 @@
#include "viewdata.hpp"
#include "chunkmanager.hpp"
#include "compositemaprenderer.hpp"
#include "terraindrawable.hpp"
namespace
{
@ -323,9 +326,8 @@ void updateWaterCullingView(HeightCullCallback* callback, ViewData* vd, osgUtil:
for (unsigned int i=0; i<vd->getNumEntries(); ++i)
{
ViewData::Entry& entry = vd->getEntry(i);
osg::BoundingBox bb = static_cast<osg::Drawable*>(entry.mRenderingNode->asGroup()->getChild(0))->getBoundingBox();
float minZ = bb._min.z();
if (minZ > highZ)
osg::BoundingBox bb = static_cast<TerrainDrawable*>(entry.mRenderingNode->asGroup()->getChild(0))->getWaterBoundingBox();
if (!bb.valid())
continue;
osg::Vec3f ofs (entry.mNode->getCenter().x()*cellworldsize, entry.mNode->getCenter().y()*cellworldsize, 0.f);
bb._min += ofs; bb._max += ofs;
@ -333,8 +335,30 @@ void updateWaterCullingView(HeightCullCallback* callback, ViewData* vd, osgUtil:
bb._max.z() = highZ;
if (cv->isCulled(bb))
continue;
lowZ = minZ;
break;
lowZ = bb._min.z();
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);
cv->popCurrentMask();

View file

@ -10,6 +10,16 @@
namespace Terrain
{
TerrainDrawable::TerrainDrawable()
{
}
TerrainDrawable::~TerrainDrawable()
{
}
TerrainDrawable::TerrainDrawable(const TerrainDrawable &copy, const osg::CopyOp &copyop)
: osg::Geometry(copy, copyop)
, mPasses(copy.mPasses)
@ -118,6 +128,25 @@ void TerrainDrawable::setLightListCallback(SceneUtil::LightListCallback *lightLi
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
{
for (PassVector::const_iterator it = mPasses.begin(); it != mPasses.end(); ++it)

View file

@ -36,8 +36,8 @@ namespace Terrain
virtual const char* className() const { return "TerrainDrawable"; }
virtual const char* libraryName() const { return "Terrain"; }
TerrainDrawable() = default;
~TerrainDrawable() = default;
TerrainDrawable();
~TerrainDrawable(); // has to be defined in the cpp file because we only forward declared some members.
TerrainDrawable(const TerrainDrawable& copy, const osg::CopyOp& copyop);
virtual void accept(osg::NodeVisitor &nv);
@ -52,10 +52,14 @@ namespace Terrain
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 setCompositeMapRenderer(CompositeMapRenderer* renderer) { mCompositeMapRenderer = renderer; }
private:
osg::BoundingBox mWaterBoundingBox;
PassVector mPasses;
osg::ref_ptr<osg::ClusterCullingCallback> mClusterCullingCallback;