2013-03-26 146 views
8

我試圖在屬性傳遞到我的頂點着色器,但由於某種原因,它不斷給我一個-1第三屬性的位置我要問的OpenGL通過glGetAttribLocation來檢索(當)。目前它一直給我一個texCoord屬性-1,如果我切換texAttrib和colAttrib(切換代碼中的行),它會給我一個-1的顏色屬性而不是紋理,我不知道爲什麼?由於-1被傳遞給glVertexAttribPointer,我得到了1281 OpenGL錯誤:GL_INVALID_VALUE。glGetAttribLocation返回-1檢索現有着色器屬性

我的頂點着色器:

#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代碼:

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 

[..] 

回答

22

應停止使用glGetAttribLocationAssign each attribute a location,在鏈接程序之前或與明確的屬性位置一起使用glBindAttribLocation,如果可以的話。

這樣一來,如果編譯器優化的屬性遠(這是這裏發生了什麼,你的片段着色器可能不使用插值之一),你不會在意。您將像常規一樣使用標準約定來設置屬性索引。另外,您不必每次都想要用不同的程序渲染屬性位置;你知道它是什麼位置,因爲你分配它。

如果你不能/不會,那麼有什麼可以做的。如果你沒有真正使用它們,編譯器會優化掉屬性。你唯一能做的就是檢測它是否返回-1,而不是爲該屬性設置數組。

+1

我明白了。從一個教程中得知(也許他們引入了這樣的內容以保持簡單或某些東西?),該變量確實被編譯器優化,並且使用glBindAttribLocation解決了這個問題。謝謝! :) – 2013-03-26 15:12:08

+2

如果有人僅使用glBindAttribLocation進行分配,則它不適用於Radeon卡。您需要直接使用GLSL代碼中輸入聲明的佈局進行賦值。最近,我花了很多時間去弄清楚爲什麼一個代碼在nVidia上工作,而不是在Radeon卡上。看起來AMD的人有點忽略了glBindAttribLocation。 – 2014-02-07 05:54:21

+0

只需在Nvidia卡上注意,我的驅動程序忽略了glBindAttribLocation和GLSL中給出的顯式位置。只有當我確實使用頂點attrib時,glGetAttribLocation纔會返回-1。 – Balk 2017-03-08 00:58:48