Advertisement

Specifying indices for text coordinades

Started by March 15, 2019 10:33 AM
1 comment, last by ajweeks 5 years, 10 months ago

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?

I don't think it's possible to interleave indices like that, however you can save yourself some work still by programmatically interleaving the position and texture coordinate data. That might look something like this:


struct Vertex
{
  glm::vec3 pos;
  glm::vec2 uv;
};

std::vector<Vertex> vertices;
for(int i = 0; i < indices.size(); ++i)
{
  vertices.emplace_back(positions[indices[i]], tex_coords[tex_indices[i]]);
}

This topic is closed to new replies.

Advertisement