GL VBO 问题:第一条和最后一条三角形没有正确显示

Posted

技术标签:

【中文标题】GL VBO 问题:第一条和最后一条三角形没有正确显示【英文标题】:GL VBO issues: First and final strip of triangles not being displayed correctly 【发布时间】:2011-09-13 11:58:20 【问题描述】:

我不是 C++ 和 OpenGL 的新手,但是我是使用 VBO 的新手。到目前为止,我一直很懒惰,几乎所有东西都使用显示列表。

我的问题很可能很简单,但很烦人!似乎第一个也是最后一个三角形列表没有正确显示,在这个例子中,我从一个简单的波前模型 obj 文件加载一个球体。我从 obj 文件中加载它的方式与显示列表和 VBO 完全相同,并且我已经验证它们从 obj 文件中获得了完全相同的数字。

在这个例子中,我使用了 STL 向量来存储顶点和顶点索引。不过,我之前也尝试过使用 float* 和 int* ,但结果完全相同。

所以这是一个从 VBO 绘制的球体屏幕

编辑:我删除了这个超链接,因为我不能发布超过 2 个,因为我的帐户仍然是新的... 正如你所看到的,有一个巨大的圆锥从球体的远侧拉到球体的中间,很难看到,但是从最近侧到最远侧的三角形条带也是错误的,这将变成在接下来的几个屏幕之一中很明显 这是从 DL 中绘制的完全相同的球体

编辑:我删除了这个超链接,因为我不能发布超过 2 个,因为我的帐户仍然是新的...

您可以在那里看到 DL 正在正确绘制它 这是它们同时绘制的,你会看到最大的不同是线条是绿色的,应该是这样的

编辑:我删除了这个超链接,因为我不能发布超过 2 个,因为我的帐户仍然是新的...

这里更明显的是从 VBO 中绘制的顶部条带错误

然后我尝试在每个顶点的 y 值上添加一个大数,这表明我的 VBO 肯定有问题,因为球体内的圆锥体顶点永远不会移动!

好的,既然您已经对问题有了一个直观的了解,我想我会在这里扔一些代码,但我可能只是错过了一步或输入了错误的数字。请看一下

这就是我创建 vbo 的方式

void VBOWFModel::Create_VBO()

    // Vertex Array VBO handle

    glGenBuffers(1, &m_VAVBO_handle);
    glBindBuffer(GL_ARRAY_BUFFER, m_VAVBO_handle);
    glBufferData(GL_ARRAY_BUFFER, 
                 m_vertices.size()*sizeof(Vec3f), 
                 &m_vertices[0].x, GL_STATIC_DRAW);

其中 m_vertices 是 Vec3f 的 STL 向量,它简单地保存 x,y,z。我也试过这个作为向量,它给出了同样的问题,所以改变为向量或浮点*不是问题。

好的,现在到我画它的地方,我觉得这是我做错了什么

void VBOWFModel::Render()

    glEnableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, m_VAVBO_handle);
    glVertexPointer(3, GL_FLOAT, sizeof(Vec3f), (float*) NULL);

        glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

    // m_Vindices are the vertex indices, not the greatest naming convention but hey...
    // it is an STL vector of integers
    glDrawElements(GL_TRIANGLES, m_Vindices.size(), GL_UNSIGNED_INT, &m_Vindices[0]);

    glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

    glDisableClientState(GL_VERTEX_ARRAY);

我正在使用 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );仅出于调试目的,因为它最好地显示了不正确三角形的问题。

谁能看看我是不是做错了什么?我是否错误地初始化了某些东西?我错过了一步吗?我查看了各种教程并在谷歌上搜索了很多,我似乎与其他人并没有太大的不同。大多数教程都使用 float* 而不是 stl 矢量,但我再次这样做了,它给出了完全相同的结果。

不确定我是否需要提供更多信息,我只包括 glew 和 freeglut(两者中的最新......在 Windows 上)

【问题讨论】:

【参考方案1】:

一方面,正如您所发现的,使用 STL 向量非常好; C++ 保证 std::vector 作为普通数组存储在内存中。我自己在使用 VBO 时使用了 std::vector,它工作得很好,所以这里不用担心。

除此之外,我没有什么好的建议,抱歉。一件小事是,在主题中您谈论的是三角形条带,但在您使用 GL_TRIANGLES 而不是 GL_TRIANGLE_STRIP 呈现的代码中。是这个意图吗?虽然我猜如果这是问题所在,输出的差异会更大,但我想检查一下不会有什么坏处。

【讨论】:

您好,感谢您的回复。我在三角形和条形之间切换,抱歉,我可能也应该在这里说明这一点。不幸的是,两者都产生了完全相同的结果:(但为我看看它的荣誉:)【参考方案2】:

好的,我发现了我的问题。这是相当愚蠢和尴尬的。 WFObject 文件存储索引,如 1st、2nd 等,而不是 0th、1st 等。

虽然是的,但我在显示列表和 VBO 中加载的顶点完全相同,不同之处在于在我的 DL 中,我在 m_Vertices[m_Vindices[i]-1] 处绘制

显然 OpenGL 不知道它必须从存储的每个索引中减去 1,这是正确的!这是我自己的问题。所以现在我从每个索引中得到-1,因为它存储在索引数组中。问题解决了!

很抱歉浪费您的时间,但感谢您观看!

【讨论】:

【参考方案3】:

m_Vindices 是什么?您在代码注释中声明它是整数 - 它应该是 std::vector<unsigned int>

【讨论】:

你好,我把它改成无符号整数,完全一样的问题。另外,这在 DL 中从来都不是问题,感谢您的评论

以上是关于GL VBO 问题:第一条和最后一条三角形没有正确显示的主要内容,如果未能解决你的问题,请参考以下文章

如何使用聚合函数在 MySQL 查询中获取分组记录的第一条和最后一条记录?

如何使用聚合函数在 MySQL 查询中获取分组记录的第一条和最后一条记录?

在分组结果中选择第一条和最后一条记录 - Oracle 11g

如何从 sql 查询中获取第一条和最后一条记录?

MySQL从一系列相同的值中选择第一条和最后一条记录

获取表中存在的每个日期的第一条和最后一条记录号