Performance 避免使用OpenGL顶点数组在屏幕外绘制
我有一个大型3D场景,其中所有对象都存储在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
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
)想知道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空间中的坐标是否可见是聊天的一部分。好的,回到记事本和一些教程。是的,这个主题在网上讨论得很好,我唯一缺少的是它的正确名称,所以我可以找到所有相关的帖子。如果将来有人需要它,它被称为“截锥剔除”。