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

Performance 避免使用OpenGL顶点数组在屏幕外绘制,performance,opengl,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, verticesNu

我有一个大型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) ;
}
for(int i=0;i
通常情况下,用户首先开始查看整个场景,但很快就会识别出感兴趣的部分并放大给定区域,这样整个场景的大部分都会落在屏幕之外。但我发现缩放时的FPS速率与查看整个屏幕时的FPS速率相同,因此OpenGL似乎绘制了所有落在屏幕之外的顶点(或者至少在管道中进行了足够的处理,在时间成本方面与绘制它们没有区别)

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

计算边界框()并进行检查。如果不可见,则不要绘制对象

所需知识:

  • 平面方程(
    ax+by+cz+d=0
  • 点到平面距离计算
  • 使用点和法线或使用3个点构造平面(方程)
  • 对点/向量应用矩阵变换
  • 向量叉积
  • 这是基本的3D技术,可以在网上的很多教程中找到。例如,谷歌的“矩阵faq”,7年前gamasutra也有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
    则在平面上

    平截体是一个“可见体积”,由在摄影机原点相交的4个平面定义。你见过3d编辑器吗?如果可视化的话,这就是frustrum的样子

    现在,让我们假设所有这些“平截面”平面的法线(平面法线,
    n
    ,记得吗?)都指向平截面之外

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


    这应该足以让你开始。你可以用谷歌搜索剩下的。谷歌提供教程和3d相关内容-这些话题在过去10年中讨论得非常透彻(主要是由游戏开发者和初学者讨论的),应该有大量关于这个主题的信息。

    你是在问自己如何做到这一点,还是你可以打开一些开关让OpenGL做到这一点?不管是哪种方式。如果碰巧有一个神奇的切换,那一定很棒。我真的不知道如何在所有转换之后查询特定的OpenGL坐标是在视口内还是在视口外,我猜这就是避免“手动”绘制的原因可以归结为。@Puchatek:实际上你可以通过应用矩阵变换来协调你自己<代码>项目
    。然而,这并不是一种裁剪对象的有效方法。您正在绘制四边形条带。你是在做某种2D渲染,还是这是一个3D场景?弄清楚3D空间中的坐标是否可见是聊天的一部分。好的,回到记事本和一些教程。是的,这个主题在网上讨论得很好,我唯一缺少的是它的正确名称,所以我可以找到所有相关的帖子。如果将来有人需要它,它被称为“截锥剔除”。