2016-03-23 23 views
0

現在、プロジェクトからテクスチャアトラスを使用して配列テクスチャに変換しようとしていますが、私の人生ではそれを動作させることはできません。OpenGL配列のテクスチャはまったくレンダリングされていません

私の環境に関するいくつかの注意事項:

  • 私はテクスチャはすべて128×128とアトラスを使用する際に完全に微細化(どのエッジアーティファクトがなければされているGLSLバージョン3.30
  • でのOpenGL 3.3コアコンテキストを使用しています私は信じている)

問題を切り替えるために確信させた私は除外しました:

  • の解像度の問題 - 128×128、2の累乗であることは、テクスチャロード(それは以前と同様に、それは完璧に動作します)
  • 不完全なテクスチャ(ミップマップの問題)
  • 問題ないはず - 私はミップマップに関する一般的な問題を経てきたし、

    public void createTextureArray() { 
        glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
        glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
        glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
        glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    
        int handle = glGenTextures(); 
        glActiveTexture(GL_TEXTURE0); 
        glBindTexture(GL_TEXTURE_2D_ARRAY, handle); 
        glPixelStorei(GL_UNPACK_ROW_LENGTH, Texture.SIZE); 
        glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 
        glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, Texture.SIZE, Texture.SIZE, textures.size()); 
    
        try { 
         int layer = 0; 
         for (Texture tex : textures.values()) { 
          // Next few lines are just for loading the texture. They've been ruled out as the issue. 
          PNGDecoder decoder = new PNGDecoder(ImageHelper.asInputStream(tex.getImage())); 
          ByteBuffer buffer = BufferUtils.createByteBuffer(decoder.getWidth() * decoder.getHeight() * 4); 
          decoder.decode(buffer, decoder.getWidth() * 4, PNGDecoder.Format.RGBA); 
          buffer.flip(); 
    
          glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, decoder.getWidth(), decoder.getHeight(), 1, 
            GL_RGBA, GL_UNSIGNED_BYTE, buffer); 
    
          tex.setLayer(layer); 
    
          layer++; 
         } 
        } catch (IOException ex) { 
         ex.printStackTrace(); 
         System.err.println("Failed to create/load texture array"); 
         System.exit(-1); 
        } 
    } 
    

    VAO/VBOを作成するためのコード:

    私は

はここで、配列のテクスチャを作成するための私のコードのOpenGLは、それらを期待しなければならないとは思いません

private static int prepareVbo(int handle, FloatBuffer vbo) { 
    IntBuffer vaoHandle = BufferUtils.createIntBuffer(1); 
    glGenVertexArrays(vaoHandle); 
    glBindVertexArray(vaoHandle.get()); 
    glBindBuffer(GL_ARRAY_BUFFER, handle); 

    glBufferData(GL_ARRAY_BUFFER, vbo, GL_STATIC_DRAW); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D_ARRAY, GraphicsMain.TEXTURE_REGISTRY.atlasHandle); 

    glEnableVertexAttribArray(positionAttrIndex); 
    glEnableVertexAttribArray(texCoordAttrIndex); 

    glVertexAttribPointer(positionAttrIndex, 3, GL_FLOAT, false, 24, 0); 
    glVertexAttribPointer(texCoordAttrIndex, 3, GL_FLOAT, false, 24, 12); 

    glBindVertexArray(0); 

    vaoHandle.rewind(); 
    return vaoHandle.get(); 
} 

フラグメントシェーダ:

#version 330 core 

uniform sampler2DArray texArray; 

varying vec3 texCoord; 

void main() { 
    gl_FragColor = texture(texArray, texCoord); 
} 

texCoordが正常に動作しています。 )頂点シェーダから正常に渡されています。

私は考えていないので、現代のOpenGLにはまだまだ新しくなっています。私のコードには驚くべきことがありますか?

+1

テクスチャの座標は?レイヤインデックスが整数で、正規化された '0' -'1'値ではないことを確認してください。 –

+0

"' texture2DArray' "これは合法的なGLSL 3.30関数ではありません。テクスチャ配列からサンプルするために使用する関数は、すべての種類のテクスチャからサンプルするために使用する関数と同様に、 'texture'と呼ばれます。 –

+0

@ColonelThirtyTwo xy座標は、レンダリングされる頂点に応じて0または1のいずれかです。このレイヤーは 'int'として格納され、アクセサから直接VBOとして提供される' FloatBuffer'に渡されます。 – caseif

答えて

1

いくつかの注意事項:

  • あなたは、すべての層がウィキsays
  • として、レベル/ミップマップの同じ数を持っていることを確認してください2つのテクスチャ
  • の力を持っているために、それ以上を必要としません最初の4つのglTexParameteriはその瞬間でGL_TEXTURE_2D_ARRAYにバインドされているものに影響しますので、あなたはより良いあなたがspecifできるかglBindTexture
  • 後にそれらを移動したいですどのくらい多くのテクスチャをglGenTextures()で作成したいですか?より具体的な方法の可能性がある場合は、
  • GL_UNPACK_ROW_LENGTH 0より大きい場合は、行内のピクセル数を定義してください。私はTexture.SIZEが実際にテクスチャのサイズではなく、片面(あなたの場合は128)の寸法ではないと思います。とにかくそれを設定する必要はありません。スキップすることができます。
  • GL_UNPACK_ALIGNMENTを4に設定するのは、行の長さが複数の場合のみです。ほとんどの人はテクスチャをロードする前にテクスチャをロードする前にそれを1に設定し、それを4に戻してから設定します。サイズ(128×128)
  • glActiveTextureglBindTextureprepareVbo内部に役に立たない、彼らはVAO
  • の一部ではないあなたがインスピレーションをしたいことがあり、単純なin out
  • に切り替え、それは非推奨です、GLSLでvaryingを使用していません〜からthis sample
  • 使用サンプラー、彼らはあなたにそれ以外の場合はglGetError()、いくつかのサイレントエラーはあなたがprepareVboそれを呼ばれていますが、それにVAOとVBOの両方を初期化しないレンダリング出力
  • によって明示的に見られない場合があり、より多くの柔軟性
  • 使用Debug Output可能な場合を与えます
+0

これらのすべてを確認してOPを更新しましたが、テクスチャはまだ機能しません。カップルノート: 'glGenTextures()'(argsなし)は生成される1つのテクスチャを意味します。 'textures.size()'はテクスチャ 'List'の個々のテクスチャの数を返します。これは正しいレイヤ数です。 – caseif

+0

解決済み - 'prepareVbo'から' glBindTexture'呼び出しを削除するのを忘れてしまいました。これを省略すると、テクスチャが完全に機能します。好奇心のために、なぜこの関数を呼び出してプログラムを破壊するのでしょうか? – caseif

+0

あなたはうれしかった。私が考えることができる唯一の論理的な理由は、 'prepareVbo'の後のどこかで、' GL_TEXTURE_2D_ARRAY'にバインドされたテクスチャのパラメータ、つまりGraphicsMain.TEXTURE_REGISTRY.atlasHandle'を変更するいくつかの関数を呼び出していることです。 Ps:もう1つのヒントを追加しました;) – elect

関連する問題