繁体   English   中英

在iPhone上使用CADisplayLink在OpenGL ES视图中进行恒速旋转

[英]Constant-velocity rotation in OpenGL ES view using CADisplayLink on iPhone

我的OpenGL ES类和代码均来自Apple的GLES2Sample代码示例 我用它们来显示3D对象绕一个轴平稳地旋转,并以恒定的旋转速度实现。 目前,该应用使用的帧间隔为1,并且每次绘制OpenGL视图(在EAGLView的drawView方法中)时,我都会将模型旋转一定角度。

实际上,这给出了不错的结果,但并不是完美的结果:在旋转过程中,当物体的大部分不可见时,渲染变得更快,因此旋转没有恒定的角速度。 我的问题是: 如何使它更平滑?

尽管我欢迎所有建议,但我已经有了一个主意:每半秒测量一次渲染FPS,并在此基础上调整每次重绘的旋转角度。 但是,这听起来不太好:您对此有何看法,您将如何处理该问题?

我倾向于使用CADisplayLink触发新帧,并在帧请求中进行简单的时间计算,以弄清楚我的逻辑前进了多少。

假设您有一个NSTimeInterval类型的成员变量timeOfLastDraw。 您希望您的逻辑以每秒60次的速度跳动。 然后(使用一堆变量使代码更清晰):

- (void)displayLinkDidTick
{
    // get the time now
    NSTimeInterval timeNow = [NSDate timeIntervalSinceReferenceDate];

    // work out how many quantums (rounded down to the nearest integer) of
    // time have elapsed since last we drew
    NSTimeInterval timeSinceLastDraw = timeNow - timeOfLastDraw;
    NSTimeInterval desiredBeatsPerSecond = 60.0;
    NSTimeInterval desiredTimeInterval = 1.0 / desiredBeatsPerSecond;

    NSUInteger numberOfTicks = (NSUInteger)(timeSinceLastDraw / desiredTimeInterval);

    if(numberOfTicks > 8)
    {
        // if we're more than 8 ticks behind then just do 8 and catch up
        // instantly to the correct time
        numberOfTicks = 8;
        timeOfLastDraw = timeNow;
    }
    else
    {
        // otherwise, advance timeOfLastDraw according to the number of quantums
        // we're about to apply. Don't update it all the way to now, or we'll lose
        // part quantums
        timeOfLastDraw += numberOfTicks * desiredTimeInterval;
    }

    // do the number of updates
    while(numberOfTicks--)
        [self updateLogic];

    // and draw
    [self draw];
}

在您的情况下,updateLogic将应用固定的旋转量。 如果确实需要恒定旋转,则可以将旋转常数乘以numberOfTicks,甚至跳过整个方法,然后执行以下操作:

glRotatef([NSDate timeIntervalSinceReferenceData] * rotationsPerSecond, 0, 0, 1);

而不是保留自己的变量。 但是,在最琐碎的情况下,您通常希望每个时间段执行一堆复杂的事情。

如果您不希望渲染速度变化,并且不希望通过CADisplayLink或其他动画计时器运行开环(即全倾斜),则可以执行以下两项操作:

1)优化您的代码,使其永远不会低于60 FPS(在任何情况下使用您的型号设备的最大帧速率)。

2)在运行时,通过几个完整的周期来测量应用程序的帧速率,并设置绘制速率,以使其永远不会超过最低的测量绘制性能。

我认为,调整旋转角度不是解决此问题的正确方法,因为您现在尝试使两个参数彼此保持同步(绘制速率和旋转速率),而不是简单地固定一个参数:绘制速率。

干杯。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM