Opengl es 为OpenGL(ES)创建稳定的(帧速率稳定的)游戏引擎

Opengl es 为OpenGL(ES)创建稳定的(帧速率稳定的)游戏引擎,opengl-es,Opengl Es,我很难为我的OpenGL应用程序创建一个稳定的游戏引擎。这是一个由多个精灵和大量动作组成的游戏 我创建的对象基本上都是我的精灵。另一个称为“游戏引擎”的对象每隔一秒(一个计时器)循环一组计算,产生新的游戏变量。之后,精灵对象现在知道其图形数据 问题是,在收集了所有绘图数据后,绘图应该在正确的时间进行,从而产生稳定的动画。根据当前场景的复杂性,游戏计算需要的时间不确定。因此,实际绘图发生在不同的时刻。我该如何防止这种情况发生 为了澄清,我的方法如下: // Every something of a

我很难为我的OpenGL应用程序创建一个稳定的游戏引擎。这是一个由多个精灵和大量动作组成的游戏

我创建的对象基本上都是我的精灵。另一个称为“游戏引擎”的对象每隔一秒(一个计时器)循环一组计算,产生新的游戏变量。之后,精灵对象现在知道其图形数据

问题是,在收集了所有绘图数据后,绘图应该在正确的时间进行,从而产生稳定的动画。根据当前场景的复杂性,游戏计算需要的时间不确定。因此,实际绘图发生在不同的时刻。我该如何防止这种情况发生

为了澄清,我的方法如下:

// Every something of a second I call tick
-(void)tick
{
  drawingData = gameEngine();
  draw(drawingData); 
}

我不知道构建这样的游戏引擎一定有一个最佳实践?

这有点依赖于平台,但一个通常有效的基本方法是在渲染循环中使用高性能计时器,并使用它帮助您在帧之间睡眠,以获得稳定的帧速率

您可以为帧的渲染计时,然后按一定数量睡眠以保持稳定的帧速率

但是,如果您的平台无法跟上您想要达到的帧速率,您需要开始寻找优化游戏引擎的方法。这只会减缓事情的发展,使之保持一致和顺利,而不是加速

---澄清----


}


这实际上与OpenGL无关;这更多地与您正在使用的操作系统或系统API有关(即Carbon/Cocoa/Win32)。但真正非常简单的情况是(伪代码):

您尽可能频繁地进行绘图,但仅每50毫秒(即每秒20次)进行一次更新。显然,还有很多其他的事情要考虑,特别是当你落后时(跳过帧),你会做些什么

进入OpenGL的最佳场所是Nehe的课程:


它们有点过时了,但是每节课底部的示例代码是一个很好的起点,它有多种语言和多种操作系统。

最好的解决方案是多线程应用程序—一个线程将图形数据计算到缓冲区,另一个线程渲染数据

如果您正在寻找一个真正简单的解决方案,只需颠倒计算和渲染的顺序即可

void Main()
{
   StartTime = Now();

   while (!ExitRequested)
   {     
      DrawingData = GameEngine(Now() - StartTime);
      Draw(DrawingData);
   }
}
在应用程序启动时计算第一个图形数据,当计时器启动时,您只需绘制它。之后,您可以在下一个计时器事件之前的所有时间再次计算图形数据

但一般来说,以可变帧速率进行渲染可能是一个更好的解决方案-如果机器为达到所需帧速率而变慢,并且在高速机器上提供高帧速率,则可以避免问题


尽可能快地渲染帧-不是在每个帧之间使用固定的间隔,而是使用应用程序运行的实时性。这意味着不要每帧将对象向前移动20毫秒,只需将它们移动到当前运行时间显示的位置。

游戏循环有很多种,但更好的循环会将动画与绘图或更经典的术语模型和视图分开。基本上,您希望构建一个游戏模型,在该模型中,您可以建立时间流逝并更新模型(物理帧率),然后在连续的时间点(渲染帧率)独立渲染模型快照

这里有几篇文章对游戏循环的一些变化及其优缺点进行了更详细的解释。还有源代码。我希望有帮助


事实上,除非你编写了非常简单的程序,否则使用固定步长的游戏循环通常是首选。严重+1表示“固定你的时间步长!”。这是一个必须阅读的人,想真正知道最好的方法来设计你的游戏循环。它可能需要读几遍才能理解它的呈现方式,但它确实非常简单。
checkTime = currentTime
while not exitCondition
    if currentTime - checkTime >= 50 milliseconds
        checkTime = checkTime + 50 milliseconds
        updateScene
    else drawScene
void Initialize()
{    
   DrawingData = GameEngine();
}

void Tick()
{
   Draw(DrawingData);
   DrawingData = GameEngine();
}
void Main()
{
   StartTime = Now();

   while (!ExitRequested)
   {     
      DrawingData = GameEngine(Now() - StartTime);
      Draw(DrawingData);
   }
}