Wie gehen Sie mit mehreren Texturen in einer OpenGL indiziert Pufferarray für die Verwendung mit einem Daten-Shader?

StackOverflow https://stackoverflow.com/questions/1678925

Frage

Ich versuche dieses Papier zu implementieren. Ich habe die meisten davon haben nach unten, aber der Teil über das Senden von beliebigen, nicht-geometrischen Daten an den Shader für die Verwendung bei der Bestimmung und geometrische Kanten Anzeige macht mir Probleme. Ich habe es geschafft, erfolgreich die meisten meiner Daten senden ganz gut mit, was ich kenne VBOs. Ich brauche aber eine große Menge an Daten zu senden, die die Verwendung von mehreren Texturkoordinaten erforderlich macht.

Ich habe implementiert bereits mehrere Varianten von dem, was ich glaube, die richtige Art und Weise der Einrichtung mehrere Sätze von Texturkoordinaten, und die Anweisungen vieler Forum Poster zu sein. Keine Lösungen arbeiten so weit.

Zusammenhang das Programm sendet 4 fast identische Kopien von einem Satz von 4 Ecken, 2 Normalvektoren, ein Schwimmer und eine ganzen Zahl (als Float abgelegt) für jeden eindeutigen Rand im Modell. Ich habe die Daten wie folgt aufgebaut:

v0 is stored in gl_Vertex (vec3)
v1 is stored in gl_Color (vec3)
v2 is stored in gl_MultiTexCoord0 (vec3)
v3 is stored in gl_MultiTexCoord1 (vec3)
n0 is stored in gl_Normal (vec3)
n1 is stored in gl_SecondaryColor (vec3)
r and i are stored in gl_MultiTexCoord2 (vec2)

Der einzige Unterschied zwischen den 4 Kopien ist der i-Wert, der bestimmen hilft, wie die Eckpunkte zu organisieren, ob und wann eine ziehbar Kante gefunden wird.

Wie Sie sehen können, ich brauche mindestens drei Texturkoordinaten. Ich konnte die erste Arbeits (gl_MultiTexCoord0) ganz gut bekommen, aber alle folgenden Texturkoordinaten, obwohl auf der Grafikkarte, erscheinen unkontrollierbares Verhalten zu haben, manchmal arbeiten, aber in der Regel nicht.

Meine Rendering-Funktion aussehen wie folgt verwendet:

void Mesh::RenderLineEdgesGPU()
{
    // Enable client state
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    // Turn on edge shader
    edgeProgram.Activate();

    // Link buffers
    // v0
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[0]);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    // v1
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[1]);
    glColorPointer(3, GL_FLOAT, 0, 0);

    // v2
    glClientActiveTextureARB(GL_TEXTURE0_ARB);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[2]);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);

    // v3
    glClientActiveTextureARB(GL_TEXTURE1_ARB);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[3]);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);

    // n0
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[4]);
    glNormalPointer(GL_FLOAT, 0, 0);

    // n1
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[5]);
    glSecondaryColorPointer(3, GL_FLOAT, 0, 0);

    // r and i
    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[6]);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    // Indicies
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, edgeMeshHandles[7]);

    // Draw
    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);

    // Turn off edge shader
    edgeProgram.Deactivate();

    // Disable client state
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

Dies war mein Original. Es funktioniert auf jeden Fall für v0, v1 und v2. Es scheint für „r und i“ zu arbeiten, aber das könnte eine Illusion sein. Ich habe nicht die Möglichkeit, noch n0 oder n1 zu testen. v3 geht definitiv nicht. Wie Sie sehen können, bin ich sie als Punkte zeichnen, die mir sagt, wenn sie dort oder nicht (über den Shader) sind. v0, v1 und v2 sind alle da. Der Versuch, das gleiche gilt für v3 Erträge entweder einen einzigen Punkt am Ursprung oder gar nichts zu tun.

an den Vorschlägen, Online Nach suchen, ist hier mein neues Setup:

void Mesh::RenderLineEdgesGPU()
{
    // Enable client state
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_SECONDARY_COLOR_ARRAY);

    // Turn on edge shader
    edgeProgram.Activate();

    // Link buffers
    // v0
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[0]);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    // v1
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[1]);
    glColorPointer(3, GL_FLOAT, 0, 0);

    // v2
    glClientActiveTextureARB(GL_TEXTURE0_ARB);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glEnable(GL_TEXTURE_2D);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[2]);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);

    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    // v3
    glClientActiveTextureARB(GL_TEXTURE1_ARB);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glActiveTextureARB(GL_TEXTURE1_ARB);
    glEnable(GL_TEXTURE_2D);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[3]);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);

    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    // n0
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[4]);
    glNormalPointer(GL_FLOAT, 0, 0);

    // n1
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[5]);
    glSecondaryColorPointer(3, GL_FLOAT, 0, 0);

    // r and i
    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[6]);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    // Indicies
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, edgeMeshHandles[7]);

    // Draw
    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);

    // Turn off edge shader
    edgeProgram.Deactivate();

    // Disable client state
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
}

