2013-03-26 5 views
8

Ich versuche, Attribute an meinen Vertex-Shader zu übergeben, aber aus irgendeinem Grund gibt es mir eine -1 am dritten Attributort. Ich möchte openGl über glGetAttribLocation abrufen (). Momentan gibt es mir immer noch eine -1 für das texCoord Attribut und wenn ich den texAttrib und colAttrib umschalte (die Zeilen im Code wechseln), gibt es mir eine -1 auf der Farbeigenschaft statt der Textur und ich habe keine Ahnung warum? Da eine -1 an glVertexAttribPointer übergeben wird, erhalte ich den 1281 OpenGL-Fehler: GL_INVALID_VALUE.glGetAttribLocation gibt -1 beim Abrufen des vorhandenen Shader-Attributs zurück

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

OpenGL-Code:

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 

[..] 

Antwort

22

sollten Sie mit glGetAttribLocation stoppen. Assign each attribute a location, entweder mit glBindAttribLocation vor dem Verknüpfen des Programms oder mit expliziten Attributpositionen, wenn diese Ihnen zur Verfügung stehen.

Auf diese Weise, wenn der Compiler ein Attribut entfernt (was ist hier passiert; Ihr Fragment-Shader verwendet wahrscheinlich nicht einen der interpolierten Werte), ist es Ihnen egal. Sie richten Ihre Arrays wie gewohnt ein, indem Sie eine Standardkonvention für Attributindizes verwenden. Außerdem müssen Sie nicht jedes Mal fragen, was ein Attributspeicherort ist, wenn Sie mit einem anderen Programm rendern möchten. Sie wissen, welcher Ort ist es, weil Sie es zugewiesen haben.

Wenn Sie nicht können/nicht, dann gibt es nichts, was Sie tun können. Der Compiler optimiert Attribute, wenn Sie sie nicht verwenden. Das einzige, was Sie tun können, ist zu erkennen, dass es -1 zurückgibt und das Array für dieses Attribut nicht eingerichtet.

+1

Ich sehe. Haben Sie das aus einem Tutorial (vielleicht haben sie es eingeführt, um die Dinge einfach zu halten oder so?), Wurde die Variable tatsächlich vom Compiler optimiert und die Verwendung von glBindAttribLocation löst das Problem. Vielen Dank! :) –

+2

Wenn jemand nur glBindAttribLocation zugewiesen hat, funktioniert es nicht auf Radeon-Karten. Sie müssen die Zuordnung direkt über das Layout der Eingabedeklaration im GLSL-Code vornehmen. Vor kurzem habe ich viel Zeit verloren, um herauszufinden, warum ein Code auf einem nVidia funktioniert und nicht auf einer Radeon-Karte. Es scheint, AMD Jungs irgendwie glBindAttribLocation ignoriert. –

+0

Um auf einer Nvidia-Karte zu notieren, ignorierte Mein Treiber sowohl glBindAttribLocation als auch die explizite Position in GLSL. Nur wenn ich tatsächlich die Verwendung des Vertex-Attributs sicherstellte, würde glGetAttribLocation nicht -1 zurückgeben. – Balk

Verwandte Themen