1
\$\begingroup\$

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"<<endl;
}

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 enter image description here

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 enter image description here

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?

\$\endgroup\$
4
  • 2
    \$\begingroup\$ so you have a mesh and you want to calculate normals for it ? \$\endgroup\$
    – concept3d
    Dec 6, 2013 at 19:30
  • 2
    \$\begingroup\$ hm seems like perhaps a long-winded approach to a simple question :) \$\endgroup\$
    – Engineer
    Dec 6, 2013 at 19:31
  • \$\begingroup\$ @NickWiggill yes that's what I thought. \$\endgroup\$
    – concept3d
    Dec 6, 2013 at 19:31
  • \$\begingroup\$ I wanted to add as much as possible details. \$\endgroup\$
    – lapots
    Dec 6, 2013 at 19:39

1 Answer 1

6
\$\begingroup\$

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]);
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .