用顶点缓冲对象(VBO)渲染Kinect点云
Rendering Kinect Point Cloud with Vertex Buffer Object (VBO)
我正在尝试制作一个动态点云可视化器。用Kinect Sensor每帧更新点。为了抓取帧,我使用OpenCV和GLUT来显示。对于点xyz位置,OpenCV API返回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();
}
PS:程序已经启动并运行,但与Vertex Array版本相比,我看不到平均性能有任何提高。这样可以吗?问题解决了。我做了三个改动:
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();
}
相关文章:
- OpenGL将纹理四边形渲染为(0,0)
- 按需渲染帧
- 使用专用显卡进行 OpenGL 渲染时帧速率较低
- Azure Kinect 使用正文索引映射裁剪正文
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法
- dx11 渲染到纹理仅显示透明颜色
- 在 opengl 中渲染 obj 文件时出现黑窗口
- Qt 如何渲染 mainwidget
- C++ SDL2:如何将矩形渲染到多个视口中
- 纹理单位重叠?渲染了错误的纹理
- Qt OpenGL 渲染到纹理性能问题
- SDL_ttf清除我之前和将来的所有渲染
- 向 vulkan 管道添加额外的 UBO 会停止所有几何体渲染
- 尝试渲染像素坐标时,简单线条渲染失败
- (C++) OpenGL 渲染瓦片映射会导致丢帧
- 使用计算着色器渲染到交换链
- 深度缓冲区未填充阴影贴图渲染通道中的数据
- OpenGL只是渲染一个黑色的方块
- 在Visual Studio 2013 C++中使用GLUT渲染Kinect输出(堆栈溢出)
- 用顶点缓冲对象(VBO)渲染Kinect点云