KOB
KOB

Reputation: 4565

Normals to a cube seem to be pointing inwards

I have written the following function to draw a cube:

void drawCube() {

   Point vertices[8] = { Point(-1.0, -1.0, -1.0), Point(-1.0, -1.0, 1.0), Point(1.0, -1.0, 1.0), Point(1.0, -1.0, -1.0),
                         Point(-1.0, 1.0, -1.0), Point(-1.0, 1.0, 1.0), Point(1.0, 1.0, 1.0), Point(1.0, 1.0, -1.0) };

   int faces[6][4] = {{0, 1, 2, 3}, {0, 3, 7, 4}, {0, 1, 5, 4}, {1, 2, 6, 5}, {3, 2, 6, 7}, {4, 5, 6, 7}};

   glBegin(GL_QUADS);

   for (unsigned int face = 0; face < 6; face++) {

     Vector v = vertices[faces[face][1]] - vertices[faces[face][0]];
     Vector w = vertices[faces[face][2]] - vertices[faces[face][0]];

     Vector normal = v.cross(w).normalised();

     glNormal3f(normal.dx, normal.dy, normal.dz);

     for (unsigned int vertex = 0; vertex < 4; vertex++) {

       switch (vertex) {
         case 0: glTexCoord2f(0, 0); break;
         case 1: glTexCoord2f(1, 0); break;
         case 2: glTexCoord2f(1, 1); break;
         case 3: glTexCoord2f(0, 1); break;
       }

       glVertex3f(vertices[faces[face][vertex]].x, vertices[faces[face][vertex]].y, vertices[faces[face][vertex]].z);
     }
   }

   glEnd();
}

When the cube is rendered with a light shining on to it, it appears that as I rotate the cube, the correct shading transitions are only happening for around half the faces. The rest just remain a very dark shade, as if I had removed the normal calculations.

I then decided to remove a couple of faces to see inside the cube. The faces that are not reflecting the light correctly on the outside, are doing so correctly on the inside. How can I ensure that the normal to each face is pointing out from that face, rather than in towards the centre of the cube?

Upvotes: 2

Views: 1146

Answers (2)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123431

Maybe there is a more efficient way, but a imho quite easy to understand way is the following....

Calculate the vector that points from the center of the side to the center of the cube. Call it

m = center cube - center side

Then calculate the scalar product of that vector with your normal:

x = < m , n >

The scalar product is positive if the two vectors point in the same direction with respect to the side (the angle between them is less than 90 degree). It is negative, if they point in opposite directions (angle is bigger than 90 degree). Then correct your normal via

if ( x > 0 ) n = -n;

to make sure it always points outwards.

Upvotes: 0

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32727

To reverse the direction of the normal, swap the order you use for the cross product:

Vector normal = w.cross(v).normalised();

Upvotes: 1

Related Questions