📄 tutorial_09.htm
字号:
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td background="Tutorial_09_files/l.gif"><img src="Tutorial_09_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">紧接着上面的代码就是我们用来载入纹理的代码。我不打算再详细的解释这段代码。这跟我们在第六、七、八课中所用的代码是一模一样的。这一次载入的位图叫做star.bmp。这里我们使用glGenTextures(1,
&texture[0]),来生成一个纹理。纹理采用线性滤波方式。</td>
<td background="Tutorial_09_files/r.gif"><img src="Tutorial_09_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_09_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_09_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_09_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">AUX_RGBImageRec *LoadBMP(char *Filename) <font color="#ffffaa">// 载入位图文件</font>
{
FILE *File=NULL; <font color="#ffffaa">// 文件句柄</font>
if (!Filename) <font color="#ffffaa">// 确认已给出文件名</font>
{
return NULL; <font color="#ffffaa">// 若无返回 NULL</font>
}
File=fopen(Filename,"r"); <font color="#ffffaa">// 检查文件是否存在</font>
if (File) <font color="#ffffaa">// 文件存在么?</font>
{
fclose(File); <font color="#ffffaa">// 关闭文件句柄</font>
return auxDIBImageLoad(Filename); <font color="#ffffaa">// 载入位图并返回指针</font>
}
return NULL; <font color="#ffffaa">// 如果载入失败返回 NULL</font>
}
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_09_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_09_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_09_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_09_files/l.gif"><img src="Tutorial_09_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">下面的代码(调用上面的代码)载入位图,并转换成纹理。变量用来跟踪纹理是否已载入并创建好了。</td>
<td background="Tutorial_09_files/r.gif"><img src="Tutorial_09_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_09_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_09_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_09_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">int LoadGLTextures() <font color="#ffffaa">// 载入位图并转换成纹理</font>
{
int Status=FALSE; <font color="#ffffaa">// 状态指示器</font>
AUX_RGBImageRec *TextureImage[1]; <font color="#ffffaa">// 为纹理分配存储空间</font>
memset(TextureImage,0,sizeof(void *)*1); <font color="#ffffaa">// 将指针设为 NULL</font>
<font color="#ffffaa">// 载入位图,查错,如果未找到位图文件则退出</font>
if (TextureImage[0]=LoadBMP("Data/Star.bmp"))
{
Status=TRUE; <font color="#ffffaa">// 将 Status 设为TRUE</font>
glGenTextures(1, &texture[0]); <font color="#ffffaa">// 创建一个纹理</font>
<font color="#ffffaa">// 创建一个线性滤波纹理</font>
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
}
if (TextureImage[0]) <font color="#ffffaa">// 如果纹理存在</font>
{
if (TextureImage[0]->data) <font color="#ffffaa">// 如果纹理图像存在</font>
{
free(TextureImage[0]->data); <font color="#ffffaa">// 释放纹理图像所占的内存</font>
}
free(TextureImage[0]); <font color="#ffffaa">// 释放图像结构</font>
}
return Status; <font color="#ffffaa">// 返回 Status的值</font>
}
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_09_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_09_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_09_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_09_files/l.gif"><img src="Tutorial_09_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">现
在设置OpenGL的渲染方式。这里不打算使用深度测试,如果您使用第一课的代码的话,请确认是否已经去掉了
glDepthFunc(GL_LEQUAL); 和
glEnable(GL_DEPTH_TEST);两行。否则,您所见到的效果将会一团糟。这里我们使用了纹理映射,因此请您确认您已经加上了这些第一课
中所没有的代码。您会注意到我们通过混色来启用了纹理映射。</td>
<td background="Tutorial_09_files/r.gif"><img src="Tutorial_09_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_09_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_09_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_09_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">int InitGL(GLvoid) <font color="#ffffaa">// 此处开始对OpenGL进行所有设置</font>
{
if (!LoadGLTextures()) <font color="#ffffaa">// 调用纹理载入子例程</font>
{
return FALSE; <font color="#ffffaa">// 如果未能载入,返回FALSE</font>
}
glEnable(GL_TEXTURE_2D); <font color="#ffffaa">// 启用纹理映射</font>
glShadeModel(GL_SMOOTH); <font color="#ffffaa">// 启用阴影平滑</font>
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); <font color="#ffffaa">// 黑色背景</font>
glClearDepth(1.0f); <font color="#ffffaa">// 设置深度缓存</font>
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); <font color="#ffffaa">// 真正精细的透视修正</font>
glBlendFunc(GL_SRC_ALPHA,GL_ONE); <font color="#ffffaa">// 设置混色函数取得半透明效果</font>
glEnable(GL_BLEND); <font color="#ffffaa">// 启用混色</font>
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_09_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_09_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_09_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_09_files/l.gif"><img src="Tutorial_09_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">以下是新增的代码。设置了每颗星星的起始角度、距离、和颜色。您会注意到修改结构的属性有多容易。全部50颗星星都会被循环设置。要改变star[1]的角度我们所要做的只是star[1].angle={某个数值};就这么简单!</td>
<td background="Tutorial_09_files/r.gif"><img src="Tutorial_09_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_09_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_09_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_09_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre> for (loop=0; loop<num; loop++) <font color="#ffffaa">// 创建循环设置全部星星</font>
{
star[loop].angle=0.0f; <font color="#ffffaa">// 所有星星都从零角度开始</font>
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_09_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_09_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_09_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_09_files/l.gif"><img src="Tutorial_09_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">第loop
颗星星离中心的距离是将loop的值除以星星的总颗数,然后乘上5.0f。基本上这样使得后一颗星星比前一颗星星离中心更远一点。这样当loop为50时
(最后一颗星星),loop 除以 num正好是1.0f。之所以要乘以5.0f是因为1.0f*5.0f 就是
5.0f。『CKER:废话,废话!这老外怎么跟孔乙己似的!:)』5.0f已经很接近屏幕边缘。我不想星星飞出屏幕,5.0f是最好的选择了。当然如果
如果您将场景设置的更深入屏幕里面的话,也许可以使用大于5.0f的数值,但星星看起来就更小一些(都是透视的缘故)。<br>
您还会注意到每颗星星的颜色都是从0~255之间的一个随机数。也许您会奇怪为何这里的颜色得取值范围不是OpenGL通常的0.0f~1.0f之间。这
里我们使用的颜色设置函数是glColor4ub,而不是以前的glColor4f。ub意味着参数是Unsigned
Byte型的。一个byte的取值范围是0~255。这里使用byte值取随机整数似乎要比取一个浮点的随机数更容易一些。</td>
<td background="Tutorial_09_files/r.gif"><img src="Tutorial_09_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_09_files/bl.gif" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_09_files/bc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_09_files/br.gif" height="28" width="28"></td>
</tr>
</tbody>
</table>
<font color="#aaffaa" size="3">
<pre> star[loop].dist=(float(loop)/num)*5.0f; <font color="#ffffaa">// 计算星星离中心的距离</font>
star[loop].r=rand()%256; <font color="#ffffaa">// 为star[loop]设置随机红色分量</font>
star[loop].g=rand()%256; <font color="#ffffaa">// 为star[loop]设置随机红色分量</font>
star[loop].b=rand()%256; <font color="#ffffaa">// 为star[loop]设置随机红色分量</font>
}
return TRUE; <font color="#ffffaa">// 初始化一切OK</font>
}
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td><img src="Tutorial_09_files/tl.jpg" height="28" width="28"></td>
<td width="100%"><img src="Tutorial_09_files/tc.gif" height="28" width="100%"></td>
<td><img src="Tutorial_09_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_09_files/l.gif"><img src="Tutorial_09_files/l.gif" height="28" width="28"></td>
<td valign="top" width="100%">Resize的代码也是一样的,现在我们转入绘图代码。如果您使用第一课的代码,删除旧的DrawGLScene代码,只需将下面的代码复制过去就行了。实际上,第一课的代码只有两行,所以没太多东西要删掉的。</td>
<td background="Tutorial_09_files/r.gif"><img src="Tutorial_09_files/r.gif" height="28" width="28"></td>
</tr>
</tbody>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -