Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement the btIDebugDraw interface of Bullet in OpenGL 4.0

Bullet has an implementation of the btIDebugDraw interface in older OpenGL which is used to draw the physics world for debugging. The interface is like this :

class GLDebugDrawer : public btIDebugDraw
{
int m_debugMode;

public:

GLDebugDrawer();
virtual ~GLDebugDrawer(); 

virtual void    drawLine(const btVector3& from,const btVector3& to,const btVector3&  fromColor, const btVector3& toColor);

virtual void    drawLine(const btVector3& from,const btVector3& to,const btVector3& color);

virtual void    drawSphere (const btVector3& p, btScalar radius, const btVector3& color);

virtual void    drawTriangle(const btVector3& a,const btVector3& b,const btVector3& c,const btVector3& color,btScalar alpha);

virtual void    drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color);

virtual void    reportErrorWarning(const char* warningString);

virtual void    draw3dText(const btVector3& location,const char* textString);

virtual void    setDebugMode(int debugMode);

virtual int     getDebugMode() const { return m_debugMode;}

};

The OpenGL 1.1 implementation works in immediate mode sending vertices down to the GPU at every function call. eg. here is drawLine()

void    GLDebugDrawer::drawLine(const btVector3& from,const btVector3& to,const btVector3& fromColor, const btVector3& toColor)
{

    glBegin(GL_LINES);
        glColor3f(fromColor.getX(), fromColor.getY(), fromColor.getZ());
        glVertex3d(from.getX(), from.getY(), from.getZ());
        glColor3f(toColor.getX(), toColor.getY(), toColor.getZ());
        glVertex3d(to.getX(), to.getY(), to.getZ());
    glEnd();
}

To convert this into OpenGL 4.0, I am thinking of using a Vertex Array Object defined as a member of this class, say mVAO and the VBOs will also be members. I will setup the VAO in the ctor of GLDebugDrawer and then generate and send vertices to the VBO as well as render it within drawLine()

drawLine()
{
    // Update buffers
    // Bind and render the buffer
}

But since I ll be sending vertices everytime drawLine() gets called, it seems I am not using the power of VAO but instead simulating immediate mode rather badly!

What would be a better way to implement a line drawing function in this interface whose vertices can change in every call ?

I want to use this code in my android app later to check my physics, so I am rewriting the interface in OpenGL 4.0 which I assume will be easier to convert to openGLES 2.0 .

I was thinking of recording the vertices in a vector at every drawLine() call and then updating the VBO after all of Bullet's calls to the btIDebugDraw functions are complete. Then I would not need to send pairs of vertices intermittently to the GPU as Bullet calls the btIDebugDraw functions.

I have got some information here about managing vertex data so far : http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html

like image 494
safe_malloc Avatar asked Dec 23 '12 03:12

safe_malloc


1 Answers

Do not immediately draw on drawLine(). :)
Instead push the Vertices/Colors into a buffer in Host/RAM.

After the call to dynamicsWorld->debugDrawWorld(), you know that your DebugDrawer got all the lines for the frame, so you can do:

  1. update the VBOs once
  2. glDraw ...
  3. clear the Host Buffer
like image 142
paroj Avatar answered Jan 03 '23 10:01

paroj