📄 tutorial_13.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><!-- 这篇文章由Dancingwind翻译,作者的联系方式zhouwei02@mails.tsinghua.edu.cn --><title>NeHe OpenGL教程第十三课,DancingWind翻译</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css">A:link {
COLOR: #ccaaff; TEXT-DECORATION: none
}
A:visited {
COLOR: #ccaaff; TEXT-DECORATION: none
}
A:active {
COLOR: #ccaaff; TEXT-DECORATION: none
}
A:hover {
COLOR: #ffccaa; TEXT-DECORATION: none
}
</style>
<meta content="Microsoft FrontPage 3.0" name="GENERATOR"></head><body bgcolor="#000000" text="#ffffff">
<center><br>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td height="130" width="326"><img src="Tutorial_13_files/logo.png" height="130" width="326"></td>
<td align="center" valign="center" width="75%"><div align="center"><font color="#ffccaa" size="+3"><b><i>第13课</i></b></font></div></td>
</tr>
</tbody>
</table>
<!-- 上边框-->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/tr.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<!-- 中部-->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<!-- 中部左边框-->
<td background="Tutorial_13_files/l.gif"><img src="Tutorial_13_files/l.gif" height="28" width="28"></td>
<!-- 中部文字部分-->
<td valign="top" width="100%">
<table border="0" width="100%">
<tbody><tr>
<td width="34%"><img src="Tutorial_13_files/lesson13.jpg" height="180" width="240"></td>
<td width="66%"><p><font class="head">图像字体:</font></p>
<p><font size="3">这一课我们将创建一些基于2D图像的字体,它们可以缩放,但不能旋转,并且总是面向前方,但作为基本的显示来说,我想已经够了。</font></p></td>
</tr>
</tbody></table>
</td>
<!-- 中部右边框-->
<td background="Tutorial_13_files/r.gif"><img src="Tutorial_13_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<!-- 下边框-->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/tr.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td background="Tutorial_13_files/l.gif"><img src="Tutorial_13_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%"><p>欢迎来到另一课教程,这次我将教你如何使用位图字体,也许你会对自己说:“在屏幕上显示文字有什么难的?”。但是你真正尝试过就会知道,它确实没那么容易。
</p>
<p>当
然,你可以载入一段美术程序,把文字写在一个图片上,再把这幅图片载入你的OpenGL程序中,打开混合选项,从而在屏幕上显示出文字。但是这种做法非常
耗时。而且根据你选择的滤波类型,最终结果常常会显得很模糊,或者有很多马赛克。另外,除非你的图像包含一个Alpha通道,否则一旦绘制在屏幕上,那些
文字就会不透明(与屏幕中的其它物体混合)。 </p>
<p>如果你使用过记事本、微软的Word或者其它文字处理软件,你会注意到所有不同的字体都是可用的。这课就会教你如何在自己的OpenGL程序中使用和原样相同的字体。事实上,任何安装在你的计算机中的字体都可以使用在演示中(中文不行)。</p>
<p>使用位图字体比起使用图形字体(贴图)看起来不止强100倍。你可以随时改变显示在屏幕上的文字,而且用不着为它们逐个制作贴图。只需要将文字定位,再使用我最新的gl命令就可以在屏幕上显示文字了。</p>
<p>我
尽可能试着将命令做的简单。你只需要敲入glPrint("Hello")
。它是那么简单。不管怎样,从这段长长的介绍就可以看出,我对这课教程是多么的满意。写这段代码大概花了我一个半小时,为什么这么长的时间呢?那是因为在
使用位图字体方面完全没有可用的资料,除非你愿意使用MFC中的代码。为了使代码简单,我想,如果我把它全部重写为容易理解的C语言代码,那一定会好些
:)</p>
<p>一个小注释,这段代码是专门针对Windows写的,它使用了Windows的wgl函数
来创建字体,显然,Apple机系统有agl,X系统有glx来支持做同样事情的,不幸的是,我不能保证这些代码也是容易使用的。如果那位有能在屏幕上显
示文字且独立于平台的代码,请告诉我,我将重写一个有关字体的教程。</p>
<p>我们从第一课的典型代码开始,添加上stdio.h头文件以便进行标准输入/输出操作,另外,stdarg.h头文件用来解析文字以及把变量转换为文字。最后加上math.h头文件,这样我们就可以使用SIN和COS函数在屏幕中移动文字了。<br>
</p></td>
<td background="Tutorial_13_files/r.gif"><img src="Tutorial_13_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre>#include <stdarg.h> <font color="#ffffaa">// 用来定义可变参数的头文件</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/tr.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td background="Tutorial_13_files/l.gif"><img src="Tutorial_13_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%"><p>另外,我们还要添加3个变量。base将保存我们创建的第一个显示列表的编号。每个字符都需要有自己的显示列表。例如,字符‘A’在显示列表中是65,‘B’是66,‘C’是67,等等。所以,字符‘A’应保存在显示列表中的base
+ 65这个位置。</p>
<p> 然后添加两个计数器(cnt1 和 cnt2),它们采用不用的累加速度,通过SIN和COS函数来改变文字在屏幕上的位置。在屏幕上创造出一种看起来像是半随机的移动方式。同时,我们用这两个计数器来改变文字的颜色(后面会进一步解释)。<br>
</p></td>
<td background="Tutorial_13_files/r.gif"><img src="Tutorial_13_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">GLuint base; <font color="#ffffaa">// 绘制字体的显示列表的开始位置</font>
GLfloat cnt1; <font color="#ffffaa">// 字体移动计数器1</font>
GLfloat cnt2; <font color="#ffffaa">// </font><font color="#aaffaa" size="3"><font color="#ffffaa">字体移动计数器2</font></font>
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/tr.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td background="Tutorial_13_files/l.gif"><img src="Tutorial_13_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">下面这段代码用来构建真实的字体,这也是最难写的一部分代码。‘HFONT font’告诉Windows我们将要使用一个Windows字体。Oldfont用来存放字体。
<p>接下来我们在定义base的同时使用glGenLists(96)创建了一组共96个显示列表。<br>
</p></td>
<td background="Tutorial_13_files/r.gif"><img src="Tutorial_13_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre>GLvoid BuildFont(GLvoid) <font color="#ffffaa"> // 创建位图字体</font>
{
HFONT font; <font color="#ffffaa">// 字体句柄</font>
HFONT oldfont; <font color="#ffffaa">// <font size="3">旧的</font>字体句柄</font>
base = glGenLists(96); <font color="#ffffaa">// 创建96个显示列表</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/tr.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td background="Tutorial_13_files/l.gif"><img src="Tutorial_13_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">下面该有趣的部分了,我们将创建属于自己的字体。我们从指定字体的大小开始,你会注意到它是一个负数,我们通过加上一个负号来告诉Windows寻找一个基于CHARACTER高度的字体。如果我们使用一个正数,就是寻找一个与基于CELL的高度相匹配的字体。<br></td>
<td background="Tutorial_13_files/r.gif"><img src="Tutorial_13_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre> font = CreateFont( -24, <font color="#ffffaa">// 字体高度</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/tr.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td background="Tutorial_13_files/l.gif"><img src="Tutorial_13_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">然后我们指定每个单元的宽度,你会注意到我把它定义为0,这样,Windows就会使用默认值。如果你愿意的话,可以改变它的值,比如更宽一点,等等。</td>
<td background="Tutorial_13_files/r.gif"><img src="Tutorial_13_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre> 0, <font color="#ffffaa">// 字体宽度</font></pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/tr.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td background="Tutorial_13_files/l.gif"><img src="Tutorial_13_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">Angle Of Escapement会将字体旋转,它不是一个常用的属性,除了0,90,180,270四个角度以外,由于字体本身要适应其看不见的方形边框,常常会显的裁切不正。MSDN帮助中解释Orientation
Angle用于指定每个字的底边和显示设备的X轴之间的角度,每个单位是十分之一个角度,不幸的是我对这个没有概念。<br></td>
<td background="Tutorial_13_files/r.gif"><img src="Tutorial_13_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_13_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_13_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre> 0, <font color="#ffffaa">// 字体的旋转角度 Angle Of Escapement</font>
0, <font color="#ffffaa">// </font><font color="#aaffaa" size="3"><font color="#ffffaa">字体底线的旋转角度</font></font><font color="#ffffaa">Orientation Angle</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_13_files/tl.jpg" height="28" width="28"></td>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -