Реализация btIDebugDraw ничего не рисует - PullRequest
0 голосов
/ 30 марта 2020

Я недавно реализовал интерфейс btIDebugDraw из библиотеки движка пули, я использую C ++.

Когда я запускаю приложение, ничего не рисуется, ни одна линия. Затем я вставил несколько вызовов печати в стандартный вывод, чтобы проверить, был ли вызван метод drawLine, и, как ни странно, его никогда не вызывают.

Единственный вызываемый метод - это draw3dText ... и я даже не хочу чтобы сделать это сейчас.

Что не так с моим кодом? PS: я протестировал свою функцию drawLine вне класса, и она работает.

Вот код:

Реализация btIDebugDraw

#include "debugDraw.hpp"

DebugDraw::DebugDraw() :
    debug_mode(btIDebugDraw::DBG_DrawWireframe),
    line_shader("../shaders/line/vertex.glsl", "../shaders/line/fragment.glsl", "../shaders/line/geometry.glsl")
{
    // line VAO and VBO
    glGenVertexArrays(1, &line_VAO);
    glBindVertexArray(line_VAO);

    glGenBuffers(1, &line_VBO);
    glBindBuffer(GL_ARRAY_BUFFER, line_VBO);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), nullptr, GL_DYNAMIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    std::cout << "debug draw constructor" << std::endl;
}

void DebugDraw::drawLine(const btVector3 & from, const btVector3 & to, const btVector3 & color)
{
    line_shader.use();
    float vertices[] = {from.x(), from.y(), from.z(), to.x(), to.y(), to.z()};

    glBindVertexArray(line_VAO);
    glBindBuffer(GL_ARRAY_BUFFER, line_VBO);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
    glDrawArrays(GL_LINES, 0, 2);
    glBindVertexArray(0);

    std::cout << "draw line" << std::endl;
}

void DebugDraw::drawContactPoint(const btVector3 & PointOnB, const btVector3 & normalOnB, btScalar distance, int lifeTime, const btVector3 & color)
{
    std::cout << "draw contact point" << std::endl;
}

void DebugDraw::reportErrorWarning(const char * warningString)
{
    std::cout << "-=-=-=- Debug Draw ERROR -=-=-=-" << std::endl;
    std::cout << warningString << std::endl;
    std::cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << std::endl;
}

void DebugDraw::draw3dText(const btVector3 & location, const char * textString)
{
    std::cout << "draw 3d text" << std::endl;
}

void DebugDraw::setDebugMode(int debugMode)
{
    std::cout << "set debug mode" << std::endl;
    debug_mode = debugMode;
}

int DebugDraw::getDebugMode() const { return debug_mode; }

main

#include <SDL2/SDL.h>
#include <GL/glew.h>
#include "object.hpp"
#include "mesh.hpp"
#include "shader.hpp"
#include "camera.hpp"
#include "debugDraw.hpp"
#include <iostream>
#include <cmath>
#include <omp.h>
#include <string>
#include <btBulletDynamicsCommon.h>
/*
#include <BulletCollision/BroadphaseCollision/btDispatcher.h>
#include <btGImpactCollisionAlgorithm.h>
#include <btGImpactShape.h>
*/
#define SCREEN_W 1560
#define SCREEN_H 780

// -----global-----
struct UserActions user_actions;
bool app = true;

// -----prototypes-----
SDL_Window* createWindow(int w, int h, const std::string & title);
void check_events(SDL_Event& event, const Uint8* keyboardState, Uint32& mouseButtonBitMask, int& mouseX_rel, int& mouseY_rel);
glm::mat4 bullet2glmMatrix(btScalar* matrix);
void draw_line(glm::vec3 from, glm::vec3 to, Shader & shader, GLuint & lineVAO, GLuint & lineVBO);

