Question

here is my Setup() function:

void Setup()  // TOUCH IT !! 
{ 
    glEnable(GL_LIGHTING);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_COLOR_MATERIAL);

    //Parameter handling
    glShadeModel (GL_SMOOTH);
    //glEnable(GL_NORMALIZE); 

    glDepthFunc(GL_LEQUAL);  //renders a fragment if its z value is less or equal of the stored value
    glClearDepth(1);

    //Set up light source
    GLfloat light_position[] = { 20.0, 0.0, 0.0, 0.0 };
    GLfloat ambientLight[] = { 0.3, 0.3, 0.3, 1.0 };
    GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0 };

    glLightfv( GL_LIGHT0, GL_POSITION, light_position);
    glLightfv( GL_LIGHT0, GL_AMBIENT, ambientLight );
    glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseLight );


    glEnable(GL_LIGHT0);

    // polygon rendering mode
    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CCW);

    glColorMaterial( GL_FRONT, GL_EMISSION );
    // material identities
    float specReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    float ambReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    float diffReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection);
    glMaterialfv(GL_FRONT, GL_AMBIENT, ambReflection);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, diffReflection);
    glMateriali(GL_FRONT,GL_SHININESS,20);


    //// about texture
    //glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);   

    // Black background
    glClearColor(0.0f,0.0f,0.0f,1.0f);

}

here is my CalcNormal() function, where normals are being calculated. v1 and v2 are two vectors of a triangle:

Point CalcNormal(Point v1, Point v2)
{
    Point normal;

    normal.x = v1.y*v2.z - v1.z*v2.y;       
    normal.y = -v1.x*v2.z + v2.x*v1.z;
    normal.z = v1.x*v2.y - v2.x*v1.y;

    float dist1 = sqrt( pow(v1.x,2) + pow(v1.y,2) + pow(v1.z,2));
    float dist2 = sqrt( pow(v2.x,2) + pow(v2.y,2) + pow(v2.z,2));
    float dist = dist1*dist2;

    normal.x = normal.x/dist;
    normal.y = normal.y/dist;
    normal.z = normal.z/dist;

    return normal;

}

here is the vectors i send to CalcNormal():

Point n;
Point a1, a2;
a1.x=triangles.at(i).p2.x-triangles.at(i).p1.x; a1.y=triangles.at(i).p2.y-triangles.at(i).p1.y; a1.z=triangles.at(i).p2.z-triangles.at(i).p1.z;
a2.x=triangles.at(i).p3.x-triangles.at(i).p1.x; a2.y=triangles.at(i).p3.y-triangles.at(i).p1.y; a2.z=triangles.at(i).p3.z-triangles.at(i).p1.z;
n = CalcNormal(a1, a2);

and the result is like this:

rendering result

Was it helpful?

Solution

For smooth shading to be effective, you also need smooth normals - per vertex. The code you have posted so far shown only per-triangle normal calculations. In that case, the result will still look flat.

The easiest way to get smooth normals is, after you have calculated a normal per triangle, to average all normals of the adjacent triangles of each vertex. More complex schemes use a weighted average based on some function of the area of the triangles. There are also some heuristics whcih try to conserve hard edges, but as it is always the case with heuristics, there will always be some corner cases. Ideally, the normals are created when the model is created and stored in the file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top