Итак, я пытался научиться использовать VBO, чтобы повысить производительность моего проекта OpenGL и изучить более сложные вещи, чем рендеринг с фиксированными функциями. Но я не нашел ничего достойного учебника; лучшие из них, которые я нашел до сих пор, - это учебники Сонхо и материалы на OpenGL.org , но мне кажется, что мне не хватает каких-то базовых знаний, чтобы полностью понять, что происходит, хотя я не могу точно сказать, что именно я не получаю, за исключением использования нескольких параметров.
В любом случае, я пошел вперед и придумал какой-то каннибализированный код, который, по крайней мере, не дает сбоев, но приводит к странным результатам. Я хочу отобразить это (визуализировано с использованием фиксированной функции; он должен быть коричневым, а фон - серым, но все мои скриншоты OpenGL, похоже, используют пурпурный как свой любимый цвет; возможно, это потому, что я использую SFML для окна?).
Однако я получаю следующее:
Я в растерянности. Вот соответствующий код, который я использую, сначала для настройки объектов буфера (я выделяю много памяти согласно рекомендации этого парня , чтобы выделить 4-8 МБ):
GLuint WorldBuffer;
GLuint IndexBuffer;
...
glGenBuffers(1, &WorldBuffer);
glBindBuffer(GL_ARRAY_BUFFER, WorldBuffer);
int SizeInBytes = 1024 * 2048;
glBufferData(GL_ARRAY_BUFFER, SizeInBytes, NULL, GL_STATIC_DRAW);
glGenBuffers(1, &IndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
SizeInBytes = 1024 * 2048;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, SizeInBytes, NULL, GL_STATIC_DRAW);
Затем для загрузки данных в буфер. Обратите внимание, что CreateVertexArray () заполняет вектор в переданном месте данными вершин, при этом каждая вершина вносит 3 числа с плавающей запятой для позиции и 3 числа с плавающей запятой для обычного (одна из самых запутанных вещей в различных руководствах заключалась в том, какой формат я должен хранить и передавать свои фактические данные). данные вершин в; это выглядело как хорошее приближение):
std::vector* VertArray = new std::vector;
pWorld->CreateVertexArray(VertArray);
unsigned short Indice = 0;
for (int i = 0; i < VertArray->size(); ++i)
{
std::cout << (*VertArray)[i] << std::endl;
glBufferSubData(GL_ARRAY_BUFFER, i * sizeof(float), sizeof(float), &((*VertArray)[i]));
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * sizeof(unsigned short), sizeof(unsigned short), &(Indice));
++Indice;
}
delete VertArray;
Indice -= 1;
После этого в игровом цикле я использую этот код:
glBindBuffer(GL_ARRAY_BUFFER, WorldBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
glNormalPointer(GL_FLOAT, 0, 0);
glDrawElements(GL_TRIANGLES, Indice, GL_UNSIGNED_SHORT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Я буду полностью честен - я не уверен, что понимаю, какой третий параметр glVertexPointer ()
и glNormalPointer ()
должны быть (шаг - это смещение в байтах, но Songho использует смещение в 0 байтов между значениями - что?) , или каков последний параметр любого из них.Начальное значение называется 0; но это должен быть указатель. Передача нулевого указателя для получения первой координаты / нормального значения массива кажется странной. Этот парень использует BUFFER_OFFSET (0)
и BUFFER_OFFSET (12)
, но когда я пытаюсь это сделать, мне говорят, что BUFFER_OFFSET () не определено.
Кроме того, последний параметр glDrawElements ()
должен быть адресом, но опять же, Songho использует адрес 0. Если я использую и IndexBuffer
вместо 0, я получить пустой экран без какого-либо рендеринга, кроме фона.
Может ли кто-нибудь просветить меня или хотя бы указать мне на то, что поможет мне в этом разобраться? Спасибо!