0

私のOpenGLESクラスとコードは、AppleのGLES2Sampleコードサンプルから派生しています。これらを使用して、一定の回転速度であると予想される1つの軸を中心にスムーズに回転する3Dオブジェクトを表示します。現在、アプリは1のフレーム間隔を使用しており、OpenGLビューが描画されるたびに(EAGLViewのdrawViewメソッドで)、モデルを特定の角度で回転させます。

実際には、これはまともな結果をもたらしますが、完全ではありません。回転中にオブジェクトの大部分が見えなくなると、レンダリングが速くなり、回転の角速度が一定になりません。私の質問は、どうすればスムーズにすることができるかということです。

すべての提案を歓迎しますが、私はすでに1つのアイデアを持っています。それは、0.5秒ごとにレンダリングFPSを測定し、それに基づいて再描画するたびに回転角を調整することです。しかし、あまり良くないように聞こえます。これについてどう思いますか。また、この問題をどのように処理しますか。

4

2 に答える 2

3

I tend to use a CADisplayLink to trigger new frames and a simple time calculation within the frame request to figure out how far to advance my logic.

Suppose you have a member variable, timeOfLastDraw, of type NSTimeInterval. You want your logic to tick at, say, 60 beats per second. Then (with a whole bunch of variables to make the code more clear):

- (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];
}

In your case, updateLogic would apply a fixed amount of rotation. If constant rotation is really all you want then you could just multiply the rotation constant by numberOfTicks, or even skip this whole approach and do something like:

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

instead of keeping your own variable. In anything but the most trivial case though, you usually want to do a whole bunch of complicated things per time quantum.

于 2010-11-07T22:46:56.853 に答える
1

レンダリングの速度を変化させたくない場合、およびCADisplayLinkまたは他のアニメーションタイマーを使用して開ループを実行している(つまり、フルティルト)場合は、次の2つの方法があります。

1)コードを最適化して、60FPSを下回らないようにします。これはモデルのどのような状況でもデバイスの最大フレームレートです。

2)実行時に、数回の完全なサイクルでアプリケーションのフレームレートを測定し、測定された最低の描画パフォーマンスを超えないように描画レートを設定します。

回転角を調整することは、この問題の正しいアプローチではないと思います。これは、単に1つのパラメーター(描画速度)を固定するのではなく、2つのパラメーター(描画速度と回転速度)を互いに動かし続けようとしているためです。

乾杯。

于 2010-11-07T22:00:06.753 に答える