2

p aを (0.5, y ) の点、p b(5.5, y ) の点とする。p aからp bに線分を引くと、x軸上に 5 ピクセルの線分が得られます。問題は、これらのピクセルが正確にどこにあるかです。

OpenGL ES 2.0 仕様 3.4.1によると:

p ap bがフラグメントの中心にある場合、フラグメントのこの特徴付けは、1 つの変更を加えた Bresenham のアルゴリズムに帰着します。この記述で生成される線は「半分開いた」ものであり、最終的なフラグメント (p b に対応する)描画されないことを意味します。

p aからp bまでのセグメントを描画すると、ピクセル 1 から 5 ( x座標) が得られます。p aは最初のピクセルの中心にあり、p bは 6 番目のピクセルの中心にあります。p bからp aに描画すると、2 から 6 になります。これは、iPhone 4s で取得した結果です。ただし、Android (Nexus 7およびエミュレーター) では、結果は常に 1 ~ 5 です (方向は関係ありません)。描画コードはまったく同じです (NDK を使用)。

問題は、どの動作が正しいかということです。また、両方のシステムで同じ結果を得るには、どのような回避策を使用する必要がありますか?

編集

Mac OS で次のコードを実行すると (単純なNSOpenGLViewサ​​ブクラスを使用):

glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.85f, 0.35f);
float pa = 0.5;
float pb = 5.5;
float y =  5.5;
glOrtho(-50, 50, -50, 50, -1, 1);
glBegin(GL_LINES);
{
    //pa to pb - lower line
    glVertex3f(pa, y, 0.0);
    glVertex3f(pb, y, 0.0);
    ++y;
    //pb to pa - upper line
    glVertex3f(pb, y, 0.0);
    glVertex3f(pa, y, 0.0);
}
glEnd();
glFlush();

次の結果が得られます。 ここに画像の説明を入力

スクリーンショット

ということで、期待通りの結果です。また、Nexus 7 では仕様の解釈が異なるか、特別な設定を有効にする必要があるようです。

編集2:

私のエミュレーターは画面に収まらず、画面出力を再スケーリングしていたため、エミュレーターがデバイスと同じ問題を抱えているという錯覚が生じました。DDMS でスクリーンショットを撮った後、エミュレーターが期待どおりの結果を生成することは明らかでした。エミュレータ

しかし、デバイスは次の結果を生成しています:ネクサス7

これを再現するには、gl_code.cpp ファイルの内容を次のコードに置き換え、 hello-gl2 ndk サンプル プロジェクトを実行します。

4

1 に答える 1

2

リンク先の仕様を引用します。

ひし形出口ルールの初期条件と最終条件は実装が難しい場合があるため、次のルールに従って、他のライン セグメント ラスター化アルゴリズムを使用できます。

  1. アルゴリズムによって生成されたフラグメントの座標は、ダイヤモンド出口規則によって生成された対応するフラグメントから、x または y ウィンドウ座標のいずれかで 1 単位を超えて逸脱することはできません。

したがって、残念ながら法的な逸脱のようです。

回避策として、両方のラスタライザーで同じ結果が得られる可能性がある場合は、0.5 ではなく 0.25 や 0.75 などの座標を使用してみます。

または、最初に 1 行をラスタライズし、ラスタライザが使用しているルールを確認し、後ですべての座標をそれに合わせます。

于 2012-12-09T14:39:12.267 に答える