1

すべてのフレームと呼ばれるこのOpenGLES1.1コードについて考えてみます。

glPushMatrix();
glRotatef(m_currentAngle, 0, 0, 1);

//... enable, point, draw vertices

glPopMatrix();

すべてうまくいっています。ここで、プッシュ/ポップを削除すると、連続回転アニメーションが得られます。これは理にかなっています。

ただし、ES 2.0では、これと同等の効果があります。

 //no glRotate so doing this:
float radians = m_currentAngle * 3.14159f / 180.0f;
float s = std::sin(radians);
float c = std::cos(radians);
float zRotation[16] = {
    c, s, 0, 0,
    -s, c, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
};
GLint modelviewUniform = glGetUniformLocation(m_simpleProgram, "Modelview");
glUniformMatrix4fv(modelviewUniform, 1, 0, &zRotation[0]);

//... then enable, point and draw vertices

これも適切な画像を作成しますが、「プッシュ/ポップ」手法に相当するものはありませが、継続的に回転することはありません。1.1が回転するのに、2.0が連続回転しないのはなぜですか?

言い換えれば、1.1では連続アニメーションを防ぐためにプッシュ/ポップが必要なのに、2.0では必要ないのはなぜですか?

4

1 に答える 1

4

古いスタイルのパイプラインは、シーングラフで使用するために設計されています。新しい変換を導入すると、現在の変換と連結されるため、シーングラフを作成できるようにするために、子ノードにアクセスするときに現在の変換を提供されたスタックにプッシュし、ローカル変換を適用し、いくつかを実行できます。レンダリングしてから、トランスフォームを再度ポップして、親のトランスフォームに戻ります。

また、GLのレンダリング/ライティングパイプラインでは、使用されるマトリックスを理解できる必要があります。そのため、GLは「プロジェクション」と「モデルビュー」に分割されます。

新しいスタイルのパイプラインはそれを行いません。そのパイプラインで行っているのは、レンダリングする正確なマトリックスを指定することです。別のマトリックスを指定すると、すでに存在するものがすべて置き換えられます。

あなたの例は、次のことを行うのと同じです。

glLoadIdentity()
glRotate()

したがって、連続的な回転はありません。

連結、プッシュ、ポップなどが必要な場合は、自分で実装する必要があります。前の行列値を保存し、それを乗算する必要があります。または、回転値を更新します。

これには多くの理由がありますが、特に、プログラム可能なパイプラインでは、頂点を変換する方法が厳密に定義されていないため、必要な行列の作成はプログラマーに任されています。おそらく、マトリックスさえ持っていませんが、シェーダーで変換を構築します。

于 2012-12-27T08:03:30.123 に答える