2013-04-04 39 views
21

Tôi đang thiết lập một bộ đệm đỉnh trong OpenGL, như thế này:Cách thích hợp để sửa đổi bộ đệm đỉnh OpenGL là gì?

int vboVertexHandle = glGenBuffers(); 
glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle); 
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_DYNAMIC_DRAW); 

Sau đó, nếu tôi muốn thêm hoặc loại bỏ các đỉnh để "vertexData", cách thích hợp để làm điều này là gì? Thậm chí có thể không? Tôi giả sử tôi không thể sửa đổi trực tiếp mảng mà không cần gửi lại nó tới GPU.

Nếu tôi thay đổi mảng vertexData, sau đó gọi này một lần nữa:

glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle); 
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_DYNAMIC_DRAW); 

... đó sẽ ghi đè lên bộ đệm cũ bằng dữ liệu mới của tôi? Hay tôi cũng phải xóa cái cũ? Có cách nào tốt hơn?

Trả lời

23

Kích thước của bất kỳ đối tượng bộ đệm OpenGL nào được đặt khi bạn gọi glBufferData. Đó là, OpenGL sẽ phân bổ số lượng bộ nhớ bạn chỉ định trong đối số thứ hai của glBufferData (không được liệt kê trong OP). Thực tế, nếu bạn gọi, ví dụ: glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_DYNAMIC_DRAW); OpenGL sẽ tạo bộ đệm gồm bufferSize byte của dữ liệu chưa được khởi tạo.

Bạn có thể tải bất kỳ lượng dữ liệu nào (tối đa kích thước của bộ đệm) bằng cách sử dụng glBufferSubData, glMapBuffer hoặc bất kỳ thói quen nào khác để truyền dữ liệu. Cách duy nhất để thay đổi kích thước bộ đệm là gọi glBufferData với kích thước mới cho cùng một id đệm (giá trị được trả lại từ glGenBuffers).

Điều đó nói rằng, bạn luôn có thể sử dụng một tập hợp con dữ liệu trong bộ đệm (sẽ giống như xóa đỉnh) và nếu bạn kết xuất bằng cách sử dụng glDrawElements, bạn có thể truy cập ngẫu nhiên các phần tử trong bộ đệm. Việc thêm các đỉnh vào một bộ đệm sẽ yêu cầu phân bổ một bộ đệm lớn hơn, và sau đó bạn cần phải tải lại tất cả dữ liệu trong bộ đệm.

+0

Bạn không muốn nói "dữ liệu chưa được khởi tạo" ở cuối đoạn đầu tiên của mình? – Ancurio

+0

@Ancurio Thật vậy tôi đã làm. Cảm ơn vì sự đúng đắn của bạn. – radical7

4

http://www.opengl.org/wiki/GLAPI/glBufferData

glBufferData tạo ra một lưu trữ dữ liệu mới cho đối tượng đệm hiện ràng buộc để nhắm mục tiêu. Mọi kho lưu trữ dữ liệu đã tồn tại trước đó sẽ bị xóa.

Điều này giải thích cuộc gọi đến glBufferData sẽ "phân bổ lại" dữ liệu, bộ đệm sẽ có kích thước mới. Tất cả dữ liệu cũ sẽ bị mất. Nếu bạn muốn ghi vào chỉ một phần của bộ đệm, hãy sử dụng glBufferSubData để thay thế.

http://www.opengl.org/wiki/GLAPI/glBufferSubData

Edit: glBufferSubData là chỉ khi bạn muốn thay thế dữ liệu; để thay đổi kích thước bộ đệm thay vào đó, bạn phải gọi glBufferData.

Ngoài ra, bạn không phải hủy bộ đệm trước và tạo bộ đệm mới. Hãy nhớ rằng GLuint chỉ là một 'con trỏ' của các loại cho OpenGL. Nó không phải là lưu trữ thực tế, do đó nó là hoàn toàn tốt đẹp để tái sử dụng cùng một 'con trỏ' (nếu bạn không xóa nó được tất nhiên).

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