避免使用OpenGL顶点数组在屏幕外绘图

时间:2013-08-19 07:30:25

标签: performance opengl

我有一个大的3D场景,所有对象都存储在OpenGL顶点数组中,每个帧都用:

绘制
for(int i = 0 ; i < noLists ; ++i)
{
    glVertexPointer(3, GL_FLOAT, 0, vertexArraysList[i] ) ;
    glColorPointer(4, GL_FLOAT, 0, colorArraysList[i] ) ;
    glDrawArrays(GL_QUAD_STRIP, 0, verticesNumber) ;
}

通常,用户首先开始查看整个场景,但很快就会识别感兴趣的部分并放大给定区域,以便整个场景的大部分落在屏幕之外。但是我发现缩放时的FPS速率与观看整个屏幕时的FPS速率相同,所以OpenGL似乎绘制了所有那些落在屏幕之外的顶点(或者至少在管道中与它们一起进展得足够远,因为它们与绘图没有区别他们在时间成本方面)。

有没有办法测试特定顶点数组的内容是否落在屏幕之外,所以我可以避免绘制它?

1 个答案:

答案 0 :(得分:9)

计算边界框({​​{3}})并检查axis-aligned (AABB) or oriented (OBB)。如果它不可见,请不要绘制对象。

所需知识:

  1. 平面方程(ax + by + cz + d = 0
  2. 指向平面距离计算。
  3. 使用点和法线或使用3个​​点构造平面(方程式)。
  4. 将矩阵变换应用于点/矢量。
  5. 矢量交叉产品。
  6. 这是基本的3D内容,可以在网上的大量教程中找到。谷歌“矩阵常见问题”,例如,gamasutra 7年前也有aabb / obb教程。

    - 编辑 -

      

    确定3D空间中的坐标是否可见是部分聊天逃脱了我。好吧,回到记事本和一些教程

    平面可以由点(p)和法线(n)定义。 p是平面上的一个点,n是一个垂直于平面的矢量。

    给定点p1,您可以通过执行简单计算来确定此点是位于平面上方,平面上还是位于其下方。

    dist = dot((p1 - p), n),其中dot是点积(dot(a, b) = a.x*b.x + a.y+b.y + a.z*b.z)如果n是单位长度(dot(n, n) == 1),则dist将存储距离点的距离平面。否则,它的标志将指示p1所在的位置。如果dist > 0 p1位于平面上方,如果是dist < 0,则位于平面下方,如果dist == 0位于平面上。

    Frustrum是一个“可见体积”,由4个在相机原点相交的平面定义。曾经在3D编辑器中看到过if it is visible吗?如果想象的话,那就是截头形状。

    现在,让我们假设对于所有那些“截头”平面法线(平面法线,n,还记得吗?)指向截头外面。

    现在,您有一个要测试的对象。如果该对象的边界框的所有点都在“上方”(或“外部”),即使对于一个截头体平面,对象也是不可见的,因为它不会使截头体变形。这是基于分离轴定理。即使您使用对象的点而不是边界框,这也会起作用。

    这应该足以让你入门。你可以谷歌休息。谷歌的教程和3D相关的东西 - 这些话题在过去10年中被讨论过死亡(主要是由想要的游戏开发者和初学者),应该有关于这个主题的信息海洋。