1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-30 16:20:21 +00:00

Merge branch 'crashfix_debugdraw' into 'master'

crashfix of debug draw on game exit

Closes #7004

See merge request OpenMW/openmw!2398
This commit is contained in:
elsid 2022-09-14 20:56:03 +00:00
commit ae812701ec
2 changed files with 46 additions and 57 deletions

View File

@ -225,12 +225,34 @@ static int getIdexBufferWriteFromFrame(const long long int& nFrame)
namespace Debug namespace Debug
{ {
static void makeLineInstance(osg::Geometry& lines)
{
auto vertices = new osg::Vec3Array;
auto color = new osg::Vec3Array;
lines.setDataVariance(osg::Object::STATIC);
lines.setUseVertexArrayObject(true);
lines.setUseDisplayList(false);
lines.setCullingActive(false);
lines.setVertexArray(vertices);
lines.setNormalArray(color, osg::Array::BIND_PER_VERTEX);
lines.addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertices->size()));
}
DebugCustomDraw::DebugCustomDraw()
{
mLinesToDraw = new osg::Geometry();
makeLineInstance(*mLinesToDraw);
}
void DebugCustomDraw::drawImplementation(osg::RenderInfo& renderInfo) const void DebugCustomDraw::drawImplementation(osg::RenderInfo& renderInfo) const
{ {
auto state = renderInfo.getState(); auto state = renderInfo.getState();
osg::GLExtensions* ext = osg::GLExtensions::Get(state->getContextID(), true); osg::GLExtensions* ext = osg::GLExtensions::Get(state->getContextID(), true);
const osg::StateSet* stateSet = this->getStateSet(); const osg::StateSet* stateSet = getStateSet();
auto program = static_cast<const osg::Program*>(stateSet->getAttribute(osg::StateAttribute::PROGRAM)); auto program = static_cast<const osg::Program*>(stateSet->getAttribute(osg::StateAttribute::PROGRAM));
const osg::Program::PerContextProgram* pcp = program->getPCP(*state); const osg::Program::PerContextProgram* pcp = program->getPCP(*state);
@ -271,13 +293,13 @@ namespace Debug
switch (shapeToDraw.mDrawShape) switch (shapeToDraw.mDrawShape)
{ {
case DrawShape::Cube: case DrawShape::Cube:
this->mCubeGeometry->drawImplementation(renderInfo); mCubeGeometry->drawImplementation(renderInfo);
break; break;
case DrawShape::Cylinder: case DrawShape::Cylinder:
this->mCylinderGeometry->drawImplementation(renderInfo); mCylinderGeometry->drawImplementation(renderInfo);
break; break;
case DrawShape::WireCube: case DrawShape::WireCube:
this->mWireCubeGeometry->drawImplementation(renderInfo); mWireCubeGeometry->drawImplementation(renderInfo);
break; break;
} }
} }
@ -286,36 +308,6 @@ namespace Debug
static_cast<osg::Vec3Array*>(mLinesToDraw->getNormalArray())->clear(); static_cast<osg::Vec3Array*>(mLinesToDraw->getNormalArray())->clear();
} }
struct DebugLines
{
static void makeLineInstance(osg::Geometry& lines)
{
auto vertices = new osg::Vec3Array;
auto color = new osg::Vec3Array;
lines.setUseVertexArrayObject(true);
lines.setUseDisplayList(false);
lines.setCullingActive(false);
lines.setVertexArray(vertices);
lines.setNormalArray(color, osg::Array::BIND_PER_VERTEX);
lines.addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertices->size()));
}
DebugLines()
{
mLinesGeom[0] = new osg::Geometry();
mLinesGeom[1] = new osg::Geometry();
makeLineInstance(*mLinesGeom[0]);
makeLineInstance(*mLinesGeom[1]);
}
std::array<osg::ref_ptr<osg::Geometry>, 2> mLinesGeom;
};
class DebugDrawCallback : public SceneUtil::NodeCallback<DebugDrawCallback> class DebugDrawCallback : public SceneUtil::NodeCallback<DebugDrawCallback>
{ {
public: public:
@ -325,9 +317,9 @@ namespace Debug
{ {
mDebugDrawer.mCurrentFrame = nv->getTraversalNumber(); mDebugDrawer.mCurrentFrame = nv->getTraversalNumber();
int indexRead = getIdexBufferReadFromFrame(mDebugDrawer.mCurrentFrame); int indexRead = getIdexBufferReadFromFrame(mDebugDrawer.mCurrentFrame);
auto& lines = mDebugDrawer.mDebugLines; auto& lines = mDebugDrawer.mCustomDebugDrawer[indexRead]->mLinesToDraw;
lines->mLinesGeom[indexRead]->removePrimitiveSet(0, 1); lines->removePrimitiveSet(0, 1);
lines->mLinesGeom[indexRead]->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, static_cast<osg::Vec3Array*>(lines->mLinesGeom[indexRead]->getVertexArray())->size())); lines->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, static_cast<osg::Vec3Array*>(lines->getVertexArray())->size()));
nv->pushOntoNodePath(mDebugDrawer.mCustomDebugDrawer[indexRead]); nv->pushOntoNodePath(mDebugDrawer.mCustomDebugDrawer[indexRead]);
nv->apply(*mDebugDrawer.mCustomDebugDrawer[indexRead]); nv->apply(*mDebugDrawer.mCustomDebugDrawer[indexRead]);
@ -338,14 +330,13 @@ namespace Debug
}; };
} }
Debug::DebugDrawer::DebugDrawer(Shader::ShaderManager& shaderManager, osg::ref_ptr<osg::Group> parentNode) Debug::DebugDrawer::DebugDrawer(Shader::ShaderManager& shaderManager, osg::ref_ptr<osg::Group> parentNode) : mParentNode(parentNode)
{ {
mCurrentFrame = 0; mCurrentFrame = 0;
auto vertexShader = shaderManager.getShader("debug_vertex.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::Type::VERTEX); auto vertexShader = shaderManager.getShader("debug_vertex.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::Type::VERTEX);
auto fragmentShader = shaderManager.getShader("debug_fragment.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::Type::FRAGMENT); auto fragmentShader = shaderManager.getShader("debug_fragment.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::Type::FRAGMENT);
auto program = shaderManager.getProgram(vertexShader, fragmentShader); auto program = shaderManager.getProgram(vertexShader, fragmentShader);
mDebugLines = std::make_unique<DebugLines>();
mDebugDrawSceneObjects = new osg::Group; mDebugDrawSceneObjects = new osg::Group;
mDebugDrawSceneObjects->setCullingActive(false); mDebugDrawSceneObjects->setCullingActive(false);
@ -375,9 +366,9 @@ Debug::DebugDrawer::DebugDrawer(Shader::ShaderManager& shaderManager, osg::ref_p
wireCube->setUseVertexBufferObjects(true); wireCube->setUseVertexBufferObjects(true);
generateWireCube(*wireCube, 1.); generateWireCube(*wireCube, 1.);
for (std::size_t i = 0; i < mShapesToDraw.size(); i++) for (std::size_t i = 0; i < mCustomDebugDrawer.size(); i++)
{ {
mCustomDebugDrawer[i] = new DebugCustomDraw(mShapesToDraw[i], mDebugLines->mLinesGeom[i]); mCustomDebugDrawer[i] = new DebugCustomDraw();
mCustomDebugDrawer[i]->setStateSet(stateset); mCustomDebugDrawer[i]->setStateSet(stateset);
mCustomDebugDrawer[i]->mWireCubeGeometry = wireCube; mCustomDebugDrawer[i]->mWireCubeGeometry = wireCube;
mCustomDebugDrawer[i]->mCubeGeometry = cubeGeometry; mCustomDebugDrawer[i]->mCubeGeometry = cubeGeometry;
@ -385,16 +376,17 @@ Debug::DebugDrawer::DebugDrawer(Shader::ShaderManager& shaderManager, osg::ref_p
} }
mDebugDrawSceneObjects->addCullCallback(new DebugDrawCallback(*this)); mDebugDrawSceneObjects->addCullCallback(new DebugDrawCallback(*this));
parentNode->addChild(mDebugDrawSceneObjects); mParentNode->addChild(mDebugDrawSceneObjects);
} }
Debug::DebugDrawer::~DebugDrawer() Debug::DebugDrawer::~DebugDrawer()
{ {
} mParentNode->removeChild(mDebugDrawSceneObjects);
}
void Debug::DebugDrawer::drawCube(osg::Vec3f mPosition, osg::Vec3f mDims, osg::Vec3f mColor) void Debug::DebugDrawer::drawCube(osg::Vec3f mPosition, osg::Vec3f mDims, osg::Vec3f mColor)
{ {
mShapesToDraw[getIdexBufferWriteFromFrame(this->mCurrentFrame)].push_back({ mPosition, mDims, mColor, DrawShape::Cube }); mCustomDebugDrawer[getIdexBufferWriteFromFrame(mCurrentFrame)]->mShapesToDraw.push_back({ mPosition, mDims, mColor, DrawShape::Cube });
} }
void Debug::DebugDrawer::drawCubeMinMax(osg::Vec3f min, osg::Vec3f max, osg::Vec3f color) void Debug::DebugDrawer::drawCubeMinMax(osg::Vec3f min, osg::Vec3f max, osg::Vec3f color)
@ -406,14 +398,15 @@ void Debug::DebugDrawer::drawCubeMinMax(osg::Vec3f min, osg::Vec3f max, osg::Vec
void Debug::DebugDrawer::addDrawCall(const DrawCall& draw) void Debug::DebugDrawer::addDrawCall(const DrawCall& draw)
{ {
mShapesToDraw[getIdexBufferWriteFromFrame(this->mCurrentFrame)].push_back(draw); mCustomDebugDrawer[getIdexBufferWriteFromFrame(mCurrentFrame)]->mShapesToDraw.push_back(draw);
} }
void Debug::DebugDrawer::addLine(const osg::Vec3& start, const osg::Vec3& end, const osg::Vec3 color) void Debug::DebugDrawer::addLine(const osg::Vec3& start, const osg::Vec3& end, const osg::Vec3 color)
{ {
const int indexWrite = getIdexBufferWriteFromFrame(this->mCurrentFrame); const int indexWrite = getIdexBufferWriteFromFrame(mCurrentFrame);
auto vertices = static_cast<osg::Vec3Array*>(mDebugLines->mLinesGeom[indexWrite]->getVertexArray()); const auto& lines = mCustomDebugDrawer[indexWrite]->mLinesToDraw;
auto colors = static_cast<osg::Vec3Array*>(mDebugLines->mLinesGeom[indexWrite]->getNormalArray()); auto vertices = static_cast<osg::Vec3Array*>(lines->getVertexArray());
auto colors = static_cast<osg::Vec3Array*>(lines->getNormalArray());
vertices->push_back(start); vertices->push_back(start);
vertices->push_back(end); vertices->push_back(end);

View File

@ -58,20 +58,18 @@ namespace Debug
class DebugCustomDraw : public osg::Drawable class DebugCustomDraw : public osg::Drawable
{ {
public: public:
DebugCustomDraw(std::vector<DrawCall>& cubesToDraw, osg::ref_ptr<osg::Geometry>& linesToDraw) : mShapesToDraw(cubesToDraw), mLinesToDraw(linesToDraw) {} DebugCustomDraw();
std::vector<DrawCall>& mShapesToDraw; mutable std::vector<DrawCall> mShapesToDraw;
osg::ref_ptr<osg::Geometry>& mLinesToDraw; osg::ref_ptr<osg::Geometry> mLinesToDraw;
osg::ref_ptr<osg::Geometry> mCubeGeometry; osg::ref_ptr<osg::Geometry> mCubeGeometry;
osg::ref_ptr<osg::Geometry> mCylinderGeometry; osg::ref_ptr<osg::Geometry> mCylinderGeometry;
osg::ref_ptr<osg::Geometry> mWireCubeGeometry; osg::ref_ptr<osg::Geometry> mWireCubeGeometry;
virtual void drawImplementation(osg::RenderInfo&) const; virtual void drawImplementation(osg::RenderInfo&) const override;
}; };
struct DebugLines;
struct DebugDrawer struct DebugDrawer
{ {
friend DebugDrawCallback; friend DebugDrawCallback;
@ -85,13 +83,11 @@ namespace Debug
void addLine(const osg::Vec3& start, const osg::Vec3& end, const osg::Vec3 color = colorWhite); void addLine(const osg::Vec3& start, const osg::Vec3& end, const osg::Vec3 color = colorWhite);
private: private:
std::unique_ptr<DebugLines> mDebugLines;
std::array<std::vector<DrawCall>, 2> mShapesToDraw;
long long int mCurrentFrame; long long int mCurrentFrame;
std::array<osg::ref_ptr<DebugCustomDraw>, 2> mCustomDebugDrawer; std::array<osg::ref_ptr<DebugCustomDraw>, 2> mCustomDebugDrawer;
osg::ref_ptr<osg::Group> mDebugDrawSceneObjects; osg::ref_ptr<osg::Group> mDebugDrawSceneObjects;
osg::ref_ptr<osg::Group> mParentNode;
}; };
} }
#endif // ! #endif // !