0
\$\begingroup\$

I'm integrating Bullet Physics into my project for collision detection and have just gotten some debug draw functionality to work. However, the results are not what I'm expecting. I have tried to draw a sphere and box shape, but each time they turn out looking like below (this specific screenshot is how a btBoxShape is being rendered):

enter image description here

Relevant code is as follows:

//From CollisionWorld.h
class CollisionWorld {

private:
    btCollisionConfiguration*   bt_collision_configuration;
    btCollisionDispatcher*      bt_dispatcher;
    btBroadphaseInterface*      bt_broadphase;
    btCollisionWorld*           bt_collision_world;
    btScalar                    scene_size = 500;
    unsigned int                max_objects = 1000;
    CollisionDebugDrawer        collision_debug_drawer;

public:
                                CollisionWorld(bool debug = false);
                                ~CollisionWorld();
    void                        draw();
    CollisionDebugDrawer&       getCollisionDebugDrawer();
};


//From CollisionWorld.cpp
CollisionWorld::CollisionWorld(bool debug){

    bt_collision_configuration = new btDefaultCollisionConfiguration();
    bt_dispatcher = new btCollisionDispatcher(bt_collision_configuration);

    btVector3 worldAabbMin(-scene_size, -scene_size, -scene_size);
    btVector3 worldAabbMax(scene_size, scene_size, scene_size);
    bt_broadphase = new bt32BitAxisSweep3(worldAabbMin, worldAabbMax, max_objects, 0, true);

    bt_collision_world = new btCollisionWorld(bt_dispatcher, bt_broadphase, bt_collision_configuration);
    if (debug) {
        bt_collision_world->setDebugDrawer(&collision_debug_drawer);
    }

    /*btCollisionObject* sphere = new btCollisionObject();
    sphere->getWorldTransform().setOrigin(btVector3((btScalar)0, (btScalar)2, (btScalar)0));
    btSphereShape* sphere_shape = new btSphereShape(2);
    sphere->setCollisionShape(sphere_shape);
    bt_collision_world->addCollisionObject(sphere);*/

    btCollisionObject* box = new btCollisionObject();
    box->getWorldTransform().setOrigin(btVector3((btScalar)0, (btScalar)2, (btScalar)4));
    btBoxShape* box_shape = new btBoxShape(btVector3((btScalar)1, (btScalar)1, (btScalar)1));
    box->setCollisionShape(box_shape);
    bt_collision_world->addCollisionObject(box);

}

CollisionWorld::~CollisionWorld(){}

CollisionDebugDrawer& CollisionWorld::getCollisionDebugDrawer() {
    return this->collision_debug_drawer;
}

void CollisionWorld::draw() {
    this->bt_collision_world->debugDrawWorld();
}


//From CollisionDebugDrawer.h
class CollisionDebugDrawer : public btIDebugDraw {

private:
    Shader      debug_shader;

public:
                CollisionDebugDrawer();
                ~CollisionDebugDrawer();
    Shader&     getDebugShader();
    void        drawLine(const btVector3& from, const btVector3& to, const btVector3& color) override;
    void        drawContactPoint(const btVector3 &, const btVector3 &, btScalar, int, const btVector3 &) override;
    void        reportErrorWarning(const char *) override;
    void        draw3dText(const btVector3 &, const char *) override;
    void        setDebugMode(int p) override;
    int         getDebugMode(void) const override;
};


//From CollisionDebugDrawer.cpp
CollisionDebugDrawer::CollisionDebugDrawer() :
    debug_shader(GlobalConstants::DEBUG_VERTEX_SHADER, 
    GlobalConstants::DEBUG_FRAGMENT_SHADER) {};

CollisionDebugDrawer::~CollisionDebugDrawer() {};

Shader& CollisionDebugDrawer::getDebugShader() {
    return this->debug_shader;
}

void CollisionDebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color) {

    // I know this is highly inefficient, but this is just to insure everything is working as expected,
    // I plan on implementing a better solution once everything clicks

    unsigned int VBO2, VAO2;

    GLfloat points[6];

    points[0] = from.x();
    points[1] = from.y();
    points[2] = from.z();
    points[3] = to.x();
    points[4] = to.y();
    points[5] = to.z();

    glGenVertexArrays(1, &VAO2);
    glGenBuffers(1, &VBO2);
    glBindVertexArray(VAO2);

    glBindBuffer(GL_ARRAY_BUFFER, VBO2);
    glBufferData(GL_ARRAY_BUFFER, sizeof(points), &points, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glDrawArrays(GL_LINES, 0, 2);

    glBindVertexArray(0);
    glDeleteBuffers(1, &VBO2);
    glDeleteVertexArrays(1, &VAO2);

}

void CollisionDebugDrawer::drawContactPoint(const btVector3&, const btVector3&, btScalar, int, const btVector3&) {}
void CollisionDebugDrawer::reportErrorWarning(const char*) {}
void CollisionDebugDrawer::draw3dText(const btVector3&, const char *) {}
void CollisionDebugDrawer::setDebugMode(int p) {}
int CollisionDebugDrawer::getDebugMode(void) const { return 3; } // TF is 3?


//From Scene.cpp (where all of this is called)
void Scene::render(float alpha) {

    GameState lerp_render_state = lerpRenderState(alpha);

    // Set player_actor point (debug only)
    player_actor.getModel().setTranslation(lerp_render_state.player_point.position + glm::vec3(0.0f, 0.0f, -3.0f));

    // Select a color to clear the screen with and clear screen
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Same shader used for all models (collision_world uses it's own shader)
    shader.use();

    // Draw the stage
    shader.setMat4("mvp", camera.getProjectionMatrix() * camera.getViewMatrix() * stage.getModel().getModelMatrix());
    stage.getModel().draw(shader);

    // Draw the player capsule (wouldn't normally do this as capsule is for collision only)
    shader.setMat4("mvp", camera.getProjectionMatrix() * camera.getViewMatrix() * player_actor.getModel().getModelMatrix());
    player_actor.getModel().draw(shader);

    // Debug draw for collision world
    collision_world.getCollisionDebugDrawer().getDebugShader().use();
    collision_world.getCollisionDebugDrawer().getDebugShader().setMat4("vp", camera.getProjectionMatrix() * camera.getViewMatrix());
    collision_world.draw();

}

Does anything stick out as being horribly incorrect? I feel like this is probably something simple I've missed.

\$\endgroup\$
  • \$\begingroup\$ I don't really have the knowledge to take a stab at answering this anymore, but in case it helps I did successfully implement the bullet debug drawer with OpenGL a couple years ago: github.com/Chaosed0/SpiderGame/blob/master/Engine/src/Renderer/… \$\endgroup\$ – Chaosed0 Jun 12 at 22:05
  • \$\begingroup\$ @Chaosed0 My answer may lie within your code! Thank you for posting this. I will take a look. \$\endgroup\$ – nullReference Jun 12 at 22:51
0
\$\begingroup\$

Issue wound up being something simple as expected. I was using the incorrect value for the stride parameter in the glVertexAttribPointer function

This:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);

Should have been this:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.