Jump to content
  • Advertisement
Sign in to follow this  
solinent

OpenGL Seperate vertex and normal indices (glDrawElements)

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having a new problem now: please look to post #7 I am loading from OBJ files (because of simplicity, I am new to opengl, and even 3d), to display a decently complex model (about 45k triangles). Now, and OBJ file stores a vertex like so: v x y z ie. v 1.0 0.0 -1.0232 where v identifies it is a vertex, and x y and z are the co-ordinates. Later, is specifies indices to draw faces with: f 1 2 3 This would draw a face with the first three vertices. This is all straightforward. However, when I export an obj model using blender, there is a different number of vertices than vertex normals, presumably because of lines rather than faces. I wish TO GET RID of these lines, but not using blender. However, there is a different corresponding index for a face between a vertex and a normal. This is stored like so: vn x y z (for a normal) f 1//2 2//3 3//1 This is just an example, but as you can see, the vertex index of one vertex of a face do not correspond with the normal's index. This is all fine: I simply store them in seperate arrays with seperate indices. However, to prevent duplication, I want to use glDrawElements, which only accepts one indice paramater. I'm just asking what I can do, or will I have to parse the data furhter so that the indices correspond (which may take alot of processing power, and I can't get my head around that for some reason). I'm sure this has been asked before, but couldn't find anything with some quick searches. [Edited by - solinent on February 9, 2008 8:14:36 PM]

Share this post


Link to post
Share on other sites
Advertisement
An .obj file stores at most three different indices (vertex, texture coordinate, normal) for vertex. A face can be made up of any number of vertices which would require triangulation.

Since in OpenGL (and also DX) you can only have one index array at a time you have to process the data from the obj file further so that using a single index specifies all three data elements.

You would basically have a large final array with a struct containing vertex, normal and texture coordinates and a hashtable that maps from the vertex references (1/2/3) of the obj file to the resulting index in the output array. This way you reduce vertex duplication. It would also work to just create a single new vertex with all three data elements for each vertex reference in the obj file, but then you will not get any sharing between vertices which might be bad.

Share this post


Link to post
Share on other sites
OpenGL VA (Vertex Array) uses a single index to access all vertex information (vertex coords, colour, normals, etc), wether or not you have separate arrays for normals.

What you can do is that create a normal array which has exactly same size of your vertex array. Then fill the array based upon corresponding normal coords in OBJ.

Share this post


Link to post
Share on other sites
Thanks, I'll try that.

First, though, I think I need to do a controlled testing by myself with opengl, and maybe use a simple OBJ file first.

Would it be alright to just start off without doing normals? Will I be able to make out if it is right or not without lighting? I guess, I'll try first...

Share this post


Link to post
Share on other sites
For loading meshes, I always just loaded the faces first. Make sure they are loaded and displayed correctly, then the UVs, and then the normals. You can tell the model is being display correctly if you enable wireframe in OpenGL.

Share this post


Link to post
Share on other sites
I'm having some weird stuff happening, almost as if it is clipping. You can't really tell, but at times it looks like a cube (like it should):

Almost as if it is being clipped, but I set the gluperspective(45, width/height, 0.01f, 500.0f), and the units specified in the object file are just 1, so it should be displayed.




It also works fine if I only rotate x or y or z, it looks as it should. This is the result of rotating them all.

[Edited by - solinent on February 8, 2008 9:29:16 PM]

Share this post


Link to post
Share on other sites
I had some opengl problem: it is now fixed.

I have since added VBO support (using the ARB functions, I don't know about opengl 1.5 and such), with glew. (which works like GLee)

Anyways, my problem is when I try to add normals using an interleaved array. It is specified like so:

struct VERTEX {
float x, y, z;
float nx, ny, nz;
};

So, I know that the offset for the normals should be 3*float + pointer to array, which is actually just zero (due to using VBOs).

Anyways, when I try to use this to pass the buffer object (I have no idea how this works, I only know that glVertexPointer uses a void pointer to accept any type in its fourth argument).

This is the code I found:
#define BUFFER_OFFSET(i) ((char)* NULL + (i))

OR
#define BUFFER_OFFSET(i) ((char *) NULL + (i))

and then called like:

glNormalPointer (3, GL_FLOAT, 6*sizeof(float), BUFFER_OFFSET(sizeof(float)*3));

However, I get errors (respectively):

src/Mesh.cpp:187: error: invalid type argument of ‘unary *’

OR

src/Mesh.cpp:187: error: invalid conversion from ‘unsigned int’ to ‘const GLvoid*’

Anyone have an idea how I should do this?

Share this post


Link to post
Share on other sites
Ah, I was thinking too hard: I had too many arguments to the function!

glNormalPointer (GL_FLOAT, 6*sizeof(float), BUFFER_OFFSET(12));

instead of
glNormalPointer (3, GL_FLOAT, 6*sizeof(float), BUFFER_OFFSET(12));


Very satisfying to solve :)

Share this post


Link to post
Share on other sites
When it comes to setting the stride for structures I prefer to do this;

glNormalPointer (GL_FLOAT, sizeof(VERTEX), BUFFER_OFFSET(12));

as it makes it clear what you are sizing on AND protects you from things going wrong is for some reason the size of VERTEX changes and you forget to update your code.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!