📄 tutorial_21.htm
字号:
counter时才启用。</p>
<p>变量performance_timer用来标识计算机是否有performance counter</p>
<p>如果performance counter启用,最后两个变量用来保存计时器开始时的时间和计时器开始后流失的时间,它们比普通的根据精确。</p></td><td background="Tutorial_21_files/r.png"><img src="Tutorial_21_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_21_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
<pre>struct <font color="#ffffaa">// 保存时间信息的结构</font>
{
__int64 frequency; <font color="#ffffaa">// 频率</font>
float resolution; <font color="#ffffaa">// 时间间隔</font>
unsigned long mm_timer_start; <font color="#ffffaa">// 多媒体计时器的开始时间</font>
unsigned long mm_timer_elapsed; <font color="#ffffaa">// 多媒体</font><font color="#aaffaa" size="3"><font color="#ffffaa">计时器的开始时间</font></font>
bool performance_timer; <font color="#ffffaa">// 使用Performance Timer?</font>
__int64 performance_timer_start; <font color="#ffffaa">// Performance Timer</font><font color="#aaffaa" size="3"><font color="#ffffaa">计时器的开始时间</font></font>
__int64 performance_timer_elapsed; <font color="#ffffaa">// Performance Timer</font><font color="#aaffaa" size="3"><font color="#ffffaa">计时器的开始时间</font></font>
} timer;
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_21_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_21_files/l.png"><img src="Tutorial_21_files/l.png"></td>
<td valign="top" width="100%">下一行代码定义了速度表。如前所说,对象移动的速度依赖于值adjust,而以adjust为下标去检索速度表,就可以获得对象的移动速度。</td>
<td background="Tutorial_21_files/r.png"><img src="Tutorial_21_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_21_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3"><pre>int steps[6]={ 1, 2, 4, 5, 10, 20 }; <font color="#ffffaa">// 用来调整显示的速度</font>
</pre></font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_21_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_21_files/l.png"><img src="Tutorial_21_files/l.png"></td>
<td valign="top" width="100%">接下来我们将为纹理分配空间。纹理一共2张,一张是背景而另外一张是一张字体纹理。如本系列教程中的其他课程一样,base用来指出字符显示列表的基,同样的我们在最后声明了窗口过程WndProc()。</td>
<td background="Tutorial_21_files/r.png"><img src="Tutorial_21_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_21_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">GLuint texture[2]; <font color="#ffffaa">// 字符纹理</font>
GLuint base; <font color="#ffffaa">// 字符显示列表的开始值</font>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_21_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_21_files/l.png"><img src="Tutorial_21_files/l.png"></td>
<td valign="top" width="100%">接下来会是很有趣的工作。接下来的一段代码会初始化我们的计时器。代码会检查performance
counter(非常精确的计数器)是否可用,如果不可用,则使用多媒体计时器。这段代码是可以移植的。</td>
<td background="Tutorial_21_files/r.png"><img src="Tutorial_21_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_21_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre>void TimerInit(void) <font color="#ffffaa">// 初始化我们的计时器</font>
{
memset(&timer, 0, sizeof(timer)); <font color="#ffffaa">// 清空计时器结构</font>
<font color="#ffffaa">// 检测Performance Counter是否可用,可用则创建</font>
if (!QueryPerformanceFrequency((LARGE_INTEGER *) &timer.frequency))
{
<font color="#ffffaa">// 如果不可用</font>
timer.performance_timer = FALSE; <font color="#ffffaa">// 设置Performance Timer为false</font>
timer.mm_timer_start = timeGetTime(); <font color="#ffffaa">// 使用普通的计时器</font>
timer.resolution = 1.0f/1000.0f; <font color="#ffffaa">// 设置单位为毫秒</font>
timer.frequency = 1000; <font color="#ffffaa">// 设置频率为1000</font>
timer.mm_timer_elapsed = timer.mm_timer_start; <font color="#ffffaa">// 设置流失的时间为当前的时间</font>
}
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_21_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_21_files/l.png"><img src="Tutorial_21_files/l.png"></td>
<td valign="top" width="100%">如果performance counter 可用,则执行下面的代码:</td>
<td background="Tutorial_21_files/r.png"><img src="Tutorial_21_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_21_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3"> else
{
<font color="#ffffaa">// 使用Performance Counter计时器</font>
QueryPerformanceCounter((LARGE_INTEGER *) &timer.performance_timer_start);
timer.performance_timer = TRUE; <font color="#ffffaa">// 设置Performance Timer为TRUE</font>
<font color="#ffffaa">// 计算计时的精确度</font>
timer.resolution = (float) (((double)1.0f)/((double)timer.frequency));
<font color="#ffffaa">// </font><font color="#aaffaa" size="3"><font color="#ffffaa">设置流失的时间为当前的时间</font></font>
timer.performance_timer_elapsed = timer.performance_timer_start;
}
}
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_21_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_21_files/l.png"><img src="Tutorial_21_files/l.png"></td>
<td valign="top" width="100%">上面的代码设置了计时器,而下面的代码则读出计时器并返回已经经过的时间,以毫秒计。代码很简单,首先检查是否支持performance
counter,若支持,则调用其相关函数;否则调用多媒体函数。</td>
<td background="Tutorial_21_files/r.png"><img src="Tutorial_21_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_21_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">float TimerGetTime() <font color="#ffffaa">// 返回经过的时间,以毫秒为单位</font>
{
__int64 time; <font color="#ffffaa">// 使用64位的整数</font>
if (timer.performance_timer) <font color="#ffffaa">// 是否使用Performance Timer计时器?</font>
{
QueryPerformanceCounter((LARGE_INTEGER *) &time); <font color="#ffffaa">// 返回当前的时间</font>
<font color="#ffffaa">// 返回时间差</font>
return ( (float) ( time - timer.performance_timer_start) * timer.resolution)*1000.0f;
}
else
{
<font color="#ffffaa">// 使用普通的计时器,返回时间差</font>
return( (float) ( timeGetTime() - timer.mm_timer_start) * timer.resolution)*1000.0f;
}
}
</font></pre>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_21_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_21_files/l.png"><img src="Tutorial_21_files/l.png"></td>
<td valign="top" width="100%">在下面的代码里,我们把玩家重置在屏幕的左上角,而给敌人设置一个随机的位置。</td>
<td background="Tutorial_21_files/r.png"><img src="Tutorial_21_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_21_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre>void ResetObjects(void) <font color="#ffffaa">// 重置玩家和敌人</font>
{
player.x=0; <font color="#ffffaa">// 把玩家置于左上角</font>
player.y=0;
player.fx=0;
player.fy=0;
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_21_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_21_files/l.png"><img src="Tutorial_21_files/l.png"></td>
<td valign="top" width="100%">接着我们给敌人一个随机的开始位置,敌人的数量等于难度乘上当前关卡号。记着,难度最大是3,而最多有3关。因此敌人最多有9个。</td>
<td background="Tutorial_21_files/r.png"><img src="Tutorial_21_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_21_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre> for (loop1=0; loop1<(stage*level); loop1++) <font color="#ffffaa">// 循环随即放置所有的敌人</font>
{
enemy[loop1].x=5+rand()%6;
enemy[loop1].y=rand()%11;
enemy[loop1].fx=enemy[loop1].x*60;
enemy[loop1].fy=enemy[loop1].y*40;
}
}
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_21_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_21_files/l.png"><img src="Tutorial_21_files/l.png"></td>
<td valign="top" width="100%">并
没有做任何改动,因此我将跳过它。在LoadGLTextures函数里我将载入那两个纹理--背景和字体。并且我会把这两副图都转化成纹理,这样我们就
可以在游戏中使用他们。纹理创建好之后,象素数据就可以删除了。没有什么新东西,你可以阅读以前的课程以获得更多信息。<br></td><td background="Tutorial_21_files/r.png"><img src="Tutorial_21_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_21_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_21_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_21_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
<pre>int LoadGLTextures()
{
int Status=FALSE;
AUX_RGBImageRec *TextureImage[2];
memset(TextureImage,0,sizeof(void *)*2);
if ((TextureImage[0]=LoadBMP("Data/Font.bmp")) && <font color="#ffffaa">// 载入字体纹理</font>
(TextureImage[1]=LoadBMP("Data/Image.bmp"))) <font color="#ffffaa">// 载入图像纹理</font>
{
Status=TRUE;
glGenTextures(2, &texture[0]);
for (loop1=0; loop1<2; loop1++)
{
glBindTexture(GL_TEXTURE_2D, texture[loop1]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop1]->sizeX, TextureImage[loop1]->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop1]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
for (loop1=0; loop1<2; loop1++)
{
if (TextureImage[loop1])
{
if (TextureImage[loop1]->data)
{
free(TextureImage[loop1]->data);
}
free(TextureImage[loop1]);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -