2013-03-26 40 views
8

Vertex shader'ımdaki öznitelikler arasında geçiş yapmaya çalışıyorum ama bir nedenden dolayı glGetAttribLocation aracılığıyla almak için openGl sorduğum 3. öznitelik konumu üzerinde bana bir -1 veriyor.). Şu anda texCoord özniteliği için bir -1 verir ve ben texAttrib ve colAttrib değiştirirseniz (kod satırları arasında geçiş) bana doku yerine renk özelliği -1 verir ve neden hiçbir fikrim yok? Bir -1 glVertexAttribPointer'a iletildiğinden 1281 OpenGL hatası alıyorum: GL_INVALID_VALUE.glGetAttribLocation, varolan shader özniteliği alınırken -1 değerini döndürür

Benim tepe tarayıcı:

#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 kodu:

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 

[..] 

cevap

22

Sen glGetAttribLocation kullanmayı durdurmak gerekir. Assign each attribute a location, ya programı bağlamadan önce ya da açık öznitelik konumları ile birlikte glBindAttribLocation ile kullanılabilir.

Bu şekilde, derleyici bir özniteliği uzaklaştırarak optimize eder (burada olan şeydir; parça gölgelendiriciniz muhtemelen enterpolasyonlu değerlerden birini kullanmaz), umurunda değilsiniz. Dizilerinizi, özellik indisleri için standart bir sözleşme kullanarak normal olarak kurarsınız. Ayrıca, farklı bir programla oluşturmak istediğiniz her zaman bir özellik konumunun ne olduğunu sormak zorunda kalmazsınız; numaralı telefonu numaralı telefondan öğrenebilirsiniz.

Yapamazsanız/yapamazsanız, yapabileceğiniz hiçbir şey yoktur. Derleyici aslında onları kullanmıyorsanız özniteliklerini optimize eder. Yapabileceğiniz tek şey, -1 döndürdüğünü ve bu öznitelik için diziyi ayarlamadığını saptamaktır.

+1

Görüyorum. Bunu bir öğreticiden aldım (belki de işleri basitleştirmek için böyle bir şey yaptılar mı?), Değişken gerçekten de derleyici tarafından optimize edildi ve glBindAttribLocation kullanımı sorunu çözdü. Teşekkürler! :) –

+2

Birisi sadece glBindAttribLocation kullanarak atarsa, Radeon kartlarında çalışmayacaktır. GLSL kodundaki giriş bildirimi üzerindeki düzeni kullanarak doğrudan atamanız gerekecektir. Son zamanlarda, bir kodun nVidia üzerinde neden çalıştığını ve bir Radeon kartında olmadığını anlamaya çalışırken çok zaman kaybettim. AMD adamları glBindAttribLocation'ı göz ardı etmiş gibi görünüyor. –

+0

Sadece bir Nvidia kartına dikkat çekmek için, Sürücüm glBindAttribLocation ve GLSL'de verilen açık konumu göz ardı etti. Yalnızca verttex özniteliğinin kullanılmasını sağladığımda glGetAttribLocation -1 döndürmez. – Balk