Hi there.
I'm trying to render an object using an index buffer instead of just having all the combinations of vertices with each texture coordinate. I'd like to have two buffers, one for cube vertices and one for the tex coordinates and then add them in an interleaved way to the VBO.
In the code below you can see the differences of the two versions. On the right hand side it works perfectly with my design, but it's a lot to process with a lot of duplicated vertices and tex coordinates. On the left, my try to convert it to index data.
const std::vector<glm::vec3> vertices //static constexpr float vertices[]
{ //{
{-0.5f, -0.5f, -0.5f}, //0.0f, 0.0f, // a = 0 // -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // a = 0 - t = 0
{ 0.5f, -0.5f, -0.5f}, //1.0f, 0.0f, // b = 1 // 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, // b = 1 - t = 1
{ 0.5f, 0.5f, -0.5f}, //1.0f, 1.0f, // c = 2 // 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // c = 2 - t = 2
{-0.5f, 0.5f, -0.5f}, //0.0f, 1.0f, // d = 3 // 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // c = 2 - t = 2
{-0.5f, -0.5f, 0.5f}, //0.0f, 0.0f, // e = 4 // -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, // d = 3 - t = 3
{ 0.5f, -0.5f, 0.5f}, //1.0f, 0.0f, // f = 5 // -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // a = 0 - t = 0
{ 0.5f, 0.5f, 0.5f}, //1.0f, 1.0f, // g = 6
{-0.5f, 0.5f, 0.5f}, //0.0f, 1.0f, // h = 7 // -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // e = 4 - t = 0
}; // 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // f = 5 - t = 1
// 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // g = 6 - t = 2
const std::vector<unsigned int> indices // 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // g = 6 - t = 2
{ // -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, // h = 7 - t = 3
0, 1, 2, // -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // e = 4 - t = 0
2, 3, 0,
// -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // h = 7 - t = 1
4, 5, 6, // -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // d = 3 - t = 2
6, 7, 4, // -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // a = 0 - t = 3
// -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // a = 0 - t = 3
7, 3, 0, // -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // e = 4 - t = 0
0, 4, 7, // -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // h = 7 - t = 1
6, 2, 1, // 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // g = 6 - t = 1
1, 5, 6, // 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // c = 2 - t = 2
// 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // b = 1 - t = 3
0, 1, 5, // 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // b = 1 - t = 3
5, 4, 0, // 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // f = 5 - t = 0
// 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // g = 6 - t = 1
3, 2, 6,
6, 7, 3, // -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // a = 0 - t = 3
// 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, // b = 1 - t = 2
}; // 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // f = 5 - t = 1
// 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // f = 5 - t = 1
const std::vector<glm::vec2> tex_coord // -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // e = 4 - t = 0
{ // -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // a = 0 - t = 3
{0.0f, 0.0f},
{1.0f, 0.0f}, // -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, // d = 3 - t = 3
{1.0f, 1.0f}, // 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // c = 2 - t = 2
{0.0f, 1.0f}, // 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // g = 6 - t = 1
}; // 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // g = 6 - t = 1
// -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, // h = 7 - t = 0
const std::vector<unsigned int> tex_indices // -0.5f, 0.5f, -0.5f, 0.0f, 1.0f // d = 3 - t = 3
{ //};
0, 1, 2,
2, 3, 0,
0, 1, 2,
2, 3, 0,
1, 2, 3,
3, 0, 1,
1, 2, 3,
3, 0, 1,
3, 2, 1,
1, 0, 3,
3, 2, 1,
1, 0, 3,
};
What I'm struggling with is to then send this data to the GPU in the correct way.
(see code below)
// more...
m_vb = new VertexBuffer();
for(int i = 0; i < vertices.size(); ++i)
{
// add vertex to VBO
//..
// add tex coordinate to VBO
//..
}
VertexBufferLayout layout;
layout.Push<float>(3);
layout.Push<float>(2);
m_va.AddBuffer(*m_vb, layout);
m_ib = new IndexBuffer();
for(int i = 0; i < indices.size(); ++i)
{
// add index to IBO
//..
// add tex index to IBO
//..
}
m_ib->SendToGPU();
// other....
// drawing
// using shader program
// bound VAO
// bound index buffer
glDrawElements(GL_TRIANGLES, ib.GetCount(), GL_UNSIGNED_INT, nullptr);
I believe what I'm try to achieve is feasible, but is this the right approach? Anyone with a better idea, or a solution that doesn't include specifying all the combinations of vertices and tex coordinates one by one?