// -----functions-----
SDL_Window* createWindow(int w, int h, const std::string & title)
{
    SDL_Window* window = nullptr;

    if(SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        std::cerr << SDL_GetError() << std::endl;
        return nullptr;
    }

    // OpenGL Version
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);

    // Double Buffer
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

    if(window == nullptr)
    {
        std::cerr << SDL_GetError() << std::endl;
        return nullptr;
    }

    return window;
}

void check_events(SDL_Event& event, const Uint8* keyboardState, Uint32& mouseButtonBitMask, int& mouseX_rel, int& mouseY_rel)
{
    keyboardState = SDL_GetKeyboardState(nullptr);
    mouseButtonBitMask = SDL_GetRelativeMouseState(&mouseX_rel, &mouseY_rel);

    while(SDL_PollEvent(&event))
    {
        if(event.type == SDL_QUIT)
        {
           app = false; 
        }
        if(event.type == SDL_MOUSEWHEEL)
        {
            user_actions.mouse_scroll = true;
            user_actions.scroll_direction = event.wheel.y;
        }
        else
        {
            user_actions.mouse_scroll = false;
            user_actions.scroll_direction = 0;
        }
        if(event.type == SDL_MOUSEMOTION)
        {
            user_actions.mouseX = event.motion.x;
            user_actions.mouseY = event.motion.y;
        }
    }

    if(SDL_BUTTON(mouseButtonBitMask) == SDL_BUTTON_MIDDLE)
    {
        user_actions.xRel = mouseX_rel;
        user_actions.yRel = mouseY_rel;
        user_actions.mouse_middle = true;
    }
    else
    {
        user_actions.xRel = 0;
        user_actions.yRel = 0;
        user_actions.mouse_middle = false;
    }
    if(SDL_BUTTON(mouseButtonBitMask) == SDL_BUTTON_LEFT)
        user_actions.mouse_left = true;
    else
        user_actions.mouse_left = false;

    if(keyboardState[SDL_SCANCODE_LSHIFT])
        user_actions.key_shift = true;
    else
        user_actions.key_shift = false;
    if(keyboardState[SDL_SCANCODE_DOWN])
        user_actions.key_down = true;
    else
        user_actions.key_down = false;
    if(keyboardState[SDL_SCANCODE_UP])
        user_actions.key_up = true;
    else
        user_actions.key_up = false;
    if(keyboardState[SDL_SCANCODE_LEFT])
        user_actions.key_left = true;
    else
        user_actions.key_left = false;
    if(keyboardState[SDL_SCANCODE_RIGHT])
        user_actions.key_right = true;
    else
        user_actions.key_right = false;
}

glm::mat4 bullet2glmMatrix(btScalar* matrix)
{
    return glm::mat4(
            matrix[0], matrix[1], matrix[2], matrix[3],
            matrix[4], matrix[5], matrix[6], matrix[7],
            matrix[8], matrix[9], matrix[10], matrix[11],
            matrix[12], matrix[13], matrix[14], matrix[15]);
}

void draw_line(glm::vec3 from, glm::vec3 to, Shader & shader, GLuint & lineVAO, GLuint & lineVBO)
{
    shader.use();
    float vertices[] = {from.x, from.y, from.z, to.x, to.y, to.z};

    glBindVertexArray(lineVAO);
    glBindBuffer(GL_ARRAY_BUFFER, lineVBO);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
    glDrawArrays(GL_LINES, 0, 2);
    glBindVertexArray(0);
}

// -----main-----

