PDA

View Full Version : Vertex Arrays and Lighting



bdxxxx
03-22-2010, 01:02 AM
Hello everyone
i draw a cube using Vertex Arrays, and then i want to enable lighting. How to set normals to ensure that the cube can be displayed correctly?
it seems that one vertex would be used three times, shall i define normals independently or store them in Vertex Arrays?
i tried the former one, it doesn't work. i want totried the latter one, but i don't know how to set normals.
Thanks.

Aeluned
03-22-2010, 11:54 AM
Have you looked at enabling GL_NORMAL_ARRAY and the glNormalPointer function?

bdxxxx
03-22-2010, 08:07 PM
here is my code

GLfloat vertices[]=
{
1,1,1,
1,1,-1,
-1,1,-1,
-1,1,1,
1,-1,1,
1,-1,-1,
-1,-1,-1,
-1,-1,1
};

glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,vertices);
glNormalPointer(GL_FLOAT,0,vertices);
GLubyte top[]={0,1,2,3};
GLubyte front[]={0,3,7,4};
glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,top);
glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,front);

i don't know how to specify normals.

Aeluned
03-23-2010, 08:36 AM
Well, first of all, you're passing your vertex data as normal data.
That isn't going to work. A surface normal is a vector that is perpendicular to and pointing outward from the surface of your polygon.

Knowing this, think about what the first entry in your vertex data is (1,1,1). This defines a normal that points, simultaneously, along the positive x,y & z axes. This is impossible.

The normal for all of your vertices for the top of the cube should be (0,1,0). That is a normal pointing straight up along the Y-axis.

The other normals would be:
bottom: 0,-1,0
left -1,0,0
right 1,0,0
front 0,0,1
back 0,0,-1.


The second problem is that you are reusing vertices for each face. This means that each vertex will make use of 3 normals (as each vertex is shared by 3 faces of the cube).

Since you can't have the same index point to 3 different normals you need to repackage your data. Try this:


GLfloat vertices[]=
{
1,1,1,
1,1,-1,
-1,1,-1,
-1,1,1, //top
1,-1,1,
1,-1,-1,
-1,-1,-1,
-1,-1,1,//bottom
-1,1,1
-1,1,-1,
-1,-1,-1,
-1,-1,1,//left
1,1,1,
1,-1,1,
1,-1,-1,
1,1,-1,//right
1,1,1,
-1,1,1,
-1,-1,1,
1,-1,1,//front
1,1,-1,
-1,1,-1,
-1,-1,-1,
1,-1,-1,//back
};

GLfloat normals[] =
{
0,1,0,
0,1,0,
0,1,0,
0,1,0,//top
0,-1,0,
0,-1,0,
0,-1,0,
0,-1,0,//bottom
..etc...
};

GLubyte top[] = {0,1,2,3};
GLybyte front[] = {16,17,18,19};


Obviously, this duplicates some data in your arrays so it may not be the best way to store it. But it should get you started.

bdxxxx
03-24-2010, 02:41 AM
Thank you.
i know my normal data is not correct, that's because i don't know how to specify it.
My question is the second point you talked.
i want to draw a cube using vertex arrays with only 8 vertices, each vertex should be used 3 times. i don't know how to set the normal arrays. is that impossible?

Aeluned
03-24-2010, 06:22 AM
Once a vertex becomes shared by 2 faces or more it must be duplicated. There is no way to only have 8 vertices in your vertex data anymore since you need to access different normals for each shared vertex.

So, in short, yes, it's impossible. You must duplicate your data.

Nevermind what I said in my previous post when I said there may be a better way to package data as to avoid duplicates. It's not possible.

bdxxxx
03-24-2010, 06:06 PM
soga...

thanks very much