Beachten Sie, wie ich die glEnableClientState / glDisableClientState Anrufe rund um den eigentlichen „Laden“ -Liste Koordinate jede Textur getan habe. Ich benutze auch glActiveTextureARB und glEnable(GL_TEXTURE_2D). Während ich glaube, ich könnte verstehen, warum glActiveTextureARB hier gebraucht wird, Leitbleche die andere mir. Nach dem GLSL Häufige Fehler , bist du eigentlich nicht glEnable(GL_TEXTURE_2D) verwenden wenn Sie Ihre eigenen Shadern machen, da die Verwendung von Shadern ohnehin diesen Aufruf ignoriert.

Das ist es also. Ich habe so weit gekommen, ohne irgendwelche Tutorials speziell zu finden in der Lage, Adressierung, wie nicht-Textur senden Koordinatendaten in Texturkoordinaten. Vielleicht, wenn jemand ein Tutorial über das weiß, würde mein Problem gelindert werden. Vielen Dank für Ihre Zeit!

War es hilfreich?

Lösung

glClientActiveTextureARB Änderungen, welche spezifische Texturkoordinateneinheit Anrufe folgenden glEnableClientState(GL_TEX_COORD_ARRAY) und glTexCoordPointer verändern wird.

glActiveTextureARB wirkt glEnable(GL_TEXTURE_2D), die, wie Sie erwähnt haben, brauchen Sie nicht für Shadern.

Wenn Sie genau auf den Code schauen, Kommissionierung nur die fünf Anrufe (und deren Äquivalent Disable), hier ist das, was Sie haben:

    glClientActiveTextureARB(GL_TEXTURE0_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glEnable(GL_TEXTURE_2D);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glClientActiveTextureARB(GL_TEXTURE1_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glActiveTextureARB(GL_TEXTURE1_ARB);
    glEnable(GL_TEXTURE_2D);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);
    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);

Ok, wir schon gesagt, dass glActiveTextureARB und glEnable nicht nützlich sind (übrigens, Sie aktivieren / deaktivieren GL_TEXTURE_2D ohne Unentschieden dazwischen, das ist nicht sinnvoll), so entfernen sie:

    glClientActiveTextureARB(GL_TEXTURE0_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glClientActiveTextureARB(GL_TEXTURE1_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);

Was jetzt zeichnet sich durch? 2 Ausgaben:

  • Sie Deaktivieren Sie Ihren Client-Zustand, bevor überhaupt die Ausführung Draw
  • Sie setzen nicht die Enable-Bit für texture2

Was sollten Sie schreiben? Etwas in diese Richtung: (Vorsicht, Sie werden die BindBuffer ruft zurück zu jedem Pointer Anruf hinzufügen müssen):

    // texture coord 0
    glClientActiveTextureARB(GL_TEXTURE0_ARB); // program texcoord unit 0
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); // enable array data to shader
    glTexCoordPointer(3, GL_FLOAT, 0, 0); // say what data

    // texture coord 1
    glClientActiveTextureARB(GL_TEXTURE1_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);

    // texture coord 2
    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);

    // done with those texcoord units, turn them off
    glClientActiveTextureARB(GL_TEXTURE0_ARB);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glClientActiveTextureARB(GL_TEXTURE1_ARB);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

Einige weiteren Kommentare zu BindBuffer: glBindBufferARB(GL_ARRAY_BUFFER_ARB,...) ist nicht von den glClientActiveTextureARB Mitleidenschaft gezogen werden, aber es hat den nächsten glTexCoordPointer Anruf beeinflussen. Im Wesentlichen, denken Sie an glClientActiveTextureARB und glBindBufferARB als zusätzliche Argumente zu glTexCoordPointer bereitstellt.

Das Letzte, was wollen Sie wahrscheinlich einige dieser VBOs in weniger Puffer zu gruppieren. Etwas für andere vielleicht Frage? (Hinweis, die zwei Argumente glTexCoordPointer müssen nicht 0 sein)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top