cuốn sách gpt4 ai đã làm

Bộ đệm của OpenGL hoạt động như thế nào?

In lại Tác giả: Taklimakan Thời gian cập nhật: 2023-11-03 01:36:56 25 4
mua khóa gpt4 Nike

Tôi không hiểu bộ đệm của OpenGL hoạt động như thế nào. Tôi đã học OpenGL thông qua Sách đỏ OpenGL phiên bản thứ 8. Ví dụ: tôi có một mảng vị trí, một mảng màu và một mảng chỉ mục:

const tĩnh GLfloat dải_position[] =
{
-4.0f, 0.0f, -1.0f, 1.0f, //0
-3,5f, -1,0f, -1,0f, 1,0f, //1
-3.0f, 0.0f, -1.0f, 1.0f, //2
-2,5f, -1,0f, -1,0f, 1,0f, //3
-2.0f, 0.0f, -1.0f, 1.0f, //4
-1,5f, -1,0f, -1,0f, 1,0f, //5
-1.0f, 0.0f, -1.0f, 1.0f, //6
-0,5f, -1,0f, -1,0f, 1,0f, //7
0,0f, 0,0f, -1,0f, 1,0f //8
};
const tĩnh GLfloat dải_colors[] =
{
1.0f, 1.0f, 1.0f, 1.0f,
1,0f, 1,0f, 0,0f, 1,0f,
1,0f, 0,0f, 1,0f, 1,0f,
1,0f, 0,0f, 0,0f, 1,0f,
0,0f, 1,0f, 1,0f, 1,0f,
0,0f, 1,0f, 0,0f, 1,0f,
0,0f, 0,0f, 1,0f, 1,0f,
1,0f, 0,0f, 1,0f, 1,0f,
1,0f, 1,0f, 0,0f, 1,0f,
};

const tĩnh GLushort dải_indices[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8
};

rất tốt. Sau đó tôi tạođối tượng mảng đỉnh如下:

    GLuint vao[1] // đối tượng mảng đỉnh
glGenVertexArrays(1, vao);
glBindVertexArray(vao[0]);

Theo hiểu biết của tôi, tham số đầu tiên (Kích cỡ GL) là số vị trí của mảng (hoặc tọa độ đỉnh của một đối tượng my). Sau đó tôi tạo Bộ đệm mảng phần tử 如下:

GLuint ebo[1] // đối tượng bộ đệm phần tử
glGenBuffers(1, ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]);
glBufferData(
GL_ELEMENT_ARRAY_BUFFER,
sizeof(strip_indices),
dải_indices,
GL_STATIC_DRAW
);

Sau đó tôi tạođối tượng đệm đỉnh如下:

GLuint vbo[1] // đối tượng bộ đệm đỉnh
glGenBuffers(1, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(strip_position) + sizeof(strip_colors),
NULL,
GL_STATIC_DRAW
);
glBufferSubData(
GL_ARRAY_BUFFER,
0, // bù
sizeof(strip_position), // ngày kích thước
dải_vị trí // dữ liệu
);
glBufferSubData(
GL_ARRAY_BUFFER,
sizeof(strip_position), // offset
sizeof(strip_colors), //dữ liệu kích thước
dải_colors // dữ liệu
);

Tiếp theo tôi gọi glVertexAttribPointer() 如下:

glVertexAttribPointer(
0, //chỉ mục
4, // kích thước
GL_FLOAT, // gõ
GL_FALSE, // chuẩn hóa
0, // sải bước
NULL // con trỏ
);
glVertexAttribPointer(
1,
4,
GL_FLOAT,
GL_FALSE,
0,
(const GLvoid*)sizeof(strip_position)
);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

Chức năng này làm gì? (glVertexAttribPointer()glEnableVertexAttribArray())
ĐƯỢC RỒI Tôi đã hoàn tất việc khởi tạo dữ liệu của mình. Bây giờ tôi có thể vẽ nó như sau:

glBindVertexArray(vao[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]);
glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_SHORT, NULL);

OpenGL hiểu như thế nào, bộ đệm nào cần được sử dụng và nó ở đâu? Từ "ràng buộc" có ám chỉ một mối quan hệ không? Đó là, một cái gì đó kết hợp với một cái gì đó? Nếu tôi muốn hiển thị hai đối tượng thì làm cách nào? Ví dụ: tôi có hai mảng vị trí, hai mảng vị trí và hai mảng chỉ mục?

const tĩnh GLfloat TWOstrip_colors[] =
{
1.0f, 1.0f, 1.0f, 1.0f,
1,0f, 1,0f, 0,0f, 1,0f,
1,0f, 0,0f, 1,0f, 1,0f,
1,0f, 0,0f, 0,0f, 1,0f,
0,0f, 1,0f, 1,0f, 1,0f,
0,0f, 1,0f, 0,0f, 1,0f,
0,0f, 0,0f, 1,0f, 1,0f,
1,0f, 0,0f, 1,0f, 1,0f,
1,0f, 1,0f, 0,0f, 1,0f
};
const tĩnh GLfloat TWOstrip_colors[] =
{
1.0f, 1.0f, 1.0f, 1.0f,
1,0f, 1,0f, 0,0f, 1,0f,
1,0f, 0,0f, 1,0f, 1,0f,
1,0f, 0,0f, 0,0f, 1,0f,
0,0f, 1,0f, 1,0f, 1,0f,
0,0f, 1,0f, 0,0f, 1,0f,
0,0f, 0,0f, 1,0f, 1,0f,
1,0f, 0,0f, 1,0f, 1,0f,
1,0f, 1,0f, 0,0f, 1,0f,
};

