btIDebugDraw with OpenGL 4.4 - [SOLVED]

Post Reply
User avatar
manmohan29
Posts: 15
Joined: Wed Aug 20, 2014 9:26 pm
Location: Chandigarh, India

btIDebugDraw with OpenGL 4.4 - [SOLVED]

Post by manmohan29 »

I am trying to implement btIDebugDraw interface in an OpenGL 4.4 application.

First I initialize the Physics world like this :

Code: Select all

void initPhysics()
{
    broadphase = new btDbvtBroadphase();
    collisionConfiguration = new btDefaultCollisionConfiguration();
    dispatcher = new btCollisionDispatcher(collisionConfiguration);
    solver = new btSequentialImpulseConstraintSolver;

    dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
    dynamicsWorld->setGravity(btVector3(0, -10, 0));

    //groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 1);
    groundShape = new btBoxShape(btVector3(5, 5, 5));
    fallShape = new btBoxShape(btVector3(1, 1, 1));
    //fallShape = new btSphereShape(1);

    // Orientation and Position of Ground
    groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, -3, 0)));
    btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0, groundMotionState, groundShape, btVector3(0, 0, 0));
    groundRigidBody = new btRigidBody(groundRigidBodyCI);
    dynamicsWorld->addRigidBody(groundRigidBody);

    // Orientation and Position of Falling body
    fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(-1, 5, 0)));
    btScalar mass = 1;
    btVector3 fallInertia(0, 0, 0);
    fallShape->calculateLocalInertia(mass, fallInertia);
    btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, fallMotionState, fallShape, fallInertia);
    fallRigidBody = new btRigidBody(fallRigidBodyCI);
    dynamicsWorld->addRigidBody(fallRigidBody);

    bulletDebugugger.setDebugMode(btIDebugDraw::DBG_DrawWireframe);
    dynamicsWorld->setDebugDrawer(&bulletDebugugger);

}
This is my debug drawer class's definition :

Code: Select all

#pragma once
#include <LinearMath/btIDebugDraw.h>

class CDebugDraw :
    public btIDebugDraw
{
private:
    int m_debugMode;
public:
    CDebugDraw(void);
    virtual ~CDebugDraw(void);

    struct _LINE {
        btVector3 from;
        btVector3 to;

        _LINE(btVector3 f, btVector3 t) {
            from = f;
            to = t;
        }
    };

    std::vector<_LINE> LINES;

    struct _COLOR {
        btVector3 col;

        _COLOR(btVector3 c) {
            col = c;
        }
    };

    std::vector<_COLOR> COLORS;

    GLuint vao, vbo[2];

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

    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 m_debugMode);

    virtual int getDebugMode() const;

    void doDrawing();
    void cleanDrawing();
};


In the Implementaion DebugDraw.cpp I push all the fromand to vertices in a std::vector struct and save that in a VBO later.

Code: Select all

void CDebugDraw::drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
{
    LINES.push_back(_LINE(from, to));
    COLORS.push_back(_COLOR(color));
}

void CDebugDraw::doDrawing()
{
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(2, vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, LINES.size() * sizeof(_LINE), &LINES[0], GL_STATIC_DRAW);
    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glBufferData(GL_ARRAY_BUFFER, COLORS.size() * sizeof(_COLOR), &COLORS[0], GL_STATIC_DRAW);
    glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(1);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

}

void CDebugDraw::cleanDrawing()
{
    // delete buffers
    glDeleteBuffers(2, vbo);
    glDeleteBuffers(1, &vao);
}
now in my rendering function I draw like this :

Code: Select all

// Debug drawing
    glBindVertexArray(bulletDebugugger.vao);
    glDrawArrays(GL_LINES, 0, bulletDebugugger.LINES.size());
    // Clear vectors
    bulletDebugugger.LINES.clear();
    bulletDebugugger.COLORS.clear();

The "triangle" seems to fall from top and stop at the position shown in the screenshot attached. The color of some lines changes from blue to red.

But there are weird lines in the window, I guess that is due to the Debug Drawing function. I think I am doing something wrong in my code.

Can someone guide me where am I doing wrong ?
Has anyone implemented a debug drawer using VAO and/or VBO in OpenGL 4 ?
Attachments
Screenshot
Screenshot
ttt.png (85.87 KiB) Viewed 14915 times
Last edited by manmohan29 on Fri Aug 22, 2014 1:22 pm, edited 1 time in total.
rebirth
Posts: 24
Joined: Thu Jul 24, 2014 2:48 am

Re: btIDebugDraw with OpenGL 4.4

Post by rebirth »

The way I have it set up using 3.3 (core profile) is by making the line out of a triangle (start-end-start). After all the lines are collected they are passed to the vertex/index buffers and rendered without polygon fill. It's probably not the best way to do it, but it works. Another way is to maybe use a geometry shader, but I haven't tried that myself.
User avatar
manmohan29
Posts: 15
Joined: Wed Aug 20, 2014 9:26 pm
Location: Chandigarh, India

Re: btIDebugDraw with OpenGL 4.4

Post by manmohan29 »

I got it to fix a little bit.

In my CDebugDraw::drawLine function I changed the way I was adding vertices to the vectors. I also changed the definition of structs LINE and COLORS to use glm::vec3 instead of btVector3. Now code is like this :

Code: Select all

void CDebugDraw::drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
{
    // Changed these lines 
    /*LINES.push_back(_LINE(from, to));
    COLORS.push_back(_COLOR(color));*/

    // to these
    LINES.push_back(_LINE(vec3(from.getX(), from.getY(), from.getZ()), vec3(to.getX(), to.getY(), to.getZ())));
    COLORS.push_back(_COLOR(vec3(color.getX(), color.getY(), color.getZ())));
}
If I clear the vectors LINE and COLORS before next call to my render function then the sphere is not perfect. But if I DO NOT clear the vectors then, all the positions of sphere are drawn (as expected) but sphere is perfect.
pic.png
pic.png (122.56 KiB) Viewed 14896 times
do I need to store some vertices in my LINES vector for the next call to drawLine, to draw perfect sphere ?
rebirth
Posts: 24
Joined: Thu Jul 24, 2014 2:48 am

Re: btIDebugDraw with OpenGL 4.4

Post by rebirth »

By the looks of it, your buffers are incomplete, because the colours are also wrong. Bullet is not giving out lines which blend between two colours as can be seen by the axis widget in the centre of the cube. They should be fixed coloured RGB lines to represent the XYZ axis.
User avatar
manmohan29
Posts: 15
Joined: Wed Aug 20, 2014 9:26 pm
Location: Chandigarh, India

Re: btIDebugDraw with OpenGL 4.4

Post by manmohan29 »

@rebirth seems like you are right about incomplete buffers.
can you post your OpenGL 3.3 core profile code (just the part where you store vertices and pass to buffer arrays) here or may be on pastebin ?
rebirth
Posts: 24
Joined: Thu Jul 24, 2014 2:48 am

Re: btIDebugDraw with OpenGL 4.4

Post by rebirth »

I'm away from my home PC at the moment so it will have to wait a few hours. However, from the top of my head I am using indexed triangles. So, the line is created using the two points:

glm::vec3 points[2]

And rendered using 3 indices:
short indices[3] = { 0, 1, 0 }
User avatar
manmohan29
Posts: 15
Joined: Wed Aug 20, 2014 9:26 pm
Location: Chandigarh, India

Re: btIDebugDraw with OpenGL 4.4

Post by manmohan29 »

I have two rigid bodies in my world. So if I add a condition to clear the vectors only if there have been two passes for the drawLine()

Code: Select all

++c; // increment counter
if (c == 2)
    {
        // Yes counter is equal to number of bodies, then we have all the vertices for debug drawing, now reset the vectors.
        LINES.clear();
        COLORS.clear();
        c = 0; // reset counter
    }
then I get FULL sphere (Ignore the color of vertices at the moment) as seen below in screenshot :
full.png
full.png (65.5 KiB) Viewed 14849 times
and if I change falling body's shape to btBoxShape, then I see full cube (Ignore the color of vertices at the moment) as seen below :
full_cube.png
full_cube.png (72.65 KiB) Viewed 14849 times
So if I have say 100 rigid bodies in my world, then to debug draw all 100 objects I need 100 passes of drawLine, is it so ?
Does bullet render only one rigid body in a single pass to drawLine() ? seems like that to me.
User avatar
manmohan29
Posts: 15
Joined: Wed Aug 20, 2014 9:26 pm
Location: Chandigarh, India

Re: btIDebugDraw with OpenGL 4.4 - SOLVED

Post by manmohan29 »

All this issue was due to incorrect count being passed to glDrawArrays().
In my previous code if I use this :

Code: Select all

glDrawArrays(GL_LINES, 0, bulletDebugugger.LINES.size() * 2); // size * 2 , because I have TWO vertices in my LINES struct.
then I have proper lines drawn.

I am not passing COLORS to VBO so all lines are in same color and have changed background color to white.
indices.png
indices.png (77.14 KiB) Viewed 14805 times
Using indices seems to do the trick.

Code: Select all

// Debug drawing
    /*
    glBindVertexArray(bulletDebugugger.vao);
    glDrawArrays(GL_LINES, 0, bulletDebugugger.LINES.size());*/
    ///////////////////////////
    vector<GLfloat> vertices;
    vector<GLuint> indices;
    unsigned int indexI = 0;
    
    for (vector<CDebugDraw::_LINE>::iterator it = bulletDebugugger.LINES.begin(); it != bulletDebugugger.LINES.end(); it++)
    {
        CDebugDraw::_LINE l = *it;
        
        vertices.push_back(l.from.x);
        vertices.push_back(l.from.y);
        vertices.push_back(l.from.z);

        vertices.push_back(l.to.x);
        vertices.push_back(l.to.y);
        vertices.push_back(l.to.z);
        
        indices.push_back(indexI);
        indices.push_back(indexI + 1);
        indexI += 2;
    }
    glBindVertexArray(bulletDebugugger.vao);
    glDrawElements(GL_LINES, indices.size(), GL_UNSIGNED_INT, (void*)&indices[0]);
    ///////////////////////////
I found this code while surfing on YouTube !!! Yes, here's link to his cool project video : https://www.youtube.com/watch?v=nhQK1dfCxDQ
:D so unexpected !!
Thanks to "Tomáš Kimer", I found his code useful. Here's the link to it : https://github.com/david-sabata/Univers ... e.cpp#L584
For Visual Studio 2010 here's code : https://docs.google.com/file/d/0BzrGmqQ ... hyb3c/edit
so that others can refer it.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: btIDebugDraw with OpenGL 4.4

Post by Erwin Coumans »

latest Bullet has OpenGL 3+ rendering, see App_AllBullet2Demos and those links:

https://github.com/bulletphysics/bullet ... .cpp#L1382
https://github.com/bulletphysics/bullet ... ugDrawer.h
Ziket
Posts: 3
Joined: Thu Mar 23, 2017 11:17 am

Re: btIDebugDraw with OpenGL 4.4 - [SOLVED]

Post by Ziket »

Use this in your DrawLine and it will work fine (with the correct colors represent the normals)
First u have to compile you program! Dont forgot it, and multiply the gl_FragPosition with the view and projection matrix (the position is getter in world pos)

Code: Select all

 struct btLine{
    GLfloat vertices[6];
    btLine(const btVector3& f, const btVector3& t){
      vertices[0] = f.x();
      vertices[1] = f.y();
      vertices[2] = f.z();

      vertices[3] = t.x();
      vertices[4] = t.y();
      vertices[5] = t.z();
    }
  };

Code: Select all

GME::btLine lines(from, to);
  btVector3 result = to - from;
  glm::vec3 colors = {result.x(), result.y(), result.z()};
  colors = glm::normalize(colors);
  GLuint indices[] = {0,1};

  GLuint vao, vbo, ebo;

  glGenVertexArrays(1, &vao);
  glGenBuffers(1, &vbo);
  glGenBuffers(1, &ebo);

  glBindVertexArray(vao);

  //UPLOADING VERTEX
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  glBufferData(GL_ARRAY_BUFFER,
               sizeof(GLfloat) * 6, lines.vertices, GL_STATIC_DRAW);
  //UPLOADING INDEXES
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER,
               sizeof(GLuint) * 2,
               indices,
               GL_STATIC_DRAW);
  glEnableVertexAttribArray(0);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
                        sizeof(GLfloat) * 3, (GLvoid*)0);
  glBindVertexArray(0);


  //use program
  material_->use();
  material_->setValue(glm::value_ptr(colors), "ph_objectColor");
  material_->setProjectionMatrix(gmeinstance->getCurrentCamera()->getProjectionMatrix());
  material_->setViewMatrix(gmeinstance->getCurrentCamera()->getViewMatrix());
  //use geometry
  glBindVertexArray(vao);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ebo);
  glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, 0);
  glBindVertexArray(0);

  //delete buffers
  glDeleteVertexArrays(1, &vao);
  glDeleteBuffers(1, &vbo);
  glDeleteBuffers(1, &ebo);
Post Reply