Commit d5031736 authored by Christopher Tenter's avatar Christopher Tenter
Browse files

- add box and line-box to GLPrimitive

- use new GLLineBox in BoundingBoxNode

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@19667 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 021317f2
......@@ -58,6 +58,7 @@ GLPrimitive::GLPrimitive() :
vboDataInvalid_(true),
normalOrientation_(OUTSIDE),
numTris_(0),
numLines_(0),
vboData_(0),
curTriPtr_(0),
vbo_(0)
......@@ -88,6 +89,9 @@ void GLPrimitive::addTriangleToVBO(const ACG::Vec3f* _p, const ACG::Vec3f* _n, c
if (!numTris_)
return;
assert(numLines_ == 0);
if (!vboData_)
vboData_ = new float[8 * 3 * numTris_];
......@@ -109,6 +113,39 @@ void GLPrimitive::addTriangleToVBO(const ACG::Vec3f* _p, const ACG::Vec3f* _n, c
}
}
void GLPrimitive::addLineToVBO( const ACG::Vec3f* _p, const ACG::Vec3f* _n, const ACG::Vec2f* _tex )
{
if (!numLines_ || vboDataInvalid_)
numLines_ = getNumLines();
if (!numLines_)
return;
assert(numTris_ == 0);
if (!vboData_)
vboData_ = new float[8 * 2 * numLines_];
if (curTriPtr_ == numLines_)
return;
float* pLine = &vboData_[0] + (curTriPtr_++) * 2 * 8;
// copy line segment
for (int i = 0; i < 2; ++i) {
for (int k = 0; k < 3; ++k)
*(pLine++) = _p[i][k];
for (int k = 0; k < 3; ++k)
*(pLine++) = _n[i][k];
for (int k = 0; k < 2; ++k)
*(pLine++) = _tex[i][k];
}
}
//------------------------------------------------------------------------
void GLPrimitive::bindVBO()
......@@ -138,22 +175,23 @@ bool GLPrimitive::checkVBO()
// update vbo data and upload to gpu if needed
// return false iff vbo empty
int bufSize = numTris_ ? numTris_ * 3 * 8 * 4 : numLines_ * 2 * 8 * 4;
if (!vbo_) {
if (!vboData_ || !numTris_)
if (!vboData_ || (!numTris_ && !numLines_) || (numTris_ && numLines_))
return false;
// create vbo
glGenBuffersARB(1, &vbo_);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, numTris_ * 3 * 8 * 4, vboData_, GL_STATIC_DRAW_ARB);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufSize, vboData_, GL_STATIC_DRAW_ARB);
delete[] vboData_;
vboData_ = 0;
} else if (vboDataInvalid_) {
updateVBOData();
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, numTris_ * 3 * 8 * 4, vboData_, GL_STATIC_DRAW_ARB);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufSize, vboData_, GL_STATIC_DRAW_ARB);
vboDataInvalid_ = false;
}
......@@ -176,7 +214,10 @@ void GLPrimitive::draw()
{
bindVBO();
glDrawArrays(GL_TRIANGLES, 0, getNumTriangles() * 3);
if (numTris_)
glDrawArrays(GL_TRIANGLES, 0, numTris_ * 3);
else
glDrawArrays(GL_LINES, 0, numLines_ * 2);
unBindVBO();
}
......@@ -190,8 +231,10 @@ void GLPrimitive::addToRenderer( class IRenderer* _renderer, RenderObject* _ro )
_ro->vertexBuffer = vbo_;
_ro->vertexDecl = &vertexDecl_;
_ro->glDrawArrays(GL_TRIANGLES, 0, getNumTriangles() * 3);
if (numTris_)
_ro->glDrawArrays(GL_TRIANGLES, 0, numTris_ * 3);
else
_ro->glDrawArrays(GL_LINES, 0, numLines_ * 2);
_renderer->addRenderObject(_ro);
}
......@@ -210,6 +253,18 @@ void GLPrimitive::updateVBOData() {
updateVBO();
}
//------------------------------------------------------------------------
unsigned int GLPrimitive::getVBO()
{
return checkVBO() ? vbo_ : 0;
}
const VertexDeclaration* GLPrimitive::getVertexDecl() const
{
return &vertexDecl_;
}
//========================================================================
// GLSphere
//========================================================================
......@@ -841,6 +896,187 @@ GLDisk::GLDisk(int _slices, int _loops, float _innerRadius, float _outerRadius)
{
}
//========================================================================
// GLBox
//========================================================================
GLBox::GLBox()
{
updateVBO();
}
GLBox::~GLBox()
{
}
int GLBox::getNumTriangles()
{
return 12;
}
//------------------------------------------------------------------------
void GLBox::updateVBO()
{
static const Vec3f pos[8] =
{
Vec3f(-0.5f,-0.5f,0.5f), Vec3f(-0.5f,-0.5f,-0.5f), Vec3f(0.5f,-0.5f,-0.5f),
Vec3f(0.5f,-0.5f,0.5f), Vec3f(-0.5f,0.5f,0.5f), Vec3f(0.5f,0.5f,0.5f),
Vec3f(0.5f,0.5f,-0.5f), Vec3f(-0.5f,0.5f,-0.5f)
};
static const Vec3f norm[6] =
{
Vec3f(0.0f,-1.0f,0.0f), Vec3f(0.0f,1.0f,0.0f), Vec3f(0.0f,0.0f,1.0f),
Vec3f(1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), Vec3f(-1.0f,0.0f,0.0f)
};
static const Vec2f texc[4] =
{
Vec2f(1.0f,0.0f), Vec2f(1.0f,1.0f), Vec2f(0.0f,1.0f), Vec2f(0.0f,0.0f)
};
// tri: p,p,p ,n,n,n ,t,t,t
static const int tris[12][9] =
{
{0,1,2 ,0,0,0 ,0,1,2}, {2,3,0 ,0,0,0 ,2,3,0}, {4,5,6 ,1,1,1 ,3,0,1},
{6,7,4 ,1,1,1 ,1,2,3}, {0,3,5 ,2,2,2 ,3,0,1}, {5,4,0 ,2,2,2 ,1,2,3},
{3,2,6 ,3,3,3 ,3,0,1}, {6,5,3 ,3,3,3 ,1,2,3}, {2,1,7 ,4,4,4 ,3,0,1},
{7,6,2 ,4,4,4 ,1,2,3}, {1,0,4 ,5,5,5 ,3,0,1}, {4,7,1 ,5,5,5 ,1,2,3}
};
for (int i = 0; i < 12; ++i)
{
Vec3f triPos[3] = { pos[tris[i][0]], pos[tris[i][1]], pos[tris[i][2]] };
Vec3f triNorm[3] = { norm[tris[i][3]], norm[tris[i][4]], norm[tris[i][5]] };
Vec2f triTexc[3] = { texc[tris[i][6]], texc[tris[i][7]], texc[tris[i][8]] };
addTriangleToVBO(triPos, triNorm, triTexc);
}
}
//------------------------------------------------------------------------
GLLineBox::GLLineBox()
{
updateVBO();
}
GLLineBox::~GLLineBox()
{
}
//------------------------------------------------------------------------
int GLLineBox::getNumTriangles()
{
return 0;
}
int GLLineBox::getNumLines()
{
return 12;
}
//------------------------------------------------------------------------
void GLLineBox::updateVBO()
{
static const Vec3f pos[8] =
{
Vec3f(-0.5f,-0.5f,0.5f), Vec3f(-0.5f,-0.5f,-0.5f), Vec3f(0.5f,-0.5f,-0.5f),
Vec3f(0.5f,-0.5f,0.5f), Vec3f(-0.5f,0.5f,0.5f), Vec3f(0.5f,0.5f,0.5f),
Vec3f(0.5f,0.5f,-0.5f), Vec3f(-0.5f,0.5f,-0.5f)
};
static const Vec3f norm[6] =
{
Vec3f(0.0f,-1.0f,0.0f), Vec3f(0.0f,1.0f,0.0f), Vec3f(0.0f,0.0f,1.0f),
Vec3f(1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), Vec3f(-1.0f,0.0f,0.0f)
};
static const Vec2f texc[4] =
{
Vec2f(1.0f,0.0f), Vec2f(1.0f,1.0f), Vec2f(0.0f,1.0f), Vec2f(0.0f,0.0f)
};
// line: p,p ,n,n ,t,t
static const int lines[12][6] =
{
{1,2, 0,0, 0,3}, {0,3, 0,0, 0,3}, {4,5, 0,0, 0,3}, {7,6, 0,0, 0,3},
{1,7, 0,0, 0,3}, {0,4, 0,0, 0,3}, {2,6, 0,0, 0,3}, {3,5, 0,0, 0,3},
{1,0, 0,0, 0,3}, {2,3, 0,0, 0,3}, {7,4, 0,0, 0,3}, {6,5, 0,0, 0,3}
};
for (int i = 0; i < 12; ++i)
{
Vec3f p[2] = { pos[lines[i][0]], pos[lines[i][1]]};
Vec3f n[2] = { norm[lines[i][3]], norm[lines[i][4]]};
Vec2f t[2] = { texc[lines[i][6]], texc[lines[i][7]]};
addLineToVBO(p, n, t);
}
}
//------------------------------------------------------------------------
/*
bool GLBox::checkLineIBO()
{
bool success = false;
if (lineIbo_)
success = true;
else
{
if (lineIboData_)
{
glGenBuffersARB(1, &lineIbo_);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, lineIbo_);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, numLines_*2*4, lineIboData_, GL_STATIC_DRAW_ARB);
delete[] lineIboData_;
lineIboData_ = 0;
success = true;
}
}
return success;
}
//------------------------------------------------------------------------
void GLBox::drawLines()
{
bindVBO();
if (checkLineIBO())
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, lineIbo_);
glDrawElements(GL_LINES, numLines_*2, GL_UNSIGNED_INT, 0);
unBindVBO();
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
void GLBox::addToRendererLines(class IRenderer* _renderer, const struct RenderObject* _base)
{
if (checkLineIBO() && checkVBO())
{
RenderObject ro = *_base;
ro.vertexBuffer = getVBO();
ro.indexBuffer = lineIbo_;
ro.vertexDecl = getVertexDecl();
ro.glDrawElements(GL_LINES, numLines_*2, GL_UNSIGNED_INT, 0);
_renderer->addRenderObject(&ro);
}
}
*/
//------------------------------------------------------------------------
}
......@@ -74,13 +74,22 @@ public:
virtual ~GLPrimitive();
// bind vbo + gl draw call
void draw();
virtual void draw();
// add to deferred draw call to renderer
void addToRenderer(class IRenderer* _renderer, struct RenderObject* _ro);
virtual void addToRenderer(class IRenderer* _renderer, struct RenderObject* _ro);
// triangle count must be known before updateVBO
// Triangle or line count must be known before updateVBO.
// A GLPrimitive can consist of either only lines or only triangles.
// If getNumTriangles returns nonzero, its assumed to consist of tris only.
// Otherwise, getNumLines has to return nonzero and GLPrimitive is treated as a line-list.
virtual int getNumTriangles() = 0;
virtual int getNumLines() {return 0;}
// get opengl vbo id
unsigned int getVBO();
const VertexDeclaration* getVertexDecl() const;
enum NormalOrientation {OUTSIDE, INSIDE};
......@@ -90,6 +99,7 @@ protected:
virtual void updateVBO() = 0;
void addTriangleToVBO(const ACG::Vec3f* _p, const ACG::Vec3f* _n, const ACG::Vec2f* _tex);
void addLineToVBO(const ACG::Vec3f* _p, const ACG::Vec3f* _n, const ACG::Vec2f* _tex);
void bindVBO();
......@@ -106,6 +116,7 @@ private:
void updateVBOData();
int numTris_;
int numLines_;
float* vboData_;
int curTriPtr_;
......@@ -236,6 +247,40 @@ public:
//------------------------------------------------------------------------
// axis-aligned unit cube centered at origin
class ACGDLLEXPORT GLBox: public GLPrimitive {
public:
GLBox();
~GLBox();
int getNumTriangles();
private:
void updateVBO();
};
//------------------------------------------------------------------------
// axis-aligned unit cube centered at origin, only lines
class ACGDLLEXPORT GLLineBox: public GLPrimitive {
public:
GLLineBox();
~GLLineBox();
int getNumTriangles();
int getNumLines();
private:
void updateVBO();
};
//------------------------------------------------------------------------
} // namespace ACG
#endif // ACG_GLPRIMITIVES_HH defined
......@@ -54,6 +54,7 @@
#include "BoundingBoxNode.hh"
#include "SceneGraph.hh"
#include "../GL/gl.hh"
#include "../GL/GLPrimitives.hh"
//== NAMESPACES ===============================================================
......@@ -71,65 +72,101 @@ availableDrawModes() const
}
//----------------------------------------------------------------------------
BoundingBoxNode::~BoundingBoxNode() {
BoundingBoxNode::BoundingBoxNode( BaseNode* _parent, std::string _name ) :
MaterialNode(_parent,
_name,
MaterialNode::BaseColor |
MaterialNode::LineWidth),
box_(0)
{
drawMode(DrawModes::WIREFRAME);
box_ = new GLLineBox();
}
//----------------------------------------------------------------------------
BoundingBoxNode::~BoundingBoxNode() {
delete box_;
}
void
BoundingBoxNode::
draw(GLState& /* _state */ , const DrawModes::DrawMode& _drawMode)
{
//----------------------------------------------------------------------------
void BoundingBoxNode::computeAABB( Vec3d* _outMin, Vec3d* _outMax )
{
ACG::SceneGraph::BoundingBoxAction act;
ACG::SceneGraph::traverse(this, act);
ACG::Vec3d bbmin = (ACG::Vec3d) act.bbMin();
ACG::Vec3d bbmax = (ACG::Vec3d) act.bbMax();
if (_outMin)
*_outMin = (ACG::Vec3d) act.bbMin();
if (_outMax)
*_outMax = (ACG::Vec3d) act.bbMax();
}
//----------------------------------------------------------------------------
void
BoundingBoxNode::
draw(GLState& _state , const DrawModes::DrawMode& _drawMode)
{
if (_drawMode & DrawModes::WIREFRAME)
{
ACG::Vec3d bbmin;
ACG::Vec3d bbmax;
computeAABB(&bbmin, &bbmax);
ACG::Vec3d bbcenter = (bbmin + bbmax) * 0.5;
ACG::Vec3d bbsize = bbmax - bbmin;
glPushAttrib (GL_ENABLE_BIT);
ACG::GLState::disable(GL_LIGHTING);
glBegin(GL_LINES);
glVertex3f(bbmin[0],bbmin[1],bbmin[2]);
glVertex3f(bbmax[0],bbmin[1],bbmin[2]);
glVertex3f(bbmax[0],bbmin[1],bbmin[2]);
glVertex3f(bbmax[0],bbmax[1],bbmin[2]);
glVertex3f(bbmax[0],bbmax[1],bbmin[2]);
glVertex3f(bbmin[0],bbmax[1],bbmin[2]);
glVertex3f(bbmin[0],bbmax[1],bbmin[2]);
glVertex3f(bbmin[0],bbmin[1],bbmin[2]);
glVertex3f(bbmin[0],bbmin[1],bbmax[2]);
glVertex3f(bbmax[0],bbmin[1],bbmax[2]);
glVertex3f(bbmax[0],bbmin[1],bbmax[2]);
glVertex3f(bbmax[0],bbmax[1],bbmax[2]);
glVertex3f(bbmax[0],bbmax[1],bbmax[2]);
glVertex3f(bbmin[0],bbmax[1],bbmax[2]);
glVertex3f(bbmin[0],bbmax[1],bbmax[2]);
glVertex3f(bbmin[0],bbmin[1],bbmax[2]);
glVertex3f(bbmin[0],bbmin[1],bbmin[2]);
glVertex3f(bbmin[0],bbmin[1],bbmax[2]);
glVertex3f(bbmax[0],bbmin[1],bbmin[2]);
glVertex3f(bbmax[0],bbmin[1],bbmax[2]);
glVertex3f(bbmax[0],bbmax[1],bbmin[2]);
glVertex3f(bbmax[0],bbmax[1],bbmax[2]);
glVertex3f(bbmin[0],bbmax[1],bbmin[2]);
glVertex3f(bbmin[0],bbmax[1],bbmax[2]);
glEnd();
_state.push_modelview_matrix();
_state.translate(bbcenter);
_state.scale(bbsize[0], bbsize[1], bbsize[2]);
glColor4f(0.0f,1.0f,0.0f,1.0f);
box_->draw();
_state.pop_modelview_matrix();
glPopAttrib ();
}
}
//----------------------------------------------------------------------------
void BoundingBoxNode::getRenderObjects(IRenderer* _renderer, GLState& _state , const DrawModes::DrawMode& _drawMode , const ACG::SceneGraph::Material* _mat)
{
int dmlayerId = _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_WIREFRAME);
if (dmlayerId >= 0)
{
ACG::Vec3d bbmin;
ACG::Vec3d bbmax;
computeAABB(&bbmin, &bbmax);
ACG::Vec3d bbcenter = (bbmin + bbmax) * 0.5;
ACG::Vec3d bbsize = bbmax - bbmin;
// create renderobject
RenderObject ro;
ro.initFromState(&_state);
ro.depthTest = true;
ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
ro.emissive = Vec3f(0.0f, 1.0f, 0.0f);
ro.modelview.translate(bbcenter);
ro.modelview.scale(bbsize[0], bbsize[1], bbsize[2]);
box_->addToRenderer(_renderer, &ro);
}
}
//=============================================================================
} // namespace SceneGraph
......
......@@ -63,6 +63,10 @@
//== NAMESPACES ===============================================================
namespace ACG {
// prototype declaration
class GLLineBox;
namespace SceneGraph {
//== CLASS DEFINITION =========================================================
......@@ -80,14 +84,7 @@ public:
/// default constructor
BoundingBoxNode( BaseNode* _parent=0,
std::string _name="<BoundingBoxNode>" ) :
MaterialNode(_parent,
_name,
MaterialNode::BaseColor |
MaterialNode::LineWidth)
{
drawMode(DrawModes::WIREFRAME);
}
std::string _name="<BoundingBoxNode>" );
/// destructor
virtual ~BoundingBoxNode();
......@@ -100,6 +97,16 @@ public:
/// draw lines and normals
void draw(GLState& _state, const DrawModes::DrawMode& _drawMode);
/// draw with renderobjects
void getRenderObjects(IRenderer* _renderer, GLState& _state , const DrawModes::DrawMode& _drawMode , const ACG::SceneGraph::Material* _mat);
/// compute aabb of subtree
void computeAABB(Vec3d* _outMin, Vec3d* _outMax);
private:
GLLineBox* box_;
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment