- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在阅读有关不同游戏循环解决方案的Koen Witters detailed article,但是我在使用GLUT实现最后一个方面遇到了一些问题,这是推荐的解决方案。
在阅读过其他一些关于如何实现恒定游戏速度的文章,教程和代码后,我认为我目前实现的(我将在下面的代码中发布)就是Koen Witters所说的依赖于可变FPS的游戏速度。 ,他文章的第二篇。
首先,根据我的搜索经验,可能会有一些人对此有帮助的知识,但是他们不知道GLUT是什么,因此我将尽力解释(随时纠正我)与之相关的功能我的OpenGL工具包的问题。如果您知道什么是GLUT以及如何使用它,请跳过本节。
GLUT工具包:
GLUT是OpenGL工具包,可帮助完成OpenGL中的常见任务。glutDisplayFunc(renderScene)
带有指向renderScene()
函数回调的指针,该函数负责呈现所有内容。 renderScene()
函数将仅在回调注册后被调用一次。glutTimerFunc(TIMER_MILLISECONDS, processAnimationTimer, 0)
在调用回调processAnimationTimer()
之前花费了毫秒数。最后一个参数只是传递给计时器回调的值。 processAnimationTimer()
不会被每个TIMER_MILLISECONDS
调用,而只会被调用一次。glutPostRedisplay()
函数请求GLUT渲染新帧,因此每次我们更改场景中的内容时都需要调用此帧。glutIdleFunc(renderScene)
可以用于注册到renderScene()
的回调(这不会使glutDisplayFunc()
无关紧要),但应避免使用此函数,因为在未接收到事件时会连续调用空闲回调,从而增加了CPU负载。glutGet(GLUT_ELAPSED_TIME)
函数返回自调用glutInit
(或首次调用glutGet(GLUT_ELAPSED_TIME)
)以来的毫秒数。那就是我们使用GLUT的计时器。我知道高分辨率计时器还有更好的选择,但是现在让我们继续使用它。
我认为这是有关GLUT如何渲染帧的足够信息,因此不知道它的人也可以提出这个问题,以尝试帮助他们,如果他们喜欢它。
当前实施:
现在,我不确定我是否已经正确实施了Koen提出的第二种解决方案,即依赖可变FPS的游戏速度。与此相关的代码如下所示:
#define TICKS_PER_SECOND 30
#define MOVEMENT_SPEED 2.0f
const int TIMER_MILLISECONDS = 1000 / TICKS_PER_SECOND;
int previousTime;
int currentTime;
int elapsedTime;
void renderScene(void) {
(...)
// Setup the camera position and looking point
SceneCamera.LookAt();
// Do all drawing below...
(...)
}
void processAnimationTimer(int value) {
// setups the timer to be called again
glutTimerFunc(TIMER_MILLISECONDS, processAnimationTimer, 0);
// Get the time when the previous frame was rendered
previousTime = currentTime;
// Get the current time (in milliseconds) and calculate the elapsed time
currentTime = glutGet(GLUT_ELAPSED_TIME);
elapsedTime = currentTime - previousTime;
/* Multiply the camera direction vector by constant speed then by the
elapsed time (in seconds) and then move the camera */
SceneCamera.Move(cameraDirection * MOVEMENT_SPEED * (elapsedTime / 1000.0f));
// Requests to render a new frame (this will call my renderScene() once)
glutPostRedisplay();
}
void main(int argc, char **argv) {
glutInit(&argc, argv);
(...)
glutDisplayFunc(renderScene);
(...)
// Setup the timer to be called one first time
glutTimerFunc(TIMER_MILLISECONDS, processAnimationTimer, 0);
// Read the current time since glutInit was called
currentTime = glutGet(GLUT_ELAPSED_TIME);
glutMainLoop();
}
TICKS_PER_SECOND
个帧。这感觉不对,您不应该限制强大的硬件,这是错误的。据我了解,我仍然需要计算
elapsedTime
。只是因为我要告诉GLUT每个
TIMER_MILLISECONDS
调用计时器回调,但这并不意味着它将始终按时执行。]
while( game_is_running )
循环。 [编辑:据我了解,GLUT是事件驱动的,当我调用
glutMainLoop()
(永不返回)时,游戏循环便开始了,是吗?]
glutIdleFunc()
注册一个空闲的回调并将其用作
glutTimerFunc()
的替换,仅在必要时渲染(而不是像往常一样),但是当我使用空回调(例如
void gameLoop() {}
)对其进行测试时基本上什么也没做,只有黑屏,CPU飙升到25%并保持在那里,直到我杀死了游戏,然后它恢复了正常。所以我不认为这是可以遵循的道路。
glutTimerFunc()
绝对不是一种执行所有动作/动画的好方法,因为我将游戏限制为恒定的FPS,而不是炫酷。还是我使用错了,而我的实现不正确?
renderScene()
中进行计算。每当场景发生变化时,我都会调用
glutPostRedisplay()
(即:摄像机移动,某些对象动画等),这将调用
renderScene()
。例如,我可以在此功能中使用经过的时间来移动相机。
int previousTime;
int currentTime;
int elapsedTime;
void renderScene(void) {
(...)
// Setup the camera position and looking point
SceneCamera.LookAt();
// Do all drawing below...
(...)
}
void renderScene(void) {
(...)
// Get the time when the previous frame was rendered
previousTime = currentTime;
// Get the current time (in milliseconds) and calculate the elapsed time
currentTime = glutGet(GLUT_ELAPSED_TIME);
elapsedTime = currentTime - previousTime;
/* Multiply the camera direction vector by constant speed then by the
elapsed time (in seconds) and then move the camera */
SceneCamera.Move(cameraDirection * MOVEMENT_SPEED * (elapsedTime / 1000.0f));
// Setup the camera position and looking point
SceneCamera.LookAt();
// All drawing code goes inside this function
drawCompleteScene();
glutSwapBuffers();
/* Redraw the frame ONLY if the user is moving the camera
(similar code will be needed to redraw the frame for other events) */
if(!IsTupleEmpty(cameraDirection)) {
glutPostRedisplay();
}
}
void main(int argc, char **argv) {
glutInit(&argc, argv);
(...)
glutDisplayFunc(renderScene);
(...)
currentTime = glutGet(GLUT_ELAPSED_TIME);
glutMainLoop();
}
glutPostRedisplay()
并不断调用它,直到没有新内容可以重绘为止。我认为,为了更好的原因,在代码中添加了一些复杂性。
最佳答案
过剩被设计为游戏循环。当您调用glutMainLoop()时,它将执行一个“ for循环”,除了exit()信号外,没有终止条件。您可以像现在一样执行程序,但是需要一些小的更改。首先,如果您想知道什么是FPS,则应将该跟踪放入renderScene()函数中,而不要放在update函数中。自然地,您的更新函数将按照计时器指定的速度被调用,并且您将elapsedTime视为帧之间时间的度量。通常,这是正确的,因为您调用glutPostRedisplay的速度很慢,并且在不需要时glut不会尝试更新屏幕(如果场景未更改,则无需重绘)。但是,有时还会调用renderScene。例如,如果您在窗口上拖动某些东西。如果这样做的话,您会看到更高的FPS(如果您在渲染功能中正确跟踪了FPS)。
关于c - 恒定的游戏速度与GLUT在OpenGL中与可变FPS无关吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5357119/
假设我们要描述一个满足以下真值表的组合电路: a b | s0 s1 s2 s3 ----------------- 0 0 | 1 d d d 0 1 | 0 1 d d 1 0 |
.mainIDv { height:300px; width:400px; padding:5px; margin: 8px auto 8px auto; } .ImgDisp{
我的 iOS 应用程序遇到了一个恼人的问题。突然,当我启动带有 TableView 的 View Controller 时,出现以下错误: Unrecognized selector sent to
我有一个简单的 PreferenceActivity 类,它的 onCreate 将我的 R.xml.preferences 屏幕传递给 ((PreferenceActivity)super).add
在大学项目范围内,我应该实现数据库的聚合。 我得到了一个实体关系模型,它看起来与此类似: 现在我应该实现一个 SQL 脚本来创建这样的数据库,但我在谷歌或其他任何地方找不到有关此主题的任何内容。在我教
我一直在努力阅读 GCD 并试图弄明白。我读了很多地方,应该始终使用 GCD,如果一个人正在做一些繁重的工作,这会卡住 UI,我确实理解这一点,但是 GCD 也可以仅仅为了性能而使用吗?假设我有一个循
当有人用他们自己的类重载线程时,这个问题似乎已经以一种或另一种形式得到了回答,但是如果只是尝试使用 QTimer 类而不扩展 QThread 类呢?我正在尝试将 QTimer 用于 QT。他们在 上的
在网上看了类似的问题/错误,没有一个对我有帮助... 未处理的拒绝 SequelizeEagerLoadingError:任务未关联到用户! 我的用户路线 router.get('', functio
如果我正在评估两个变量而不是两个方法调用,那么我使用“&&”或“&”是否重要 //some logic that sets bool values boolean X = true; boolean
我们目前正在内部为我们的项目使用 Oracle 10g,这不太可能改变,但最终我们将向其他客户提供此应用程序,我们需要能够提出替代的免费数据库。 那么使 Hibernate 持久层独立于所使用的底层
我的 AsyncTask 类中的 onPostExecute() 方法有问题。 我有一个SignupActivity: public class SignupActivity extends AppC
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我一直在大量关注 sequelize 的文档,但在处理关系时遇到了问题。这是我使用 belongsTo 创建两个非常基本的 1:1 关系的非常简单的代码 import Sequelize, { STR
我希望这与 GMT 无关,否则我会觉得自己很愚蠢。 2 个快速相关的问题。为什么这会转换为不同的日期?正在失去一天。我查看了其他答案中所述的时区,但它始终是 GMT 时区 0000,这正是我所期望的。
我发现了这个问题的很多版本,但似乎都没有比明显的 Google Chrome 错误更进一步。 发生的情况是,每当我将 codeigniter 设置复制到服务器上的新文件夹,以基于它启动新项目时,我在尝
我需要一个与 UI 无关的简单布局管理器。通过这个,我的意思是它不应该指定我想如何在屏幕上表示我的形状/控件。它应该能让我说: 我想要 X 形状。我想要 X 形下的 Y 形。我希望形状 Z 包围 X,
当有一个方法== , 方法 !=被定义为采用该结果并应用 !给它。 (可能还有 =~ 和 !~ 。) 与此不同,>= , 通常表示 >或 == , 实际上独立于 >和 == .这两个定义似乎都不会影响
我在 Ruby Netbeans 6.5.1 中获得了大量(我称之为)无关的自动完成信息。 例如,如果我输入一个模型对象的名称,然后输入一个句点(无论我是在 Controller 中还是在 View
我是 NodeJS 的新手,有 express 和 Sequelize。当我想创建图书租赁时,控制台会提示我“图书与租赁无关”。 当我将表迁移到 sql 数据库时,id 就在它们的位置并且我的播种机正
我有众所周知的错误: implicit declaration of function 'STLINKReadSytemCalls' [-Wimplicit-function-declaration]
我是一名优秀的程序员,十分优秀!