Come si fa a gestire texture multiple in un OpenGL indicizzato matrice di memorizzazione temporanea per l'utilizzo con un data-Shader?

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

Domanda

Sto cercando di implementare questo documento . Sono hanno la maggior parte di esso verso il basso, ma la parte che riguarda l'invio di dati arbitrari, non geometriche per lo shader per l'uso nella determinazione e la visualizzazione di bordi geometrici mi sta causando problemi. Sono riuscito a trasmettere con successo la maggior parte dei miei dati più che bene con quello che so di VBOs. Tuttavia, ho bisogno di inviare una grande quantità di dati, che richiede l'utilizzo di più coordinate di texture.

Ho già implementato diverse varianti di quello che ritengo essere il modo corretto di creare più set di coordinate di texture, e seguito le istruzioni di molti manifesti forum. Non ci sono soluzioni funzionano finora.

Per contesto, il programma sta trasmettendo 4 copie quasi identiche di un set di 4 vertici, 2 vettori ortogonali, un galleggiante, e un intero (memorizzato come float) per ciascun bordo unico nel modello. Ho disposto i dati in questo modo:

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)

L'unica differenza tra le 4 copie è il valore i, che aiuta a determinare come organizzare i vertici se e quando viene trovato un bordo disegnabile.

Come potete vedere, ho bisogno di almeno 3 coordinate di texture. Sono stato in grado di ottenere il primo lavoro (gl_MultiTexCoord0) bene, ma qualsiasi seguenti coordinate di texture, anche se sulla scheda grafica, sembrano avere un comportamento incontrollabile, a volte di lavoro, ma di solito non.

La mia funzione di rendering utilizzata per assomigliare a questo:

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

Questa era la mia originale. Funziona sicuramente per v0, v1, v2 e. Sembra di lavorare per "R and I", ma che potrebbe essere un'illusione. Non ho la possibilità di testare n0 o n1 ancora. v3 sicuramente non funziona. Come potete vedere, io li sto disegnando come punti, che mi dice se ci sono o no (tramite lo shader). v0, v1, v2 e sono tutti lì. Il tentativo di fare lo stesso per i rendimenti v3 sia un unico punto all'origine o niente del tutto.

Dopo aver guardato suggerimenti on-line, ecco il mio nuovo 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);
}

Notate come ho fatto le chiamate glEnableClientState / glDisableClientState tutto il "carico" effettivo di ogni texture lista di coordinate. Io uso anche glActiveTextureARB e glEnable(GL_TEXTURE_2D). Mentre penso che potrei capire perché è necessario qui glActiveTextureARB, l'altro mi sconcerta. Secondo il GLSL pagina Errori comuni , non dovresti usare glEnable(GL_TEXTURE_2D) quando si fanno le proprie shader, dal momento che l'uso di shaders ignora questa chiamata in ogni caso.

Quindi il gioco è fatto. Ho ottenuto fino a questo punto, senza riuscire a trovare alcun tutorial specificamente rivolte come inviare coordinare non consistenza dei dati in coordinate di texture. Forse, se qualcuno conosce un tutorial su questo, il mio problema sarebbe alleviato. Grazie per il tuo tempo!

È stato utile?

Soluzione

modifiche glClientActiveTextureARB quale unità coordinate struttura specifica seguente chiamate glEnableClientState(GL_TEX_COORD_ARRAY) e glTexCoordPointer altererà.

glActiveTextureARB colpisce glEnable(GL_TEXTURE_2D), che, come lei ha ricordato, non è necessario per shaders.

Se si guarda il codice da vicino, raccogliendo solo i 5 chiamate (e il loro equivalente Disabilita), qui è quello che hai:

    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, abbiamo già detto che glActiveTextureARB e glEnable non sono utili (a proposito, si abilita / disabilita GL_TEXTURE_2D senza pareggio in mezzo, che non è utile), in modo da rimuoverli:

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

Quello che distingue la società? 2 problemi:

  • si disattiva il tuo stato cliente prima ancora di eseguire Draw
  • non si imposta il bit Attiva per texture2

Che cosa si dovrebbe scrivere? Qualcosa del genere: (Attenzione, è necessario aggiungere il BindBuffer richiama a ogni chiamata puntatore):

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

Alcuni altri commenti su BindBuffer: glBindBufferARB(GL_ARRAY_BUFFER_ARB,...) non ottenere colpiti dal glClientActiveTextureARB, ma fa influenzano la chiamata glTexCoordPointer successivo. In sostanza, pensare glClientActiveTextureARB e glBindBufferARB a fornire argomenti in più per glTexCoordPointer.

L'ultima cosa, che probabilmente vuole gruppo alcuni di questi VBOs in meno buffer. Qualcosa per un'altra domanda forse? (Suggerimento, i 2 argomenti di glTexCoordPointer non devono essere 0)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top