2013-03-26 20 views
8

Tôi đang cố chuyển thuộc tính vào vertex shader nhưng vì lý do nào đó nó giữ cho tôi -1 trên vị trí thuộc tính thứ 3 tôi yêu cầu openGl truy xuất qua glGetAttribLocation (). Hiện tại nó giữ cho tôi một -1 cho thuộc tính texCoord và nếu tôi chuyển texAttrib và colAttrib xung quanh (chuyển đổi các dòng trong mã) nó mang lại cho tôi một -1 trên thuộc tính màu thay vì kết cấu và tôi không biết tại sao? Kể từ khi -1 đang được chuyển đến glVertexAttribPointer tôi nhận được lỗi 1281 OpenGL: GL_INVALID_VALUE.glGetAttribLocation trả về -1 khi truy xuất thuộc tính shader hiện có

vertex của tôi:

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

đang 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 

[..] 

Trả lời

22

Bạn nên ngừng sử dụng glGetAttribLocation. Assign each attribute a location, với glBindAttribLocation trước khi liên kết chương trình hoặc với vị trí thuộc tính rõ ràng, nếu có sẵn cho bạn.

Bằng cách đó, nếu trình biên dịch tối ưu hóa thuộc tính (đó là những gì đang xảy ra ở đây; trình đổ bóng phân đoạn của bạn có thể không sử dụng một trong các giá trị nội suy), bạn sẽ không quan tâm. Bạn sẽ thiết lập các mảng của mình như bình thường, sử dụng một quy ước chuẩn cho các chỉ mục thuộc tính. Ngoài ra, bạn sẽ không phải tiếp tục hỏi vị trí thuộc tính là gì mỗi khi bạn muốn kết xuất với một chương trình khác; bạn biết vị trí của nó là vì bạn đã gán nó.

Nếu bạn không thể/không, thì bạn không thể làm gì cả. Trình biên dịch sẽ tối ưu hóa các thuộc tính đi nếu bạn không thực sự sử dụng chúng. Điều duy nhất bạn có thể làm là phát hiện rằng nó trả về -1 và không thiết lập mảng cho thuộc tính đó.

+1

Tôi hiểu. Có được từ một hướng dẫn (có thể họ giới thiệu nó như thế để giữ cho mọi thứ đơn giản hay gì đó?), Biến thực sự được optmized bởi trình biên dịch và sử dụng glBindAttribLocation giải quyết vấn đề. Cảm ơn! :) –

+2

Nếu ai đó chỉ định sử dụng glBindAttribLocation, nó sẽ không hoạt động trên thẻ Radeon. Bạn sẽ cần chỉ định trực tiếp bằng cách sử dụng bố cục trên khai báo đầu vào trong mã GLSL. Gần đây, tôi đã mất rất nhiều thời gian cố gắng tìm ra lý do tại sao một mã đã làm việc trên một nVidia và không phải trên một thẻ Radeon. Có vẻ như AMD guys kinda bỏ qua glBindAttribLocation. –

+0

Chỉ cần lưu ý trên thẻ Nvidia, Trình điều khiển của tôi đã bỏ qua cả glBindAttribLocation và vị trí rõ ràng được đưa ra trong GLSL. Chỉ khi tôi thực sự đảm bảo sử dụng các attrib đỉnh sẽ glGetAttribLocation không trở lại -1. – Balk

Các vấn đề liên quan