I've got a landscape(created in Photoshop .raw file) and a .tga texture for it. I read .raw file and read .tga file like this
LoadRawFile("landscape.Raw", MapSize * MapSize, &HeightMap[0][0]);
Texture landscape;
if (LoadTGA(&landscape, "landscape.tga")) {
glGenTextures(1, &landscape.texID);
glBindTexture(GL_TEXTURE_2D, landscape.texID);
glTexImage2D(GL_TEXTURE_2D,
0,
landscape.bpp / 8,
landscape.width,
landscape.height,
0,
landscape.type,
GL_UNSIGNED_BYTE,
landscape.imageData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (landscape.imageData) free(landscape.imageData);
} else {
cout<<"Cannot load texture"< }
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer (3, GL_FLOAT, 0, VertexMap);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, TextureMap);
for (int Row=0; Row < MapSize*2; Row++)
{
Indices[Row] = Row;
}
I render landscape like this(method renderLandscape
)
int x, y, i, j;
int Index = 0;
for (i = 0; i < MapSize-1; i++)
{
Index = 0;
for (j = 0;j < MapSize-1; j++)
{
x = j * Zoom;
y = i * Zoom;
TextureMap[Index+0][0]= j * TextureBit;
TextureMap[Index+0][1]= i * TextureBit;
TextureMap[Index+1][0]= j * TextureBit;
TextureMap[Index+1][2]= (i+1) * TextureBit;
VertexMap[Index+0][2] = HeightMap[j][i];
VertexMap[Index+1][2] = HeightMap[j][i+1];
VertexMap[Index+0][0] = x;
VertexMap[Index+0][3] = y;
VertexMap[Index+1][0] = x;
VertexMap[Index+1][4] = y+Zoom;
Index += 2;
}
glDrawElements(GL_TRIANGLE_STRIP, Index, GL_UNSIGNED_INT, Indices);
}
draw
method
glPushMatrix();
glTranslatef(-20, 0, 0);
glScalef(0.01, 0.01, 0.01);
glRotatef(90, 1, 0, 0);
landscape.RenderLandscape();
glPopMatrix();
So by default(without lighting) it looks like this
But when I enable lighting(add this lines to my opengl init
function)
GLfloat light_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
The result landscape looks like this
I don't need any special or difficult lighting. So it seems I need to calculate normales(I am new in opengl and usually create .obj models where vn
precalculated). What is the best way to calculate normales in my case?
Answer
This is how you calculate normals for a mesh. This methods averages vertex normals that is shared by multiple faces.
void CalculateNormals()
{
size_t vertexCount = m_triangles.size();
m_normals.reserve( m_vertices.size() );
for( int i = 0; i < vertexCount; i += 3 )
{
// get the three vertices that make the faces
glm::vec3 p0 = m_vertices[m_triangles[i+0]];
glm::vec3 p1 = m_vertices[m_triangles[i+1]];
glm::vec3 p2 = m_vertices[m_triangles[i+2]];
glm::vec3 e1 = p1 - p0;
glm::vec3 e2 = p2 - p0;
glm::vec3 normal = glm::cross( e1, e2 );
normal = glm::normalize(normal);
// Store the face's normal for each of the vertices that make up the face.
m_normals[m_triangles[i+0]] += normal ;
m_normals[m_triangles[i+1]] += normal ;
m_normals[m_triangles[i+2]] += normal ;
}
// Now loop through each vertex vector, and avarage out all the normals stored.
for( int i = 0; i < m_normals.size(); ++i )
{
m_normals[i] = glm::normalize(m_normals[i]);
}
}
No comments:
Post a Comment