int main(int argc, char* argv[])
{
    // create an opengl window
    SDL_Window * window = createWindow(SCREEN_W, SCREEN_H, "test bullet-physics");

    // create OpenGL context
    SDL_GLContext glContext = SDL_GL_CreateContext(window);

    // Glew init
    glewExperimental = true;
    GLenum err = glewInit();
    if(err != GLEW_OK)
    {
        std::cerr << glewGetErrorString(err) << std::endl;
        SDL_GL_DeleteContext(glContext);
        SDL_DestroyWindow(window);
        SDL_Quit();
        std::exit(-1);
    }

    // OpenGL states
    glViewport(0, 0, SCREEN_W, SCREEN_H);
    glEnable(GL_DEPTH_TEST);
    glLineWidth(2.5f);
    SDL_GL_SetSwapInterval(1);

    // lineVAO and lineVBO
    GLuint lineVAO, lineVBO;
    glGenVertexArrays(1, &lineVAO);
    glBindVertexArray(lineVAO);

    glGenBuffers(1, &lineVBO);
    glBindBuffer(GL_ARRAY_BUFFER, lineVBO);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), nullptr, GL_DYNAMIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // create camera
    Camera* cam = new Camera(60.0f, SCREEN_W, SCREEN_H);

    // sunshine
    glm::vec3 sun_dir(1.0f, -1.0f, 1.0f);
    glm::vec3 sun_color(1.0, 1.0, 1.0);

    // line shader
    Shader* line_shader = new Shader("../shaders/line/vertex.glsl", "../shaders/line/fragment.glsl", "../shaders/line/geometry.glsl");
    line_shader->use();
    line_shader->set_Matrix("model", glm::mat4(1.0f));

    // basic shader
    Shader* basic = new Shader("../shaders/vertex.glsl", "../shaders/fragment.glsl", "../shaders/geometry.glsl");
    basic->use();
    basic->set_Matrix("model", glm::mat4(1.0f));
    basic->set_Matrix("view", cam->get_view());
    basic->set_Matrix("proj", cam->get_projection());
    basic->set_vec3f("sun.dir", sun_dir);
    basic->set_vec3f("sun.color", sun_color);

    // load ground
    Object* ground = new Object("../assets/ground.obj", true);

    // load suzy
    Object* suzy = new Object("../assets/suzanne.obj", true);

    // ----- bullet initialization start -----
    btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
    btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
    btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase();
    btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
    btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
    dynamicsWorld->setGravity(btVector3(0, -10, 0));

    btIDebugDraw * debug = new DebugDraw();
    dynamicsWorld->setDebugDrawer(debug);

    //btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);
    // ----- bullet initialization end -----

    // array of rigid bodies
    btAlignedObjectArray<btCollisionShape*> collisionShapes;

    // ----- ground static rigid body
    {
        std::vector<Mesh*> meshes = ground->get_mesh_collection();
        for(int i = 0; i < meshes.size(); i++)
        {
            Mesh* m = meshes.at(i);
            const std::vector<Vertex> & vertices = m->get_vertex_list();
            const std::vector<int> & indices = m->get_index_list();

            btTriangleMesh* striding_interface = new btTriangleMesh();
            for(int j = 0; j < indices.size(); j += 3)
            {
                btVector3 v0(vertices.at(indices.at(j)).position.x, vertices.at(indices.at(j)).position.y, vertices.at(indices.at(j)).position.z);
                btVector3 v1(vertices.at(indices.at(j+1)).position.x, vertices.at(indices.at(j+1)).position.y, vertices.at(indices.at(j+1)).position.z);
                btVector3 v2(vertices.at(indices.at(j+2)).position.x, vertices.at(indices.at(j+2)).position.y, vertices.at(indices.at(j+2)).position.z);

                striding_interface->addTriangle(v0, v1, v2, true);
            }
            //btCollisionShape* groundShape = new btGImpactMeshShape(striding_interface);
            btCollisionShape* groundShape = new btBvhTriangleMeshShape(striding_interface, true);

            collisionShapes.push_back(groundShape);

            btTransform groundTransform;
            groundTransform.setIdentity();
            groundTransform.setOrigin(btVector3(0, 0, 0));

            btScalar mass(0.0);
            btVector3 localInertia(0, 0, 0);
            btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
            btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
            btRigidBody* body = new btRigidBody(rbInfo);

            // add the body to the dynamics world
            dynamicsWorld->addRigidBody(body);
        }
    }
    // suzy dynamic rigid body
    {
        std::vector<Mesh*> meshes = suzy->get_mesh_collection();
        for(int i = 0; i < meshes.size(); i++)
        {
            Mesh* m = meshes.at(i);
            const std::vector<Vertex> & vertices = m->get_vertex_list();
            const std::vector<int> & indices = m->get_index_list();

            btTriangleMesh* striding_interface = new btTriangleMesh();
            for(int j = 0; j < indices.size(); j += 3)
            {
                btVector3 v0(vertices.at(indices.at(j)).position.x, vertices.at(indices.at(j)).position.y, vertices.at(indices.at(j)).position.z);
                btVector3 v1(vertices.at(indices.at(j+1)).position.x, vertices.at(indices.at(j+1)).position.y, vertices.at(indices.at(j+1)).position.z);
                btVector3 v2(vertices.at(indices.at(j+2)).position.x, vertices.at(indices.at(j+2)).position.y, vertices.at(indices.at(j+2)).position.z);

                striding_interface->addTriangle(v0, v1, v2, true);
            }
            //btCollisionShape* suzyShape = new btGImpactMeshShape(striding_interface);
            btCollisionShape* suzyShape = new btBvhTriangleMeshShape(striding_interface, true);

            collisionShapes.push_back(suzyShape);

            btTransform suzyTransform;
            suzyTransform.setIdentity();
            suzyTransform.setOrigin(btVector3(0, 0, 0));

            btScalar mass(1.0);
            btVector3 localInertia(0, 0, 0);

            suzyShape->calculateLocalInertia(mass, localInertia);

            btDefaultMotionState* myMotionState = new btDefaultMotionState(suzyTransform);
            btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, suzyShape, localInertia);
            btRigidBody* body = new btRigidBody(rbInfo);

            // add the body to the dynamics world
            dynamicsWorld->addRigidBody(body);
        }

    }

    // main loop
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    SDL_Event event;
    const Uint8 * keyboardState = nullptr;
    Uint32 mouseButtonBitMask;
    int mouseX_rel = 0, mouseY_rel = 0;
    double delta = 0.0;
    double current_time = 0.0;
    double last_time = 0.0;

    while(app)
    {
        // compute delta
        last_time = current_time;
        current_time = omp_get_wtime();
        delta = current_time - last_time;

        // update camera data
        check_events(event, keyboardState, mouseButtonBitMask, mouseX_rel, mouseY_rel);
        cam->update_view(user_actions, delta);

        // clear screen
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // physics simulations
        dynamicsWorld->stepSimulation(1.0f/60.0f, 10);
        btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[1];
        btRigidBody* body = btRigidBody::upcast(obj);
        btTransform trans;
        if(body && body->getMotionState())
            body->getMotionState()->getWorldTransform(trans);
        else
            trans = obj->getWorldTransform();

        btScalar matrix[16];
        trans.getOpenGLMatrix(matrix);
        glm::mat4 bullet_model = bullet2glmMatrix(matrix);

        // draw
        /*
        basic->use();
        basic->set_Matrix("model", glm::mat4(1.0f));
        basic->set_Matrix("view", cam->get_view());
        basic->set_Matrix("proj", cam->get_projection());
        ground->draw(*basic);
        basic->set_Matrix("model", bullet_model);
        suzy->draw(*basic);

        // draw some lines
        line_shader->use();
        line_shader->set_Matrix("view", cam->get_view());
        line_shader->set_Matrix("proj", cam->get_projection());
        draw_line(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 25.0f, 0.0f), *line_shader, lineVAO, lineVBO);
        draw_line(glm::vec3(0.0f, 25.0f, 0.0f), glm::vec3(25.0f, 25.0f, 0.0f), *line_shader, lineVAO, lineVBO);
        draw_line(glm::vec3(25.0f, 25.0f, 0.0f), glm::vec3(25.0f, 0.0f, 0.0f), *line_shader, lineVAO, lineVBO);
        */

        // debug draw
        dynamicsWorld->debugDrawWorld();

        SDL_GL_SwapWindow(window);
    }

    // clean
    SDL_GL_DeleteContext(glContext);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

Спасибо!

...