OpenGL glDrawElements

Posted

技术标签:

【中文标题】OpenGL glDrawElements【英文标题】: 【发布时间】:2016-10-23 16:12:00 【问题描述】:

给定一组面,每个面包含顶点数和指向向量 std::Vector 中顶点的指针,我想遍历所有面并使用 glDrawElements 绘制每个面:

编辑:我刚刚注意到我忘了激活 vertex_array

for(std::vector<Face>::iterator it = faces.begin();it != faces.end();++it) 
    const Face &f = *it;

    std::Vector<GLint> indices;
    std::Vector<GLfloat> positions;

    for(int i=0;i<f.vcount;++i)
        const Vertex &v = vertices[f.vertices[i]];

        positions.push_back(v.x);
        positions.push_back(v.y);
        positions.push_back(v.z);

        indices.push_back(f.vertices[i]);
    
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3,GL_FLOAT,3*sizeof(GL_FLOAT),&positions[0]);                     

    glDrawElements(GL_POLYGON,indices.size(),GL_UNSIGNED_INT,&indices[0]);
    glDisableClientState(GL_VERTEX_ARRAY);
    positions.clear();
    indices.clear();

但显然这不能正常工作并且没有显示任何内容。

编辑:启用 GL_VERTEX_ARRAY 会在屏幕上绘制一些东西,但不是我试图创建的模型。所以地址似乎有问题。

【问题讨论】:

glVertexPointer 应该有 GL_FLOAT 而不是 GL_INT 作为第二个参数,3 * sizeof(GLfloat) 作为第三个参数。 另外,GL_POLYGON 不再是有效的绘图模式。从文档中:“符号常量 GL_POINTS、GL_LINE_STRIP、GL_LINE_LOOP、GL_LINES、GL_LINE_STRIP_ADJACENCY、GL_LINES_ADJACENCY、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN、GL_TRIANGLES、GL_TRIANGLE_STRIP_ADJACENCY、GL_TRIANGLES_ADJACENCY 和 GL_PATCH 被接受。” @poetryofruins:“此外,GL_POLYGON 不再是有效的绘图模式”因此,glVertexPointer 在核心配置文件 OpenGL 中也不再可用。所以如果他能用一个,他就可以清楚地使用另一个。 我进行了建议的更改,但仍然没有任何内容。 你确定你的索引是正确的吗?如果它们不是从源数据中按顺序排列的,则顶点的位置与索引指向的位置完全不同。此外,如果(极有可能)在源数据中多次引用顶点,您可能会复制顶点数据。 【参考方案1】:

您的索引数组没有意义。索引glDrawElements 将仅引用您设置的顶点数组 - 并且您正在为每个单独的多边形设置一个新数组。

这意味着

indices.push_back(f.vertices[i]);

应该只是概念上的

indices.push_back(i);

这最终意味着您可以完全跳过索引而直接使用

glDrawArrays(GL_POLYGON,0,f.vcount);

请注意,您在这里所做的是一种非常低效的渲染对象的方式。如果您对整个对象使用单个绘制调用,您会好得多。您可以通过手动将多边形三角剖分为三角形作为预处理步骤来做到这一点。

【讨论】:

那行得通。但是我将如何使用索引。顶点数组是否应该保留每个循环,索引数组是否应该指向每个多边形的开始? 这取决于。在最简单的形式中,您只需为整个对象构建一个顶点数组,根本没有索引 - 您在构建数组时已经取消引用索引,就像以前一样。这意味着您将数组本身和绘图调用从内部循环移动到外部循环,并且内部循环将解包每个多边形。更好的方法是将所有不同的顶点打包到一个数组中,并构建一个索引数组,该数组将包含每个多边形的三角剖分。

以上是关于OpenGL glDrawElements的主要内容,如果未能解决你的问题,请参考以下文章

glfw 包含了opengl吗

qt opengl的图形怎么刷新

OpenGL是啥?

OpenGL 4 采用

OpenGL - 002_2OpenGL 常见专业名词解析

如何使用 OpenGL 保存 OpenGL 绘制?