mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 06:35:30 +00:00
Multiple shapes to draw
adds wireCube primitive scale of the command taken into account shading light is more vertical
This commit is contained in:
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)
|
||||
{
|
||||
mCubesToDrawWrite.push_back({ mDims, mColor, mPosition });
|
||||
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::addDrawCall(const DrawCall& draw)
|
||||
{
|
||||
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);
|
||||
|
||||
|
||||
struct CubeDraw
|
||||
enum class DrawShape
|
||||
{
|
||||
Cube,
|
||||
Cylinder,
|
||||
WireCube,
|
||||
};
|
||||
|
||||
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…
x
Reference in New Issue
Block a user