Multiple shapes to draw

adds wireCube primitive

scale of the command taken into account

shading light is more vertical
crashfix_debugdraw
florent.teppe 2 years ago
parent 93af569a68
commit 76008e1ff8

@ -31,14 +31,21 @@ namespace MWRenderDebug
osg::Uniform* uTrans = const_cast<osg::Uniform*>( stateSet->getUniform("trans"));
osg::Uniform* uCol = const_cast<osg::Uniform*>( stateSet->getUniform("passColor"));
osg::Uniform* uScale = const_cast<osg::Uniform*>( stateSet->getUniform("scale"));
auto transLocation = pcp->getUniformLocation(uTrans->getNameID() );
auto colLocation = pcp->getUniformLocation(uCol->getNameID() );
auto scaleLocation = pcp->getUniformLocation(uScale->getNameID() );
for (int i = 0; i < mCubesToDraw.size(); i++)
for (int i = 0; i < mShapsToDraw.size(); i++)
{
osg::Vec3f translation = mCubesToDraw[i].mPosition;
osg::Vec3f color = mCubesToDraw[i].mColor;
const auto& shapeToDraw = mShapsToDraw[i];
osg::Vec3f translation = shapeToDraw.mPosition;
osg::Vec3f color = shapeToDraw.mColor;
osg::Vec3f scale = shapeToDraw.mDims;
if (uTrans)
ext->glUniform3f(transLocation, translation.x(), translation.y(), translation.z());
@ -46,7 +53,22 @@ namespace MWRenderDebug
{
ext->glUniform3f(colLocation, color.x(), color.y(), color.z());
}
this->mCubeGeometry->drawImplementation(renderInfo);
if (uScale)
{
ext->glUniform3f(scaleLocation, scale.x(), scale.y(), scale.z());
}
switch (shapeToDraw.mDrawShape)
{
case DrawShape::Cube:
this->mCubeGeometry->drawImplementation(renderInfo);
break;
case DrawShape::Cylinder:
this->mCylinderGeometry->drawImplementation(renderInfo);
break;
case DrawShape::WireCube:
this->mWireCubeGeometry->drawImplementation(renderInfo);
break;
}
}
@ -54,6 +76,61 @@ namespace MWRenderDebug
}
}
static osg::Vec3 sphereCoordToCarthesian(float theta ,float phi ,float r )
{
osg::Vec3 returnVec = osg::Vec3(0.0,0.0,0.0);
float phiToHorizontal = osg::PI_2 - phi ;
returnVec.x() = std::cos( theta);
returnVec.y() = std::sin( theta);
returnVec.z() = std::sin(phiToHorizontal);
returnVec.x() *= std::cos(phiToHorizontal);
returnVec.y() *= std::cos(phiToHorizontal);
returnVec.x() *= r;
returnVec.z() *= r;
returnVec.y() *= r;
return returnVec;
}
static void generateWireCube(osg::Geometry& geom, float dim)
{
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
geom.setVertexAttribArray(0, vertices, osg::Array::BIND_PER_VERTEX);
geom.setVertexAttribArray(1, normals, osg::Array::BIND_PER_VERTEX);
osg::Vec2i indexPos[] = { osg::Vec2i(0,0),osg::Vec2i(1,0),osg::Vec2i(1,1),osg::Vec2i(0,1) };
for (int i = 0; i < 4; i++)
{
osg::Vec3 vert1 = osg::Vec3(indexPos[i].x() - 0.5, indexPos[i].y()- 0.5, 0.5);
int next = (i + 1) % 4;
osg::Vec3 vert2 = osg::Vec3(indexPos[next].x()- 0.5, indexPos[next].y()- 0.5, 0.5);
vertices->push_back(vert1 * dim);
vertices->push_back(vert2 * dim);
vert1.z() *= -1;
vert2.z() *= -1;
vertices->push_back(vert1 * dim);
vertices->push_back(vert2 * dim);
auto vert3 = vert1;
vert3.z() *= -1;
vertices->push_back(vert1 * dim);
vertices->push_back(vert3 * dim);
}
for (int i = 0; i < vertices->size(); i ++)
{
normals->push_back(osg::Vec3(1., 1., 1.));
}
geom.addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertices->size()));
}
static void generateCube(osg::Geometry& geom, float dim)
{
@ -105,6 +182,113 @@ static void generateCube(osg::Geometry& geom, float dim)
}
static void generateCylinder(osg::Geometry& geom, float radius, float height, int subdiv)
{
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
osg::ref_ptr<osg::DrawElementsUShort> indices = new osg::DrawElementsUShort(osg::DrawElementsUShort::TRIANGLES, 0);
int vertexCount = subdiv * 4 + 2; //2 discs + top and bottom + 2 center
indices->reserve(vertexCount );
int iVertex = 0;
int beginTop = iVertex;
auto topNormal = osg::Vec3(0.,0.,1.);
//top disk
for (int i = 0 ;i < subdiv; i++)
{
float theta = (float(i )/ float(subdiv )) * osg::PI * 2.;
osg::Vec3 pos= sphereCoordToCarthesian(theta, osg::PI_2, 1.);
pos *= radius;
pos.z() = height / 2.;
vertices->push_back(pos);
normals->push_back(topNormal);
iVertex+=1;
}
auto centerTop = iVertex;
//centerTop
{
vertices->push_back(osg::Vec3(0.,0.,height/2.));
normals->push_back(topNormal);
iVertex+=1;
}
auto centerBot = iVertex;
//centerBot
{
vertices->push_back(osg::Vec3(0.,0.,-height/2));
normals->push_back(-topNormal);
iVertex+=1;
}
//bottom disk
auto begin_bot = iVertex;
for (int i = 0 ;i < subdiv; i++)
{
float theta = float(i)/ float(subdiv) * osg::PI*2.;
osg::Vec3 pos= sphereCoordToCarthesian(theta, osg::PI_2, 1.);
pos *= radius;
pos.z() = - height / 2.;
vertices->push_back(pos);
normals->push_back(-topNormal);
iVertex+=1;
}
//sides
int beginSide = iVertex;
for (int i = 0 ;i < subdiv; i++)
{
float theta = float(i )/ float(subdiv) * osg::PI*2.;
osg::Vec3 normal = sphereCoordToCarthesian(theta, osg::PI_2, 1.);
auto posTop = normal;
posTop *= radius;
auto posBot = posTop;
posTop.z() = height /2.;
posBot.z() = -height /2.;
vertices->push_back(posTop);
normals->push_back(normal);
iVertex+=1;
vertices->push_back(posBot);
normals->push_back(normal);
iVertex+=1;
}
//create triangles sides
for (int i = 0 ;i < subdiv; i++)
{
auto next_vert = (i+1)%subdiv;
auto v1 = (beginSide + 2 *i);
auto v2 = (beginSide + 2 *i +1);
auto v3 = (beginSide + 2 *next_vert);
auto v4 = (beginSide + 2 *next_vert +1);
indices->push_back(v1);
indices->push_back(v2);
indices->push_back(v4);
indices->push_back(v4);
indices->push_back(v3);
indices->push_back(v1);
}
for (int i = 0 ;i < subdiv; i++)
{
auto next_vert = (i+1)%subdiv;
auto top1 = (beginTop + i) ;
auto top2 = (beginTop + next_vert) ;
auto bot1 = (begin_bot + i) ;
auto bot2 = (begin_bot + next_vert) ;
indices->push_back(top2);
indices->push_back(centerTop);
indices->push_back(top1);
indices->push_back(bot1);
indices->push_back(centerBot);
indices->push_back(bot2);
}
geom.setVertexAttribArray(0, vertices, osg::Array::BIND_PER_VERTEX);
geom.setVertexAttribArray(1, normals, osg::Array::BIND_PER_VERTEX);
geom.addPrimitiveSet(indices);
}
MWRenderDebug::DebugDrawer::DebugDrawer(MWRender::RenderingManager& renderingManager,osg::ref_ptr<osg::Group> parentNode)
{
auto& shaderManager = renderingManager.getResourceSystem()->getSceneManager()->getShaderManager();
@ -112,25 +296,33 @@ MWRenderDebug::DebugDrawer::DebugDrawer(MWRender::RenderingManager& renderingMan
auto fragmentShader = shaderManager.getShader("debugDraw_fragment.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::Type::FRAGMENT);
auto program = shaderManager.getProgram(vertexShader, fragmentShader);
program->addBindAttribLocation("aPos", 0);
program->addBindAttribLocation("aNormal", 1);
mCubeGeometry = new osg::Geometry;
mcustomCubesDrawer = new CubeCustomDraw(mCubeGeometry, mCubesToDrawRead, mDrawCallMutex);
mcustomCubesDrawer = new CubeCustomDraw(mCubeGeometry, mShapesToDrawRead, mDrawCallMutex);
osg::StateSet* stateset = mcustomCubesDrawer->getOrCreateStateSet();
stateset->addUniform(new osg::Uniform("passColor", osg::Vec3f(1., 1., 1.)));
stateset->addUniform(new osg::Uniform("trans", osg::Vec3f(1., 1., 1.)));
stateset->addUniform(new osg::Uniform("scale", osg::Vec3f(1., 1., 1.)));
stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
stateset->setMode(GL_DEPTH_TEST, GL_TRUE);
stateset->setMode(GL_CULL_FACE, GL_TRUE);
mCubeGeometry->setCullingActive(false);
mCubeGeometry->setSupportsDisplayList(false);
mCubeGeometry->setUseVertexBufferObjects(true);
generateCube(*mCubeGeometry,50.);
generateCube(*mCubeGeometry,1.);
auto cylinderGeom = new osg::Geometry;
cylinderGeom->setSupportsDisplayList(false);
cylinderGeom->setUseVertexBufferObjects(true);
mcustomCubesDrawer->mCylinderGeometry = cylinderGeom;
generateCylinder(*cylinderGeom, .5, 1., 20);
mCubeGeometry->setStateSet(stateset->clone(osg::CopyOp::DEEP_COPY_ALL)->asStateSet());
auto wireCube = new osg::Geometry;
wireCube->setSupportsDisplayList(false);
wireCube->setUseVertexBufferObjects(true);
mcustomCubesDrawer->mWireCubeGeometry = wireCube;
generateWireCube(*wireCube, 1.);
//mCubeGeometry->setStateSet(stateset->clone(osg::CopyOp::DEEP_COPY_ALL)->asStateSet());
parentNode->addChild(mcustomCubesDrawer);
}
@ -139,14 +331,24 @@ void MWRenderDebug::DebugDrawer::update()
{
{
std::lock_guard lock(mDrawCallMutex);
mCubesToDrawRead.swap(mCubesToDrawWrite);
mShapesToDrawRead.swap(mShapesToDrawWrite);
}
mCubesToDrawWrite.clear();
mShapesToDrawWrite.clear();
}
void MWRenderDebug::DebugDrawer::drawCube(osg::Vec3f mPosition, osg::Vec3f mDims, osg::Vec3f mColor)
{
mShapesToDrawWrite.push_back({mPosition, mDims, mColor, DrawShape::Cube});
}
void MWRenderDebug::DebugDrawer::drawCubeMinMax(osg::Vec3f min, osg::Vec3f max, osg::Vec3f color)
{
osg::Vec3 dims = max - min;
osg::Vec3 pos = min + dims * 0.5f;
drawCube(pos, dims, color);
}
void MWRenderDebug::DebugDrawer::drawCube(osg::Vec3f mPosition, osg::Vec3f mDims, osg::Vec3f mColor)
void MWRenderDebug::DebugDrawer::addDrawCall(const DrawCall& draw)
{
mCubesToDrawWrite.push_back({ mDims, mColor, mPosition });
mShapesToDrawWrite.push_back(draw);
}

@ -19,25 +19,41 @@ 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);
enum class DrawShape
{
Cube,
Cylinder,
WireCube,
};
struct CubeDraw
struct DrawCall
{
osg::Vec3f mPosition;
osg::Vec3f mDims;
osg::Vec3f mColor;
osg::Vec3f mPosition;
DrawShape mDrawShape;
static DrawCall cube(osg::Vec3f pos, osg::Vec3 dims = osg::Vec3(50., 50., 50.), osg::Vec3 color = colorWhite) { return { pos, dims, color, DrawShape::Cube}; }
static DrawCall wireCube(osg::Vec3f pos, osg::Vec3 dims = osg::Vec3(50., 50., 50.), osg::Vec3 color = colorWhite) { return { pos, dims, color, DrawShape::WireCube}; }
static DrawCall cylinder(osg::Vec3f pos, osg::Vec3 dims = osg::Vec3(50., 50., 50.), osg::Vec3 color = colorWhite) { return { pos, dims, color, DrawShape::Cylinder}; }
};
class CubeCustomDraw : public osg::Drawable
{
public:
CubeCustomDraw(osg::ref_ptr<osg::Geometry>& CubeGeometry, std::vector<CubeDraw>& cubesToDraw,std::mutex& mutex) : mCubeGeometry( CubeGeometry), mCubesToDraw(cubesToDraw),mDrawCallMutex(mutex) {}
CubeCustomDraw(osg::ref_ptr<osg::Geometry>& CubeGeometry, std::vector<DrawCall>& cubesToDraw,std::mutex& mutex) : mCubeGeometry( CubeGeometry), mShapsToDraw(cubesToDraw),mDrawCallMutex(mutex) {}
std::vector<CubeDraw>& mCubesToDraw;
std::vector<DrawCall>& mShapsToDraw;
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();
@ -52,15 +68,17 @@ namespace MWRenderDebug
DebugDrawer(MWRender::RenderingManager& manager,osg::ref_ptr<osg::Group> parentNode);
void update();
void drawCube(osg::Vec3f mPosition, osg::Vec3f mDims = osg::Vec3(50.,50.,50.), osg::Vec3f mColor = osg::Vec3(1.,1.,1.));
void drawCubeMinMax(osg::Vec3f min, osg::Vec3f max, osg::Vec3f mColor = osg::Vec3(1.,1.,1.));
void addDrawCall(const DrawCall& draw);
private:
std::vector<CubeDraw> mCubesToDrawRead;
std::vector<CubeDraw> mCubesToDrawWrite;
std::vector<DrawCall> mShapesToDrawRead;
std::vector<DrawCall> mShapesToDrawWrite;
std::mutex mDrawCallMutex;
osg::ref_ptr<CubeCustomDraw> mcustomCubesDrawer;
osg::ref_ptr<osg::Geometry> mCubeGeometry;
void drawCube(osg::Vec3f mPosition, osg::Vec3f mDims = osg::Vec3(50.,50.,50.), osg::Vec3f mColor = osg::Vec3(1.,1.,1.));
};
}

@ -7,7 +7,7 @@ out vec4 fragColor;
void main()
{
vec3 lightDir = normalize(vec3(-1.,-2.,-0.5));
vec3 lightDir = normalize(vec3(-1.,-0.5,-2.));
float lightAttenuation = dot(-lightDir, vertexNormal) * 0.5 + 0.5;

@ -10,6 +10,7 @@ uniform mat4 projectionMatrix;
uniform vec3 passColor;
uniform vec3 trans;
uniform vec3 scale;
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
@ -19,7 +20,7 @@ out vec3 vertexNormal;
void main()
{
gl_Position = projectionMatrix * gl_ModelViewMatrix * vec4(aPos + trans, 1.);
gl_Position = projectionMatrix * gl_ModelViewMatrix * vec4(aPos * scale + trans, 1.);
vertexNormal = aNormal;
vertexColor = passColor.xyz;

Loading…
Cancel
Save