Рисование куба с использованием Indexed Draw в современном OpenGL - PullRequest
0 голосов
/ 12 мая 2019

Я пытаюсь нарисовать куб, используя индексированное рисование в OpenGL 3.3.Но это не отображается правильно ... Вот то, что я пытался сделать.

GLfloat vertices01[] = {
  -1.0f,1.0f,0.0f,
  -1.0f,-1.0f,0.0f,
  1.0f,1.0f,0.0f,
  1.0f,-1.0f,0.0f,
  -1.0f,1.0f,-1.0f,
  -1.0f,-1.0f,-1.0f,
  1.0f,1.0f,-1.0f,
  1.0f,-1.0f,-1.0f
};
unsigned int indices01[] = {
  0, 2, 3, 1,
  2, 6, 7, 3,
  6, 4, 5, 7,
  4, 0, 1, 5,
  0, 4, 6, 2,
  1, 5, 7, 3
};


Mesh* obj3 = new Mesh();
obj3->CreateMesh(vertices01, indices01, 24, 24);
meshList.push_back(obj3);

meshList[0]->RenderMesh();

// в классе сетки indexCount = numOfIndices;

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);

glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0])*numOfIndices, indices, GL_STATIC_DRAW);

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0])*numOfVertices, vertices, GL_STATIC_DRAW);

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

glBindVertexArray(0);

glBindVertexArray(VAO);

//bind ibo
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);

glDrawElements(GL_TRIANGLES,indexCount, GL_UNSIGNED_INT, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);

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

1 Ответ

1 голос
/ 12 мая 2019

Если вы используете контекст профиля совместимости, вы можете оставить для своих индексов значение GL_QUADS вместо GL_TRIANGLES.Но это не рекомендуется ( Legacy OpenGL ).

Поскольку тип примитива GL_TRIANGLES, каждая сторона куба должна быть образована 2 треугольниками.См. Примитивы треугольника .

Измените индексный буфер для решения проблемы:

unsigned int indices01[] = {
  0, 2, 3, 0, 3, 1,
  2, 6, 7, 2, 7, 3,
  6, 4, 5, 6, 5, 7,
  4, 0, 1, 4, 1, 5,
  0, 4, 6, 0, 6, 2,
  1, 5, 7, 1, 7, 3,
};

Альтернативным решением будет использование примитивного типа GL_TRIANGLE_STRIP и перезапуск примитива index.

Включение перезапуска примитива и определение индекса перезапуска:

например,

glEnable( GL_PRIMITIVE_RESTART );
glPrimitiveRestartIndex( 99 );

Определение 2 треугольных полос, которые разделяются индексом перезапуска:

unsigned int indices01[] = {
    0, 1, 2, 3, 6, 7, 4, 5,
    99, // 99 is the restart index
    7, 3, 5, 1, 4, 0, 6, 2
};
int indexCOunt = 17;

и рисуют элементы:

glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0);

Обратите внимание, что привязка Index buffer хранится в Vertex Array Object .
Таким образом, при настройке VAO достаточно один раз связать буфер индекса:

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);  

// [...]

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);

// [...]

// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); <---- delete this

glBindVertexArray(0);

Тогда излишне снова связывать буфер индексадо розыгрыша:

glBindVertexArray(VAO);

// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); <---- now this is superfluous 

glDrawElements(GL_TRIANGLES,indexCount, GL_UNSIGNED_INT, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
...