I'm in the process of learning Open GL and am having issues with lighting on my Terrian, I don't know if the issue is related to how I calculate my normals or the shader itself (I am using the shader from the Open GL wikibook - Lighting Arc tutorial 1). I calculate the normals like this:
void Terrian::construct_normals() {
terrian_normals.reserve(width * height);
for (int i = 0; i < terrian_elements.size() / 3; i++) {
int index1 = terrian_elements.at(i * 3);
int index2 = terrian_elements.at(i * 3 + 1);
int index3 = terrian_elements.at(i * 3 + 2);
glm::vec3 side1 = terrian_vertices.at(index1) - terrian_vertices.at(index3);
glm::vec3 side2 = terrian_vertices.at(index1) - terrian_vertices.at(index2);
glm::vec3 normal = glm::cross(side1, side2);
normal = glm::normalize(normal);
terrian_normals.emplace_back(normal);
terrian_normals.emplace_back(normal);
terrian_normals.emplace_back(normal);
}
std::cout << "Terrian Vertices: " << terrian_vertices.size() << "\nTerrian Normals: " << terrian_normals.size();
}
And the vertex shader can be viewed here:
http://pastebin.com/3vU8SHvK
Here's what the terrain looks like:

If you would like me to post any more of my code I would be happy to do so.
Edit:
Vertices:
void Terrian::construct_vertices() {
terrian_vertices.reserve(width * height);
terrian_colors.reserve(width * height);
std::cout << "Generating data\n";
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int i = x + y * width;
terrian_vertices.emplace_back(glm::vec3(x, terrian_heightmap[y][x], -y));
terrian_colors.emplace_back(Color(0.0, 1.0, 0.0, true));
}
}
}
and elements:
void Terrian::construct_elements() {
terrian_elements.reserve((width - 1) * (height - 1) * 6);
for (int y = 0; y < height - 1; y++) {
for (int x = 0; x < width - 1; x++) {
GLushort bottom_left = x + y * width;
GLushort bottom_right = (x + 1) + y * width;
GLushort top_left = x + (y + 1) * width;
GLushort top_right = (x + 1) + (y + 1) * width;
terrian_elements.emplace_back(top_left);
terrian_elements.emplace_back(bottom_right);
terrian_elements.emplace_back(bottom_left);
terrian_elements.emplace_back(top_left);
terrian_elements.emplace_back(top_right);
terrian_elements.emplace_back(bottom_right);
}
}
}