Шаг и смещение OpenGL Interleaved VBO

Я делаю эту программу, которая должна отображать цветные квадраты. Я использую для этого VBO.

Вот как я храню данные для вершин и цветов:

четверка:

 buff.put(3 floats color)
 render the quad (3 floats per vertex * 4 per face * 6 per quad) 

Теперь, как вы видите, моя цель - использовать чередующиеся VBO, но я не могу определить шаг и смещение.

Вот мои вызовы при рендеринге:

(Обратите внимание, что я использую сопоставленные vbos, поэтому фактической привязки данных нет):

        glBindBufferARB(GL_ARRAY_BUFFER_ARB, etn.getVboHandel());
        glBufferDataARB(GL_ARRAY_BUFFER_ARB, etn.getVboData().capacity() << 2, GL_STATIC_DRAW_ARB);

        glColorPointer(3, GL_FLOAT, /* stride **/6 << 2, /* offset **/0); 
        glVertexPointer(3, GL_FLOAT, /* stride **/6 << 2, /* offset **/0);

        glDrawArrays(GL_QUADS, 0,  etn.getVboData().capacity());    

Я не могу получить правильное смещение и шаг, поэтому при рендеринге я вижу эти странные артефакты.


person Amit Assaraf    schedule 08.06.2013    source источник
comment
Здесь слишком много недостающей информации, чтобы ответить на вопрос. Непонятно, что вы пытаетесь сделать. Например, что означает цвет 3 поплавка? Кроме того, прекратите использовать суффикс ARB. Буферные объекты — это функциональность GL 1.5; они были основой OpenGL более десятилетия.   -  person Nicol Bolas    schedule 08.06.2013
comment
Я удалил материал ARB   -  person Amit Assaraf    schedule 08.06.2013


Ответы (2)


Шаг — это расстояние между двумя кортежами, а смещение — это расстояние между 0 и первым появлением первого кортежа.

например, для треугольников с 3 поплавками на позицию, а затем 3 поплавками для нормали это выглядит так

glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE, 24, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1,3, GL_FLOAT, GL_FALSE, 24, (GLvoid*) (sizeof(float)*3));
glEnableVertexAttribArray(1);

Таким образом, ваш указатель вершины имеет смещение 0 (при условии, что первые три записи являются позициями) и шаг 24 (при условии, что ваш цвет вершины идет сразу после позиции вершины)

для указателя цвета смещение будет (GLvoid*) (sizeof(float)*3) как три GLfloat перед первой тройкой цветов

Все это предполагает, что ваш чередующийся массив построен следующим образом

VVVCCCVVVCCCVVVCCC и так далее

Для очень простого примера на C++ с использованием модели, имеющей только информацию о вершинах и нормалях, а также грани, вы можете проверить этот код: http://www.incentivelabs.de/Sourcecode/OpenGL10.zip

person glethien    schedule 08.06.2013
comment
Дело в том, что у четырехугольника не может быть более 1 другого цвета, что означает, что мне нужен только 1 цвет для каждых 4 * 6 вызовов вершин, поэтому он построен следующим образом: VVVVVVVVVVVVVVVVVVVVVVVVC - person Amit Assaraf; 08.06.2013
comment
Я не совсем уверен, но цвет должен быть установлен для каждой вершины, а не для каждого квадрата. если четырехугольник (который является плоскостью в OpenGL) имеет разный цвет для каждой вершины, цвет будет интерполирован на плоскости. То же самое для треугольников. Поэтому, если ваш четырехугольник должен иметь только один цвет, каждая вершина четырехугольника должна иметь один и тот же цвет. - person glethien; 08.06.2013
comment
Оооо ок спасибо! Можете ли вы помочь мне с тем, что другой парень сказал о емкости? - person Amit Assaraf; 08.06.2013
comment
Емкость — это количество записей в коллекции. - person glethien; 08.06.2013

Ваше описание не совсем последовательно: 3 поплавка на вершину недостаточно для описания 3D-позиции и цвета RGB. ВАШ код предполагает, что у вас на самом деле есть 6 значений для каждой вершины, поэтому буфер может выглядеть так:

    +0    +4    +8    +12   +16   +20
 0: pos.x pos.y pos.z col.r col.g col.b
24: pos.x pos.y pos.z col.r col.g col.b
...

Шаг - это «расстояние» двух последовательных значений одного и того же атрибута, поэтому в этом случае, как вы правильно установили, это 6 * sizeof (GLfloat). Смещение — это смещение атрибута в байтах относительно начала буфера. В моем примере это 0 для pos и 3*sizeof(GLfloat) для col. Вы устанавливаете для обоих одно и то же смещение, поэтому вы используете одни и те же данные для разных атрибутов, что редко бывает хорошей идеей.

Кроме того, настройка вашего буфера кажется неясной. Линия

glDrawArrays(GL_QUADS, 0,  etn.getVboData().capacity());

предполагает, что etn.getVboData().capacity() — это количество вершин в буфере. Если так,

glBufferDataARB(GL_ARRAY_BUFFER_ARB, etn.getVboData().capacity() << 2, GL_STATIC_DRAW_ARB);

явно неправильно, так как вам нужно 6*sizeof(GLfloat) байт на вершину, поэтому вы копируете только части данных и получаете доступ к данным вне буфера, что является неопределенным поведением и может привести ко всем видам странных эффектов. .

person derhass    schedule 08.06.2013
comment
Я не понимаю часть о емкости ... можете ли вы объяснить это подробнее и использовать ссылки на Java, потому что в Java нет sizeof - person Amit Assaraf; 08.06.2013
comment
@gopgop: скажем, у вас есть N вершин, и, как и в вашем случае, вам нужно 6 чисел с плавающей запятой (= 24 байта при плотной упаковке) на вершину, ваш буфер имеет общий размер N * 24 байта. glDrawArrays ожидает количество вершин. Таким образом, либо etn.getglDrawArraysVboData().capacity() — это ваше количество вершин, тогда вызов glDrawArrays верен, а glBufferData — нет, либо etn.getglDrawArraysVboData().capacity() относится к размеру буфера в байтах, чем обе другие строки неверны, так как должно быть capacity()/24 вершин в буфер (и вы загружаете в четыре раза больше данных, чем есть на самом деле) - person derhass; 08.06.2013
comment
Но когда я умножаю это на 24 в bufferData, это не работает, я получаю кучу артефактов. - person Amit Assaraf; 08.06.2013
comment
@gopgop: Как я уже сказал: If capacity() — это количество вершин. Я предполагаю, что на самом деле это размер буфера в байтах. - person derhass; 08.06.2013
comment
К спасибо! Кстати, я переключился на использование VAO и glVetrexAttribPointers, и цвет не работает. Можно ли использовать сопоставленные VBO и VAO вместе? - person Amit Assaraf; 08.06.2013