I have been able to get everything to work, after a lot of PM between me and haegarr (big thank you for that!).
Here are some screenshots:
Red ambient mixed with white diffuse light...
Red ambient light only...
White diffuse light only...
And this is how I compute the normals:
void cterrain::load_normals ( void ){ trn = new cdata[MAP_SIZE * MAP_SIZE * 3]; normals = new cdata[MAP_SIZE * MAP_SIZE * 3]; for ( int x = 0; x < MAP_SIZE ; x++ ) // loop through horizontal data { for ( int z = 0; z < MAP_SIZE; z++ ) // loop through vertical data { // get vertex data trn[x + ( z * MAP_SIZE )].x = ( float ) x; trn[x + ( z * MAP_SIZE )].y = ( float ) get_height ( x, z ); trn[x + ( z * MAP_SIZE )].z = ( float ) z; } } float DELTA = STEP_SIZE; // to be scaled if the unit length between 2 neighboured vertices should differ from 1 for ( x = 0; x < MAP_SIZE - STEP_SIZE; x += STEP_SIZE ) { for ( int z = 0; z < MAP_SIZE - STEP_SIZE; z += STEP_SIZE ) { // preparations int base = z * MAP_SIZE + x; // involved vertices const cdata& v0 = trn[base]; // upper left vertex of quad const cdata& v1 = trn[base + STEP_SIZE]; // upper right vertex of quad const cdata& v2 = trn[base + MAP_SIZE * STEP_SIZE]; // lower left vertex of quad const cdata& v3 = trn[base + MAP_SIZE * STEP_SIZE + STEP_SIZE]; // lower right vertex of quad // edges of the quad cdata e01 ( // edge from v0 to v1 DELTA, // v1.x - v0.x; v1.y - v0.y, 0.0f ); // v1.z - v0.z; cdata e02 ( // edge from v0 to v2 0.0f, // v2.x - v0.x; v2.y - v0.y, DELTA ); // v2.z - v0.z; cdata e31 ( // edge from v3 to v1 0.0f, // v1.x - v3.x; v1.y - v3.y, -DELTA ); // v1.z - v3.z; cdata e32 ( // edge from v3 to v2 -DELTA, // v2.x - v3.x; v2.y - v3.y, 0.0f ); // v2.z - v3.z; // the both normals cdata n012 = e02.cross ( e01 ); // normal of tris of vertices v0, v1, v2 cdata n213 = e31.cross ( e32 ); // normal of tris of vertices v2, v1, v3 n012.normalize ( ); n213.normalize ( ); // accumulate normals ... cdata& n0 = normals[base]; // at upper left vertex of quad cdata& n1 = normals[base + STEP_SIZE]; // at upper right vertex of quad cdata& n2 = normals[base + MAP_SIZE * STEP_SIZE]; // at lower left vertex of quad cdata& n3 = normals[base + MAP_SIZE * STEP_SIZE + STEP_SIZE]; // at lower right vertex of quad // ... of tri 012 n0 += n012; n1 += n012; n2 += n012; n0 += n012; // double to consider 90 degree angle of adjacent face // ... of tri 213 n2 += n213; n3 += n213; n1 += n213; n3 += n213; // double to consider 90 degree angle of adjacent face } for ( int x = 0; x < MAP_SIZE - STEP_SIZE; x += STEP_SIZE ) { for ( int z = 0; z < MAP_SIZE - STEP_SIZE; z += STEP_SIZE ) { normals[z * MAP_SIZE + x].normalize ( ); } } }}
Next thing to worry about is textures...