2015-08-04 2 views
3

Согласно LWJGL javadooc, есть функция:Как я могу генерировать несколько VBO с ByteBuffer

public static void glGenBuffers(int n, ByteBuffer buffer) 

Но я не совсем понимаю, как это работает. ли я создать ByteBuffer:

ByteBuffer buffer = ByteBuffer.allocate("how much???") 
glGenBuffers(4, buffer); 

И уж тем более я должен заполнить буфер с glBufferSubData ИЛИ это лучше создать 4 буфера и привязку и заполнить их?

Я подумал, что это более эффективно, когда я создаю только 1 буфер, в котором хранятся вершины, текстурные сокеты, нормали и индексы.

ответ

2

glGenBuffers(int n, ByteBuffer buffer) генерирует n объектов буфера вершин (VBOs), которые вы можете использовать для хранения ваших данных и помещает их в указанный буфер. Этот буфер на самом деле не тот, который содержит ваши данные, но только ids только что созданных VBOs. Вы должны вручную определить данные VBO с помощью glBufferData.

Эта функция полезна, если вы хотите создать несколько VBO с одним вызовом. Каждый идентификатор VBO является целым числом, и буфер должен быть достаточно большим для хранения буферов n (в данном случае 4).

ByteBuffer buffer = BufferUtils.createByteBuffer(4 * Integer.BYTES); 
glGenBuffers(4, buffer); 

Однако, чтобы сделать вещи проще, вы можете также использовать IntBuffer.

IntBuffer buffer = BufferUtils.createIntBuffer(4); 
glGenBuffers(4, buffer); 

Затем вы можете прикрепить данные к каждому из VBOs.

glBindBuffer(GL_ARRAY_BUFFER, buffer.get(2); /*value from 0 to 3*/ 
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW); 

(Если вы используете ByteBuffer, вы должны вызвать buffer.getInt(2) вместо этого.)


Это, как правило, более эффективным, чтобы иметь все данные в одном буфере , но учтите, что в этом в случае, если вы должны использовать не менее двух, потому что индексы должны быть в GL_ELEMENT_ARRAY_BUFFER. Однако разница в производительности очень мала, поэтому может быть проще использовать несколько разных VBOs.

Предпочтительно плотно упаковывать все данные в буфер и загружать их с помощью glBufferData вместо вызова glBufferSubData для каждого типа данных. Ваш макет данных будет выглядеть примерно так (P = положение, T = текстурные координаты, N = нормальный вектор):

PPPTTNNNPPPTTNNNPPPTTN... 

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

int vbo = glGenBuffers(); 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, tightlyPackedData, GL_STATIC_DRAW); 

int stride = (3 + 2 + 3) * Float.BYTES; 

glVertexAttribPointer(positionIndex, 3, GL_FLOAT, false, stride, 0); 
glVertexAttribPointer(texCoordIndex, 2, GL_FLOAT, false, stride, 3 * Float.BYTES); 
glVertexAttribPointer(normalIndex, 3, GL_FLOAT, false, stride, (3 + 2) * Float.BYTES); 

positionIndex, texCoordIndex и normalIndex являются расположение атрибутов ваших атрибутов шейдерных вершинных. Вы можете получить их с glGetAttribLocation.

stride - это количество байтов между значением одной вершины и значением следующего. У нас есть 3 позиции, 2 координаты текстуры и 3 нормали, которые все плавают, поэтому мы умножаем их на Float.BYTES.

Последний параметр, равный glVertexAttribPointer, представляет собой смещение в байтах, то есть количество байт от начала буфера до места нахождения первого значения.

+0

Вау, спасибо за это Хорошее объяснение – greedsin

+1

Сортировка по терминологии: 'glGenBuffers()' не генерирует VBOs, он генерирует ** имена ** (или ** ids **, если вы предпочитаете их называть) для объектов буфера. VBO создается только при первом соединении имени. Кроме того, вам не нужно использовать два VBOs, если вы используете индексы. Несмотря на то, что это обычно не делается, вполне естественно хранить индексы и данные вершин в том же буфере. –

+0

да, я знал это раньше, все равно спасибо – greedsin

Смежные вопросы