GL VBO 问题:第一条和最后一条三角形未正确显示
我的问题是第一个和最后一个三角形列表未正确显示,在本示例中,我从简单的波前模型 obj 文件加载球体。我以与显示列表和 VBO 完全相同的方式从 obj 文件加载它,并且我已经验证它们从 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。我也尝试过将其作为向量,但它给出了相同的问题,因此更改为向量或 float* 不是问题。
好吧,现在到我绘制它的地方,我有一种感觉,这是我做错的地方,
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 ); 进行绘制;只是为了调试目的,因为它最好地显示了不正确三角形的问题。
谁能看出我是否做错了什么?我是否初始化了一些错误的东西?我是不是少了一步?
不确定是否需要提供更多信息,我只是包括 glew 和 freeglut (两者中最新的..在 Windows 上)
My problem is that the first, and final list of triangles are not being displayed properly, in this example I am loading a sphere from a simple wavefront model obj file. I load it from the obj file exactly the same way for both the display list and VBO and I have verified that the they are getting the exact same numbers from the obj file.
In this example I have used the STL vector to store the vertices and vertex indices. However I have tried using float* and int* before as well but it gave the exact same result.
So here is a screen of the sphere being drawn from a VBO
edit: I removed this hyperlink as I can't post more than 2 as my account is still newb...
As you can see, there is a huge cone being drawn from the far side coming in to the middle of the sphere, it is hard to see but the strip of triangles from the closest side to the furthest side is also wrong, this will become apparent in one of the next few screens
Here is the exact same sphere being drawn from the DL
edit: I removed this hyperlink as I can't post more than 2 as my account is still newb...
You can see there that the DL is drawing it correctly
Here is them both being drawn at the same time, you will see the biggest difference where the lines are green, that is how they should be
edit: I removed this hyperlink as I can't post more than 2 as my account is still newb...
Here it is more apparent that the top strip is being drawn wrong from the VBO
I then tried adding a large number to the y value of each vertex which shows that there is definitely something wrong with my VBO because the cone's apex inside the sphere never moves!
Ok, so now that you have a visual idea of the problem I thought I'd throw some code in here, I've probably just missed a step or have a number wrong. Please take a look
this is how I create the 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);
}
Where m_vertices is the STL vector of Vec3f which simply holds x,y,z. I've tried this as vector as well and it gave the same problem so changing to vector or to float* isn't the issue.
Ok, now onto where I draw it, I got a feeling this is where I'm doing something wrong
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);
}
I am drawing using glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); simply for debugging purposes because it shows the problem with the incorrect triangles the best.
Can anyone see if I've done something wrong? Have I initialised something incorrectly? Am I missing a step?
Not sure if there is any more info I have to give, I'm just including glew and freeglut (the latest of both.. on windows)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一方面,正如您所发现的,使用 STL 向量是完全没问题的; C++ 保证 std::vector<>作为普通数组存储在内存中。我自己在使用 VBO 时使用过 std::vector ,它工作得很好,所以这里不需要担心。
除此之外,我没有什么好的建议,抱歉。一件小事是,在主题中您谈论了三角形带,但在代码中您使用 GL_TRIANGLES 而不是 GL_TRIANGLE_STRIP 进行渲染。这是意图吗?虽然我猜如果这是问题的话,输出会有更大的差异,但我想检查一下总没有坏处。
For one thing, using STL vectors is perfectly fine, as you have found out; C++ guarantees that a std::vector<> is stored in memory as normal array. I've used std::vector myself when working with VBO's, and it works just fine, so no need to worry here.
Other than that, I have no good suggestions, sorry. One minor thing is that in the subject you talk about triangle strips, but in the code you render with GL_TRIANGLES and not GL_TRIANGLE_STRIP. Is that the intention? Although I'd guess there would be a larger difference in the output if this was the problem, but it never hurts to check, I suppose.
好吧,我想出了我的问题。这是非常愚蠢和尴尬的。 WFObject 文件存储索引,如第 1 个、第 2 个等,而不是第 0 个、第 1 个等。
虽然是的,我在显示列表和 VBO 中加载的顶点完全相同,区别在于我的 DL 中的顶点我正在
m_Vertices[m_Vindices[i]-1]
处绘制,显然 OpenGL 不知道它必须从存储的每个索引中减去 1,这是正确的 所以!这是我自己的问题。所以现在每个索引都有 -1,因为它存储在索引数组中。问题解决了!
抱歉浪费您的时间,但感谢您的浏览!
OK, I figured my problem. It's quite silly and embarrassing. WFObject files store the indices like 1st, 2nd, etc., etc., rather than 0th, 1st, etc.
While yes, I loaded in the vertices exactly the same in both my display list and VBO, the difference was that in my DL I was drawing at
m_Vertices[m_Vindices[i]-1]
Obviously OpenGL doesn't know that it has to minus 1 from each index being stored, and rightly so! It was my own problem. So now I have -1 from each index as it is stored in the indices array. Problem solved!
Sorry to waste your time but thank you for taking a look!
什么是
m_Vindices
?您在代码注释中声明它是整数 - 它应该是std::vector
。What is
m_Vindices
? You state that it's integers in the code comment - it should bestd::vector<unsigned int>
.