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

时间:2010-11-06 20:05:34

标签: ios opengl-es cadisplaylink

我的OpenGL ES类和代码源自Apple的GLES2Sample code sample。我用它们来显示围绕一个轴平滑旋转的3D物体,我希望它是一个恒定的旋转速度。目前,应用程序使用的帧间隔为1,每次绘制OpenGL视图时(在EAGLView的drawView方法中),我都会将模型旋转一定角度。

在实践中,这给出了不错的结果,但并不完美:在旋转期间,当物体的大部分不在视线范围内时,渲染变得更快,因此旋转不具有恒定的角速度。我的问题是:如何让它更顺畅?

虽然我欢迎所有的建议,但我已经有了一个想法:每隔半秒测量一次渲染FPS,并在每次重绘的基础上调整旋转角度。然而,这听起来并不是很好,所以:你怎么看待这个问题,你将如何处理这个问题呢?

2 个答案:

答案 0 :(得分:3)

我倾向于使用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);

而不是保留自己的变量。除了最微不足道的情况之外,你通常希望每次都能做一大堆复杂的事情。

答案 1 :(得分:1)

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

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

2)在运行时,通过几个完整的循环测量应用的帧速率,并设置绘制速率,使其永远不会超过您的最低测量绘图性能。

我认为调整旋转角度不是解决此问题的正确方法,因为您现在正试图保持两个参数相互竞争(绘制速率和旋转速率),而不是简单地固定单个参数:绘制速率

干杯。