I want to read PLY file. My problem is that when I apply normals to my object it looks not nice. I calculate normals for each triangle. Should I calculate normals for each vertex?
Rendered object has got bad looking shades.
External Media
each object it’s seperate file. It looks fine when I get calculated normals from cooked mesh in PhysX 3.2 and render it.
//--------------------------------------------------------------------
// CPLYReader class atributes
//--------------------------------------------------------------------
vector pxTriVertex; // vector of read vertexes from .ply file
vector normals; // vector of calculated normals
vector pxIndices; // vector of read vertexes from .ply file
//------------------------------------------------------
for(unsigned int i = 0; i < pxIndices.size(); i+=3)
{
vertex1 = pxTriVertex.at( pxIndices.at(i) );
vertex2 = pxTriVertex.at( pxIndices.at(i+1) );
vertex3 = pxTriVertex.at( pxIndices.at(i+2) );
normal = calculateNormal(vertex1,vertex2,vertex3);
normals.push_back(normal); // dodaj do wektora
}
//--------------------------------------------------------------
// calculate normal
//--------------------------------------------------------------
PxVec3 calculateNormal(PxVec3 vertex1, PxVec3 vertex2, PxVec3 vertex3)
{
// Licz wektory 1 i 2
PxVec3 v1, v2, vc, normal;
float value;
v1.x = vertex1.x - vertex2.x;
v1.y = vertex1.y - vertex2.y;
v1.z = vertex1.z - vertex2.z;
v2.x = vertex1.x - vertex3.x;
v2.y = vertex1.y - vertex3.y;
v2.z = vertex1.z - vertex3.z;
// iloczyn wektorowy (cross)
vc.x = (v1.y * v2.z) - (v2.y * v1.z);
vc.y = (v2.x * v1.z) - (v1.x * v2.z);
vc.z = (v1.x * v2.y) - (v2.x * v1.y);
// normalizacja
value = sqrt( (vc.x * vc.x) + (vc.y * vc.y) + (vc.z * vc.z) );
normal.x = vc.x / value;
normal.y = vc.y / value;
normal.z = vc.z / value;
return normal;
}
//------------------------------------------------------------
// OpenGL
//--------------------------------------------------------------
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//glEnable(GL_LIGHT1);
GLfloat ambient[4]={0.2f,0.2f,0.2f,1.0f};
GLfloat diffuse[4]={0.8,0.8,0.8,1.0f};
GLfloat specular[4]={0.0f, 0.0f, 0.0f, 1.0f};
GLfloat mat_diffuse[4]={0.85f,0.85f,0.85f,1.0f};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
GLfloat LightPosition[] = {10, 45, 0.0, 1.0};
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
//glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_diffuse);
glMaterialf(GL_FRONT, GL_SHININESS, 0.1 * 128.0);
/------------------------------------------------------
// render object
// vector ply;
// -----------------------------------------------------
glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
glEnable ( GL_COLOR_MATERIAL );
glColor3b(63,63,63);
glMultMatrixf(mat);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, ply[number].pxTriVertex.data() );
glNormalPointer(GL_FLOAT, 0, ply[number].normals.data());
glDrawElements(GL_TRIANGLES, ply[number].pxIndices.size() , GL_UNSIGNED_INT , ply[number].pxIndices.data() );
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable( GL_COLOR_MATERIAL);
glPopMatrix();
