我目前正在尝试以较快的速度渲染复杂模型,但遇到了一些问题。渲染单个模型会导致我的帧率过低,而程序中没有任何额外的工作。我的模型(场景中只有一个)似乎太大了。上传到缓冲区的顶点数组中有444384个浮点数(模型中有24688个三角形)。
//Create vertex buffers
glGenBuffers(1, &m_Buffer);
glBindBuffer(GL_ARRAY_BUFFER, m_Buffer);
int SizeInBytes = m_ArraySize * 6 * sizeof(float);
glBufferData(GL_ARRAY_BUFFER, SizeInBytes, NULL, GL_DYNAMIC_DRAW);
//Upload buffer data
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * VertArray.size(), &VertArray[0]);
我知道VBO的大小是造成差异的原因,因为A)减小大小可以提高性能,B)注释掉渲染代码:
glPushMatrix();
//Translate
glTranslatef(m_Position.x, m_Position.y, m_Position.z);
glMultMatrixf(m_RotationMatrix);
//Bind buffers for vertex and index arrays
glBindBuffer(GL_ARRAY_BUFFER, m_Buffer);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), 0);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 6 * sizeof(float), (void*)12);
//Draw
glDrawArrays(GL_TRIANGLES, 0, m_ArraySize);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
//Unbind the buffers
glBindBuffer(GL_ARRAY_BUFFER, 0);
glPopMatrix();
这段代码让我的FPS保持在2000-2500左右,而取消注释后,我的FPS降至约130FPS或每帧8毫秒(仅此就足够了,但我还需要在程序中做其他事情,其中一些可能是CPU密集型)。一个更复杂的模型有85k个三角形,将其降至不到50 FPS,或每帧约20毫秒,此时程序明显卡顿。
我使用的一对着色器目前非常简单,我怀疑这不是问题所在。以下是它们,以防万一;首先是顶点着色器:
void main()
{
vec3 normal, lightDir;
vec4 diffuse;
float NdotL;
/* first transform the normal into eye space and normalize the result */
normal = normalize(gl_NormalMatrix * gl_Normal);
/* now normalize the light's direction. Note that according to the
OpenGL specification, the light is stored in eye space. Also since
we're talking about a directional light, the position field is actually
direction */
lightDir = normalize(vec3(gl_LightSource[0].position));
/* compute the cos of the angle between the normal and lights direction.
The light is directional so the direction is constant for every vertex.
Since these two are normalized the cosine is the dot product. We also
need to clamp the result to the [0,1] range. */
NdotL = max(dot(normal, lightDir), 0.0);
/* Compute the diffuse term */
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
gl_FrontColor = NdotL * diffuse;
gl_Position = ftransform();
}
而且片段着色器:
void main()
{
gl_FragColor = gl_Color;
}
我正在使用 GTX 660M 作为我的显卡来运行程序。
据我所知,VBO是OpenGL中渲染大量多边形的最快方法,互联网上似乎表明许多机器可以同时计算和显示数百万个多边形,所以我相信一定有一种方法来优化我的相对微不足道的27k个三角形的渲染。我宁愿现在这样做,而不是将来必须重写和重构更大量的代码。
我已启用背面剔除;我不确定视锥体剔除是否有所帮助,因为有时整个或大部分模型都在屏幕上(我目前舍弃对象,但不舍弃单个对象内的三角形)。在视口中裁剪不朝向摄像机的面可能会有所帮助,但我不确定如何做到这一点。除此之外,我不知道如何优化渲染。我还没有实现一个顶点缓冲区,但我已经读到说那可能只会增加速度约10%。
人们如何在屏幕上同时以可接受的帧率显示数万个三角形并进行其他操作?我该怎么样提高我的VBO渲染性能?更新:根据下面的评论,我将数组画了一半,如下所示:glDrawArrays(GL_TRIANGLES, 0, m_ArraySize/2); 然后是数组的四分之一:glDrawArrays(GL_TRIANGLES, 0, m_ArraySize/4); 每次减少绘制的数组量实际上使速度加倍(从12毫秒到6和3毫秒),但模型完好无损 - 没有任何丢失的部分。这似乎表明我在其他地方做错了什么,但我不知道是什么;我相当自信,在组成模型时不会添加相同的三角形4次或更多次,那么它可能是什么?也许我在多次上传缓冲区?