我正在按照this教程编写OpenGL应用程序。我有一个3D对象的数据集,其中每个对象的描述如下:
到目前为止,我设法绘制了从pcd文件加载的点云(here,您可以找到代码)。在渲染循环中,我写道:
//3) bind VAO
glBindVertexArray(_VAO);
//4) draw
glDrawArrays(GL_POINTS,0,_num_vertices);
我在GL_BUFFER_ARRAY
中存储了云的顶点。
现在,我的问题是:
对于此对象,我还想绘制一个边界框(作为线框矩形)和一组以其位置为中心的3d轴(作为一组三个圆柱)。最好的方法是什么?
@MichaelIV
感谢您的回复。我正在听取您的建议,但是我的行为很奇怪。
要填充缓冲区,我编写了以下代码:
Eigen::Vector3f min(1.7921,-0.2782,0.0);
Eigen::Vector3f max(2.1521,0.1994,0.9915);
insertVertex(_box_vertices,min.x(),min.y(),min.z(),0.0,0.0,1.0);
insertVertex(_box_vertices,max.x(),min.y(),min.z(),0.0,0.0,1.0);
insertVertex(_box_vertices,max.x(),max.y(),min.z(),0.0,0.0,1.0);
insertVertex(_box_vertices,min.x(),max.y(),min.z(),0.0,0.0,1.0);
_num_box_vertices = _box_vertices.size()/6.0f;
std::cerr << "Box vertices:" << std::endl;
for(size_t i=0; i<_num_box_vertices; ++i){
std::cerr << _box_vertices[6*i] << " " << _box_vertices[6*i+1] << " " << _box_vertices[6*i+2] << " ";
std::cerr << _box_vertices[6*i+3] << " " << _box_vertices[6*i+4] << " " << _box_vertices[6*i+5] << std::endl;
}
其中_box_vertices
是一个std::vector<float>
数组,而insertVertex
只是一个实用函数。如果我打印数组,这就是我得到的:
dede@srrg-02:~/source/develop/opengl_viewer/bin$ ./opengl_viewer
Box vertices:
1.7921 -0.2782 0 0 0 1
2.1521 -0.2782 0 0 0 1
2.1521 0.1994 0 0 0 1
1.7921 0.1994 0 0 0 1
因此,它应该是正确的。然后,我使用以下代码(OpenGL 3.3)分配gl对象:
//[OPENGL] create box buffers
glGenBuffers(1, &_bVBO);
glBindBuffer(GL_ARRAY_BUFFER, _bVBO);
glBufferData(GL_ARRAY_BUFFER, _box_vertices.size()*sizeof(float), &_box_vertices[0], GL_STATIC_DRAW);
glGenVertexArrays(1, &_bVAO);
glBindVertexArray(_bVAO);
//[OPENGL] link box vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float)));
glEnableVertexAttribArray(1);
并以此呈现它们:
//3) bind box VAO
glBindVertexArray(_bVAO);
//4) draw box
glDrawArrays(GL_LINE_LOOP,0,_num_box_vertices);
但是结果却不是我所期望的:
似乎每一行都从(0,0,0)开始,而不是从我想要的点开始。
能否请您解释一下该如何解决?
谢谢。
答案 0 :(得分:0)
这是我如何绘制边界(GL 4.5 API):
初始化一次:
Gluint mVao = 0;
//CReate VAO:
glCreateVertexArrays(1, &mVao);
glEnableVertexArrayAttrib(mVao, 0);
glVertexArrayAttribFormat(mVao, 0, 3, GL_FLOAT, GL_FALSE, 0);
//Create VBO
glCreateBuffers(1,&mVbo);
glNamedBufferData(mVbo, dataSize, NULL, GL_DYNAMIC_DRAW);
//Bind VBO to VAO
glVertexArrayAttribBinding(mVao, 0, 0);
glVertexArrayVertexBuffer(mVao, 0, mVbo, 0, sizeof(float) * 3);
在每一帧上:
准备AABB顶点(使用GLM数学库),aabb可能是一些DrawDebug()
函数参数:
const GLfloat data[48] = {
// Loop 1: XY Z (min)
aabb.mMin.x, aabb.mMin.y, aabb.mMin.z,
aabb.mMax.x, aabb.mMin.y, aabb.mMin.z,
aabb.mMax.x, aabb.mMax.y, aabb.mMin.z,
aabb.mMin.x, aabb.mMax.y, aabb.mMin.z,
// Loop 2: XY Z (max)
aabb.mMin.x, aabb.mMin.y, aabb.mMax.z,
aabb.mMax.x, aabb.mMin.y, aabb.mMax.z,
aabb.mMax.x, aabb.mMax.y, aabb.mMax.z,
aabb.mMin.x, aabb.mMax.y, aabb.mMax.z,
// Lists:
// 1
aabb.mMin.x, aabb.mMin.y, aabb.mMin.z,
aabb.mMin.x, aabb.mMin.y, aabb.mMax.z,
// 2
aabb.mMax.x, aabb.mMin.y, aabb.mMin.z,
aabb.mMax.x, aabb.mMin.y, aabb.mMax.z,
// 3
aabb.mMax.x, aabb.mMax.y, aabb.mMin.z,
aabb.mMax.x, aabb.mMax.y, aabb.mMax.z,
// 4
aabb.mMin.x, aabb.mMax.y, aabb.mMin.z,
aabb.mMin.x, aabb.mMax.y, aabb.mMax.z,
};
glNamedBufferSubData(mVbo,0, mDataSize, data);
//combine line loop and line drawing to minimize number of draw calls:
glDrawArrays(GL_LINE_LOOP, 0, 4);
glDrawArrays(GL_LINE_LOOP, 4, 4);
glDrawArrays(GL_LINES, 8, 8));
重要注意:我在这里省略了着色器程序绑定,因为那里没有什么特别的。但是您必须提供着色器程序,其中顶点着色器使用MVP对aabb坐标进行转换(模型-视图-投影)矩阵,或者如果您在客户端使用模型矩阵转换了aabb顶点,则仅使用视图-投影矩阵。