光栅位置
设置当前光栅位置的命令是glRasterPos,其原型为:
void glRasterPos{[2][3][4]}{[d][f][i][s]}[v](TYPE x,TYPE y,TYPE z,TYPE w);
其中234表示光栅位置的坐标值个数,也决定了后面的参数个数。dfis表示参数取值类型,如果带v则表示参数是一个向量。例如设置一个光栅位置的三维坐标可以使用glRasterPos3f(1.0, 1.0, 1.0)。
在glRasterPos4命令中,w可以有多种含义,它可以是一个裁减坐标,视点坐标距离、有效位,也可以表示是颜色数据和纹理坐标。
glRasterPos4显式地指定x,y,z和w的值,glRasterPos3显式地指定x,y,z的值,并且把w设置为1,glRasterPos2则显式指定x,y的值,并且将z和w设置为0和1。
如果不进行设置,则当前光栅坐标的缺省值为(0,0,0,1)。当前光栅距离(z)为0,有效位被设置为有效,相应的RGBA颜色值为(1,1,1,1),颜色索引值为1,相应纹理坐标为(0,0,0,1)。除了glRasterPos外,glBitmap也可以改变光栅坐标。
显示位图
设置光栅坐标后,就可以使用函数glBitmap()显示位图。glBitmap()的原型如下:
void glBitmap(
GLsizei width,
GLsizei height,
GLfloat xorig,
GLfloat yorig,
GLfloat xmove,
GLfloat ymove,
const GLubyte *bitmap
);
其中width, height表示位图的宽度和高度,以像素为单位。xorig, yorig 表示位图的原点,原点的计算以从位图的左下角开始,向右为x的正轴,向上为y的正轴。
xmove, ymove 表示位图显示之后,当前光栅位置增加的x和y方向的偏移量。bitmap是一个指针,指向需要显示的位图数据。例如一个Times字体字符“X”的8X8的位图如下图8-2所示,
图8-2 X字符位图
其点阵数据从最下边的扫描行到最上边的扫描行数据定义为:
GLubyte xBitmap[8] = {0xe7, 0x62, 0x34, 0x08, 0x14, 0x22, 0x77, 0x00};
位图的宽度是8,高度也是8。实际上,位图的高度通常可以改变,但是宽度应该是8的倍数,否则OpenGL无法处理。例如一个隶书体的汉字“好”的16X16点阵位图如下图8-3所示。
图8-3 隶书字体“好”的位图
其点阵数据定义为:
GLubyte haoBitmap[32]=
{
0x00, 0x00,
0x00, 0x00,
0x00, 0xe0,
0xe1, 0xf0,
0x3e, 0x18,
0x0c, 0x18,
0x1c, 0x18,
0x34, 0x19,
0x25, 0xff,
0xfe, 0x10,
0x30, 0x30,
0x18, 0x8e,
0x0c, 0xfe,
0x04, 0x00,
0x00, 0x00,
0x00, 0x00
};
下面我们来使用一个例程说明位图的显示。由于使用位图显示基本上是纯二维操作,涉及到的三维设置均可以忽略。
int glInit()
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glClearColor(1.0f,1.0f,1.0f,0.0f);
return TRUE;
}
//字符“X”位图数据
GLubyte xBitmap[8] =
{
0xe7,
0x62,
0x34,
0x08,
0x14,
0x22,
0x77,
0x00
};
//隶书汉字“好”的位图数据
GLubyte haoBitmap[32]=
{
0x00, 0x00,
0x00, 0x00,
0x00, 0xe0,
0xe1, 0xf0,
0x3e, 0x18,
0x0c, 0x18,
0x1c, 0x18,
0x34, 0x19,
0x25, 0xff,
0xfe, 0x10,
0x30, 0x30,
0x18, 0x8e,
0x0c, 0xfe,
0x04, 0x00,
0x00, 0x00,
0x00, 0x00
};
//字体位置的变化量
int dx=1, dy=1;
void glMain()
{
static int x=0, y=0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); //加载单位矩阵
//显示字符的颜色为红色
glColor3f(1.0f, 0.0f, 0.0f);
//将当前的变换属性值视点属性值压入属性堆栈
glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );
// 使用新的投影矩阵和模型观察矩阵
glMatrixMode( GL_PROJECTION ); // 设置我们的投影矩阵
glPushMatrix();
glLoadIdentity(); // 使用新的投影矩阵
glMatrixMode( GL_MODELVIEW ); // 设置观察矩阵
glPushMatrix();
glLoadIdentity(); // 使用新的观察矩阵
glViewport( x, y, 0, 0 ); // 创建一个新的视点
glRasterPos4f( 0.0, 0.0, 0.0, 1.0 ); // 设置绘图位置(x, y, z, w)
//绘制“X”字符
glBitmap(8, 8, 0, 0, 16, 16, xBitmap);
//绘制汉字“好”
glBitmap(16,16,0,0,0,0, haoBitmap);
//恢复模型观察矩阵
glPopMatrix();
//恢复投影矩阵
glMatrixMode( GL_PROJECTION );
glPopMatrix();
//恢复变换和视点的属性值
glPopAttrib();
//修改x,y的位置,使得字符“X”在窗口内运动,遇到窗口边框即返回
x+=dx;
y+=dy;
if(x>WIDTH || x<0)dx=-dx;
if(y>HEIGHT || y<0) dy=-dy;
SwapBuffers(g_hDC);//交换前后缓冲区
}
程序运行后,可以看到一个红色的“X”字符和汉字“好”一起不断在窗口内运动,并且碰到窗口的边沿即折回,类似一个乒乓球的碰撞运动,效果如图8-4所示。
图8-4 OpenGL位图