2012-10-23 23 views
5

vertex của tôi là,Issue với glBindBufferRange() OpenGL 3.1

uniform Block1{ vec4 offset_x1; vec4 offset_x2;}block1; 

out float value; 

in vec4 position; 

void main() 
{ 
    value = block1.offset_x1.x + block1.offset_x2.x;    

    gl_Position = position; 
} 

Mã Tôi đang sử dụng để vượt qua giá trị là:

GLfloat color_values[8];// contains valid values 

glGenBuffers(1,&buffer_object); 

glBindBuffer(GL_UNIFORM_BUFFER,buffer_object); 

glBufferData(GL_UNIFORM_BUFFER,sizeof(color_values),color_values,GL_STATIC_DRAW); 

glUniformBlockBinding(psId,blockIndex,0); 

glBindBufferRange(GL_UNIFORM_BUFFER,0,buffer_object,0,16);            

glBindBufferRange(GL_UNIFORM_BUFFER,0,buffer_object,16,16); 

Dưới đây là những gì tôi đang mong đợi được, để vượt qua 16 byte cho mỗi bộ đồng phục vec4. Tôi nhận được lỗi GL_INVALID_VALUE cho offset = 16, size = 16. Tôi bị nhầm lẫn với giá trị offset. Spec nói rằng nó tương ứng với "buffer_object".

Trả lời

8

alignment restriction cho UBO khi liên kết. Bất kỳ khoản bù trừ nào của glBindBufferRange/Base phải là bội số của GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT. Sự liên kết này có thể là bất cứ điều gì, vì vậy bạn phải truy vấn nó trước khi xây dựng mảng bộ đệm thống nhất của bạn. Điều đó có nghĩa là bạn không thể làm điều đó trực tiếp trong logic C++ biên dịch thời gian; nó phải là logic thời gian chạy.

Nói về truy vấn mọi thứ trong thời gian chạy, mã của bạn bị chia nhỏ khủng khiếp theo nhiều cách khác. Bạn đã không xác định một vòng loại bố trí cho khối đồng phục của bạn; do đó, mặc định được sử dụng: shared. Và bạn không thể sử dụng bố cục 'được chia sẻ * mà không cần querying the layout of each block's members from OpenGL.Bao giờ.

Nếu bạn đã thực hiện một truy vấn, bạn sẽ nhanh chóng phát hiện ra rằng khối thống nhất của bạn là ít nhất 32 byte về kích thước, không 16. Và vì bạn chỉ được cung cấp ở 16 byte phạm vi của bạn, hành vi không xác định (trong đó bao gồm các khả năng kết thúc chương trình chương trình).

Nếu bạn muốn có thể xác định đối tượng C/C++ ánh xạ chính xác đến định nghĩa khối đồng nhất, bạn cần sử dụng bố cục std140 và thực hiện theo các quy tắc bố trí std140 trong đối tượng C/C++ của bạn.

+0

Cảm ơn rất nhiều câu trả lời! Tôi không biết về GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT. Tôi đã truy vấn Block Uniform của mình với kích thước (32 byte), nhưng tôi nghĩ bằng cách chỉ định 16 byte, tôi có thể cung cấp dữ liệu cho thành phần thứ hai "vec4" của Uniform Block, mà tôi đoán là sai. Tôi nghĩ rằng tôi nên xử lý thành phần thứ hai "vec4" như một bộ đồng phục cá nhân. Chỉ cần thêm thông tin, nếu bố cục không phải là std140 thì bù đắp phải là bội số của GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT. Do đó, bộ đệm liên kết cũng phải là bội số của kích thước GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT. – maverick9888

+0

Tiếp theo - Do đó, bộ đệm liên kết cũng phải là bội số của kích thước GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT với điều kiện chúng ta đang sử dụng một đối tượng đệm duy nhất để cung cấp dữ liệu cho nhiều khối đồng nhất. – maverick9888

+0

"* nếu bố cục không phải là std140 thì bù đắp phải là bội số của GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT. *" Không; bù đắp * luôn * phải là bội số của điều đó. Bố cục 'std140' chỉ có nghĩa là bạn không phải truy vấn kích thước bộ đệm hoặc độ lệch của bất kỳ đồng phục riêng lẻ nào, bởi vì bạn có thể tính chúng trực tiếp. Bộ đệm có thể là bất kỳ kích thước nào bạn muốn, nhưng khi bạn liên kết một phạm vi, thì độ lệch phải là bội số của căn chỉnh đó. –