如何在OpenGL 4.0中实现Bullet的btIDebugDraw接口

saf*_*loc 6 bulletphysics opengl-3

Bullet在旧的OpenGL中有一个btIDebugDraw接口的实现,用于绘制物理世界以进行调试.界面是这样的:

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;}

};
Run Code Online (Sandbox Code Playgroud)

OpenGL 1.1实现以立即模式工作,在每次函数调用时将顶点向下发送到GPU.例如.这是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();
}
Run Code Online (Sandbox Code Playgroud)

要将其转换为OpenGL 4.0,我正在考虑使用定义为此类成员的顶点数组对象,例如mVAO,VBO也将是成员.我将在GLDebugDrawer的ctor中设置VAO,然后生成顶点并将其发送到VBO并在drawLine()中渲染它

drawLine()
{
    // Update buffers
    // Bind and render the buffer
}
Run Code Online (Sandbox Code Playgroud)

但是因为每次调用drawLine()时我都会发送顶点,看来我没有使用VAO的强大功能,而是模拟立即模式而非常糟糕!

在这个接口中实现线条绘制功能的更好方法是什么?它的顶点可以在每次调用中改变

我想稍后在我的Android应用程序中使用此代码来检查我的物理,所以我在OpenGL 4.0中重写接口,我认为这将更容易转换为openGLES 2.0.

我想在每次drawLine()调用时在向量中记录顶点,然后在所有Bullet对btIDebugDraw函数的调用完成后更新VBO.然后,当Bullet调用btIDebugDraw函数时,我不需要间歇性地向GPU发送成对的顶点.

到目前为止,我在这里有一些关于管理顶点数据的信息:http: //developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html

小智 6

不要马上画画drawLine().:)
而是将Vertices/Colors推入主机/ RAM中的缓冲区.

通话结束后dynamicsWorld->debugDrawWorld(),您知道您DebugDrawer获得了该帧的所有行,因此您可以执行以下操作:

  1. 更新VBO一次
  2. glDraw ...
  3. 清除主机缓冲区