设为首页 加入收藏

TOP

OpenGL超级宝典学习笔记——遮挡查询
2015-02-25 22:42:51 】 浏览:227
Tags:OpenGL 超级 宝典 学习 笔记 遮挡 查询

在一个场景中,如果有有些物体被其他物体遮住了不可见。那么我们就不需要绘制它。在复杂的场景中,这可以减少大量的顶点和像素的处理,大幅度的提高帧率。遮挡查询就是允许我们判断一组图形在进行了深度测试之后是否可见。



为了显示遮挡查询对性能的提升,我们需要一个对照组(不使用遮挡查询来渲染场景)。


首先我们先绘制“主遮挡物”。这个主遮挡物不需要太多的细节,一般是墙,天花板,地板之类的物体。在下面的例子中我们,使用6面墙来组成这个主遮挡物。


image


现在我们在每一个单元格中,放置一个高度分挌化的纹理球体。这些球体可能是被遮挡物,也可能是遮挡物。


在我的机器上没有遮挡查询下渲染的帧率是20左右。



image



在遮挡查询中,如果一个物体的边界都是不可见的,那么就代表这个物体不可见。所以我们只需检测物体外围的包围体可见,就可以判断物体是否被遮挡。物体外围的包围体包含着整个物体,这也就意味着包围体的体积是大于等于物体的体积的。对于一个球体来说,包围体可以有很多种,最常见的就是立方盒子,四面体等。


image


为什么要选择包围体去判断遮挡,而不是直接用球体的。因为球体太过于复杂,包含的顶点也多,渲染较耗时。遮挡之所以能够提升性能,就是我们可以在无光照,无纹理等其他效果的下,并且不需要改变缓冲区的值,先渲染简单的包围体。通过这些包围体进行深度测试,我们就能判断出哪些物体被遮挡,那些被遮挡的物体就可以不需要被渲染(不需要调用任何渲染该物体的命令),如果这个物体拥有非常多的顶点,那么遮挡在这个时候就能大幅度的提高性能。



遮挡查询的步骤:


查询对象的标识符(ID/名称)是一个无符号整数,我们可以通过glGenQueries函数生成,也可以自己定义。一般用OpenGL提供的glGenQueries会比较方便。


void glGenQueries(GLsizei n, GLuint *ids);


第一个参数是生成ID的个数,第二个参数是来存放这些ID的数组。0是保留的ID,不会被产生。我们还可以通过glIsQuery来判断一个ID是否是一个遮挡查询对象的ID。


void glIsQuery(GLuint id);


如果是返回GL_TRUE,不是则返回GL_FALSE。


有了遮挡查询对象的ID后,可以开始遮挡查询了。例如


void glBeginQuery(GLenum target, GLuint id);


其中target必须是GL_SAMPLES_PASSED. id是用来标识这次遮挡查询的ID。


void glEndQuery(GLenum target);结束这次遮挡查询,其中target必须是GL_SAMPLES_PASSED。


在完成对需要遮挡查询的物体渲染之后,我们需要提取遮挡查询的结果,可以通过glGetQueryObject[u]iv来提取结果,函数将返回片段或采样的数量。


void glGetQueryObjectiv(GLenum id, GLenum pname, GLint *param);


void glGetQueryObjectuiv(GLenum id, GLenum pname, GLuint *param);


id是这个遮挡查询对象的id,pname如果是GL_QUERY_RESULT, param将包含了通过深度测试的片段或样本(如果启用了多重采样)的数量,如果数量为0,则表示这个物体完全被遮挡。


在完成遮挡查询操作时,可能会有延迟。我们可以通过设置pname为GL_QUERY_RESULT_AVAILABLE来检查是否完成了。如果遮挡查询有效地完成了,则param将为GL_TRUE,否则为GL_FALSE.


例:


使用完遮挡查询对象之后,调用glDeleteQueries回收资源。


void glDeleteQueries(GLsizei n, const GLuint *ids);


修改前面的例子,我们可以先渲染27个球体的包围体,进行遮挡查询,如果有哪个包围体被完全遮挡,我们就不需要绘制这个球体了。代码片段如下:


image


有了遮挡查询后,帧率达到了32左右,当然还要看观察场景的角度。如果从某个角度看大部分球体都被遮挡了,性能的提升更大。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇OpenGL超级宝典学习笔记——反馈 下一篇OpenGL超级宝典学习笔记——深度..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目