📄 tutorial_32.htm
字号:
glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
return true; <font color="#ffffaa">// 材质建立成功, 返回正确</font>
}
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_32_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_32_files/l.png"><img src="Tutorial_32_files/l.png"></td>
<td valign="top" width="100%">2D 字体材质代码同我已在前一课用的是一样的. 然而, 有一些小不同. 第一是你将看到仅仅唯一生成95
显示列表. 若你看字体材质, 你会看到只有 95 字母计算空间在图片顶,左. 第二个事是你将通知分在16.0f 为 cx 和 我们只分在8.0f
为cy. 我这样做的结果是因为字体材质是256 象素宽, 但仅仅一伴就高(128 象素). 所以计算cx 我们分为16.0f 和计算分cy 为一半(8.0f).
<p>若你不懂下面的代码, 回去读17课. 建立字体的代码的详细解释在第17课里! </p>
<p><br>
</p></td><td background="Tutorial_32_files/r.png"><img src="Tutorial_32_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_32_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">GLvoid BuildFont(GLvoid) <font color="#ffffaa">// 建立我们字体显示列表</font>
{
base=glGenLists(95); <font color="#ffffaa">// 建立 95 显示列表</font>
glBindTexture(GL_TEXTURE_2D, textures[9].texID); <font color="#ffffaa">// 绑我们字体材质</font>
for (int loop=0; loop<95; loop++) <font color="#ffffaa">// 循环在 95 列表</font>
{
float cx=float(loop%16)/16.0f; <font color="#ffffaa">// X 位置 在当前字母</font>
float cy=float(loop/16)/8.0f; <font color="#ffffaa">// Y 位置 在当前字母</font>
glNewList(base+loop,GL_COMPILE); <font color="#ffffaa">// 开始建立一个列表</font>
glBegin(GL_QUADS); <font color="#ffffaa">// 用四边形组成每个字母</font>
glTexCoord2f(cx, 1.0f-cy-0.120f); glVertex2i(0,0); <font color="#ffffaa">// 质地 / 点 座标 (底 左)</font>
glTexCoord2f(cx+0.0625f, 1.0f-cy-0.120f); glVertex2i(16,0); <font color="#ffffaa">// 质地 / 点 座标 (底 右)</font>
glTexCoord2f(cx+0.0625f, 1.0f-cy); glVertex2i(16,16); <font color="#ffffaa">// 质地 / 点 座标 (顶 右)</font>
glTexCoord2f(cx, 1.0f-cy); glVertex2i(0,16); <font color="#ffffaa">// 质地 / 点 座标 (顶 左)</font>
glEnd(); <font color="#ffffaa">// 完成建立我们的 四边形 (字母)</font>
glTranslated(10,0,0); <font color="#ffffaa">// 移到字体的右边</font>
glEndList(); <font color="#ffffaa">// 完成建军立这个显示列表</font>
} <font color="#ffffaa">// 循环直到所有 256 完成建立</font>
}
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_32_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_32_files/l.png"><img src="Tutorial_32_files/l.png"></td>
<td valign="top" width="100%">输出的代码也在第17课, 但已修改为在屏幕输出我们的分数, 等级和士气(不断改变的值). </td>
<td background="Tutorial_32_files/r.png"><img src="Tutorial_32_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_32_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">GLvoid glPrint(GLint x, GLint y, const char *string, ...) <font color="#ffffaa">// 输出在屏慕的位置</font>
{
char text[256]; <font color="#ffffaa">// 保存在我们的字符串</font>
va_list ap; <font color="#ffffaa">// 到列表的指针</font>
if (string == NULL) <font color="#ffffaa">// 若文字为空</font>
return; <font color="#ffffaa">// 返回</font>
va_start(ap, string); <font color="#ffffaa">// 解析字符串</font>
vsprintf(text, string, ap); <font color="#ffffaa">// 转换字符串</font>
va_end(ap); <font color="#ffffaa">// 结果的字符串</font>
glBindTexture(GL_TEXTURE_2D, textures[9].texID); <font color="#ffffaa"> // 选择我们字体材质</font>
glPushMatrix(); <font color="#ffffaa">// 存观看模式矩阵</font>
glLoadIdentity(); <font color="#ffffaa"> // 设观看模式矩阵</font>
glTranslated(x,y,0); <font color="#ffffaa">// 文字输出位置 (0,0 - 底 左-Bottom Left)</font>
glListBase(base-32); <font color="#ffffaa">// 选择字体设置</font>
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); <font color="#ffffaa">// 输出显示列表中的文字</font>
glPopMatrix(); <font color="#ffffaa">// 取出以前的模式矩阵</font>
}
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_32_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_32_files/l.png"><img src="Tutorial_32_files/l.png"></td>
<td valign="top" width="100%">这些代码调用排序程序. 它比较距离在两个结构并返回-1 若第一个结构的距离小于第二个 , 1 i若
第一个结构的距离大于第二个 0 否则 (若 距离相等) </td>
<td background="Tutorial_32_files/r.png"><img src="Tutorial_32_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_32_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
<pre>int Compare(struct objects *elem1, struct objects *elem2) <font color="#ffffaa">// 比较 函数</font>
{
if ( elem1->distance < elem2->distance) <font color="#ffffaa">// 若 第一个结构的距离小于第二个</font>
return -1; <font color="#ffffaa">// 返回 -1</font>
else if (elem1->distance > elem2->distance) <font color="#ffffaa">// 若 第一个结构的距离大于第二个</font>
return 1; <font color="#ffffaa">// 返回1</font>
else <font color="#ffffaa">// 否则 (若 距离相等)</font>
return 0; <font color="#ffffaa">// 返回 0</font>
}
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_32_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_32_files/l.png"><img src="Tutorial_32_files/l.png"></td>
<td valign="top" width="100%">InitObject() 代码是来建立每个物体. 我们开始设 rot 为 1. 这使物体顺时针旋转.
然后设爆炸效果动画帧为0(我们不想爆炸效果从中间开始).我们下面设 hit 为 FALSE, 意思是物体还没被击中或正开如. 选一个物体材质,
texid 用来给一个随机的变量从 0 到 4. 0是blueface 材质 和4 是 vase 材质. 这给我们5种随机物体.
<p>距离变量是在-0.0f to -40.0f (4000/100 is 40)的随机数 . 当我们真实的画物体,我们透过在屏幕上的另10 个单位.
所以当物体在画时, 他们将画从-10.0f to -50.0f 单位 在屏幕(不挨着, 也不离得太远). 我分随机数为 100.0f 得到更精确的浮点数值.
</p>
<p>在给完随机的距离之后, 我们给物体一个随机的 y . 我们不想物体低于 -1.5f, 否则他将低于大地, 且我们不想物体高于3.0f. 所以留在我们的区间的随机数不能高于4.5f
(-1.5f+4.5f=3.0f). </p>
<p>去计算 x 位置, 用一些狡猾的数学. 用我们的距离减去15.0f . 除以2 减5*level. 再 减随机数(0.0f 到5) 乘level.
减 5*level rndom(0.0f to 5*level) 这是最高级. </p>
<p>选一个方向. </p>
<p>使事情简单明白x, 写一个快的例子. 距离是 -30.0f ,当前级是 1: </p>
<p>object[num].x=((-30.0f-15.0f)/2.0f)-(5*1)-float(rand()%(5*1));<br>
object[num].x=(-45.0f/2.0f)-5-float(rand()%5);<br>
object[num].x=(-22.5f)-5-{lets say 3.0f};<br>
object[num].x=(-22.5f)-5-{3.0f};<br>
object[num].x=-27.5f-{3.0f};<br>
object[num].x=-30.5f; </p>
<p>开始在屏模上移 10 个单位 , 距离是 -30.0f. 其实是 -40.0f.用透视的代码在 NeHeGL.cpp 文件. </p>
<p></p>
<p></p></td><td background="Tutorial_32_files/r.png"><img src="Tutorial_32_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_32_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">GLvoid InitObject(int num) <font color="#ffffaa">// 初始化一个物体</font>
{
object[num].rot=1; <font color="#ffffaa">// 顺时针旋转</font>
object[num].frame=0; <font color="#ffffaa">// 设爆炸效果动画帧为0</font>
object[num].hit=FALSE; <font color="#ffffaa">// 设点击检测为0</font>
object[num].texid=rand()%5; <font color="#ffffaa">// 设一个材质</font>
object[num].distance=-(float(rand()%4001)/100.0f); <font color="#ffffaa">// 随机距离</font>
object[num].y=-1.5f+(float(rand()%451)/100.0f); <font color="#ffffaa">// 随机 Y 位置</font>
<font color="#ffffaa">// 随机开始 X 位置 基于物体的距离 和随机的延时量 (确定变量)</font>
object[num].x=((object[num].distance-15.0f)/2.0f)-(5*level)-float(rand()%(5*level));
object[num].dir=(rand()%2); <font color="#ffffaa">// 选一个随机的方向</font>
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_32_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_32_files/l.png"><img src="Tutorial_32_files/l.png"></td>
<td valign="top" width="100%">检查方向 <br></td><td background="Tutorial_32_files/r.png"><img src="Tutorial_32_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_32_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
<pre>
if (object[num].dir==0) <font color="#ffffaa">// 若随机的方向正确</font>
{
object[num].rot=2; <font color="#ffffaa">// 逆时针旋转</font>
object[num].x=-object[num].x; <font color="#ffffaa">// 开始在左边 (否定 变量)</font>
}
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_32_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_32_files/l.png"><img src="Tutorial_32_files/l.png"></td>
<td valign="top" width="100%">现在我们检查texid 来找出所选的的物体. 若 texid 为0, 所选的物体是 Blueface
. blueface 总是在大地上面旋转. 确定开始时在地上的层, 我们设 y 是 -2.0f. <br></td><td background="Tutorial_32_files/r.png"><img src="Tutorial_32_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_32_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
<pre>
if (object[num].texid==0) <font color="#ffffaa">// 蓝色天空表面</font>
object[num].y=-2.0f; <font color="#ffffaa">// 总是在大地上面旋转</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_32_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_32_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_32_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_32_files/l.png"><img src="Tutorial_32_files/l.png"></td>
<td valign="top" width="100%">下面检查若texid 是 1. 这样, 电脑所选物体的是 Bucket. bucket不从左到右运动,
它从天上掉下来. 首先我们不得不设 dir 是 3. 这告诉电脑我们的水桶bucket 是掉下来或向下运动.
<p>我们最初的代码假定物体从左到右运动. 因为bucket 是向下落的, 我们得不给它一个新的随机的变量 x . 若不是这样, bucket
会被看不到. 它将不在左边落下就在屏幕外面. 我们给它一个新的随机距离变量在屏幕上. 代替减去15, 我们仅仅减去 10. 这给我们一些幅度,
保持物体在屏幕??. 设我们的distance 是-30.0f, 从0.0f -40.0f的随机变量. 为什么从 0.0f 到 40.0f?
不是从0.0f to -40.0f? 答案很简单. rand() 函数总返回正数. 所以总是正数. 另外,回到我们的故事. 我们有个正数 从0.0f
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -