2

私はJavaを使用してAndroid(GL10)でオープンGLを学び始めており、いくつかのチュートリアルに従って正方形や三角形などを描画しました。

今、私は自分が持っているいくつかのアイデアを描き始めていますが、画面の頂点を描くことに本当に混乱しています。openGL ESを使用して何かを描画する場合、描画する画面の部分とテクスチャについても同じように指定する必要があります...

そこで、いくつかのテストを開始し、次の頂点を使用してフルスクリーンテクスチャを印刷しました。

(-1, -1, //top left
 -1, 1, //bottom left
 1, -1, //top right
 1, 1); //bottom right

なぜこのフルスクリーンなのですか?OpenGL座標の中心は左上(0、0)ではありませんか?なぜその頂点で描画が正しいのですか?真ん中が画面の真ん中のようで、幅と高さは-1 ... 1からですが、真ん中が左上だと思っていたのでよくわかりません...

別の質問...ピクセルを使用して印刷するC++コードをたくさん読みました。ピクセルを使用するビデオゲームでは、物事の正確な位置が必要であるため、これは本当に必要なようです。-1... 1では、正確には言えません。-1 ... 1の代わりにピクセルを使用するにはどうすればよいですか?

私の貧弱な英語について本当に感謝し、申し訳ありません。ありがとう

4

3 に答える 3

9

なぜこのフルスクリーンなのですか?OpenGL座標の中心は左上(0、0)ではありませんか?なぜその頂点で描画が正しいのですか?真ん中が画面の真ん中のようで、幅と高さは-1 ... 1からですが、真ん中が左上だと思っていたのでよくわかりません...

一緒に来る3つのものがあります。いわゆるビューポート、いわゆる正規化されたデバイス座標(NDC)、およびモデル空間からアイ空間、クリップ空間、NDC空間への投影。

ビューポートは、ウィンドウのNDC範囲が入る部分を選択します

[-1…1]×[-1…1]

にマップされます。関数のシグネチャはglViewport(x, y, width, height)です。OpenGLは、上昇するNDC x座標が右に移動し、上昇するNDCy座標が上昇する座標系を想定しています。

したがってglViewport(0, 0, window_width, window_height)、OpenGLコンテキストが最初にウィンドウにバインドされた後のデフォルトでもあるを呼び出すと、NDC座標(-1、-1)は左下になり、NDC座標(1,1)はウィンドウの右上隅。

OpenGLは、すべての変換がIDに設定されていることから始まります。つまり、通過する頂点座標がNDC空間に直接到達し、このように解釈されます。ただし、ほとんどの場合、OpenGLでは、連続する変換に適用しています。

  • modelview

  • 投影

モデルビュー変換は、静止した目/カメラ(常に(0,0,0)にあります)の前で世界中を移動するために使用されます。カメラを配置するということは、全世界の変換(ビュー変換)を追加することを意味します。これは、カメラを世界に配置する方法とは正反対です。固定関数OpenGLはこれを MODELVIEWマトリックスと呼び、マトリックスモードがGL_MODELVIEWに設定されている場合にアクセスされます。

投影変換は、OpenGLのレンズの一種です。これを使用して、広角か小角か(遠近法の場合)、直方体のエッジ(正投影)、または別の角度を設定します。固定関数OpenGLはこれを PROJECTIONマトリックスと呼び、マトリックスモードがGL_PROJECTIONに設定されている場合にアクセスされます。

投影プリミティブがクリップされた後、いわゆる同種分割が適用されます。これは、透視投影が適用されている場合、実際の遠近効果を作成します。

この時点で、頂点はNDC空間に変換され、最初に説明したように、ビューポートにマップされます。


問題について:必要なのは、頂点座標をビューポートピクセルに1:1でマッピングする投影です。簡単:

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if( origin_lower_left ) {
    glOrtho(0, width, height, 0, -1, 1);
} else {
    glOrtho(0, width, 0, height, -1, 1);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

これで、頂点座標がビューポートピクセルにマップされます。


更新:三角形でテクスチャ化された完全なビューポートクワッドを描画します。

OpenGL-2.1およびOpenGLES-1

void fullscreenquad(int width, int height, GLuint texture)
{
    GLfloat vtcs[] = {
      0, 0,
      1, 0,
      1, 1,
      0, 1
    };

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glVertexPointer(2, GL_FLOAT, 0, vtcs);
    glTexCoordPointer(2, GL_FLOAT, 0, vtcs);

    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 1, 0, 1, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
于 2012-02-19T12:51:33.463 に答える
2

デフォルトでは、openglカメラは負のz軸を指す原点に配置されます。平面の近くのカメラに投影されるものはすべて、画面に表示されるものです。したがって、画面の中央は(0,0)に対応します

描画する対象に応じて、GL_POINT、GL_LINE、およびGL_TRIANGLEを使用して描画するオプションがあります。

GL_POINTSを使用して画面上の一部のピクセルに色を付けることができますが、ティーポット、立方体などのオブジェクト/メッシュを描画する必要がある場合は、三角形を使用する必要があります。

于 2012-02-19T11:57:50.950 に答える
2

あなたは物事をより明確にするためにもう少し読む必要があります。openGLでは、ビューポートを指定します。このビューポートはOpenGLスペースのビューであるため、画面の中央が画面の中央になり、ビューが-1から1に広がるように設定すると、これがOpenGLの見通しの全体像になります。 。これをAndroidの画面座標と混合しないでください(これらの座標は、前述のように左上隅に原点があります)。他の座標系と一致させるには、これらの座標間で変換する必要があります(たとえば、タッチイベントの場合)。

于 2012-02-19T11:59:45.290 に答える