第八章 象素、位图、字体和图象的绘制

第八章 象素、位图、字体和图象的绘制

位图和字体

一个位图就是由0和1组成的矩形陈列,起到窗口中对应矩形位置的绘制掩模的作用。假定你正在绘制一幅位图,当前颜色为红色。在位图中为一个的每个地方,对应的象素将被红色象素取代(或与红色象素组合,要看哪个逐象素操作在起作用,参看Testing and Operationg on Fragments")。如果在位图中有个一0,那个象素的内容将不受影响。通常使用位图是为了在屏幕上绘制字符。

OpenGL只提供了绘制字符串和操纵字体的的最低级的支持。命令glRasterPos*()glBitmap()在屏幕上定位并绘制单个位图。另外,通过显示列表机制,你可以用一个字符编码序列去索引相应的表示这些字符的位图序列。参见第4章以获得显示列表的进一步信息。你得自己写一个例程来提供对位图、字体、字符串操纵的所需的支持。

作为一个例子,注意Example 8-1,它在屏幕上绘制字母F三次。Figure 8-1展示了作为位图的F和它对应的位图数据。

//Figure 8-1

Example 8-1 : Drawing a Bitmapped Character: drawf.c

#include <GL/gl.h>

#include <GL/glu.h>

#include "aux.h"

GLubyte rasters[24] = {

0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,

0xc0, 0x00, 0xff, 0x00, 0xff, 0x00, 0xc0, 0x00,

0xc0, 0x00, 0xc0, 0x00, 0xff, 0xc0, 0xff, 0xc0};

void myinit(void)

{

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glClearColor(0.0, 0.0, 0.0, 0.0);

}

void display(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0, 1.0, 1.0);

glRasterPos2i (20.5, 20.5);

glBitmap(10, 12, 0.0, 0.0, 12.0, 0.0, rasters);

glBitmap(10, 12, 0.0, 0.0, 12.0, 0.0, rasters);

glBitmap(10, 12, 0.0, 0.0, 12.0, 0.0, rasters);

glFlush();

}

void myReshape(GLsizei w, GLsizei h)

{

glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(0, w, 0, h, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);

}

 

int main(int argc, char** argv)

{

auxInitDisplayMode(AUX_SINGLE | AUX_RGBA);

auxInitPosition(0, 0, 500, 500);

auxInitWindow(argv[0]);

myinit();

auxReshapeFunc(myReshape);

auxMainLoop(display);

}

在图8-1中,注意字符F的可见部分有大约10个位(bit)宽。位图数据总是以8个位的若干倍的块存储的,但位图实际的宽度却不必是8的倍数。这些组成位图的位从左下角开始绘制:首先,底线被绘制,然后它上面的那条线,依此类推。正如你可以从代码中了解到的,位图以这个顺序存在内存中-光栅矩阵以0xc0, 0x00, 0xc0, 0x00从F的底部两行开始直到代表最上两行的0xff, 0xc0, 0xff, 0xc0

这个例子中我们感兴趣的命令是glRasterPos2i()glBitmap();它们将会在下一节里仔细讨论。现在先忽略对glPixelStorei()的调用,它说明了位图数据是怎样存放在计算机内存中的。这个话题在"Controlling Pixel-Storage Modes"部分讨论。

当前光栅位置

当前光栅位置是下一个位图(或图象)绘制的原点。在F的例子中,光栅位置被用glRasterPos*()设为(2020),那是所绘制F的左下角:

glRasterPos2i(20,20);

void glRasterPos{234}{sifd}{v}(TYPE x, TYPE y, TYPE z, TYPE w);

设定当前光栅位置。参数xyzw说明了光栅位置的坐标。。如果glRasterPos2*()被使用,z被简单的设为0并且w总是被设为1;类似的,对glRasterPos3*()w被设为1。

光栅位置的坐标变换为屏幕坐标的过程与glVertex*()命令所提供的坐标的变换过程完全一样(即,经模型视见和透视变换矩阵)。变换之后,它们或者定义一个屏幕上窗口中一个有效的位置,或者因为变换后位于视区之外而被裁剪掉。如变换后的点被裁剪掉则当前光栅位置无效。

要获得当前光栅位置,你可以用GL_CURRENT_RASTER_POSITION作为参数调用查询命令glGetFloatv()。第二个参数必须是一个指向内存阵列的指针,这个阵列要足以容纳(x,y,z,w)四个浮点值。以GL_CURRENT_RASTER_POSITION_VALID作为第一个参数调用glGetBooleanv()决定当前光栅位置是否有效。

绘制位图Drawing the Bitmap

一旦你已经设定了想要的光栅位置,你大概就想用glBitmap()命令去绘制那些数据了。Void glBitmap(Glsizei width,Glsizei height, Glfloat xbo, Glfloat ybo,Glfloat xbi, Glfloat ybi, const Glubyte *bitmap);

