📄 tutorial_24.htm
字号:
glPrint(192,432,1,"NeHe Productions"); <font color="#ffffaa">// 在屏幕的底端写上NeHe Productions字符串</font></pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">现在我们绘制显示扩展名的白色线框方块,并用一个更大的白色线框方块把所有的内容包围起来。</td>
<td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre> glLoadIdentity(); <font color="#ffffaa">// 重置模型变换矩阵</font>
glColor3f(1.0f,1.0f,1.0f); <font color="#ffffaa">// 设置为白色</font>
glBegin(GL_LINE_STRIP);
glVertex2d(639,417);
glVertex2d( 0,417);
glVertex2d( 0,480);
glVertex2d(639,480);
glVertex2d(639,128);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d( 0,128);
glVertex2d(639,128);
glVertex2d(639, 1);
glVertex2d( 0, 1);
glVertex2d( 0,417);
glEnd(); </pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">glScissor函数用来设置剪裁区域,如果启用了GL_SCISSOR_TEST,绘制的内容只能在剪裁区域中显示。<br>
下面的代码设置窗口的中部为剪裁区域,并获得扩展名字符串。</td>
<td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre> glScissor(1 ,int(0.135416f*sheight),swidth-2,int(0.597916f*sheight)); <font color="#ffffaa">// 定义剪裁区域</font>
glEnable(GL_SCISSOR_TEST); <font color="#ffffaa">// 使用剪裁测试</font>
char* text=(char*)malloc(strlen((char *)glGetString(GL_EXTENSIONS))+1); <font color="#ffffaa">// 为保存OpenGL扩展的字符串分配内存空间</font>
strcpy (text,(char *)glGetString(GL_EXTENSIONS)); <font color="#ffffaa">// 返回OpenGL扩展字符串</font>
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">下面我们创建一个循环,循环显示每个扩展名,并纪录扩展名的个数</td>
<td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre> token=strtok(text," "); <font color="#ffffaa">// 按空格分割text字符串,并把分割后的字符串保存在token中</font>
while(token!=NULL) <font color="#ffffaa"> // 如果token不为NULL</font>
{
cnt++; <font color="#ffffaa">// 增加计数器</font>
if (cnt>maxtokens) <font color="#ffffaa"> // 纪录最大的扩展名数量</font>
{
maxtokens=cnt;
}
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">现我们已经获得第一个扩展名,下一步我们把它显示在屏幕上。
<p>我
们已经显示了三行文本,它们在Y轴上占用了3*32=96个像素的宽度,所以我们显示的第一个行文本的位置是(0,96),一次类推第i行文本的位置是
(0,96+(cnt*32)),但我们需要考虑当前滚动过的位置,默认为向上滚动,所以我们得到显示第i行文本的位置为(0,96+(cnt*32)=
scroll)。</p>
<p>当然它们不会都显示出来,记得我们使用了剪裁,只显示(0,96)-(0,96+32*9)之间的文本,其它的都被剪裁了。</p>
<p>更具我们上面的讲解,显示的第一个行如下:<br>
1 GL_ARB_multitexture </p></td><td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre> glColor3f(0.5f,1.0f,0.5f); <font color="#ffffaa">// 设置颜色为绿色</font>
glPrint(0,96+(cnt*32)-scroll,0,"%i",cnt); <font color="#ffffaa">// 绘制第几个扩展名</font>
</pre>
</font>
<font color="#aaffaa" size="3">
<pre> glColor3f(1.0f,1.0f,0.5f); <font color="#ffffaa">// 设置颜色为黄色</font>
glPrint(50,96+(cnt*32)-scroll,0,token); <font color="#ffffaa">// 输出第i个扩展名</font>
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">当我们显示完所有的扩展名,我们需要检查一下是否已经分析完了所有的字符串。我们使用strtok(NULL,"
")函数代替strtok(text," ")函数,把第一个参数设置为NULL会检查当前指针位置到字符串末尾是否包含"
"字符,如果包含返回其位置,否则返回NULL。
<p>我们举例说明上面的过程,例如字符串"GL_ARB_multitexture GL_EXT_abgr GL_EXT_bgra",它是以空格分割字符串的,第一次调用strtok("text","
")返回text的首位置,并在空格" "的位置加入一个NULL。以后每次调用,删除NULL,返回空格位置的下一个位置,接着搜索下一个空格的位置,并在空格的位置加入一个NULL。直道返回NULL。</p>
<p>返回NULL时循环停止,表示已经显示完所有的扩展名。</p></td><td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3"><pre> token=strtok(NULL," "); <font color="#ffffaa">// 查找下一个扩展名</font>
}
</pre></font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">下面的代码让OpenGL返回到默认的渲染状态,并释放分配的内存资源</td>
<td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre> glDisable(GL_SCISSOR_TEST); <font color="#ffffaa">// 禁用剪裁测试</font>
free (text); <font color="#ffffaa">// 释放分配的内存</font>
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">下面的代码让OpenGL完成所有的任务,并返回TRUE</td>
<td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3"><pre> glFlush(); <font color="#ffffaa">// 执行所有的渲染命令</font>
return TRUE; <font color="#ffffaa">// 成功返回</font>
}
</pre></font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">KillGLWindow函数基本没有变化,唯一改变的是需要删除我们创建的字体 </td>
<td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody><tr>
<td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td>
<td><img src="Tutorial_24_files/br.png" height="28" width="28"></td>
</tr>
</tbody></table>
<font color="#aaffaa" size="3">
<pre> KillFont(); <font color="#ffffaa">// 删除字体</font>
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">CreateGLWindow(), 和 WndProc() 函数保持不变<br> <br>
在WinMain()函数中我们需要加入新的按键控制 </td>
<td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td><td valign="top" width="100%"><p>下面的代码检查向上的箭头是否被按下,如果scroll大于0,我们把它减少2</p>
</td><td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3"></font><pre><font color="#aaffaa" size="3"> if (keys[VK_UP] && (scroll>0)) <font color="#ffffaa">// 向上的箭头是否被按下?</font>
{
scroll-=2; <font color="#ffffaa">// 如果是,减少scroll的值</font>
}
</font></pre><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">如果向下的箭头被按住,并且scroll小于32*(maxtoken-9),则增加scroll的值,32是每一个字符的高度,9是可以显示的行数。</td>
<td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre> if (keys[VK_DOWN] && (scroll<32*(maxtokens-9))) <font color="#ffffaa">// 向下的箭头是否被按住</font>
{
scroll+=2; <font color="#ffffaa">// 如果是,增加scroll的值</font>
}
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_24_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_24_files/l.png"><img src="Tutorial_24_files/l.png"></td>
<td valign="top" width="100%">我希望你觉得这个教程有趣,学完了这个教程你应该知道如何获得你的显卡的发售商的名称,实现OpenGL的组织和你的显卡所使用的OpenGL的版本。进一步,你应该知道你的显卡支持的扩展的名称,并熟练的使用剪切矩形和加载TGA图像。
<p>如果你发现任何问题,请让我知道。我想做最好的教程,你的反馈对我很重要。</p>
<table border="1" width="100%">
<tbody><tr>
<td width="27%"><img src="Tutorial_24_files/logo%25203.jpg" align="middle" height="200" width="209"></td>
<td width="73%">版权与使用声明:<br>
我是个对学习和生活充满激情的普通男孩,在网络上我以DancingWind为昵称,我的联系方式是zhouwei02@mails.tsinghua.edu.cn,如果你有任何问题,都可以联系我。
<p>引子<br>
网络是一个共享的资源,但我在自己的学习生涯中浪费大量的时间去搜索可用的资料,在现实生活中花费了大量的金钱和时间在书店中寻找资料,于是我给自己起了
个昵称DancingWind,其意义是想风一样从各个知识的站点中吸取成长的养料。在飘荡了多年之后,我决定把自己收集的资料整理为一个统一的资源库。</p>
<p>版权声明<br>
所有DancingWind发表的内容,大多都来自共享的资源,所以我没有资格把它们据为己有,或声称自己为这些资源作出了一点贡献。故任何人都可以复
制,修改,重新发表,甚至以自己的名义发表,我都不会追究,但你在做以上事情的时候必须保证内容的完整性,给后来的人一个完整的教程。最后,任何人不能以
这些资料的任何部分,谋取任何形式的报酬。</p>
<p>发展计划<br>
在国外,很多资料都是很多人花费几年的时间慢慢积累起来的。如果任何人有兴趣与别人共享你的知识,我很欢迎你与我联系,但你必须同意我上面的声明。</p>
<p>感谢<br>
感谢我的母亲一直以来对我的支持和在生活上的照顾。<br>
感谢我深爱的女友田芹,一直以来默默的在精神上和生活中对我的支持,她甚至把买衣服的钱都用来给我买书了,她真的是我见过的最好的女孩,希望我能带给她幸福。</p>
<p>资源下载: <br>
文档 <a href="http://www.owlei.com/DancingWind/Res/mht/NeHe%20OpenGL%20Chinese%20Course%2024.mht">网页格式</a>
<a href="http://www.owlei.com/DancingWind/Res/pdf/OpenGL_Nehe_Course_Tutorial_24.pdf">PDF格式</a><br>
源码 <a href="http://www.owlei.com/DancingWind/Res/Src/24_TGA_Extension.rar">RAR格式</a></p></td>
</tr>
</tbody></table>
<font face="Tahoma,Verdana,sans-serif" size="-1">
<table border="0" width="100%">
<tbody><tr><td align="left" width="50%"><b><font size="-1"><a href="http://www.owlei.com/DancingWind/Course/Tutorial_23.htm"><
第23课</a></font></b></td>
<td align="right" width="50%"><b><font size="-1"><a href="http://www.owlei.com/DancingWind/Course/Tutorial_25.htm">第25课
></a></font></b></td>
</tr></tbody></table>
</font></td>
<td background="Tutorial_24_files/r.png"><img src="Tutorial_24_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_24_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_24_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_24_files/br.png" height="28" width="28"></td></tr></tbody></table>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -