2013-03-26 11 views
8

Sto provando a passare attributi al mio vertex shader ma per qualche motivo continua a darmi un -1 sulla posizione del terzo attributo, sto chiedendo a openGl di recuperare tramite glGetAttribLocation (). Attualmente continua a darmi un -1 per l'attributo texCoord e se cambio texAttrib e colAttrib in giro (cambiando le righe nel codice) mi dà un -1 sulla proprietà color invece della texture e non ho idea del perché? Poiché un -1 viene passato a glVertexAttribPointer, ottengo l'errore OpenGL 1281: GL_INVALID_VALUE.glGetAttribLocation restituisce -1 quando si recupera l'attributo shader esistente

mio vertex shader:

#version 150 

in vec3 position; 
in vec3 color; 
in vec2 texcoord; 

out vec3 Color; 
out vec2 Texcoord; 

void main() 
{ 
    Color = color; 
    Texcoord = texcoord; 
    gl_Position = vec4(position.x, position.y, position.z, 1.0); 
} 

codice OpenGL:

basicShader.Use(); 

// Buffers and shaders 
glGenVertexArrays(1, &vao); 
glBindVertexArray(vao); 

glGenBuffers(1, &vbo); 
// Make it active vbo 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 

// Build basic triangle 
float vertices[] = { 
    // position   // color   // textures 
    -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left 
    0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right 
    0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right 
    -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f// Bottom-left 
}; 
GLuint elements[] = { 
    0, 1, 2, 
    2, 3, 0 
}; 

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

GLint posAttrib = glGetAttribLocation(basicShader.shaderProgram, "position"); 
glEnableVertexAttribArray(posAttrib); // Enable attribute first before specifiying attributes 
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), 0); // 6 float sizes is every new vertex 

GLint colAttrib = glGetAttribLocation(basicShader.shaderProgram, "color"); 
glEnableVertexAttribArray(colAttrib); 
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); // same for color + offset 

GLint texAttrib = glGetAttribLocation(basicShader.shaderProgram, "texcoord"); // Returns -1 
glEnableVertexAttribArray(texAttrib); 
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); // 6 offset from beginning 

[..] 

risposta

22

Si dovrebbe smettere di usare glGetAttribLocation. Assign each attribute a location, con glBindAttribLocation prima di collegare il programma o con posizioni di attributo esplicite, se disponibile.

In questo modo, se il compilatore ottimizza un attributo di distanza (che è ciò che sta accadendo qui, il frammento shader probabilmente non usa uno dei valori interpolati), non ti interessa. Imposterai gli array normalmente, utilizzando una convenzione standard per gli indici degli attributi. Inoltre, non dovrai continuare a chiedere quale sia la posizione di un attributo ogni volta che desideri eseguire il rendering con un programma diverso; è conoscere il numero in quale posizione è stato assegnato.

Se non puoi/non vuoi, allora non c'è niente che tu possa fare. Il compilatore ottimizzerà gli attributi se non li stai effettivamente utilizzando. L'unica cosa che puoi fare è rilevare che restituisce -1 e non imposta la matrice per quell'attributo.

+1

Vedo. Ottenuto da un tutorial (forse l'hanno introdotto in questo modo per mantenere le cose semplici o qualcosa del genere?), La variabile è stata effettivamente ottimizzata dal compilatore e l'utilizzo di glBindAttribLocation risolve il problema. Grazie! :) –

+2

Se qualcuno assegna solo usando glBindAttribLocation, non funzionerà con le schede Radeon. Sarà necessario assegnare direttamente utilizzando il layout sulla dichiarazione di input nel codice GLSL. Recentemente, ho perso un sacco di tempo cercando di capire perché un codice stava lavorando su un nVidia e non era su una scheda Radeon. Sembra che i ragazzi di AMD abbiano ignorato glBindAttribLocation. –

+0

Solo per prendere nota su una scheda Nvidia, il mio driver ha ignorato sia glBindAttribLocation sia la posizione esplicita fornita in GLSL. Solo quando ho effettivamente assicurato l'utilizzo dell'attributo vertice glGetAttribLocation non restituisce -1. – Balk

Problemi correlati