const tĩnh GLushort TWOstrip_indices[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8
};

Việc này được thực hiện như thế nào?

câu trả lời hay nhất

OpenGL có một thứ gọi là对象 ý tưởng. Đây không phải là các mô hình hoặc đối tượng hình học, mà là sự đóng gói của trạng thái bên trong. Nếu bạn quen thuộc với对象 lập trình và có thể coi các đối tượng OpenGL của C++ STL là các thể hiện của lớp.

gọi glGenBuffers(đếm, out_names) có thể được hiểu đại khái là một cái gì đó như

std::map đối tượng đệm;

glGenBuffers(số lượng GLuint, std::vector *out_names)
{
out_names->thay đổi kích thước(đếm);
for(int i=0; i < count; i++) {
Tên GLuint = get_next_free_handle_ID();
đối tượng đệm[tên] = NULL;
out_names.set(i, name);
}
}

Vì vậy, những gì nó làm là giữ lại ID điều khiển (OpenGL gọi chúng là tên) và phân bổ một vị trí cho nó trong ánh xạ bên trong giữa điều khiển và con trỏ đối tượng bộ đệm.

gọi glBindBuffer thực sự tạo ra đối tượng đệm, đại loại như

glBindBuffer(mục tiêu GLenum, tên GLuint)
{

openglobject *objinstance = NULL;

nếu( tên != 0 ) {
if( !bufferobjects.has_key(name) ) {
push_openglerror(INVALID_NAME);
return;
}

objinstance = bufferobjects[name];

if( NULL == bufferobjects[name] ) {
chuyển đổi (mục tiêu) {
trường hợp GL_ARRAY_BUFFER:
objinstance = break OpenGLArrayBuffer mới;

trường hợp GL_ELEMENT_ARRAY_BUFFER:
objinstance = break OpenGLElementArrayBuffer mới;

/* ... vân vân */

default:
push_openglerror(INVALID_TARGET); trả về;
}

bufferobjects[name] = phản đối;

}
}
}

if( objinstance != NULL && target_of(objinstance) != target ) {
opengl_pusherror(INVALID_TARGET);
}

chuyển đổi (mục tiêu) {
trường hợp GL_ARRAY_BUFFER:
/* đây sẽ là một hàm tĩnh của cài đặt lớp con
* con trỏ cá thể đơn toàn cục
*/
OpenGLArrayBuffer::make_current(objinstance);
phá vỡ;

/* ... vân vân */
}
}

Tôi nghĩ bạn có thể thấy điều này đang diễn ra: Bộ đệm mục tiêu Chỉ định loại lớp con của phiên bản bạn đang sử dụng và các thành viên tĩnh của nó.

glBufferData Bộ nhớ dành cho đối tượng cụ thể sau đó thực sự được phân bổ và có thể được khởi tạo bằng nội dung của bộ đệm mà bạn đã truyền cho nó. glBufferSubData Chỉ cần sao chép dữ liệu vào bộ nhớ trong.

Chỉ có rất nhiều đối tượng đệm (có một số).


phần khác làđối tượng mảng đỉnh. Đây là những đối tượng OpenGL đặc biệt được tìm thấy trongThuộc tính đỉnhbộ đệm mảng Để thiết lập mối liên kết giữa các đối tượng, các thuộc tính đỉnh được yêu cầu chuyển dữ liệu trên mỗi đỉnh tới trình đổ bóng dựa trên chỉ mục thuộc tính.

Khi bạn gọi glGenVertexArray, điều này sẽ xảy ra:

std::map vertexarrayobjects;

glGenVertexArrays(số lượng GLuint, std::vector *out_names)
{
out_names->thay đổi kích thước(đếm);
for(int i=0; i < count; i++) {
Tên GLuint = get_next_free_handle_ID();
vertexarrayrobjects[name] = NULL;
out_names.set(i, name);
}
}

Trông quen quen phải không? Sự khác biệt duy nhất là các cấu trúc ánh xạ khác nhau được sử dụng. glBindVertexArray Thực hiện phân bổ cá thể, v.v.

gọi ngay bây giờ glEnableVertexThuộc tínhglVertexAttribCon trỏ có thể hình dung như sau:

glEnableVertexAttribution(GLuint idx)
{
((OpenGLVertexArrayObject*)currentvertexarray)->add_attribute(idx);
}

glVertexAttribPointer(GLuint idx, ..., void *ptr)
{
((OpenGLVertexArrayObject*)currentvertexarray)->bind_attribute(
idx,
OpenGLArrayBuffer::get_current(),
(tắt_t)ptr );
}

Được rồi, phần cuối cùng cần một số lời giải thích. Truyền con trỏ tới glVertexAttribPointer là một vấn đề kế thừa từ OpenGL-1.1, trong đó không có đối tượng bộ đệm OpenGL và thay vào đó trỏ trực tiếp vào bộ nhớ của chương trình. Sau đó, các đối tượng bộ đệm được giới thiệu, không yêu cầu con trỏ khi bị ràng buộc mà thay vào đó là các độ lệch có kích thước byte. Vì vậy, các nhà phát triển OpenGL đã đi vào con đường bẩn thỉu và nói dối trình biên dịch. Tôi đã giải thích chi tiết trong câu trả lời của mình cho câu hỏi "Kết quả của NULL + int là gì?"

Xin lưu ý rằng OpenGL-4 giới thiệu API mới, mạnh mẽ và linh hoạt hơn để tạo thuộc tính VAO ←→ Liên kết VBO.

Giới thiệu về c++ - Bộ đệm của OpenGL hoạt động như thế nào? , chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/20517961/

25 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress