Итак, я пытался научить себя использовать 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<float>* VertArray = new std::vector<float>;
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, я получаю пустой экран без какой-либо визуализации, кроме фона.
Может ли кто-нибудь просветить меня или, по крайней мере, указать мне в направлении чего-то, что поможет мне понять это? Спасибо!