Occlusion Query 的用处
板用黄色绘制, 球用红色绘制.
我们利用 Occlusion Query 来查询到他们分别显示在屏幕上的Fragment Count.
首先定义一些需要的函数指针
把他们定义为全局变量.
然后我们来初始化这个扩展
首先获得Token, 然后查询是否支持,
如果支持了, 就初始化这些函数指针.
然后我们来创建查询.
g_sphereQuery, g_planeQuery 为GLuint,
记录创建后此'查询'的ID.
在这里我们创建了两个查询,
一个查询球的,一个查询板的.
当然在我们关闭程序
或者不再需要查询的时候,
要释放查询
然后就是渲染循环部分处理的事情了,
1.首先初始化深度缓存.
其实没有什么很特别的东西,
就是把球和板画一遍, 填充下深度.
2.开始Occlusion Query查询.
又要重绘一遍,
这一遍可以把材质什么的都去掉, 这些对查询无用.
当以上两步都做完后, 我们就可以来读取查询结果了.
读取结果过程如下:
planeFragmentCount, sphereFragmentCount 就是分别读取的Fragement Count.
然后用文本显示出来了.
以下就是完成一个Occlusion Query的大致步骤,
参考代码在这里可以找到:
http://www.codesampler.com/oglsrc/oglsrc_7.htm#ogl_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;
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;
}
}
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 );
glGenQueriesARB( 1, &g_planeQuery );
或者不再需要查询的时候,
要释放查询
glDeleteQueriesARB( 1, &g_sphereQuery );
glDeleteQueriesARB( 1, &g_planeQuery );
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();
{
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();
又要重绘一遍,
这一遍可以把材质什么的都去掉, 这些对查询无用.
//
// 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();
// 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();
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();
参考代码在这里可以找到:
http://www.codesampler.com/oglsrc/oglsrc_7.htm#ogl_occlusion_query