Occlusion Query (ARB_occlusion_query 扩展的使用)

[ 2007-02-27 15:17:47 | 作者: Admin ]
字体大小: | |
如有转载,请注明:
http://www.azure.com.cn/

Occlusion Query 的用处
  • 增量的物体级别的剔除
  • 顺序独立的透明
  • 光晕效果实现
  • 模板阴影
这个例子中, 我们绘制一个板和一个球,
板用黄色绘制, 球用红色绘制.
我们利用 Occlusion Query 来查询到他们分别显示在屏幕上的Fragment Count.

首先定义一些需要的函数指针
把他们定义为全局变量.
PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL;
PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB = NULL;
PFNGLISQUERYARBPROC glIsQueryARB = NULL;
PFNGLBEGINQUERYARBPROC glBeginQueryARB = NULL;
PFNGLENDQUERYARBPROC glEndQueryARB = NULL;
PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;
PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;
PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL;
然后我们来初始化这个扩展
首先获得Token, 然后查询是否支持,
如果支持了, 就初始化这些函数指针.
char *ext = (char*)glGetString( GL_EXTENSIONS );

if( strstr( ext, "GL_ARB_occlusion_query" ) == NULL )
{
MessageBox(NULL,"GL_ARB_occlusion_query extension was not found",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
return;
}
else
{
glGenQueriesARB = (PFNGLGENQUERIESARBPROC)wglGetProcAddress("glGenQueriesARB");
glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)wglGetProcAddress("glDeleteQueriesARB");
glIsQueryARB = (PFNGLISQUERYARBPROC)wglGetProcAddress("glIsQueryARB");
glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)wglGetProcAddress("glBeginQueryARB");
glEndQueryARB = (PFNGLENDQUERYARBPROC)wglGetProcAddress("glEndQueryARB");
glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)wglGetProcAddress("glGetQueryivARB");
glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)wglGetProcAddress("glGetQueryObjectivARB");
glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)wglGetProcAddress("glGetQueryObjectuivARB");

if( !glGenQueriesARB || !glDeleteQueriesARB || !glIsQueryARB ||
!glBeginQueryARB || !glEndQueryARB || !glGetQueryivARB ||
!glGetQueryObjectivARB || !glGetQueryObjectuivARB
)
{
MessageBox(NULL,"One or more GL_ARB_occlusion_query functions were not found",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
return;
}
}
然后我们来创建查询.
g_sphereQuery, g_planeQuery 为GLuint,
记录创建后此'查询'的ID.

在这里我们创建了两个查询,
一个查询球的,一个查询板的.
glGenQueriesARB( 1, &g_sphereQuery );
glGenQueriesARB( 1, &g_planeQuery );
当然在我们关闭程序
或者不再需要查询的时候,
要释放查询
glDeleteQueriesARB( 1, &g_sphereQuery );
glDeleteQueriesARB( 1, &g_planeQuery );
然后就是渲染循环部分处理的事情了,
1.首先初始化深度缓存.
其实没有什么很特别的东西,
就是把球和板画一遍, 填充下深度.
glPushMatrix();
{
glTranslatef( 0.0f, -0.025f, 0.0f);
glScalef( 1.0f, 0.05f, 1.0f );
glColor3f( 1.0f, 1.0f, 0.0f );
renderSolidCube( 0.435f );
}
glPopMatrix();

glPushMatrix();
{
glTranslatef( 0.0f, 0.25f, 0.0f );
glColor3f( 1.0f, 0.0f, 0.0f );
renderSolidSphere( 0.25f, 20, 20 );
}
glPopMatrix();
2.开始Occlusion Query查询.
又要重绘一遍,
这一遍可以把材质什么的都去掉, 这些对查询无用.
//
// Render the plane first and wrap it with an occlusion query
//

glPushMatrix();
{
glTranslatef( 0.0f, -0.025f, 0.0f);
glScalef( 1.0f, 0.05f, 1.0f );

glBeginQueryARB( GL_SAMPLES_PASSED_ARB, g_planeQuery );
{
glColor3f( 1.0f, 1.0f, 0.0f );
renderSolidCube( 0.435f );
}
glEndQueryARB( GL_SAMPLES_PASSED_ARB );
}
glPopMatrix();

//
// Render the sphere second and wrap it with an occlusion query
//

glPushMatrix();
{
glTranslatef( 0.0f, 0.25f, 0.0f );

glBeginQueryARB( GL_SAMPLES_PASSED_ARB, g_sphereQuery );
{
glColor3f( 1.0f, 0.0f, 0.0f );
renderSolidSphere( 0.25f, 20, 20 );
}
glEndQueryARB( GL_SAMPLES_PASSED_ARB );
}
glPopMatrix();
当以上两步都做完后, 我们就可以来读取查询结果了.
读取结果过程如下:
planeFragmentCount, sphereFragmentCount 就是分别读取的Fragement Count.
然后用文本显示出来了.
GLuint planeFragmentCount;
GLuint sphereFragmentCount;
char planeString[50];
char sphereString[50];

glGetQueryObjectuivARB( g_planeQuery, GL_QUERY_RESULT_ARB, &planeFragmentCount);
glGetQueryObjectuivARB( g_sphereQuery, GL_QUERY_RESULT_ARB, &sphereFragmentCount);

sprintf( planeString, "Plane Fragments = %d", planeFragmentCount );
sprintf( sphereString, "Sphere Fragments = %d", sphereFragmentCount );

beginRenderText( g_nWindowWidth, g_nWindowHeight );
{
glColor3f( 1.0f, 1.0f, 1.0f );
renderText( 5, 15, BITMAP_FONT_TYPE_HELVETICA_12, planeString );
renderText( 5, 30, BITMAP_FONT_TYPE_HELVETICA_12, sphereString );
}
endRenderText();
以下就是完成一个Occlusion Query的大致步骤,
参考代码在这里可以找到:
http://www.codesampler.com/oglsrc/oglsrc_7.htm#ogl_occlusion_query

www.azure.com.cn
[最后修改由 Admin, 于 2007-02-27 16:23:25]
评论Feed 评论Feed: http://www.azure.com.cn/feed.asp?q=comment&id=301

这篇日志没有评论.

此日志不可发表评论.
ħ˽ ħ˽