OpenGL: как использовать buffer_objects для рисования - PullRequest
2 голосов
/ 20 января 2011

На странице 103 RedGL Redbook они приводят пример (пример 2-17) о том, как использовать buffer_object для рисования чего-либо.

#define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))


GLuint buffers[NUM_BUFFERS];

GLfloat vertices[][3] = {
{ -1.0, -1.0, -1.0 },
{ 1.0, -1.0, -1.0 },
{ 1.0, 1.0, -1.0 },
{ -1.0, 1.0, -1.0 },
{ -1.0, -1.0, 1.0 },
{ 1.0, -1.0, 1.0 },
{ 1.0, 1.0, 1.0 },
{ -1.0, 1.0, 1.0 }
};

GLubyte indices[][4] = {
{ 0, 1, 2, 3 },
{ 4, 7, 6, 5 },
{ 0, 4, 5, 1 },
{ 3, 2, 6, 7 },
{ 0, 3, 7, 4 },
{ 1, 5, 6, 2 }
};

glGenBuffers(NUM_BUFFERS, buffers);
//Generate NUM_BUFFERS of buffers and put them in buffers array.

glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTICES]);
//bind buffers


glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//allocate space for buffers


glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));

Здесь мы предполагаем иметь точку на массив дляукажите, в каком массиве мы найдем данные.Тогда это должен быть указатель на некоторый адрес памяти на сервере?

Я просто не понимаю, что BUFFER_OFFSET (0).

Означает ли это, что на сервере всегда есть только один Vertex_Arrayпрограмма выберет этот адрес автоматически?BUFFER_OFFSET (0) просто говорит вам, с чего начать в этом массиве ?????????

glEnableClientState(GL_VERTEX_ARRAY);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[INDICES]);

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));

То же самое здесь.Предполагается дать адрес по последнему параметру.Но я не вижу, чтобы BUFFER_OFFSET (0) был полезным адресом.

Ответы [ 3 ]

2 голосов
/ 20 января 2011
glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(0))

Последний параметр не указывает на какой-либо адрес памяти.Во всяком случае, не напрямую.

В нем говорится "используйте смещение 0 текущего ограниченного буфера".

Вы позвонили

glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTICES]);

Итак, соединение этих двух вызовов (bind first, VertexPointer second) по существу означает «использовать адрес буфера, дескриптор которого равен buffer [VERTICES], смещение на 0».

1 голос
/ 20 января 2011

Смещение становится полезным, когда у вас есть чередующиеся данные или данные в буфере, который не плотно упакован.Шаг с нуля предполагает плотно упакованные данные.Смещение нуля говорит OpenGL, что ваши данные начинаются сразу.Пример может быть следующим.Используя ваш текущий метод, вам понадобится отдельный буфер для вершин и нормалей.Однако вы можете чередовать эти данные:

vertex.x, vertex.y, vertex.z, normal.x, normal.y, normal.z

И затем вы можете связать эти данныев буфер.Затем, когда вы говорите OpenGL связать буфер, вы должны дать ему знать шаг и смещения.Предполагая, что у вас есть массив с плавающей точкой, содержащий чередующиеся вершины и нормальные данные, ваш пример может стать

glGenBuffers(NUM_BUFFERS, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(interleaved_data), interleaved_data, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(0));
glNormalPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(3 * sizeof(GLfloat)); 

Обратите внимание, что значение шага равно 6 * sizeof (GLfloat), что указывает на то, что между 24 байтамипоследовательные записи в буфере.И смещение нормального указателя равно 3 * sizeof (GLfloat), что указывает на то, что нормальные данные смещены на 12 байтов от начала буфера.

Надеюсь, это поможет - дайте мне знать, если ядопустил ошибку.

1 голос
/ 20 января 2011

Если есть связанный буфер, этот указатель, данный glDrawElements, обрабатывается как смещение к этому буферу, а не как обычный указатель.

BUFFER_OFFSET необходим, потому что исходное расширение ARB_vertex_buffer_object хотело использовать тот же прототип функции, поэтому необходимо преобразовать целочисленное смещение в указатель.

См. Дополнительную информацию в OpenGL.org wiki .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...