# Normals and VBO

I’m using VBO, so, no glBegin(). How do I set a normal to each face of my object?

I got 2 arrays. 1 for my vertex_positions, and another one for my index. Can I include my normals inside my vertex_positions array?

I got this, right now, but don’t know if its working:

``````
static GLfloat vertices[cubeMatrixSize][9] =
{//   R    G    B		   X	  Y	    Z		   NORMALS
{1.0, 0.0, 0.0,		 -1.0,  -1.0, -1.0,		  0, -1,  0},	// 0	-- REDs
{0.0, 1.0, 0.0,		  1.0,  -1.0, -1.0,		  1,  0,  0},// 1	-- GREEN
{0.0, 0.0, 1.0,		  1.0,   1.0, -1.0,		  1,  0,  0},// 2	-- BLUE
{1.0, 1.0, 1.0,		 -1.0,   1.0, -1.0,	 	  0,  1,  0},// 3	-- WHITE
{0.5, 0.5, 0.5,		 -1.0,  -1.0,  1.0,		  0,  0,  1},// 4	-- GRAY
{1.0, 1.0, 0.0,		  1.0,  -1.0,  1.0,		  0,  0,  1},// 5	-- YELLOW
{1.0, 0.0, 1.0,		  1.0,   1.0,  1.0,		  0,  1,  0},// 6	-- MAGENT
{0.0, 1.0, 1.0,		 -1.0,   1.0,  1.0,	     -1,  0,  0}// 7	-- CYAN
};

GLubyte indices[12][3] = {
{0, 4, 7 },
{0, 7, 3 },
{5, 7, 4 },
{6, 7, 5 },
{3, 7, 6 },
{6, 2, 3 },
{6, 5, 1 },
{6, 1, 2 },
{3, 1, 0 },
{3, 2, 1 },
{5, 4, 0 },
{0, 1, 5 }
};

``````

The problem is. How do the opengl know which normal belongs to which triangle?

How do I say that the vector in the first line (0, -1, 0) belongs to the first face? and not to another one?

(reading the RedBook and it doesn’t explain it (as far as I’ve read it)).

Will I need to create another array with the same size of the INDICES array and the first vector will be the normal of the first triangle in INDICES array, the second vector the second in INDICES until it’s over? Is that how it works?

thanks!

OpenGL does not know about normal (or any other attribute) per face, only normal per vertex. If a vertex belongs to “x” different faces with “x” different normals then you have to create “x” vertices at the same position.

You have to duplicate normals and positions for each vertex because OpenGL does not allow indexing per attribute:

Thanks for the response.

So good thing about using INDEX (and VBO), which is been able to provide a single vertex and share it with other faces will not really work while working with normals? Correct me if I’m wrong.

If someone could show me a example of doing VBO with normals, would be awesome. I’ve google it but all examples didn’t helped. I need to see the array with the vertex, and normals to understand.

=]

thanks!

If your model is smooth, you can compute a normal per vertex by using some average of the normals of the faces sharing the vertex (the simplest to compute is just the average, then normalized the result). In this case, the vertex and all its attributes are shared between faces.

If you want to keep the sharpness of the some crease, like for displaying a cube, you have to duplicate the vertices and duplicate the normals.

For each vertex of a cube, you have to create 3 vertices, each one having a normal being the normal of one of the faces.

The discussion here is about the normals but it is true for any other attribute. Imaging you want to set a color per face, even if the model is motth, you have to duplicate the vertex and its attribute to be able to express that a position+color belongs to a specific face.

Thanks man!

I’ll try here with my cube!

You cannot have one set of indices for positions and another for normals. You need to replicate the position information if normals are different.

You can also consider flat shading too but that has it’s limitations, it won’t just share the normals it will share the vertex result for all interpolated positions (or attributes if yu have support for flat attributes in a shader environment).

thanks @dorbie.

So I’ll have to create multiple vertex in the same location because the share different faces. Just like overlay just said, right?

I thought faces had normals, and not vertex. =/

thanks everyone for the replies!

Mathematically faces have normals, but only vertices in OpenGL calculate lighting etc.

When you want to smooth shade something vertices have a normal that is some sort of average of the adjacent faces.

Flat shading in OpenGL is the simplest solution, but flat shading only takes the lighting result for ONE vertex and uses it for the entire polygon. This will not capture several lighting effects acurately.