glNormalPointer

hi

i´m using vertex and normal array drawing to manage some quick landscape drawing. i´ve also got a facearray that indexes my vertex and normals arrays, and the vertices get drawn correctly. however, how do i have to use normal arrays when i wish to specify one normal per triangle vertex to achieve smooth shading of the polygons? as far as i´m concerned, glNormalPointer can be only used for one Normal per face, not per vertex, and i guess that´s why my shading is completely messed up.
any suggestions?

eik

Well, you are on the wrong track here. glNormalPointer does not suppor per-face normal, only per-vertex normal. So your normal array is probably somewhat incorrect.

Post some code please.

Originally posted by Bob:
[b]Well, you are on the wrong track here. glNormalPointer does not suppor per-face normal, only per-vertex normal. So your normal array is probably somewhat incorrect.

Post some code please.[/b]

ok, so suppose i use vertex/normal arrays with only one normal per face. how is that supposed to work if i have one array of faces and one array of normals?
there are 3 times as many entries in the face array as there are in the normal-array!
can i crunch the indices like { vertex1, vertex2, vertex3, normal, vertex1, vertex2… }? if yes, how do i call this and how do i set the stride parameter?

regards

eik

Originally posted by hoshi55:
[b]
ok, so suppose i use vertex/normal arrays with only one normal per face. how is that supposed to work if i have one array of faces and one array of normals?
there are 3 times as many entries in the face array as there are in the normal-array!
can i crunch the indices like { vertex1, vertex2, vertex3, normal, vertex1, vertex2… }? if yes, how do i call this and how do i set the stride parameter?

regards

eik[/b]

sorry for the above double entry.

what i wanted to add:

the redbook says the following about array drawing: “… all 20 vertices in a 20-sided polygon can be put into one array and called with oe function. if each vertex also has a surface normal, all 20 surface normals can be put into another array and also called with one function”

now what, once it talks about vertex normals, then face normals…? i´m confused, please help!

In the extract you quote, it doesn’t talk about face normal, but surface normal.

You approximate a surface by drawing triangles (faces) which have their own normals that can be different from the actual normals of the approximated surface.
What you put in the normal array are the actual normals of the approximated surface, and you have one normal per vertex.
Therefore you have as many normals in the normal array as you have vertices in the vertex array (2 arrays same size, easy).

The entry i in the normal array is the normal of the entry i in the vertex array, it is as simple as that.

You can also use face normals with vertex arrays but if one vertex is shared by n faces, it has to appear n times in the vertex array since you have to define n different vertex-normal couples. Then, you can use glDrawArray instead of glDrawElement since you never reuse vertices (not even if they are shared by several faces … which often happens ).

Sorry, this might be a bit of topic.

As I understand you can call a series of polygons using a glBegin and glEnd OR use a an array defined by OpenGL functions to do this, right? If the answer is yes, what is the diference? Performance?

And by the way, what does glNormalPointer do?

[This message has been edited by billy (edited 03-16-2001).]

Originally posted by billy:

As I understand you can call a series of polygons using a glBegin and glEnd OR use a an array defined by OpenGL functions to do this, right? If the answer is yes, what is the diference? Performance?

Yes, that’s right. If you choose to use vertex arrays, it’s obviously for performance reasons.
You can define up to five vertex arrays:
one for vertices, one for texture coordinates, one for normal vectors, one for colors (or for color indices), one for polygon edge flags.
You have to fill in those arrays with your objects’ data and then tell OpenGL which arrays you want to use (give it the address of the arrays), by using gl*Pointer. * can be Vertex, TexCoord, Normal …

[b]
And by the way, what does glNormalPointer do?
[b]

glNormalPointer is used to specify the address of the array containing the normal vectors.

Check the Red book for more info on how to use vertex arrays.
Red book, chapter 2, vertex arrays: http://s.scs.uiuc.edu/ebt-bin/nph-infosr…_RESTART_N%25#X

thx for your help, i´ve now got both vertex/normal array drawing and manual triangle drawing working properly
there´s still one confusing aspect about array drawing, though:
the index array indicates what vertices (and normals or colors) a triangle face uses. now if i enable texturecoordinate arrays, this seems to lead to a problem: if i´ve got two adjacent triangles, which share two vertices. they also share the vertex-normals, but i don´t want the vertices to share the same texture coordinates. however, since the index array specifies vertex numbers, i can´t think of a possibility to assign different texture coordinates per vertex for each face.
how can i work around this?

one more question, how do i properly switch the shading model on-the-fly?

int *param = NULL;
glGetIntegerv(GL_SHADE_MODEL, param);
if(param[0] == GL_SMOOTH) glShadeModel(GL_FLAT); else glShadeModel(GL_SMOOTH);

crashes on me

The index array is used to point out uniqe vertices from the arrays. If two vertices got the same coordinates, normal and texture coordinates, they are identical. But if they got different texture coordinates, they are no longer identical, and must be represented as two separated vertices. There is no workaround, like having a separate index array for texture coordinates. You just have to duplicate that vertex and give them different texture coordinates.

Originally posted by hoshi55:
[b]
one more question, how do i properly switch the shading model on-the-fly?

int *param = NULL;
glGetIntegerv(GL_SHADE_MODEL, param);
if(param[0] == GL_SMOOTH) glShadeModel(GL_FLAT); else glShadeModel(GL_SMOOTH);

crashes on me[/b]

Try this instead…

(Edit note ok… doing the & + param is translating to ¶m in HTML so I’m changing the variable name.)
int p;
glGetIntegerv(GL_SHADE_MODEL, &p);

You have to have memory allocated for the pointer you send into glGet* stuff. OpenGL doesn’t allocate the memory for those for you, and that’s what it would have to do in the way you tried using it. In my example the memory will be allocated on the stack.

Almost always when you get a crash, it is due to touching memory you shouldn’t be touching… in your case, you were trying to have OpenGL write to a NULL memory address. (Understanding of memory, is the key to mastering C/C++)

[This message has been edited by Deiussum (edited 03-19-2001).]