gpt4 book ai didi

c++ - glDrawElements 和立即模式之间的 OpenGL 质量差异

转载 作者:行者123 更新时间:2023-11-30 01:57:29 32 4
gpt4 key购买 nike

我第一次从事 3D 项目(实际上,我正在 Quartz Composer 插件中编写 Bullet Physics 集成程序),并且在尝试优化我的渲染方法时,我开始使用 glDrawElements而不是通过 glVertex3d 直接访问顶点...

我对结果感到非常惊讶。我没有检查它是否真的更快,但我尝试了下面这个非常简单的场景。而且,从我的角度来看,即时模式下的渲染效果确实更好。

“绘制元素”方法不断显示三角形的边缘和立方体上非常难看的阴影。

我真的很感激关于这种差异的一些信息,并且可能是保持 glDrawElements 质量的一种方式。我知道这可能真的是我的错误......

立即模式 enter image description here

绘制元素 enter image description here

在这两种方法中,顶点、索引和法线的计算方式相同。这是2个代码。

立即模式

glBegin (GL_TRIANGLES);
int si=36;
for (int i=0;i<si;i+=3)
{
const btVector3& v1 = verticesArray[indicesArray[i]];;
const btVector3& v2 = verticesArray[indicesArray[i+1]];
const btVector3& v3 = verticesArray[indicesArray[i+2]];


btVector3 normal = (v1-v3).cross(v1-v2);
normal.normalize ();
glNormal3f(-normal.getX(),-normal.getY(),-normal.getZ());
glVertex3f (v1.x(), v1.y(), v1.z());
glVertex3f (v2.x(), v2.y(), v2.z());
glVertex3f (v3.x(), v3.y(), v3.z());

}
glEnd();

glDrawElements

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(btVector3), &(normalsArray[0].getX()));
glVertexPointer(3, GL_FLOAT, sizeof(btVector3), &(verticesArray[0].getX()));
glDrawElements(GL_TRIANGLES, indicesCount, GL_UNSIGNED_BYTE, indicesArray);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

谢谢。

编辑

这是顶点/索引/法线的代码

GLubyte indicesArray[] = {
0,1,2,
3,2,1,
4,0,6,
6,0,2,
5,1,4,
4,1,0,
7,3,1,
7,1,5,
5,4,7,
7,4,6,
7,2,3,
7,6,2 };

btVector3 verticesArray[] = {
btVector3(halfExtent[0], halfExtent[1], halfExtent[2]),
btVector3(-halfExtent[0], halfExtent[1], halfExtent[2]),
btVector3(halfExtent[0], -halfExtent[1], halfExtent[2]),
btVector3(-halfExtent[0], -halfExtent[1], halfExtent[2]),
btVector3(halfExtent[0], halfExtent[1], -halfExtent[2]),
btVector3(-halfExtent[0], halfExtent[1], -halfExtent[2]),
btVector3(halfExtent[0], -halfExtent[1], -halfExtent[2]),
btVector3(-halfExtent[0], -halfExtent[1], -halfExtent[2])
};

indicesCount = sizeof(indicesArray);
verticesCount = sizeof(verticesArray);


btVector3 normalsArray[verticesCount];

int j = 0;
for (int i = 0; i < verticesCount * 3; i += 3)
{
const btVector3& v1 = verticesArray[indicesArray[i]];;
const btVector3& v2 = verticesArray[indicesArray[i+1]];
const btVector3& v3 = verticesArray[indicesArray[i+2]];

btVector3 normal = (v1-v3).cross(v1-v2);
normal.normalize ();

normalsArray[j] = btVector3(-normal.getX(), -normal.getY(), -normal.getZ());

j++;
}

最佳答案

您可以(并且将会)使用即时模式和基于顶点数组的渲染获得完全相同的结果。您的图像表明您的法线错误。由于您没有包含用于创建数组的代码,因此我只能猜测可能出了什么问题。我可以想象一件事:每个三角形使用一个法线,因此在法线数组中,您必须为每个顶点重复该法线。

你应该知道 GL 中的顶点不仅仅是位置(你在即时模式下通过 glVertex 指定),而是所有属性的集合,比如位置、法线、纹理坐标等。因此,如果您有一个网格,其中一个端点是不同三角形的一部分,那么如果共享所有属性而不仅仅是位置,则这只是一个顶点。在您的情况下,法线是每个三角形,因此每个三角形需要不同的顶点(与其他一些顶点共享位置,但使用不同的法线)。

关于c++ - glDrawElements 和立即模式之间的 OpenGL 质量差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18676729/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com