点精灵类似于billboard, 他扩展了基本的点图元的功能, 一般的点,只有一种颜色,不能拥有纹理,而点精灵可以. 那你可能这样说, 我使用个多边形上面贴上纹理不就行了, 这样做有两个弊端,
1.增加了顶点数,增大了系统的负担,
2.它不拥有billboard的效果.
那什么是billboard呢, 看英文的意思是广告牌, billboard的技术能够将一个面一直面向观察者, 无论视点怎么移动和变化, 它始终面向观察者,这项技术应用很广, 其中最常用它的就是粒子效果.由于粒子点很小, 又很多, 我们不能用三维型体来代表微小的粒子, 因为系统性能受不了,而且alpha混合的时候也不好看.
这里有个粒子效果的粒子是用一个三维交错平面绘制的, 你可以看看粒子的形状, 像个星形,而且颜色不均匀.
下面这个粒子效果的粒子是用点精灵绘制的, 粒子颜色均匀,并且粒子成圆形.
但是遗憾的是,在OGL中并不能直接使用点精灵这项功能(D3D可以),必须通过其扩展(Extension)才能实现.
下面我就讲解下如何通过Extension实现点精灵功能.
首先我们需要获得一个扩展的头文件 glext.h, 我们把它包含到你的程序里面:
#include "glext.h"
我们在设置一些全局变量
// GL_ARB_point_parameters
PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL;
PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB = NULL;
这两个变量用来获得关于点精灵的一些功能函数的入口地址
下面我们来检测你的图形硬件是否支持点精灵扩展,将这段代码加到你的初始化过程里面.
char *ext = (char*)glGetString( GL_EXTENSIONS );
if( strstr( ext, "GL_ARB_point_parameters" ) == NULL )
{
MessageBox(NULL,"GL_ARB_point_parameters extension 没有找到",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(0);
}
else
{
glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)wglGetProcAddress("glPointParameterfARB");
glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)wglGetProcAddress("glPointParameterfvARB");
if( !glPointParameterfARB || !glPointParameterfvARB )
{
MessageBox(NULL,"一个或多个 GL_ARB_point_parameters 函数没有找到",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
exit(0);
}
}
如果不支持, 我们就退出程序.
当检测通过了以后,我们就需要正式开始来绘制点精灵了.
// 点精灵的尺寸会随着与视力距离的变化而变化
float quadratic[] = { 1.0f, 0.0f, 0.01f };
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic );
因为当我们在很远的地方看粒子的时候,它会很小, 在很近的地方它会很大,这里就是设置这个大小和眼与物距离的变化关系.
quadratic的参数分别为a,b,c , 设距离为d. 粒子看到的尺寸符合下面公式:
derived_size = clamp(size * sqrt(1 / (a + b * d + c * d ^ 2)))
我们得把最大尺寸限制一下:
//把尺寸限制在100以内,否则在一些新的显卡上会看得有些大
if( maxSize > 100.0f )
maxSize = 100.0f;
glPointSize( maxSize );
设置下最小和最大尺寸
// 计算点的ALPHA值来允许消隐点,来代替使他们收缩到他们的极限尺寸,
// 极限尺寸通过定义 GL_POINT_FADE_THRESHOLD_SIZE_ARB,而不是使他们
// 限制在最小到最大的尺寸之间
glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 60.0f );
glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 13.0f );
glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, maxSize );
设置纹理替换模式
// 为没有纹理单元指定点精灵的纹理坐标替换模式
glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
下面就可以绘制了:
glEnable( GL_POINT_SPRITE_ARB );
.......
bind texture.
draw points.
........
glDisable( GL_POINT_SPRITE_ARB );
这里有个使用点精灵的演示
http://www.azure.com.cn/article.asp?id=105