# vertex, normal and texcoordinate indices

This topic is 2632 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello.

I have a question about glDrawElements and vertex, normal and texcoordinate indices.

If I have geometric vertex, vertex normals and texture vertices, each with its own indices.

Which of those indices may I use?

If I have this code:

glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
(const GLvoid*) &teapotVertices[0]);
glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,
(const GLvoid*) &teapotNormals[0]);
glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,
(const GLvoid*) &teapotTexCoords[0]);

glEnableVertexAttribArray(vertexHandle);
glEnableVertexAttribArray(normalHandle);
glEnableVertexAttribArray(textureCoordHandle);

glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID);
glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE,
(GLfloat*)&modelViewProjection.data[0] );
glDrawElements(GL_TRIANGLES, NUM_TEAPOT_OBJECT_INDEX, GL_UNSIGNED_SHORT,
(const GLvoid*) &teapotIndices[0]);

What should hold teapotIndices?

Thanks.

##### Share on other sites
Quote:
 If I have geometric vertex, vertex normals and texture vertices, each with its own indices.Which of those indices may I use?

You can't use any of them as is.

You have to generate a new set of data and indices such that vertices, vertex normals, and texture vertices all have the same index. It's not a trivial operation.

If you search here for VBO and OBJ, you'll find that this exact question has been answered and discussed hundreds of times before. Or just use ASSIMP if you don't want to do it yourself.

##### Share on other sites
Thanks for your answer but, what should I do? I must order them for each vertex, texcoord and normal...

##### Share on other sites
Quote:
 Original post by VansFannelThanks for your answer but, what should I do?

Quote:
 Original post by karwostsIf you search here for VBO and OBJ, you'll find that this exact question has been answered and discussed hundreds of times before.

Search for "vbo obj" returns:

OBJ to indexed VBO - GameDev.Net Discussion Forums
VBO - Vertices, Indices, UVs in one VBO and their indices in ...
Rendering .OBJ Meshes using VBOs - GameDev.Net Discussion Forums
[solved]wavefront obj and vbo/ibo - GameDev.Net Discussion Forums
Opengl going immediate mode to buffered drawing - GameDev.Net ...

and that's just from the first 10 results.

##### Share on other sites

I am stupid, but I can't find what I'm looking for.

I'm very very very new on OpenGL ES 2.0 development.

I only want to know if I have to order them.

If have this:

f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3

I must use the following array:

v1/v2/v3 vt1/vt2/vt3 vn1/vn2/vn3

I want to use glDrawElements, so I need indices for its third parameter.

Thanks.

##### Share on other sites
The indices should be the same for all 3 parameters. Maybe you could use interleaved data.

##### Share on other sites
The point is that while OBJ files relate to the glBegin/End way, they can't EVER work with newer methods.

Like I posted in the other two threads in this page (sigh...), you must "flatten" them to linear data.
You don't have to do it all the way if you don't need to, of course, since having indices helps the GPU work better with caching, but you need to fix shared data.

A 3D box is an excellent example of a model that must be flattened all the way.
With glBegin/End it could have 8 vertices, texcoords, and normals.
With anything newer it must have 24 of each.

The main difference between, say, the above cube and an actual model is that an actual model is continuous, while a box isn't. A real model usually wont have these "edges", it would be all roundish and in one piece.

This is why while the indices may be different, it is usually just to spare on file size by compacting many values into one.
An example to this would be a big 2D grid, where you might have 1000x1000 vertices and texcoords, but can get along just fine with 1 normal if you didn't edit normals.
In this case, you can just "add" the missing data and fix the indices. This way you will still have at the end a full list of indices, and a working model.

It's easier, however, to just go all the way and completely turn the model into linear data, so I suggest you to do that unless your world is very detailed and actually needs to be efficient.
You can always make it more efficient if you notice this is a bottleneck (remember, optimize when you NEED to, not when you WANT to).

##### Share on other sites
A vertex that is at the same location is different if any of its attributes are different, they must be split. It isn't too hard to figure out if you can use one of those vertices, or you need to duplicate and give it new texcoords/normal.

##### Share on other sites
Sorry, I've forgotten to metion that I'm working with OpenGL ES 2.0 for Android.

##### Share on other sites
Quote:
 Original post by VansFannelSorry, I've forgotten to metion that I'm working with OpenGL ES 2.0 for Android.

The actual problem (linearizing the data) has nothing to do with this. Do you actually read the comments in this thread? I guess not...

##### Share on other sites
What is the relationship between not reading the posts and saying I'm using OpenGL ES 2.0?

I don't understand.

##### Share on other sites
Lets say you have a vertex attribute arrays called posArray,normalArray and uvArray. The way normal rendering works is by specifying a list of indices into these arrays that forms your primitives, so assuming you are rendering triangles and lets say your indices list is 0,1,2,3,4,5 then you got two triangles here
first one is 0,1,2 which means that it's position is posArray[0],posArray[1],posArray[2] it's normals are normalArray[0],normalArray[1],normalArray[2] and so on.
The problem lies if for example, you are given a triangle which has different indices for the different arrays for example 0,1,2 for position 7,100,2 for normals and so on. In this case you will have to duplicate you vertices.

Hope this clarifies a bit.

##### Share on other sites
It really isn't difficult to write the algorithm for duplicating the vertex and normals and texcoords.
If you have a line like
f 1/3/4 5/5/5 2/4/3

that is a triangle.
First, we must subtract by 1 so we get
f 0/2/3 4/4/4 1/3/2

now, let's do it

j=0;
k=0;
m=0;
for(i=0; i<3; i++)
{
new_vertexarray[k]=vertexarray[vertex_index[j]*3]; //X
new_vertexarray[k+1]=vertexarray[vertex_index[j]*3+1]; //Y
new_vertexarray[k+2]=vertexarray[vertex_index[j]*3+2]; //Z

new_normalarray[k]=normalarray[normal_index[j]*3]; //NX
new_normalarray[k+1]=normalarray[normal_index[j]*3+1]; //NY
new_normalarray[k+2]=normalarray[normal_index[j]*3+2]; //NZ

new_texcoordarray[m]=texcoordarray[tex_index[j]*2]; //S
new_texcoordarray[m+1]=texcoordarray[tex_index[j]*2+1]; //T
k+=3;
m+=2;
j++;
}

in the end, new_vertexarray would have to be of size 9 (3 vertex)
in the end, new_normalarray would have to be of size 9 (3 vertex)
in the end, new_texcoordarray would have to be of size 6 (3 vertex)

You also need a new_indexarray.
Needs to be size 3.
The values will start from 0 and go up.

I suggest you to think and write whatever algorithm you want. If you are not good with algorithms, forget about programming.

##### Share on other sites
Quote:
 Original post by V-man...

Nice, but there are shared vertices anyway, so I don't think duplicating every vertex is a good idea.

##### Share on other sites
I've tried this method and it doesn't work for me.

I'm trying to draw a cube and I'm getting a flat square.

These are my vertex and fragment shader:

static const char* vertexShader = "   attribute vec4 vertexPosition;  uniform mat4 modelViewProjectionMatrix;  void main() {    gl_Position = modelViewProjectionMatrix * vertexPosition; } ";static const char* fragmentShader = "  precision mediump float;  void main() {    gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); } ";

[Edited by - VansFannel on December 10, 2010 5:59:40 AM]