使用顶点缓冲区对象(VBO)渲染Kinect点云

Ian*_*ros 8 c++ opengl stream vbo kinect

我正在尝试制作动态点云可视化工具.使用Kinect传感器每帧更新点数.为了抓住帧我使用OpenCV和GLUT来显示.对于点xyz位置,OpenCV API返回640 x 480(float*),对于rgb颜色数据,返回640 x 480(int*).为了获得最大性能,我尝试在流模式下使用顶点缓冲区对象而不是简单的顶点阵列.我能够使用Vertex Array渲染它,但是我的VBO实现没有渲染任何东西.我在声明中尝试了一堆不同的命令,但我找不到我所遗漏的东西.有人可以试着指出我正确的方向吗?以下是简化的代码:(我已经重写了Christian Rau提出的错误版本,所以你们可以理解我的错误)

int main()
{
    //Delaring variables, inittiating glut, setting camera and checking the compatibility as http://www.songho.ca/opengl/gl_vbo.html
    glutDisplayFunc(displayCB);
    glutIdleFunc(displayCB); 
    ... 
    //Inittiating the vertex buffers
    if(vboSupported)
    {
        glGenBuffers(1, &vertex_buffer);
        glBindBuffer(GL_ARRAY_BUFFER_ARB, buffer);
        glBufferData(GL_ARRAY_BUFFER_ARB, (sizeof(GLfloat) * 640 * 480 * 3), 0, GL_STREAM_DRAW_ARB);
        glBufferSubData(GL_ARRAY_BUFFER_ARB, 0,  (sizeof(float) * 640 * 480 * 3), point_cloud.points_position); 

        glGenBuffers(2, &color_buffer);
        glBindBuffer(GL_ARRAY_BUFFER_ARB, buffer);
        glBufferData(GL_ARRAY_BUFFER_ARB, (sizeof(GLbyte) * 640 * 480 * 3), 0, GL_STREAM_DRAW_ARB);
        glBufferSubData(GL_ARRAY_BUFFER_ARB, 0,  (sizeof(char) * 640 * 480 * 3), point_cloud.points_color); 
    }
    //glutMainLoop(), cleaning memory, ending main
    ..
}

//Updating the screen
void displayCB()
{
    point_cloud.update();

    // clear buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // save the initial ModelView matrix before modifying ModelView matrix
    glPushMatrix();

        glBindBuffer(GL_ARRAY_BUFFER_ARB, color_buffer);
        glBufferSubData(GL_ARRAY_BUFFER_ARB, 0,  (sizeof(char) * 640 * 480 * 3), point_cloud.points_color); 
        glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER_ARB, vertex_buffer);
        glBufferSubData(GL_ARRAY_BUFFER_ARB, 0,  (sizeof(float) * 640 * 480 * 3), point_cloud.points_position); 
        glVertexPointer(3, GL_FLOAT, 0, 0));

        // enable vertex arrays
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);

        glDrawArrays(GL_POINT, 0, 640*480);

        glDisableClientState(GL_VERTEX_ARRAY);  // disable vertex arrays
        glDisableClientState(GL_COLOR_ARRAY);

        glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);

    glPopMatrix();

    glutSwapBuffers();
}
Run Code Online (Sandbox Code Playgroud)

Ian*_*ros 0

PS:程序已启动并运行,但与顶点数组版本相比,我看不到平均性能有任何改进。可以吗?\n问题已解决。I\xc2\xb4ve 做了三处修改:

\n\n
1 - I though that glGenBuffers first parameter was the number that\nwould be associated to the buffer, instead, its the number of\nbuffers that would be allocated. This doesn't matter anyway, because\nnow I'm using a single buffer and adding all the data to it. Didn't\nsolved the problem, but was going in the right way.\n\n2 - There are two ways of being able to use OpenGL VBO functions.\nFirst, you can bind the ARB  version functions by yourself OR you\ncan add glew.h and use glewInit() after starting an OpenGL context.\nThe second option is a LOT cleaner and I changed my code so I don't\nuse the ARB versions anymore. Still didn't solved the problem.\n\n3 - Christian Rau asked me for glErrors in the code, so, I wrote it\nafter each OpenGL operation in displayCB. After glDrawArrays I got\nan 0x00500 error, that means there is an invalid enum, so I noticed\nI was using GL_POINT as parameter to glDrawArrays, instead of\nGL_POINTS, so silly that makes me want to kill myself.\n
Run Code Online (Sandbox Code Playgroud)\n\n

最终代码:

\n\n
//EDIT: Added glew.h as a header and I\xc2\xb4m not using the ARB version anymore\n#include <glew.h>\n\n    int main()\n    {\n        //Declaring variables, initiating glut, setting camera and checking the compatibility as http://www.songho.ca/opengl/gl_vbo.html\n        glutDisplayFunc(displayCB);\n        glutIdleFunc(displayCB); \n        ...\n\n        //EDIT: IS VERY IMPORTANT TO ADD IT AS SOON AS YOU START AN OPENGL CONTEXT.\n        initGlew();\n\n        //Inittiating the vertex buffers\n        if(vboSupported)\n        {\n           //EDIT: I was using two buffers, one for color and another for the vertex. I changed the code so I use  a single buffer now.\n           //EDIT: Notice that I'm not using the ARB version of the functions anymore.\n            glGenBuffers(1, &buffer);\n            glBindBuffer(GL_ARRAY_BUFFER_ARB, buffer);\n            glBufferData(GL_ARRAY_BUFFER_ARB, (sizeof(GLfloat) * 640 * 480 * 3) + (sizeof(GLbyte) * 640 * 480 * 3), 0, GL_STREAM_DRAW_ARB);\n        }\n        //glutMainLoop(), cleaning memory, ending main\n        ..\n    }\n\n    //Updating the screen\n    void displayCB()\n    {\n        point_cloud.update();\n\n        // clear buffer\n        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);\n\n        // save the initial ModelView matrix before modifying ModelView matrix\n        glPushMatrix();\n\n            glBindBuffer(GL_ARRAY_BUFFER_ARB, buffer);\n            glBufferSubData(GL_ARRAY_BUFFER_ARB, 0,  (sizeof(char) * 640 * 480 * 3), point_cloud.points_color); \n            glBufferSubData(GL_ARRAY_BUFFER_ARB, (sizeof(char) * 640 * 480 * 3), (sizeof(float) * 640 * 480 * 3), point_cloud.points_position);\n\n            // enable vertex arrays\n            glEnableClientState(GL_VERTEX_ARRAY);\n            glEnableClientState(GL_COLOR_ARRAY);\n\n            glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);\n            //EDIT: Added the right offset at the vertex pointer position\n            glVertexPointer(3, GL_FLOAT, 0, (void*)(sizeof(char) * 640 * 480 * 3));\n\n            //EDIT: Was using GL_POINT instead of GL_POINTS\n            glDrawArrays(GL_POINTS, 0, 640*480);\n\n            glDisableClientState(GL_VERTEX_ARRAY);  // disable vertex arrays\n            glDisableClientState(GL_COLOR_ARRAY);\n\n            glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);\n\n        glPopMatrix();\n\n        glutSwapBuffers();\n    }\n
Run Code Online (Sandbox Code Playgroud)\n