Я реализовал простой OBJ-парсер и использовал в качестве примера параллелепипед. Я добавил функцию вращения на основе кватернионов. Следующая цель - добавление света. Я проанализировал нормали и решил рисовать нормали как функцию «отладки» (для лучшего понимания света). Но после этого я застрял:
Вот мой параллелепипед с небольшим вращением. Посмотрите на правую нижнюю вершину и нормаль. Я не могу понять, почему он отрисован через мой параллелепипед. Это должно быть скрыто.
Я использую буфер глубины (потому что без него параллелепипед выглядит странно, когда я его вращаю). Итак, я инициализирую его:
glGenRenderbuffers(1, &_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _frameBufferWidth, _frameBufferHeight);
и включите его:
glEnable(GL_DEPTH_TEST);
Я генерирую 4 VBO: буферы вершин и индексов для параллелепипеда, буферы вершин и индексы для линий (нормали). Я использую один простой шейдер для обеих моделей (если он понадобится - могу добавить код позже, но думаю, с ним все в порядке). Сначала рисую параллелепипед, потом нормали. Вот мой код:
// _field variable - parallelepiped
glClearColor(0.3, 0.3, 0.4, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
int vertexSize = Vertex::size();
int colorSize = Color::size();
int normalSize = Normal::size();
int totalSize = vertexSize + colorSize + normalSize;
GLvoid *offset = (GLvoid *)(sizeof(Vertex));
glBindBuffer(GL_ARRAY_BUFFER, _geomBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indicesBufferID);
glVertexAttribPointer(_shaderAtributePosition, vertexSize, GL_FLOAT, GL_FALSE, sizeof(Vertex::oneElement()) * totalSize, 0);
glVertexAttribPointer(_shaderAttributeColor, colorSize, GL_FLOAT, GL_FALSE, sizeof(Color::oneElement()) * totalSize, offset);
glDrawElements(GL_TRIANGLES, _field->getIndicesCount(), GL_UNSIGNED_SHORT, 0);
#ifdef NORMALS_DEBUG_DRAWING
glBindBuffer(GL_ARRAY_BUFFER, _normalGeomBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _normalIndexBufferID);
totalSize = vertexSize + colorSize;
glVertexAttribPointer(_shaderAtributePosition, vertexSize, GL_FLOAT, GL_FALSE, sizeof(Vertex::oneElement()) * totalSize, 0);
glVertexAttribPointer(_shaderAttributeColor, colorSize, GL_FLOAT, GL_FALSE, sizeof(Color::oneElement()) * totalSize, offset);
glDrawElements(GL_LINES, 2 * _field->getVertexCount(), GL_UNSIGNED_SHORT, 0);
#endif
Я понимаю, например, если я объединю эти два вызова отрисовки в один (и использую одни и те же VBO для параллелепипеда и нормалей - все будет в порядке). Но это будет неудобно, потому что я использую линии и треугольники.
Должен быть другой способ исправить Z-порядок. Я не могу поверить, что сложная сцена (например, небо, земля и здания) отрисовывается с помощью одного вызова отрисовки.
Итак, что мне не хватает?
Заранее спасибо.