0

Ok, so I have come across a problem that seems like most others have too, but their explainations are either, you cannot do it, or its too vague for the computer to understand that it is using indexes for a vertice and another for textures. I have heard a lot that you should put a vertex struct that has a position, a texture coordinates, and a normal. But it does not help if I UV map my object that I import from an obj file. So there will be some indexes for the same vertex, but having a different index for a texture coordinate. So how am I able to tell opengl how to grab multiple indices, and use one for vertices, one for texture coordinates, and one for colors (the colors are simple, they are all the same thing, but I still need to specify that opengl need to use it)?

What I have now indices only the vertex arrays indexes.

private void InitiateBeforeDraw()
{
    // Vertex Buffer
    Gl.glGenBuffers(1, out VertexId);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, VertexId);
    Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(Vertices.Length), Vertices, Gl.GL_STATIC_DRAW);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);

    // Color Buffer
    Gl.glGenBuffers(1, out ColorId);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, ColorId);
    Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(Colors.Length), Colors, Gl.GL_STATIC_DRAW);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);

    // Texture Buffer
    Gl.glGenBuffers(1, out TexCoordId);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, TexCoordId);
    Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(UVs.Length), UVs, Gl.GL_STATIC_DRAW);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);

    // Index Buffer
    Gl.glGenBuffers(1, out IndexId);
    Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, IndexId);
    Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)(Faces.Length), Faces, Gl.GL_STATIC_DRAW);
    Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, 0);
}

private void SetupPointers()
{
    // Vertex
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, VertexId);
    Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
    Gl.glVertexPointer(3, Gl.GL_DOUBLE, 0, Vertices);
    Gl.glVertexAttribPointer(0, 3, Gl.GL_DOUBLE, Gl.GL_FALSE, 0, 0);

    // Color
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, ColorId);
    Gl.glEnableClientState(Gl.GL_COLOR_ARRAY);
    Gl.glColorPointer(4, Gl.GL_FLOAT, 0, Colors);
    Gl.glVertexAttribPointer(1, 4, Gl.GL_FLOAT, Gl.GL_FALSE, 0, 0);

    // Texture
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, TexCoordId);
    Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
    Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 0, UVs);
    Gl.glVertexAttribPointer(2, 2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, 0);

    // Index
    Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, IndexId);
}

public void Draw()
{
    if(bInitiated)
    {
        InitiateBeforeDraw();
        bInitiated= true;
    }

    SetupPointers();

    Gl.glDrawElements(Gl.GL_TRIANGLES, Faces.Length, Gl.GL_UNSIGNED_INT, Faces);

    Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
    Gl.glDisableClientState(Gl.GL_COLOR_ARRAY);
    Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
}

I am also attaching a simple cube put into obj file form

mtllib Cube.mtl
o Cube
v -10.000000 -10.000000 10.000000
v -10.000000 -10.000000 -10.000000
v 10.000000 -10.000000 -10.000000
v 10.000000 -10.000000 10.000000
v -10.000000 10.000000 10.000000
v -10.000000 10.000000 -10.000000
v 10.000000 10.000000 -10.000000
v 10.000000 10.000000 10.000000
vt 0.000087 0.250044
vt 0.250043 0.250044
vt 0.250043 0.500000
vt 0.500000 0.000087
vt 0.500000 0.250044
vt 0.749956 0.500001
vt 0.499999 0.500000
vt 0.250042 0.749957
vt 0.749956 0.250044
vt 0.999913 0.250044
vt 0.999913 0.500001
vt 0.000087 0.500000
vt 0.250042 0.000087
vt 0.499999 0.749957
usemtl Mat_Cube
s off
f 6/1 2/2 1/3
f 7/4 3/5 2/2
f 8/6 4/7 3/5
f 5/8 1/3 4/7
f 2/2 3/5 4/7
f 7/9 6/10 5/11
f 5/12 6/1 1/3
f 6/13 7/4 2/2
f 7/9 8/6 3/5
f 8/14 5/8 4/7
f 1/3 2/2 4/7
f 8/6 7/9 5/11

Now if you don't see what the problem is already, look at the first 'f', which means face, and the first number is 6, which is calling vertex number 6, and the next one to the slash is one, which is calling the texture coordinate number 1. Now on the sixth face, it calls on vertex number 6 again, but this time with texture coordinate number 10. And the next time it pops up is like the first, and the third time it pops up its calling texture coordinate number 13. As you can tell, the problem here isn't that I must hone in all the data into a struct, but actually tell opengl how to index my vertices, textures, colors, and normals with different index indicators.

Although there is always "Make every texture coordinate in your UV image all call the same point for the same vertex", but as easy as that may seem, it has quite a large margin of error and just seems very hard to texture around with, and "skinning" my models will still have a margin of error.

So how am I able to accomplish this?

PGonzBecer
  • 63
  • 1
  • 7
  • 1
    You actually have to treat each different combination of coordinates as a unique vertex. AMD has an extension that allows you to encode up to 4 separate attribute indices per vtx, but it is a non-standard hack. – Andon M. Coleman May 03 '14 at 01:58
  • 1
    I put pseudo code for an algorithm in my answer to a similar question a few days ago: http://stackoverflow.com/questions/23349080/opengl-index-buffers-difficulties/23356738#23356738. It shows how to "unify" the indices. – Reto Koradi May 03 '14 at 03:17
  • @KetoKoradi Thanks so much, I got it to work. For some reason it took me awhile to understand what his pseudo code was trying to say, but I figured it out. Again thanks for the help, it's very much appreciated! – PGonzBecer May 08 '14 at 07:23

0 Answers0