📄 tutorial_10.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></head><body bgcolor="#000000" text="#ffffff"><br><br>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td height="130" width="326"><img src="Tutorial_10_files/logo.png" height="130" width="326"></td>
<td align="center" valign="middle" width="75%"><font color="#ffccaa" size="+3"><b><i>第10课</i></b></font></td>
</tr></tbody></table>
<!-- 上边框-->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_10_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_10_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_10_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_10_files/l.gif"><img src="Tutorial_10_files/l.gif" height="28" width="28"></td>
<!-- 中部文字部分-->
<td valign="top" width="100%">
<table border="0" width="100%">
<tbody><tr>
<td width="25%"><img src="Tutorial_10_files/lesson10.jpg" height="180" width="240"></td>
<td width="75%"><p><font class="head">加载3D世界,并在其中漫游:</font></p>
<p><font size="3">在这一课中,你将学会如何加载3D世界,并在3D世界中漫游。这一课使用第一课的代码,当然在课程说明中我只介绍改变了代码。</font></p></td>
</tr>
</tbody></table>
</td>
<!-- 中部右边框-->
<td background="Tutorial_10_files/r.gif"><img src="Tutorial_10_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_10_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_10_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_10_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_10_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_10_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_10_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_10_files/l.png"><img src="Tutorial_10_files/l.png"></td>
<td valign="top" width="100%"> 这一课是由Lionel Brits (βtelgeuse)所写的。在本课中我们只对增加的代码做解释。当然只添加课程中所写的代码,程序是不会运行的。如果您有兴趣知道下面的每一行代码是如何运行的话,请下载完整的源码,并在浏览这一课的同时,对源码进行跟踪。<br>
好了现在欢迎来到名不见经传的第十课。到现在为止,您应该有能力创建一个旋转的立方体或一群星星了,对3D编程也应该有些感觉了吧?但还是请等一下!不要立马冲动地要开始写个Quake<br>
IV,好不好...:)。只靠旋转的立方体还很难来创造一个可以决一死战的酷毙了的对手....:)。现在这些日子您所需要的是一个大一点的、更复杂些
的、动态3D世界,它带有空间的六自由度和花哨的效果如镜像、入口、扭曲等等,当然还要有更快的帧显示速度。这一课就要解释一个基本的3D世界"结构",
以及如何在这个世界里游走。<br>
数据结构<br>
当您想要使用一系列的数字来完美的表达3D环境时,随着环境复杂度的上升,这个工作的难度也会随之上升。出于这个原因,我们必须将数据归类,使其具有更多
的可操作性风格。在程序清单头部出现了sector(区段)的定义。每个3D世界基本上可以看作是sector(区段)的集合。一个sector(区段)
可以是一个房间、一个立方体、或者任意一个闭合的区间。</td>
<td background="Tutorial_10_files/r.gif"><img src="Tutorial_10_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_10_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_10_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_10_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre>typedef struct tagSECTOR <font color="#ffffaa">// 创建Sector区段结构</font>
{
int numtriangles; <font color="#ffffaa">// Sector中的三角形个数</font>
TRIANGLE* triangle; <font color="#ffffaa">// 指向三角数组的指针</font>
} SECTOR; <font color="#ffffaa">// 命名为SECTOR</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_10_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_10_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_10_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_10_files/l.gif"><img src="Tutorial_10_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%"> 一个sector(区段)包含了一系列的多边形,所以下一个目标就是triangle(我们将只用三角形,这样写代码更容易些)。</td>
<td background="Tutorial_10_files/r.gif"><img src="Tutorial_10_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_10_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_10_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_10_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre>typedef struct tagTRIANGLE <font color="#ffffaa">// 创建Triangle三角形结构</font>
{
VERTEX vertex[3]; <font color="#ffffaa">// VERTEX矢量数组,大小为3</font>
} TRIANGLE; <font color="#ffffaa">// 命名为 TRIANGLE</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_10_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_10_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_10_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_10_files/l.gif"><img src="Tutorial_10_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">三角形本质上是由一些(两个以上)顶点组成的多边形,顶点同时也是我们的最基本的分类单位。顶点包含了OpenGL真正感兴趣的数据。我们用3D空间中的坐标值(x,y,z)以及它们的纹理坐标(u,v)来定义三角形的每个顶点。</td>
<td background="Tutorial_10_files/r.gif"><img src="Tutorial_10_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_10_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_10_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_10_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre>typedef struct tagVERTEX <font color="#ffffaa">// 创建Vertex顶点结构</font>
{
float x, y, z; <font color="#ffffaa">// 3D 坐标</font>
float u, v; <font color="#ffffaa">// 纹理坐标</font>
} VERTEX; <font color="#ffffaa">// 命名为VERTEX</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_10_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_10_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_10_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_10_files/l.gif"><img src="Tutorial_10_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%"><p>载入文件<br>
在程序内部直接存储数据会让程序显得太过死板和无趣。从磁盘上载入世界资料,会给我们带来更多的弹性,可以让我们体验不同的世界,而不用被迫重新编译程
序。另一个好处就是用户可以切换世界资料并修改它们而无需知道程序如何读入输出这些资料的。数据文件的类型我们准备使用文本格式。这样编辑起来更容易,写
的代码也更少。等将来我们也许会使用二进制文件。 </p>
<p> 问题是,怎样才能从文件中取得数据资料呢?首先,创建一个叫做SetupWorld()的新函数。把这个文件定义为filein,并且使用只读方式打开文件。我们必须在使用完毕之后关闭文件。大家一起来看看现在的代码:<br>
</p></td>
<td background="Tutorial_10_files/r.gif"><img src="Tutorial_10_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_10_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_10_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_10_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -