1
0
Fork 0
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:
florent.teppe 2022-08-30 22:45:04 +02:00
parent 2a980ecb50
commit bd1bbc0ab8
4 changed files with 160 additions and 151 deletions

View file

@ -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();
}

View file

@ -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;
};
}

View file

@ -1,6 +1,5 @@
#version 330 compatibility
uniform mat4 projectionMatrix;
uniform vec3 color;