# Thread: Problem with declaring vertex normals

1. ## Problem with declaring vertex normals

Hello,
I'm programming a small game with BulletPhysics and OpenGL (2.1).
Yesterday I added lighting to the game, so I needed normals for the objects, too.
But I've got a problem with that:
I'm creating a cuboid with the following code:
Code :
```m_vVertices.pObj = new CVector3D[8];
GLfloat corners[] = {-vHalfExtents.x, vHalfExtents.y, vHalfExtents.z,
vHalfExtents.x, vHalfExtents.y, vHalfExtents.z,
vHalfExtents.x, -vHalfExtents.y, vHalfExtents.z,
-vHalfExtents.x, -vHalfExtents.y, vHalfExtents.z,
-vHalfExtents.x, vHalfExtents.y, -vHalfExtents.z,
vHalfExtents.x, vHalfExtents.y, -vHalfExtents.z,
vHalfExtents.x, -vHalfExtents.y, -vHalfExtents.z,
-vHalfExtents.x, -vHalfExtents.y, -vHalfExtents.z};
for (int i = 0; i < 8; ++i)
{
m_vVertices.pObj[i].x = corners[i*3];
m_vVertices.pObj[i].y = corners[i*3+1];
m_vVertices.pObj[i].z = corners[i*3+2];
}

m_VertexIndices.pObj = new GLuint[6*4];
GLubyte indices[] = {0, 1, 2, 3,
4, 5, 1, 0,
3, 2, 6, 7,
5, 4, 7, 6,
1, 5, 6, 2,
4, 0, 3, 7};
for (int i = 0; i < 24; ++i)
{
m_VertexIndices.pObj[i] = indices[i];
}```

Later, I'm rendering with this code:

Code :
```glEnableClientState(GL_VERTEX_ARRAY);

glVertexPointer(3, GL_FLOAT, 0, static_cast<void*>(m_vVertices.pObj));
static_cast<void*>(m_VertexIndices.pObj));

glDisableClientState(GL_VERTEX_ARRAY);```

But when I wanted to add normals, I had a problem: As far as I know OpenGL doesn't support surface normals, only vertex normals.
But because I'm reusing shared vertices with the help of an index array, I can't specify normals per vertex beacause - dependent on which face a vertex belongs to - each vertex can have different normals. Is there a way I can still use indices to specify the order of the vertices drawn or do I have to declare shared vertices multiple times (for every face needed)?

2. ## Re: Problem with declaring vertex normals

OK, I've just noticed that I misunderstood what vertex normals are ( http://www.opengl.org/discussion_boards/...;gonew=1#UNREAD : "for the normal at a vertex, sum the normals for all the triangles it is shared by; divided by the number of triangles; then normalise this vector" ).
So I tried it with the following code:

Code :
```m_vNormals.pObj = new CVector3D[8];
// Every vertex normal is set here
for (size_t i = 0; i < 8; ++i)
{
size_t  iNumI = 0; // number of this vertex in the indices
GLubyte *pIndices = 0; // locations where the vertex appears
CVector3D vVertNorm = CVector3D(0.0f, 0.0f, 0.0f); // the normal
for (size_t ii = 0; ii < 24; ++ii)
{
if (m_VertexIndices.pObj[ii] == i) ++iNumI; // number of this vertex is determined
}
pIndices = new GLubyte[iNumI];
size_t  iNumICounter = 0;
for (size_t ii = 0; ii < 24; ++ii)
{
// if this vertex appears in this location
if (m_VertexIndices.pObj[ii] == i)
{
pIndices[iNumICounter] = ii;
++iNumICounter;
}
}
for (size_t j = 0; j < iNumI; ++j)
{
size_t uiStartPos = pIndices[j]/4;
cerr << "uiStartPos: " << uiStartPos << "; iNumI: " << iNumI << endl;
CVector3D vAB = m_vVertices.pObj[m_VertexIndices.pObj[uiStartPos+1]]-m_vVertices.pObj[m_VertexIndices.pObj[uiStartPos]];
CVector3D vAC = m_vVertices.pObj[m_VertexIndices.pObj[uiStartPos+2]]-m_vVertices.pObj[m_VertexIndices.pObj[uiStartPos]];
vVertNorm += Vector3DNormalize(Vector3DCross(vAB, vAC));
}
vVertNorm /= iNumI;
vVertNorm = Vector3DNormalize(vVertNorm);
m_vVertices.pObj[i] = vVertNorm;
delete[] pIndices;
}```

But it showed some very strange result and doesn't seem to be correct.

Does somebody know what I've done wrong?

3. ## Re: Problem with declaring vertex normals

ok I check my code and I was wrong about the divide.

I have tried to make your code look like mine - beware it may not compile

Code :
```CVector  normal[8], temp;

for (int i = 0; i < 8; i++)
{
normal[i].x = normal[i].y = normal[i].z = 0;
}

for (int i = 0; i < 24; i += 3)
{
CVector3D vAB = m_vVertices.pObj[m_VertexIndices.pObj[i+1]]-m_vVertices.pObj[m_VertexIndices.pObj[i];
CVector3D vAC = m_vVertices.pObj[m_VertexIndices.pObj[i+2]]-m_vVertices.pObj[m_VertexIndices.pObj[i];
// normal for triangle face
temp = Vector3DCross(vAB, vAC);
// add normal to all vertices in triangle
for (int j = 0; j < 3; j++)
{
normal[m_VertexIndices.pObj[i+1]] += temp
}
}
// normalise vertex normals
for (int i = 0; i < 8; i++)
{
Vector3DNormalize(normal);
}```

4. ## Re: Problem with declaring vertex normals

Yes, the code seems to work (with some small corrections). But the faces seem to be drawn in a wrong way (only the faces inside seem to be drawn).
But it doesn't seem to help to to put a minus sign in front of "normal" (code:
Code :
```// normalise vertex normals
for (int i = 0; i < 8; i++)
{
normal[i] = Vector3DNormalize(normal[i]);
m_vNormals.pObj[i] = -normal[i];
}```
).
Does someone know what I have to change in the code so that it works correctly?

5. ## Re: Problem with declaring vertex normals

The normal has a direction, so it can point in or out depending on the order of the vertices. You can reverse the normal by reversing the cross product

if Vector3DCross(vAB, vAC) points in, then Vector3DCross(vAC, vAB) points out.

Google a bit on normals and you find something with a diagram.

6. ## Re: Problem with declaring vertex normals

I've tried it with reversed normals but it didn't seem to help ( here you can see the results (the right picture uses vAB, vAC and the left picture vAC, vAB): http://dl.dropbox.com/u/32334047/VertexNormals.png ).
Here the output of the program that produces the right image (with "cerr << (m_vNormals.pObj[i]).x << "; " << (m_vNormals.pObj[i]).y << "; " << (m_vNormals.pObj[i]).z << endl;"):
Code :
```0; 0; 1
-0.707107; 0; -0.707107
-0.0499376; -0.998752; 0
1; 0; 0
0; -1; -2.48353e-09
-nan; -nan; -nan
0; 1; 0
-nan; -nan; -nan```
And here the output of the program that produces the left image:
Code :
```0; 0; -1
0.707107; 0; 0.707107
0.0499376; 0.998752; 0
-1; 0; 0
0; 1; 2.48353e-09
-nan; -nan; -nan
0; -1; 0
-nan; -nan; -nan```

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•