2016-03-23 12 views
0

Ich bin derzeit ein Projekt von der Verwendung eines Texturatlas zu einer Array Textur, sondern für das Leben von mir konvertieren arbeiten kann ich nicht arbeiten.OpenGL Array Texturen Rendering nicht an allen

Einige Anmerkungen zu meiner Umgebung:

  • Ich bin mit OpenGL 3.3 Core Zusammenhang mit GLSL Version 3.30
  • Die Texturen sind alle 128x128 und völlig in Ordnung gemacht wird, wenn ein Atlas mit (die Kantenartefakte Sperrung des hat mich überzeugt

Probleme zu wechseln) ich glaube, ich habe ausgeschlossen:

  • Auflösung Probleme - 128x128, eine Zweierpotenz ist, sollte
  • Texture Laden (es funktioniert perfekt wie zuvor) in Ordnung sein
  • Unvollständige Texturen (MipMap Ausgaben) - Ich habe durch die häufig gestellte Fragen in Bezug auf Mipmaps gegangen und ich glaube nicht, OpenGL erwarten sie
  • meinen Code sollte

Hier ist die Array-Textur für die Erstellung von:

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); 
    } 
} 

Der Code für die Erstellung des VAO/VBO:

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(); 
} 

Fragment-Shader:

#version 330 core 

uniform sampler2DArray texArray; 

varying vec3 texCoord; 

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

(texCoord funktioniert gut; Es wird vom Vertex-Shader korrekt übertragen.)

Ich bin über keine Ideen hinaus, da es für OpenGL noch etwas neu ist, würde ich gerne wissen, ob irgendetwas mit meinem Code grell falsch ist.

+1

Was sind Ihre Texturkoordinaten? Stellen Sie sicher, dass der Ebenenindex eine Ganzzahl ist und kein normalisierter Wert von "0" bis "1". –

+0

"' texture2DArray' "Das ist keine legale GLSL 3.30-Funktion. Die Funktion, die Sie zum Abtasten aus einem Textur-Array verwenden, wird "Textur" genannt, genau wie die Funktion, die Sie zum Abtasten von Texturen aller Art verwenden. –

+0

@ColonThirtyTwo Die xy-Koordinaten sind entweder 0 oder 1, je nachdem, welcher Stützpunkt gerendert wird. Der Layer wird als "int" gespeichert und direkt vom Accessor an den als VBO bereitgestellten "FloatBuffer" übergeben. – caseif

Antwort

1

Einige Überlegungen:

  • Sie nicht mehr brauchen keine Potenz von zwei Texturen
  • sicher sein, haben, dass jede Schicht die gleiche Anzahl von Ebenen/Mipmaps hat, wie das Wiki says
  • die ersten vier glTexParameteri beeinflussen, was zu GL_TEXTURE_2D_ARRAYin diesem Moment gebunden ist, so dass Sie besser wollen, dass sie nach glBindTexture
  • bewegen, wie können Sie SPECIF y, wie viele Texturen wollen Sie mit glGenTextures() schaffen? Wenn Sie die Möglichkeit, für eine bestimmte Methode haben, verwenden Sie es bitte
  • GL_UNPACK_ROW_LENGTH wenn sie größer als 0 ist, definiert die Anzahl der Pixel in einer Reihe. Ich nehme dann Texture.SIZE nicht wirklich die Texturgröße ist aber die Dimension auf der einen Seite (128 in diesem Fall). Auf jeden Fall brauchen Sie nicht, dass zu setzen, Sie überspringen kann es
  • gesetzt GL_UNPACK_ALIGNMENT-4 nur, wenn Ihre Zeilenlänge ein Vielfaches davon ist.Die meiste Zeit Menschen setzen sie auf 1 vor dem Laden einer Textur, um irgendwelche Probleme zu vermeiden und dann wieder auf 4 einmal
  • letzten Argument glTexStorage3D wird erwartet, dass die Anzahl der Schichten sein, hoffe ich textures.size() besser zurückgibt, als die Größe (128x128)
  • glActiveTexture und glBindTexture innen prepareVbo sind nutzlos, sie sind Inspiration nicht Teil der vao
  • nicht varying in GLSL verwenden, es ist veraltet, wechseln Sie zu einem einfachen in out
  • Sie nehmen möchten von this sample
  • Sampler 0
  • Verwendung, sie geben Ihnen mehr Flexibilität
  • Verwendung Debug Output wenn vorhanden, sonst glGetError(), einige stille Fehler explizit durch die Wiedergabeausgang nicht sein kann
  • gesehen
  • Sie es prepareVbo genannt, aber sie darin sowohl vao und vbo Sie initialisieren
+0

Ich habe alle diese überprüft und das OP aktualisiert, aber die Texturen funktionieren immer noch nicht. Ein paar Anmerkungen: 'glGenTextures()' (ohne Argumente) impliziert, dass 1 Textur generiert wird. 'textures.size()' gibt die Anzahl der einzelnen Texturen in der Textur 'List' zurück, was auch die korrekte Anzahl der Ebenen ist. – caseif

+0

Gelöst - Ich hatte vergessen, den Aufruf 'glBindTexture' von' prepareVbo' zu entfernen. Wenn dies weggelassen wird, funktionieren die Texturen perfekt. Aus Neugier, warum würde das Aufrufen dieser Funktion das Programm brechen? – caseif

+0

Froh, dass Sie gelöst haben. Der einzige logische Grund, den ich mir vorstellen kann ist, dass irgendwo nach 'prepareVbo 'eine Funktion aufgerufen wird, die einen Parameter der Textur ändert, die an' GL_TEXTURE_2D_ARRAY' gebunden ist, also' GraphicsMain.TEXTURE_REGISTRY.atlasHandle'. Ps: Ich habe noch ein paar Hinweise hinzugefügt;) – elect