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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.