Chúng là cùng một chức năng đang được sử dụng theo hai cách khác nhau. Tôi giải thích lý do tại sao nó hoạt động theo cách này, nhưng bạn sẽ không quan tâm, và nó cho những lý do rất ngu ngốc và không liên quan.
Điều quan trọng là những gì họ đang làm. Và những gì họ đang làm phụ thuộc vào một cái gì đó mà bạn không hiển thị: những gì được ràng buộc để GL_ARRAY_BUFFER
.
Xem, hành vi của glVertexAttribPointer
thay đổi tùy thuộc vào điều đó. Nếu không có đối tượng đệm nào bị ràng buộc với GL_ARRAY_BUFFER
khi bạn gọi glVertexAttribPointer
, thì hàm sẽ giả định rằng giá trị cuối cùng là một con trỏ (giống như tên của hàm cho biết: glVertexAttrib Pointer). Cụ thể, nó là một con trỏ vào bộ nhớ thuộc sở hữu của khách hàng.
Khi đến lúc hiển thị, dữ liệu thuộc tính đỉnh sẽ đến từ con trỏ được cung cấp trước đó. Do đó, ví dụ thứ hai chỉ là sử dụng một mảng dữ liệu khách hàng, được khai báo theo kiểu C chuẩn, làm dữ liệu nguồn. Không có đối tượng đệm nào có liên quan.
Lưu ý: cấu hình cốt lõi của OpenGL 3.1+ đã loại bỏ khả năng sử dụng bộ nhớ máy khách; ở đó, bạn phải sử dụng các đối tượng đệm, như được giải thích bên dưới.
Nếu đối tượng đệm bị ràng buộc ở GL_ARRAY_BUFFER
khi gọi glVertexAttribPointer
thì có điều gì đó đặc biệt xảy ra. OpenGL sẽ giả vờ rằng con trỏ (đó là những gì tham số cuối cùng là như xa như C/C + + là có liên quan) thực sự là một bù đắp byte vào bộ đệm bị ràng buộc để GL_ARRAY_BUFFER
. Nó sẽ chuyển đổi con trỏ thành một số nguyên và sau đó lưu trữ số nguyên đó bù đắp và đối tượng bộ đệm hiện đang bị ràng buộc để GL_ARRAY_BUFFER
.
Vì vậy, mã trên mất 3*sizeof(GLfloat)
, độ lệch byte và chuyển đổi thành con trỏ. OpenGL sẽ lấy con trỏ và chuyển đổi nó trở lại thành một offset, mang lại 3*sizeof(GLfloat)
một lần nữa.
Khi đến lúc hiển thị, OpenGL sau đó sẽ đọc từ đối tượng đệm đã cho trước đó, sử dụng bù trừ đã cho trước đó.
Ví dụ đầu tiên đặt dữ liệu đỉnh vào đối tượng đệm trong bộ nhớ GPU. Ví dụ thứ hai đặt dữ liệu đỉnh trong một mảng C/C++ thông thường, trong bộ nhớ CPU.
Giải thích hoàn hảo! Cảm ơn bạn. - Bạn lấy thông tin này ở đâu? Tôi không thể tìm thấy tài liệu về điều đó. - những gì bạn nói về OpenGL3.1 và không sử dụng ứng dụng bộ nhớ cũng hợp lệ cho OpenGLEs 2.0? – MatterGoal
@MatterGoal: Nói chung, các ứng dụng luôn sử dụng bộ nhớ phía máy khách hoặc các đối tượng đệm. Vì vậy, không ai cần phải nói về sự khác biệt giữa chúng. Và phần lớn tài liệu OpenGL trên máy tính để bàn đã chuyển sang hành vi hồ sơ cốt lõi, vì vậy nó cũng không nói về nó. Nhưng nó ở ngay trong [trang hướng dẫn cho GL ES] (http://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttribPointer.xml). Chỉ cần đọc đoạn thứ hai của mô tả. –
@MatterGoal: Nó cũng được giải thích trong câu trả lời này (http://stackoverflow.com/a/5402762/734069) trong một câu hỏi liên quan. –