绘制bitmap所描述位图,bitmap是指向位图图象的指针。位图的原点被放在最接近当前光栅位置的地方。如果当前光栅位置无效,什么也不绘制。而光栅位置保持无效。Widthheight参数说明位图的宽度和高度,以象素为单位。宽度不必是8的倍数,尽管数据是保存在8位无符号字符中的。(在F的例子中,如果有十个位以外的多余的位是没有关系的,应为glBitmap()是以宽度10调用的,每行只有10个位被绘制。)用xbo和ybo定义位图的原点(正值将原点移向右上;负值将它移向左下);xbi和ybi说明在位图光栅化后加给光栅位置的增量。(见Figure 8-2)。

由于可以把位图的原点放在任意位置使得处理那些伸展到原点以下的字符变得容易。(典型用于带下缘的字母,如g,j,y),或伸展在原点左边的字符(用于许多swash characters,它们夸张的伸展,或用于字体中向左倾斜的字符)。

位图被绘制之后,当前光栅位置将会在x方向和y方向分别前进xbi和ybi。对标准的拉丁(Latin)字体,ybi通常是0.0而xbi是正值(因为连继的字符是从左到右绘制的)。对希伯莱字体(Hebrew),字母是从右到左的,xbi通常将会是负值。连续的字符被垂直绘制成一列时将令xbi为0,而ybi为非负值。在Figure 8-2中,每资F被绘制,当前光栅位置前进12象素,在相邻字符间有两个象素的空间。

因为xbo,ybo,xbi,ybi是浮点值,字符的象素宽度不必是整数值。实际的字符将会在精确的象素边界上被绘制,但当前光栅位置仍保持浮点值,这样每个字符将会被绘制在尽可能接近它应该的位置。例如,如在F例子中的代码这样修改:xbi是11.5而不是12,并且绘制更多的字符,字符间的空间将被改成1到2个象素之间,以取得对所要求的1.5个象素的最佳似近。注意,位图不能用于可旋转字体,因为位图总是对齐帧缓存绘制的。

Fonts and Display Lists

对显示列表的一般性讨论在Chapter 14中。然而,一些显示列表控制命令对绘制字符串有特殊的价值。当你读这一部分是,记着这里所说的将用位图绘制的字符与用几何图元(点、线、多边形)绘制的等价起来。"Executing Mulitiple Display Lists"给出了一个几何字体的例子。

一个字体通常由一个字符集,其中每个字符有一个特征数字(通常是ASCII码),和一种绘制方法组成。对标准的ASCII字符集,大写字母A是数字65,B是66,依此类推。在最简单的近似显示列表数字65将绘制一个A,数字66绘制一个B,依此类推。那么,要绘制字符串68,65,66,只要执行相应的显示列表。

你可以用这种方式调用命令glCallLists()

Void glCallLists(Glsizei n, Glenum type, const Glvoid *lists);

第一个参数n,说明要绘制的字符个数,type通常是GL_BYTE,而lists是一个字符代码数组。

因为许多应用程序需要用不同的字体和尺寸绘制字符串,这种最简单的近似并不方便。相反,你可能想把65当作A而不管是哪个字体在起作用。你可以强制在字体1中将A、B、C编码为1065,1066,1067,而在字体2中为2065,2066,2067,然而任何超过256的数字将不再适合8位字节(byte)。一个更好的解决方法是给字符串和选择显示列表的每个条目加一个偏移量。在这种情况下,字体1中A、B、C表示为1065,1066,1067,而在字体2中可能是2065,2066,2067。当用字体1绘制字符时,设定偏移量为1000并绘制显示列表65,66,67。要用字体2绘制相同的字符串则将偏移量设为2000并绘制相同的显示列表。

在这种似近下,用命令glListBase()设定偏移量。对前面的例子,它将以1000或2000作为(唯一)参数被调用。现在你需要一串连续的未被使用的显示列表数字,它可以从glGenLists()获得。

.Gluint glGenLists(Glsizei range);

这个函数返回range个显示列表标识符组成的块。返回的列表将全部标记为已被使用尽管它们是空的,这样接下来对glGenLists()的使用就绝不会返回相同的列表(除非你你在这之前已经明确的删除了它们)。这样,如果你用4作为参数并且如果glGenLists()返回81,你可以为你的字符使用显示列表标识符81,82,83,84。如果glGenLists()找不到一个指定长度的未使用标识符块,它将返回0。(注意命令glDeleteLists()使得删除与一个字体相关联的所有显示列表简化到只用一条指令)。

许多美洲和欧洲字体一个很小的字体集(少于256),因此用不同的单字节代码代表每个字符是很容易的。其它字体中的亚洲字体可能要求一个巨大的字符集,这样每个字符一个字节编码是不可能的。通过glCallLists()type参数,OpenGL允许字符串由1、2、3、4字节字符组成。这个参数可以取以下值中的一个:

GL_BYTE  GL_UNSIGNED_BYTE

GL_SHORT  GL_UNSIGNED_SHORT

GL_INT   GL_UNSIGNED_INT

GL_FLOAT  GL_2_BYTES

GL_3_BYTES GL_4_BYTES

参见"Executing Multiple Display Lists"以得到这些值的详细信息。

