📄 tutorial_13.htm
字号:
<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"> oldfont = (HFONT)SelectObject(hDC, font); <font color="#ffffaa">// 选择我们需要的字体</font>
wglUseFontBitmaps(hDC, 32, 96, base); <font color="#ffffaa">// 创建96个显示列表,绘制从ASCII码为32-128的字符</font>
SelectObject(hDC, oldfont); <font color="#ffffaa"> // 选择原来的字体</font>
DeleteObject(font); <font color="#ffffaa">// 删除字体</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%">接下来的代码很简单。它在内存中从base开始删除96个显示列表。我不知道Windows是否会做这些工作,但还是保险为好。<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>GLvoid KillFont(GLvoid) <font color="#ffffaa">// 删除显示列表</font>
{
glDeleteLists(base, 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%">下面就是我优异的GL文字程序了。你可以通过调用glPrint(“需要写的文字”)来调用这段代码。文字被存储在字符串
* fmt中。</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 glPrint(const char *fmt, ...) <font color="#ffffaa"> // 自定义GL输出字体函数</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%">下面的第一行创建了一个大小为256个字符的字符数组,里面保存我们想要的文字串。第二行创建了一个指向一个变量列表的指针。我们在传递字符串的同时也传递了这个变量列表。如果我们传递文本时也传递了变量,这个指针将指向它们。</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> char text[256]; <font color="#ffffaa">// 保存文字串</font>
va_list ap; <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%">下面两行代码检查是否有需要显示的内容,如果什么也没有,fmt就等于空(NULL),屏幕上也就什么都没有。<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> if (fmt == NULL) <font color="#ffffaa">// 如果无输入则返回</font>
return; </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%">接下来三行代码将文字中的所有符号转换为它们的字符编号。最后,文字和转换的符号被存储在一个叫做text的字符串中。以后我会多解释一些有关字符的细节。<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> va_start(ap, fmt); <font color="#ffffaa">// 分析可变参数</font>
vsprintf(text, fmt, ap); <font color="#ffffaa">// 把参数值写入字符串</font>
va_end(ap); <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%">然后我们将GL_LIST_BIT压入属性堆栈,它会防止glListBase影响到我们的程序中的其它显示列表。
<p>GlListBase
(base-32)是一条有些难解释的命令。比如说要写字母‘A’,它的相应编号为65。如果没有glListBase(base-32)命令,
OpenGL就不知道到哪去找这个字母。它会在显示列表中的第65个位置找它,但是,假如base的值等于1000,那么‘A’的实际存放位置就是
1065了。所以通过base设置一个起点,OpenGL就知道到哪去找到正确的显示列表了。减去32是因为我们没有构造过前32个显示列表,那么就跳过
它们好了。于是,我们不得不通过从base的值减去32来让OpenGL知道这一点。我希望这些有意义。<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> glPushAttrib(GL_LIST_BIT); <font color="#ffffaa">// 把显示列表属性压入属性堆栈</font>
glListBase(base - 32); <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%">现在OpenGL知道字母的存放位置了,我们就可以让它在屏幕上显示文字了。GlCallLists是一个很有趣的命令。它可以同时将多个显示列表的内容显示在屏幕上。
<p>下
面的代码做后续工作。首先,它告诉OpenGL我们将要在屏幕上显示出显示列表中的内容。Strlen(text)函数用来计算我们将要显示在屏幕上的文
字的长度。然后,OpenGL需要知道我们允许发送给它的列表的最大值。我们不能发送长度大于255的字符串。这个字符列表的参数被当作一个无符号字符数
组处理,它们的值都介于0到255之间。最后,我们通过传递text(它指向我们的字符串)来告诉OpenGL显示的内容。</p>
<p>也许你想知道为什么字符不会彼此重叠堆积在一起。那时因为每个字符的显示列表都知道字符的右边缘在那里,在写完一个字符后,OpenGL自动移动到刚写过的字符的右边,在写下一个字或画下一个物体时就会从GL移动到的最后的位置开始,也就是最后一个字符的右边。</p>
<p>最后,我们将GL_LIST_BIT属性弹出堆栈,将GL恢复到我们使用glListBase(base-32)设置base那时的状态。<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> glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); <font color="#ffffaa"> // 调用显示列表绘制字符串</font>
glPopAttrib(); <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%">在初始化代码中唯一的变化就是BuildFont()。它调用前面的代码来创建字体,然后OpenGL就可以使用这个字体了。</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">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -