PCD数据适配OpenGL显示问题及C++代码排查求助
问题排查与格式确认:Lidar点云OpenGL显示问题
项目背景
我们正在开展3D建模项目,采用Lidar相机数据在Web门户展示3D对象,3D模型的重建、优化、简化等处理工作由桌面C应用完成。获取Lidar相机输出的e57格式文件后,C应用以此提取PCD数据及扫描图像,借助OpenGL库显示3D模型用于处理与查看,但解析后绘制PCD数据时遇到问题,需排查代码错误并确认PCD数据是否需转换格式。
待排查代码片段
void Display() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque glClear(GL_COLOR_BUFFER_BIT); // Clear the color buffer(background) glEnable(GL_STENCIL_TEST); glBegin(GL_TRIANGLES); glColor3d(0.61f, 0.65f, 0.70f); glColor3f(0.61f, 0.65f, 0.70f); glVertex3f(-3712089.00f, -8772.00f, 797511.00f); glColor3f(0.34f, 0.37f, 0.37f); glVertex3f(-3718649.00f, -8674.00f, 790862.00f); glColor3f(0.32f, 0.33f, 0.30f); glVertex3f(-3723328.00f, -8505.00f, 777755.00f); glColor3f(0.29f, 0.29f, 0.25f); glVertex3f(-3723866.00f, -8436.00f, 773824.00f); glColor3f(0.30f, 0.30f, 0.28f); glVertex3f(-3735966.00f, -7801.00f, 725951.00f); glColor3f(0.27f, 0.29f, 0.23f); glVertex3f(-3770613.00f, -7039.00f, 669964.00f); glColor3f(0.25f, 0.27f, 0.27f); glVertex3f(-3779137.00f, -6773.00f, 651281.00f); glEnd(); glFlush() } int main (int* argc, char** argv){ glutInit(&argc, argv); // Initialize GLUTconst char* title = "OpenGL Test"; glutCreateWindow(title); // Create a window with the given titleglutInitWindowSize(320, 320); // Set the window's initial width & height glutInitWindowPosition(50, 50); // Position the window's initial top-left cornerglutDisplayFunc(Display); // Register display callback handler for window re- paintglutMainLoop(); return 0; }
代码错误排查
1. 语法与书写错误
glFlush()末尾缺少分号,违反C++语法规则,会导致编译失败。main函数参数定义错误:正确参数应为int argc, char** argv,而非int* argc, char** argv,glutInit需要传入int*类型的argc地址,参数定义错误会引发运行时异常。- 代码粘连换行错误:多处注释与后续代码连写(如
// Initialize GLUTconst char* title),导致编译解析失败,需将注释与代码拆分换行。
2. OpenGL绘制逻辑错误
- 图元类型选择错误:PCD是点云数据,应该使用
GL_POINTS绘制离散点,而非GL_TRIANGLES。当前代码传入7个顶点,GL_TRIANGLES要求顶点数为3的倍数,多余顶点不会被绘制,完全不符合点云展示逻辑。 - 无意义的模板测试启用:启用
GL_STENCIL_TEST但未配置模板缓冲区,glClear也未清除GL_STENCIL_BUFFER_BIT,会导致模板缓冲区状态异常,若未用到模板功能,直接移除该行即可。 - 冗余颜色设置:连续调用
glColor3d和glColor3f,前者被后者直接覆盖,完全多余;且glColor3d接收double类型参数,此处传入float属于不必要的类型混用。 - 顶点坐标超出视锥体范围:当前顶点坐标为百万级数值,OpenGL默认视锥体范围是[-1,1],未设置投影和模型视图矩阵的情况下,所有顶点会被裁剪,导致看不到任何内容。必须设置适配大尺度坐标的投影矩阵,将点云缩放到可见范围内。
3. GLUT初始化顺序错误
glutInitWindowSize和glutInitWindowPosition必须在glutCreateWindow之前调用,否则窗口大小和位置设置不会生效——glutCreateWindow是创建窗口的动作,之后的参数无法应用到已创建的窗口上。
PCD数据格式转换确认
PCD数据无需额外转换为特定格式即可被OpenGL使用,但需注意三点:
- 坐标空间适配:PCD中的真实世界大尺度坐标,必须通过模型视图矩阵进行缩放、平移,适配到OpenGL视锥体可见范围,否则会被裁剪。
- 数据类型匹配:OpenGL顶点函数(如
glVertex3f)接收float类型数据,若PCD中坐标为double类型,需转换为float(精度要求高可使用glVertex3d)。 - 绘制方式匹配:PCD是离散点云,必须用
GL_POINTS作为图元类型;若要构建三角网格,属于点云重建环节,不是直接绘制PCD数据的方式。
修正后的示例代码
#include <GL/glut.h> void Display() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 增加深度缓冲清除 // 设置适配大尺度坐标的投影矩阵 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, 1.0f, 0.1f, 10000000.0f); // 设置模型视图矩阵,调整相机位置以观察点云 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0f, 0.0f, 5000000.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); glBegin(GL_POINTS); glColor3f(0.61f, 0.65f, 0.70f); glVertex3f(-3712089.00f, -8772.00f, 797511.00f); glColor3f(0.34f, 0.37f, 0.37f); glVertex3f(-3718649.00f, -8674.00f, 790862.00f); glColor3f(0.32f, 0.33f, 0.30f); glVertex3f(-3723328.00f, -8505.00f, 777755.00f); glColor3f(0.29f, 0.29f, 0.25f); glVertex3f(-3723866.00f, -8436.00f, 773824.00f); glColor3f(0.30f, 0.30f, 0.28f); glVertex3f(-3735966.00f, -7801.00f, 725951.00f); glColor3f(0.27f, 0.29f, 0.23f); glVertex3f(-3770613.00f, -7039.00f, 669964.00f); glColor3f(0.25f, 0.27f, 0.27f); glVertex3f(-3779137.00f, -6773.00f, 651281.00f); glEnd(); glFlush(); } int main (int argc, char** argv){ glutInit(&argc, argv); const char* title = "OpenGL Test"; glutInitWindowSize(320, 320); glutInitWindowPosition(50, 50); glutCreateWindow(title); glutDisplayFunc(Display); glutMainLoop(); return 0; }
内容的提问来源于stack exchange,提问作者sanjeev sharma
相关产品推荐
相关产品推荐

