0

Java OpenGL (JOGL) アプリがあり、画面全体をカバーするテクスチャ マップ クワッドを作成しようとしています。いくつかのピクセルをバッファに描画してから、それらのピクセルをテクスチャに読み込んで、画面上に再描画します (フラグメント シェーダを適用して)。テクスチャをビューポートにマッピングするための私のコードは次のとおりです。

        gl.glMatrixMode(GL.GL_PROJECTION);                                        
        gl.glPushMatrix();                                                 
        gl.glLoadIdentity();                                               
        gl.glOrtho( 0, width, height, 0, -1, 1 );                          
        gl.glMatrixMode(GL.GL_MODELVIEW);                                  
        gl.glPushMatrix();                                                 
        gl.glLoadIdentity();
        IntBuffer ib = IntBuffer.allocate(1);
        gl.glEnable(GL.GL_TEXTURE_2D);
        gl.glGenTextures(1, ib);
        gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
        //buff contains pixels read from glReadPixels
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buff);
        gl.glBindTexture(GL.GL_TEXTURE_2D, ib.get(0));
        gl.glBegin(GL.GL_QUADS);
        gl.glTexCoord2f(0,1);
        gl.glVertex2f(0,0); 
        gl.glTexCoord2f(0,0);
        gl.glVertex2f(0,height);
        gl.glTexCoord2f(1,0);   
        gl.glVertex2f(width,height);
        gl.glTexCoord2f(1,1);      
        gl.glVertex2f(width,0);
        gl.glEnd();
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
        gl.glPopMatrix();
        gl.glPopMatrix();

最終結果は、ビューポート全体をカバーしていない (部分的にオンになっている) クワッドであり、バッファーからのピクセルが含まれていません。ここで間違っていることは何ですか?

ありがとう、ジェフ

4

3 に答える 3

2

まず、初期化コードでテクスチャのみを作成する必要があります。フレームごとに glTexImage2D を呼び出すべきではありません。テクスチャのサイズが変更された場合にのみ glTexImage2D を再度呼び出します。glTexSubImage2D を使用して、データをテクスチャにアップロードできます。glTexImage2D を「新しい」ものと考え、glTexSubImage2D をメモリ コピーと考えてください。

OpenGL を初期化した後、これを 1 回実行します。

IntBuffer ib = IntBuffer.allocate(1);  //Store this in your object
gl.glGenTextures(1, ib);
gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
//buff contains pixels read from glReadPixels
gl.glBindTexture(GL.GL_TEXTURE_2D, ib.get(0));
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, 0);
gl.glBindTexture(GL.GL_TEXTURE_2D, 0);

次に、各フレームで次の操作を行います。

gl.glMatrixMode(GL.GL_PROJECTION);                                        
gl.glPushMatrix();                                                 
gl.glLoadIdentity();                                               
gl.glMatrixMode(GL.GL_MODELVIEW);                                  
gl.glPushMatrix();                                                 
gl.glLoadIdentity();

gl.glBindTexture(GL.GL_TEXTURE_2D, ib.get(0));  //Retrieved from your object
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buff);

gl.glBegin(GL.GL_QUADS);
    gl.glTexCoord2f(0,1);
    gl.glVertex2f(-1, -1); 
    gl.glTexCoord2f(0, 0);
    gl.glVertex2f(-1, 1);
    gl.glTexCoord2f(1, 0);   
    gl.glVertex2f(1, 1);
    gl.glTexCoord2f(1, 1);      
    gl.glVertex2f(1, -1);
gl.glEnd();

gl.glMatrixMode(GL.GL_MODELVIEW);                                  
gl.glPopMatrix();   
gl.glMatrixMode(GL.GL_PROJECTION);                                        
gl.glPopMatrix();   
gl.glMatrixMode(GL.GL_MODELVIEW);                                  

プロジェクションとモデルビューに ID を使用することで、頂点座標をクリップ空間で直接提供できます。クリップ スペースの [-1, 1] 範囲は、ウィンドウ スペースの [0, width/height] にマップされます。したがって、ウィンドウの大きさを知る必要も気にする必要もありません。glViewport が正しく設定されている限り、これは機能するはずです。

于 2011-06-10T23:00:59.467 に答える
1

問題ではないかもしれませんが、役に立たないでしょう: 1 回のプッシュでモデルビュー マトリックスを 2 回ポップしています。射影行列をまったくポップしていません。

プッシュやポップを行わずに、起動時に一度射影行列を設定することをお勧めします。モデルビュー マトリックスをプッシュおよびポップする必要もありません。(起動時に一度テクスチャ設定を行うこともできます。)

于 2011-06-10T07:19:48.240 に答える
0

以下のようなコードで glError をチェックすることから始めます。古いバージョンの JOGL と GL オブジェクトにはいくつかの問題があり、GL_QUADS が存在しないなどのばかげたことがあるため、GL2 オブジェクトを使用したことに注意してください。

上記のコードでシェーダーを有効にしている場合は、サンプラーを読み取ってテクスチャリングを行う必要があります。その場合は、このレンダリング コードで使用しているシェーダー コードを添付してください。

private static void checkForGLErrors(GL2 gl) {
    int errno = gl.glGetError();
    switch (errno) {
        case GL2.GL_INVALID_ENUM:
            System.err.println("OpenGL Error: Invalid ENUM");
            break;
        case GL2.GL_INVALID_VALUE:
            System.err.println("OpenGL Error: Invalid Value");
            break;
        case GL2.GL_INVALID_OPERATION:
            System.err.println("OpenGL Error: Invalid Operation");
            break;
        case GL2.GL_STACK_OVERFLOW:
            System.err.println("OpenGL Error: Stack Overflow");
            break;
        case GL2.GL_STACK_UNDERFLOW:
            System.err.println("OpenGL Error: Stack Underflow");
            break;
        case GL2.GL_OUT_OF_MEMORY:
            System.err.println("OpenGL Error: Out of Memory");
            break;
        default:
            return;
    }
}

また、変化しないものである場合は、フレームごとにテクスチャを生成しないようにします。textureId を保存して、後でバインドできます。

于 2011-06-10T07:12:09.597 に答える