mirror of
https://github.com/OpenMW/openmw.git
synced 2025-10-16 01:46:40 +00:00
removes mutex, and uses double buffering to avoid writing on a resource that will be read by the draw thread
changes when the buffers are reset -> at the end of the draw, because that's when we are certain the data isn't needed anymore removed useless variable fixed typo include osg::vec3 instead of osg vec3f compile linux compile ? applied clang format to the new files
This commit is contained in:
parent
2a980ecb50
commit
bd1bbc0ab8
4 changed files with 160 additions and 151 deletions
|
@ -1,14 +1,14 @@
|
|||
#include "debugdraw.hpp"
|
||||
#include <components/sceneutil/nodecallback.hpp>
|
||||
#include <components/shader/shadermanager.hpp>
|
||||
|
||||
|
||||
#include <osg/Uniform>
|
||||
#include <osg/Drawable>
|
||||
#include <osg/Program>
|
||||
#include <osg/Array>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Drawable>
|
||||
#include <osg/GLExtensions>
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Program>
|
||||
#include <osg/Uniform>
|
||||
#include <osg/Vec3>
|
||||
|
||||
static osg::Vec3 sphereCoordToCartesian(float theta, float phi, float r)
|
||||
{
|
||||
|
@ -63,7 +63,6 @@ static void generateWireCube(osg::Geometry& geom, float dim)
|
|||
geom.addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertices->size()));
|
||||
}
|
||||
|
||||
|
||||
static void generateCube(osg::Geometry& geom, float dim)
|
||||
{
|
||||
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
|
||||
|
@ -109,7 +108,6 @@ static void generateCube(osg::Geometry& geom, float dim)
|
|||
geom.addPrimitiveSet(indices);
|
||||
}
|
||||
|
||||
|
||||
static void generateCylinder(osg::Geometry& geom, float radius, float height, int subdiv)
|
||||
{
|
||||
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
|
||||
|
@ -216,6 +214,15 @@ static void generateCylinder(osg::Geometry& geom, float radius, float height, in
|
|||
geom.addPrimitiveSet(indices);
|
||||
}
|
||||
|
||||
static int getIdexBufferReadFromFrame(const long long int& nFrame)
|
||||
{
|
||||
return nFrame % 2;
|
||||
}
|
||||
|
||||
static int getIdexBufferWriteFromFrame(const long long int& nFrame)
|
||||
{
|
||||
return (nFrame + 1) % 2;
|
||||
}
|
||||
|
||||
namespace MWRenderDebug
|
||||
{
|
||||
|
@ -232,7 +239,6 @@ namespace MWRenderDebug
|
|||
{
|
||||
return;
|
||||
}
|
||||
std::lock_guard lock(mDrawCallMutex);
|
||||
|
||||
osg::Uniform* uTrans = const_cast<osg::Uniform*>(stateSet->getUniform("trans"));
|
||||
osg::Uniform* uCol = const_cast<osg::Uniform*>(stateSet->getUniform("color"));
|
||||
|
@ -253,7 +259,7 @@ namespace MWRenderDebug
|
|||
|
||||
ext->glUniform1i(normalAsColorLocation, 0);
|
||||
|
||||
for (const auto& shapeToDraw : mShapsToDraw)
|
||||
for (const auto& shapeToDraw : mShapesToDraw)
|
||||
{
|
||||
osg::Vec3f translation = shapeToDraw.mPosition;
|
||||
osg::Vec3f color = shapeToDraw.mColor;
|
||||
|
@ -276,7 +282,9 @@ namespace MWRenderDebug
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mShapesToDraw.clear();
|
||||
static_cast<osg::Vec3Array*>(mLinesToDraw->getVertexAttribArray(0))->clear();
|
||||
static_cast<osg::Vec3Array*>(mLinesToDraw->getVertexAttribArray(1))->clear();
|
||||
}
|
||||
|
||||
struct DebugLines
|
||||
|
@ -299,40 +307,46 @@ namespace MWRenderDebug
|
|||
|
||||
DebugLines()
|
||||
{
|
||||
mLinesWrite = new osg::Geometry();
|
||||
mLinesRead = new osg::Geometry();
|
||||
mLinesGeom[0] = new osg::Geometry();
|
||||
mLinesGeom[1] = new osg::Geometry();
|
||||
|
||||
makeLineInstance(*mLinesRead);
|
||||
makeLineInstance(*mLinesWrite);
|
||||
makeLineInstance(*mLinesGeom[0]);
|
||||
makeLineInstance(*mLinesGeom[1]);
|
||||
}
|
||||
|
||||
void update(std::mutex& mutex)
|
||||
std::array<osg::ref_ptr<osg::Geometry>, 2> mLinesGeom;
|
||||
};
|
||||
|
||||
class DebugDrawCallback : public SceneUtil::NodeCallback<DebugDrawCallback>
|
||||
{
|
||||
mLinesWrite->removePrimitiveSet(0, 1);
|
||||
mLinesWrite->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0,static_cast<osg::Vec3Array*>(mLinesWrite->getVertexAttribArray(0))->size()));
|
||||
public:
|
||||
DebugDrawCallback(MWRenderDebug::DebugDrawer& debugDrawer) : mDebugDrawer(debugDrawer) {}
|
||||
|
||||
void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
auto lock = std::scoped_lock(mutex);
|
||||
mLinesWrite.swap(mLinesRead);
|
||||
mDebugDrawer.mCurrentFrame = nv->getTraversalNumber();
|
||||
int indexRead = getIdexBufferReadFromFrame(mDebugDrawer.mCurrentFrame);
|
||||
auto& lines = mDebugDrawer.mDebugLines;
|
||||
lines->mLinesGeom[indexRead]->removePrimitiveSet(0, 1);
|
||||
lines->mLinesGeom[indexRead]->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, static_cast<osg::Vec3Array*>(lines->mLinesGeom[indexRead]->getVertexAttribArray(0))->size()));
|
||||
|
||||
nv->pushOntoNodePath(mDebugDrawer.mCustomDebugDrawer[indexRead]);
|
||||
nv->apply(*mDebugDrawer.mCustomDebugDrawer[indexRead]);
|
||||
nv->popFromNodePath();
|
||||
}
|
||||
|
||||
static_cast<osg::Vec3Array*>(mLinesWrite->getVertexAttribArray(0))->clear();
|
||||
static_cast<osg::Vec3Array*>(mLinesWrite->getVertexAttribArray(1))->clear();
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Geometry> mLinesWrite;
|
||||
osg::ref_ptr<osg::Geometry> mLinesRead;
|
||||
MWRenderDebug::DebugDrawer& mDebugDrawer;
|
||||
};
|
||||
}
|
||||
|
||||
MWRenderDebug::DebugDrawer::DebugDrawer(Shader::ShaderManager& shaderManager, osg::ref_ptr<osg::Group> parentNode)
|
||||
{
|
||||
mCurrentFrame = 0;
|
||||
auto vertexShader = shaderManager.getShader("debugDraw_vertex.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::Type::VERTEX);
|
||||
auto fragmentShader = shaderManager.getShader("debugDraw_fragment.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::Type::FRAGMENT);
|
||||
|
||||
auto program = shaderManager.getProgram(vertexShader, fragmentShader);
|
||||
mDebugLines = std::make_unique<DebugLines>();
|
||||
mCustomDebugDrawer = new DebugCustomDraw(mShapesToDrawRead,mDebugLines->mLinesRead, mDrawCallMutex);
|
||||
|
||||
mDebugDrawSceneObjects = new osg::Group;
|
||||
mDebugDrawSceneObjects->setCullingActive(false);
|
||||
|
@ -350,44 +364,41 @@ MWRenderDebug::DebugDrawer::DebugDrawer(Shader::ShaderManager& shaderManager,osg
|
|||
cubeGeometry->setSupportsDisplayList(false);
|
||||
cubeGeometry->setUseVertexBufferObjects(true);
|
||||
generateCube(*cubeGeometry, 1.);
|
||||
mCustomDebugDrawer ->mCubeGeometry = cubeGeometry;
|
||||
|
||||
auto cylinderGeom = new osg::Geometry;
|
||||
cylinderGeom->setSupportsDisplayList(false);
|
||||
cylinderGeom->setUseVertexBufferObjects(true);
|
||||
generateCylinder(*cylinderGeom, .5, 1., 20);
|
||||
mCustomDebugDrawer ->mCylinderGeometry = cylinderGeom;
|
||||
|
||||
auto wireCube = new osg::Geometry;
|
||||
wireCube->setSupportsDisplayList(false);
|
||||
wireCube->setUseVertexBufferObjects(true);
|
||||
generateWireCube(*wireCube, 1.);
|
||||
mCustomDebugDrawer->mWireCubeGeometry = wireCube;
|
||||
mCustomDebugDrawer->setStateSet(stateset);
|
||||
|
||||
mDebugDrawSceneObjects->addChild(mCustomDebugDrawer);
|
||||
for (unsigned long i = 0; i < mShapesToDraw.size(); i++)
|
||||
{
|
||||
mCustomDebugDrawer[i] = new DebugCustomDraw(mShapesToDraw[i], mDebugLines->mLinesGeom[i]);
|
||||
mCustomDebugDrawer[i]->setStateSet(stateset);
|
||||
mCustomDebugDrawer[i]->mWireCubeGeometry = wireCube;
|
||||
mCustomDebugDrawer[i]->mCubeGeometry = cubeGeometry;
|
||||
mCustomDebugDrawer[i]->mCylinderGeometry = cylinderGeom;
|
||||
}
|
||||
mDebugDrawSceneObjects->addCullCallback(new DebugDrawCallback(*this));
|
||||
|
||||
parentNode->addChild(mDebugDrawSceneObjects);
|
||||
}
|
||||
|
||||
MWRenderDebug::DebugDrawer::~DebugDrawer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MWRenderDebug::DebugDrawer::update()
|
||||
{
|
||||
{
|
||||
std::lock_guard lock(mDrawCallMutex);
|
||||
mShapesToDrawRead.swap(mShapesToDrawWrite);
|
||||
}
|
||||
mShapesToDrawWrite.clear();
|
||||
mDebugLines->update(mDrawCallMutex);
|
||||
}
|
||||
|
||||
void MWRenderDebug::DebugDrawer::drawCube(osg::Vec3f mPosition, osg::Vec3f mDims, osg::Vec3f mColor)
|
||||
{
|
||||
mShapesToDrawWrite.push_back({mPosition, mDims, mColor, DrawShape::Cube});
|
||||
mShapesToDraw[getIdexBufferWriteFromFrame(this->mCurrentFrame)].push_back({ mPosition, mDims, mColor, DrawShape::Cube });
|
||||
}
|
||||
|
||||
void MWRenderDebug::DebugDrawer::drawCubeMinMax(osg::Vec3f min, osg::Vec3f max, osg::Vec3f color)
|
||||
|
@ -399,13 +410,14 @@ void MWRenderDebug::DebugDrawer::drawCubeMinMax(osg::Vec3f min, osg::Vec3f max,
|
|||
|
||||
void MWRenderDebug::DebugDrawer::addDrawCall(const DrawCall& draw)
|
||||
{
|
||||
mShapesToDrawWrite.push_back(draw);
|
||||
mShapesToDraw[getIdexBufferWriteFromFrame(this->mCurrentFrame)].push_back(draw);
|
||||
}
|
||||
|
||||
void MWRenderDebug::DebugDrawer::addLine(const osg::Vec3& start, const osg::Vec3& end, const osg::Vec3 color)
|
||||
{
|
||||
auto vertices = static_cast<osg::Vec3Array*>(mDebugLines->mLinesWrite->getVertexAttribArray(0));
|
||||
auto colors = static_cast<osg::Vec3Array*>(mDebugLines->mLinesWrite->getVertexAttribArray(1));
|
||||
const int indexWrite = getIdexBufferWriteFromFrame(this->mCurrentFrame);
|
||||
auto vertices = static_cast<osg::Vec3Array*>(mDebugLines->mLinesGeom[indexWrite]->getVertexAttribArray(0));
|
||||
auto colors = static_cast<osg::Vec3Array*>(mDebugLines->mLinesGeom[indexWrite]->getVertexAttribArray(1));
|
||||
|
||||
vertices->push_back(start);
|
||||
vertices->push_back(end);
|
||||
|
@ -414,5 +426,4 @@ void MWRenderDebug::DebugDrawer::addLine(const osg::Vec3& start, const osg::Vec3
|
|||
colors->push_back(color);
|
||||
colors->push_back(color);
|
||||
colors->dirty();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef OPENMW_COMPONENTS_DEBUG_DEBUGDRAW_H
|
||||
#define OPENMW_COMPONENTS_DEBUG_DEBUGDRAW_H
|
||||
|
||||
#include <osg/Vec3f>
|
||||
#include <memory>
|
||||
#include <osg/Drawable>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/ref_ptr>
|
||||
#include <vector>
|
||||
|
||||
|
@ -9,6 +11,8 @@ namespace osg
|
|||
{
|
||||
class Group;
|
||||
class Geometry;
|
||||
class Geometry;
|
||||
class RenderInfo;
|
||||
}
|
||||
namespace Shader
|
||||
{
|
||||
|
@ -24,6 +28,8 @@ namespace MWRenderDebug
|
|||
static const osg::Vec3f colorBlack = osg::Vec3(0., 0., 0.);
|
||||
static const osg::Vec3f colorDarkGrey = osg::Vec3(0.25, 0.25, 0.25);
|
||||
|
||||
class DebugDrawCallback;
|
||||
|
||||
enum class DrawShape
|
||||
{
|
||||
Cube,
|
||||
|
@ -47,22 +53,15 @@ namespace MWRenderDebug
|
|||
class DebugCustomDraw : public osg::Drawable
|
||||
{
|
||||
public:
|
||||
DebugCustomDraw( std::vector<DrawCall>& cubesToDraw,osg::ref_ptr<osg::Geometry>& linesToDraw ,std::mutex& mutex) : mShapsToDraw(cubesToDraw),mLinesToDraw(linesToDraw), mDrawCallMutex(mutex) {}
|
||||
DebugCustomDraw(std::vector<DrawCall>& cubesToDraw, osg::ref_ptr<osg::Geometry>& linesToDraw) : mShapesToDraw(cubesToDraw), mLinesToDraw(linesToDraw) {}
|
||||
|
||||
std::vector<DrawCall>& mShapsToDraw;
|
||||
std::vector<DrawCall>& mShapesToDraw;
|
||||
osg::ref_ptr<osg::Geometry>& mLinesToDraw;
|
||||
|
||||
std::mutex& mDrawCallMutex;
|
||||
|
||||
osg::ref_ptr<osg::Geometry> mCubeGeometry;
|
||||
osg::ref_ptr<osg::Geometry> mCylinderGeometry;
|
||||
osg::ref_ptr<osg::Geometry> mWireCubeGeometry;
|
||||
|
||||
virtual osg::BoundingSphere computeBound() const
|
||||
{
|
||||
return osg::BoundingSphere();
|
||||
}
|
||||
|
||||
virtual void drawImplementation(osg::RenderInfo&) const;
|
||||
};
|
||||
|
||||
|
@ -70,6 +69,8 @@ namespace MWRenderDebug
|
|||
|
||||
struct DebugDrawer
|
||||
{
|
||||
friend DebugDrawCallback;
|
||||
|
||||
DebugDrawer(Shader::ShaderManager& shaderManager, osg::ref_ptr<osg::Group> parentNode);
|
||||
~DebugDrawer();
|
||||
|
||||
|
@ -80,14 +81,12 @@ namespace MWRenderDebug
|
|||
void addLine(const osg::Vec3& start, const osg::Vec3& end, const osg::Vec3 color = colorWhite);
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<DebugLines> mDebugLines;
|
||||
|
||||
std::vector<DrawCall> mShapesToDrawRead;
|
||||
std::vector<DrawCall> mShapesToDrawWrite;
|
||||
std::mutex mDrawCallMutex;
|
||||
std::array<std::vector<DrawCall>, 2> mShapesToDraw;
|
||||
long long int mCurrentFrame;
|
||||
|
||||
osg::ref_ptr<DebugCustomDraw> mCustomDebugDrawer;
|
||||
std::array<osg::ref_ptr<DebugCustomDraw>, 2> mCustomDebugDrawer;
|
||||
osg::ref_ptr<osg::Group> mDebugDrawSceneObjects;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#version 330 compatibility
|
||||
|
||||
|
||||
uniform mat4 projectionMatrix;
|
||||
|
||||
uniform vec3 color;
|
||||
|
|
Loading…
Reference in a new issue