OpenGL扩展之点精灵的使用

点精灵类似于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

你可能感兴趣的:(null,扩展,Parameters,float,extension,distance)