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

发布于 2024-12-06 12:03:40 字数 2389 浏览 2 评论 0原文

我正在尝试制作一个动态点云可视化工具。使用 Kinect 传感器每帧更新这些点。为了抓取帧,我使用 OpenCV 和 GLUT 来显示。 OpenCV API 对于点 xyz 位置返回 640 x 480 (float *),对于 rgb 颜色数据返回 640 x 480 (int *)。 为了获得最大性能,我尝试在流模式下使用顶点缓冲区对象而不是简单的顶点数组。我能够使用顶点数组渲染它,但我的 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();
}

I´m trying to make a dynamic point cloud visualizer. The points are updated every frame with Kinect Sensor. To grab the frames I´m using OpenCV and GLUT to display.
The OpenCV API returns a 640 x 480 (float *), for the points xyz position , and a 640 x 480 (int *) for the rgb color data.
To get the maximum performance, I´m trying to use Vertex Buffer Object in stream mode instead of a simple Vertex Array. I´m being able to render it with Vertex Array, but nothing is being rendered with my VBO implementation. I tryied a bunch of different orders in the declarations, but i can't find what I'm missing. Can someone try to point me to the right direction? Here is the simpflified code: (I´ve rewrited the wrong version as asked by Christian Rau, so you guys can understand my mistakes)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雪花飘飘的天空 2024-12-13 12:03:40

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

1 - I though that glGenBuffers first parameter was the number that
would be associated to the buffer, instead, its the number of
buffers that would be allocated. This doesn't matter anyway, because
now I'm using a single buffer and adding all the data to it. Didn't
solved the problem, but was going in the right way.

2 - There are two ways of being able to use OpenGL VBO functions.
First, you can bind the ARB  version functions by yourself OR you
can add glew.h and use glewInit() after starting an OpenGL context.
The second option is a LOT cleaner and I changed my code so I don't
use the ARB versions anymore. Still didn't solved the problem.

3 - Christian Rau asked me for glErrors in the code, so, I wrote it
after each OpenGL operation in displayCB. After glDrawArrays I got
an 0x00500 error, that means there is an invalid enum, so I noticed
I was using GL_POINT as parameter to glDrawArrays, instead of
GL_POINTS, so silly that makes me want to kill myself.

最终代码:

//EDIT: Added glew.h as a header and I´m not using the ARB version anymore
#include <glew.h>

    int main()
    {
        //Declaring variables, initiating glut, setting camera and checking the compatibility as http://www.songho.ca/opengl/gl_vbo.html
        glutDisplayFunc(displayCB);
        glutIdleFunc(displayCB); 
        ...

        //EDIT: IS VERY IMPORTANT TO ADD IT AS SOON AS YOU START AN OPENGL CONTEXT.
        initGlew();

        //Inittiating the vertex buffers
        if(vboSupported)
        {
           //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.
           //EDIT: Notice that I'm not using the ARB version of the functions anymore.
            glGenBuffers(1, &buffer);
            glBindBuffer(GL_ARRAY_BUFFER_ARB, buffer);
            glBufferData(GL_ARRAY_BUFFER_ARB, (sizeof(GLfloat) * 640 * 480 * 3) + (sizeof(GLbyte) * 640 * 480 * 3), 0, GL_STREAM_DRAW_ARB);
        }
        //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, buffer);
            glBufferSubData(GL_ARRAY_BUFFER_ARB, 0,  (sizeof(char) * 640 * 480 * 3), point_cloud.points_color); 
            glBufferSubData(GL_ARRAY_BUFFER_ARB, (sizeof(char) * 640 * 480 * 3), (sizeof(float) * 640 * 480 * 3), point_cloud.points_position);

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

            glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
            //EDIT: Added the right offset at the vertex pointer position
            glVertexPointer(3, GL_FLOAT, 0, (void*)(sizeof(char) * 640 * 480 * 3));

            //EDIT: Was using GL_POINT instead of GL_POINTS
            glDrawArrays(GL_POINTS, 0, 640*480);

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

            glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);

        glPopMatrix();

        glutSwapBuffers();
    }

PS: The program is up and running, but I can't see any improvement in the average performance when compared to the Vertex Array version. Is that alright?
THE PROBLEM WAS SOLVED. I´ve done three alterations:

1 - I though that glGenBuffers first parameter was the number that
would be associated to the buffer, instead, its the number of
buffers that would be allocated. This doesn't matter anyway, because
now I'm using a single buffer and adding all the data to it. Didn't
solved the problem, but was going in the right way.

2 - There are two ways of being able to use OpenGL VBO functions.
First, you can bind the ARB  version functions by yourself OR you
can add glew.h and use glewInit() after starting an OpenGL context.
The second option is a LOT cleaner and I changed my code so I don't
use the ARB versions anymore. Still didn't solved the problem.

3 - Christian Rau asked me for glErrors in the code, so, I wrote it
after each OpenGL operation in displayCB. After glDrawArrays I got
an 0x00500 error, that means there is an invalid enum, so I noticed
I was using GL_POINT as parameter to glDrawArrays, instead of
GL_POINTS, so silly that makes me want to kill myself.

The final code:

//EDIT: Added glew.h as a header and I´m not using the ARB version anymore
#include <glew.h>

    int main()
    {
        //Declaring variables, initiating glut, setting camera and checking the compatibility as http://www.songho.ca/opengl/gl_vbo.html
        glutDisplayFunc(displayCB);
        glutIdleFunc(displayCB); 
        ...

        //EDIT: IS VERY IMPORTANT TO ADD IT AS SOON AS YOU START AN OPENGL CONTEXT.
        initGlew();

        //Inittiating the vertex buffers
        if(vboSupported)
        {
           //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.
           //EDIT: Notice that I'm not using the ARB version of the functions anymore.
            glGenBuffers(1, &buffer);
            glBindBuffer(GL_ARRAY_BUFFER_ARB, buffer);
            glBufferData(GL_ARRAY_BUFFER_ARB, (sizeof(GLfloat) * 640 * 480 * 3) + (sizeof(GLbyte) * 640 * 480 * 3), 0, GL_STREAM_DRAW_ARB);
        }
        //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, buffer);
            glBufferSubData(GL_ARRAY_BUFFER_ARB, 0,  (sizeof(char) * 640 * 480 * 3), point_cloud.points_color); 
            glBufferSubData(GL_ARRAY_BUFFER_ARB, (sizeof(char) * 640 * 480 * 3), (sizeof(float) * 640 * 480 * 3), point_cloud.points_position);

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

            glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
            //EDIT: Added the right offset at the vertex pointer position
            glVertexPointer(3, GL_FLOAT, 0, (void*)(sizeof(char) * 640 * 480 * 3));

            //EDIT: Was using GL_POINT instead of GL_POINTS
            glDrawArrays(GL_POINTS, 0, 640*480);

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

            glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);

        glPopMatrix();

        glutSwapBuffers();
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文