Defing and Using a Complete Font

本节中样本的程序用glBitmap()命令和前面描述的显示列表机制定义一个了完整的光栅字体。一个完整的ASCII字体被定义为每个字符宽度相同(尽管这完全没必要)。代码与F的例子很象,除了需要95个不同的位图(每个可打印ASCII字符一个,含空格),并且每个都是显示列表中一条单独的命令。每个显示列表标识符与ASCII码相等,都被加上相同的偏移量。Example 8-2产生的输出与Figure 8-3所示。

Figure 8-3 : A Complete Font Definition

 

 

Example 8-2 : Defining a Complete Font: font.c

#include <GL/gl.h>

#include <GL/glu.h>

#include "aux.h"

GLubyte rasters[][13] = {

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36},

{0x00, 0x00, 0x00, 0x66, 0x66, 0xff, 0x66, 0x66, 0xff, 0x66, 0x66, 0x00, 0x00},

{0x00, 0x00, 0x18, 0x7e, 0xff, 0x1b, 0x1f, 0x7e, 0xf8, 0xd8, 0xff, 0x7e, 0x18},

{0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x6e, 0x30, 0x18, 0x0c, 0x76, 0xdb, 0xd8, 0x70},

{0x00, 0x00, 0x7f, 0xc6, 0xcf, 0xd8, 0x70, 0x70, 0xd8, 0xcc, 0xcc, 0x6c, 0x38},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x0e},

{0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c},

{0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30},

{0x00, 0x00, 0x00, 0x00, 0x99, 0x5a, 0x3c, 0xff, 0x3c, 0x5a, 0x99, 0x00, 0x00},

{0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00},

{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03},

{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c},

{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18},

{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e},

{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e},

{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c},

{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},

{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},

{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff},

{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},

{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},

{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06},

{0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60},

{0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x06, 0x03, 0xc3, 0xc3, 0x7e},

{0x00, 0x00, 0x3f, 0x60, 0xcf, 0xdb, 0xd3, 0xdd, 0xc3, 0x7e, 0x00, 0x00, 0x00},

{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18},

{0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},

{0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},

{0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc},

{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},

{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff},

{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},

{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},

{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e},

{0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06},

{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3},

{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},

{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3},

{0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3},

{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e},

{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},

{0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c},

{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},

{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e},

{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff},

{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},

{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},

{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},

{0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},

{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},

{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff},

{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c},

{0x00, 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60},

{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18},

{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x30, 0x70},

{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0x7f, 0x03, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},

{0x00, 0x00, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x03},

{0x00, 0x00, 0x7f, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x33, 0x1e},

{0x7e, 0xc3, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0},

{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00},

{0x38, 0x6c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x00},

{0x00, 0x00, 0xc6, 0xcc, 0xf8, 0xf0, 0xd8, 0xcc, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0},

{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78},

{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xfe, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},

{0xc0, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0x00, 0x00, 0x00, 0x00},

{0x03, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0xfe, 0x03, 0x03, 0x7e, 0xc0, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00},

{0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},

{0xc0, 0x60, 0x60, 0x30, 0x18, 0x3c, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0xff, 0x60, 0x30, 0x18, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00},

{0x00, 0x00, 0x0f, 0x18, 0x18, 0x18, 0x38, 0xf0, 0x38, 0x18, 0x18, 0x18, 0x0f},

{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},

{0x00, 0x00, 0xf0, 0x18, 0x18, 0x18, 0x1c, 0x0f, 0x1c, 0x18, 0x18, 0x18, 0xf0},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00}

};

GLuint fontOffset;

void makeRasterFont(void)

{

GLuint i;

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

fontOffset = glGenLists (128);

for (i = 32; i < 127; i++) {

glNewList(i+fontOffset, GL_COMPILE);

glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, rasters[i-32]);

glEndList();

}

}

void myinit(void)

{

glShadeModel (GL_FLAT);

makeRasterFont();

}

void printString(char *s)

{

glPushAttrib (GL_LIST_BIT);

glListBase(fontOffset);

glCallLists(strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s);

glPopAttrib ();

}

void display(void)

{

GLfloat white[3] = { 1.0, 1.0, 1.0 };

int i, j;

char teststring[33];

glClear(GL_COLOR_BUFFER_BIT);

glColor3fv(white);

for (i = 32; i < 127; i += 32) {

glRasterPos2i(20, 200 - 18*i/32);

for (j = 0; j < 32; j++)

teststring[j] = (char) (i+j);

teststring[32] = 0;

printString(teststring);

}

glRasterPos2i(20, 100);

printString("The quick brown fox jumps");

glRasterPos2i(20, 82);

printString("over a lazy dog.");

glFlush ();

}

void myReshape(GLsizei w, GLsizei h)

{

glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho (0.0, w, 0.0, h, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);

}

 

int main(int argc, char** argv)

{

auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);

auxInitPosition (0, 0, 500, 500);

auxInitWindow (argv[0]);

myinit();

auxReshapeFunc (myReshape);

auxMainLoop(display);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值