0

私は、ゆっくりと「いっぱい」になる円形の進行状況インジケーターを描画するアプリケーションに取り組んでいます。ここでは、いくつかの画像を見ることができます。私は中間モードを使用しており、フレームの更新ごとに頂点を描画することによって、この円形のみを描画しています (以下のコードを参照)。円が白とグレーの境界線を埋めると、少しちらつくので、どうすればもっと滑らかにできるのでしょうか。

これは具体的な例ですが、一般的には、非常に単純な線形補間を使用している場合でも、最も滑らかな動きを得るにはどうすればよいでしょうか? iPhoneでページをめくるときの動きを見ると、非常にスムーズで、(高速な)Macでこれをどのように実現できるのだろうかと思います。

ありがとう
ロクスル

PhotoBoothCountdown::PhotoBoothCountdown(float fMillisDuration)
    :duration(fMillisDuration)
    ,start_time(0)
{
    setActionCommand("take_picture");
}

void PhotoBoothCountdown::update() {
    if(start_time != 0) {
        float cur = ofGetElapsedTimeMillis();
        perc = (cur-start_time)/duration;

    }
}

void PhotoBoothCountdown::draw() {
    float resolution = 150;
    int parts_filled = resolution * perc;
    int parts_unfilled = (resolution - parts_filled);
    float part_angle = TWO_PI/resolution;
    //printf("filled: %i/%i/%i\n", parts_filled, parts_unfilled, (parts_filled+parts_unfilled));
    float radius = 300.0f;
    float width = 100;
    float radius_inner = radius-width;
    float center_x = ofGetWidth()/2;
    float center_y = ofGetHeight()/2;
    float angle = 0;

    glBegin(GL_TRIANGLE_STRIP);
        glColor4f(0.2f, 0.2f, 0.2f,0.9f);   
        for(int i = 0; i <= parts_filled; ++i) {
            float cosa = cos(angle);
            float sina = sin(angle);
            glVertex2f(center_x + cosa * radius,center_y + sina * radius);
            glVertex2f(center_x + cosa * radius_inner,center_y + sina * radius_inner);
            angle += part_angle;
        }
    glEnd();
    glBegin(GL_TRIANGLE_STRIP);
        glColor4f(1.0f, 1.0f, 1.0f,0.9f);
        angle -= part_angle;
        for(int i = 0; i <= parts_unfilled; ++i) {
            float cosa = cos(angle);
            float sina = sin(angle);
            glVertex2f(center_x + cosa * radius,center_y + sina * radius);
            glVertex2f(center_x + cosa * radius_inner,center_y + sina * radius_inner);
            angle += part_angle;
        }
    glEnd();

    if(perc >= 1) { 
        printf("should fire");
        fireEvent();
        reset();
    }
}



void PhotoBoothCountdown::start() {
    start_time = ofGetElapsedTimeMillis();
    end_time = start_time + duration;
}

void PhotoBoothCountdown::reset() {
    start_time = 0;
    end_time = 0;
    perc = 0;
}
4

3 に答える 3

1

ダブルバッファリングを見てください

于 2010-08-03T16:35:31.107 に答える
0

私が最初に行うことは、単純に1つの円を描画し、それを表示リストに格納することです(バッファーオブジェクトを選択することもできますが、このアドバイスの残りの部分はそれに依存せず、即時モードになります。したがって、最も単純な改善に固執します)。分割された円を描き、それぞれに完了率に対応するテクスチャ座標を配置します。ほとんど退屈ですが、完全性のために均一なシェーダーを適用します。テクスチャ座標が<=完全性が点灯する三角形。残りは灰色のままです。次に、描画はユニフォームの設定とディスプレイリストの呼び出しで構成されます。はるかに高速。

于 2010-08-03T21:55:20.747 に答える
0

ちらつき、エイリアシング、滑らかな動き、または描画アーティファクトなど、何について質問しているのかを推測するのは困難です。コードを見た後の自由な考え

  • もし、( )回をfloat part_angle = TWO_PI/resolution;合計すると になると仮定します。残念ながら、これは浮動小数点演算には当てはまりません。また、sin(TWO_PI) cos(TWO_PI) は必ずしも正確な値を返すわけではありません。angle += part_angleresolutionTWO_PI0.01.0

  • 描画精度を向上させるために、完全な灰色の円を描き、必要に応じてその上に白い円を描きます。これにより、完全な灰色の円が 100% になります。

  • 浮動小数点演算では丸め誤差が発生する可能性があり、この誤差は変換後の整数値に影響を与える可能性があります。おそらく、このような式から計算しても、すべての塗りつぶし部分を取得することはできませんint parts_filled = resolution * perc;。パーセンテージのカウントダウンを変換して、整数型を使用するか、少なくともパーセント値を出力してテストし、100% に達したかどうかを確認できます。
  • さらに、次のことができます
    • アンチエイリアシングを使用してエッジを滑らかにする
    • フレーム レートを上げます (描画の更新方法によって異なります)。
    • 垂直同期をオンにして、ページのティアリングを削除します
于 2010-08-03T17:12:07.870 に答える