web-dev-qa-db-ja.com

2Dワールドを画面座標OpenGLに変換する方法

現在、OpenGL搭載のレンダラーを2Dゲームエンジンに実装する作業をしています。

OpenGL画面の座標空間は[-1,1]なので、汎用のデカルト2Dワールド座標系とどのようにインターフェースするかについて少し混乱しています。

私の世界のビューポートが[-500、-500]から[1200、1200]であるとします。ここで、[0、0]は世界の原点です。変換して-1から1までの座標にスケールダウンするだけでよいですか?それとも、実行する必要がある他の形式の変換がありますか?

独自の座標系で位置が定義されているオブジェクトを画面上のどこに描画するかをどのように計算しますか?

GlOrthoを使用した場合と使用しない場合の説明に感謝します(透視効果のためにZ軸も使用できます)。

21
bgroenks

まず、OpenGLは複数の座標系を使用するため、「theOpenGL座標系」はありません。あなたが言及しているのは、3つの座標すべてが[-1、1]の範囲にある正規化デバイス座標(NDC)です。異なる座標系とその名前については、「9.011座標の変換方法?異なる座標空間とは?」のセクションで説明しています here 。 1)

第2に、混乱を避けるために、OpenGLでは「ビューポート」という用語は、レンダリング先のウィンドウの一部を指し、ウィンドウ座標内にあります。あなたの質問では、それを使用して、レンダリングしたい世界の(l、r、t、b)=(-500、-500、1200、1200)の部分を記述しました。これは、世界座標にあります。

「画面上のオブジェクトを描画する場所を計算する」方法を尋ねました。必要なのは、ある座標系から別の座標系にマッピングする変換(4x4マトリックス)を定義することです。 2D世界は世界座標で与えられるため、世界座標をNDCに変換する行列、つまり投影行列を定義する必要があります。シェーダーでは、頂点をこの射影行列で単純に乗算し、NDCを取得します。 glm::ortho/glOrthoは、このような射影行列を計算します。透視投影については、何をしたいのかはっきりしていませんが、glmでperspective関数とlookat関数を試してみてください。

明確にするために、頂点を任意の座標系(世界座標系と呼ばれます)で定義し、これらの頂点を描画するだけです。頂点シェーダーの仕事は、定義した変換を適用することです。

また、正方形を指定したことに注意してください。これは通常、望んでいることではありません。モニターとほとんどのウィンドウは正方形ではないので、その正方形を典型的なビューポートにマッピングすると、世界の歪んだビューが表示されます。ビューポートのアスペクト比(幅:高さ)を考慮する必要があります。 ここ と説明しようとしました。


1)補足として、FAQはかなり古く、OpenGLの古いバージョンを指します。現在、プログラマーはモデルビューと射影行列の両方を管理することが期待され、推奨されています。シェーダーでそれらを必要とするので、 glm を強くお勧めします。これはヘッダーのみなので、統合が非常に簡単で、GLSLをミラーリングするNice構文を持っています。

19

射影行列で glOrtho を使用して、通常どおりに描画します。あなたの例では、ビューポートを幅1000単位、高さ3000単位にするglOrtho(0、1000、0、3000、-1、1)が必要だと思います

2
Tim Mutton

シーンを任意の座標系に配置します。 glm( http://glm.g-truc.net/ )を使用して行列を初期化し、数学演算などを実行することをお勧めします。したがって、シーングラフエンジンがあり、すべてのオブジェクトを2D/3Dの世界。 glmでビューと投影を正しく設定するだけです。実際には、グラフィックスパイプラインの実装の詳細は必要ありません。そのため、ゲームエンジンの設計が間違っている可能性があります。

0
dinony