显示STL模型, 全部都是三角面片, 使用光照需要注意三角面片的法线, 法线的归一化尤为重要。
模型经过glScale变换之后, 原来的法线变得不正确, 光照效果变得不理想。解决此问题的方法是
启用OpenGL自动法线单位化功能,该功能会影响性能。
glEnable( GL_NORMALIZE );
较好的方法是提前将STL模型的法线单位化。
另外需要注意的是, 观察位置gluLookAt常常要与光照一起设置。
以下是经验使用方式:
void SetLight()
{
GLFloat box = stlObj.GetQuad().box(); // 表示模型的最大范围
GLFloat eye[3] = { box*2.0, box*3.0, box*4.0 };
gluLookAt(eye[0], eye[1], eye[2], 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
GLfloat lightPos[4] = { eye[0]*100.0, eye[1]*100.0, eye[2]*100.0, 0.0 };
GLfloat ambientLight[4] = { 0.6, 0.6, 0.6, 1.0 };
GLfloat diffuseLight[4] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat specularLight[4] = { 0.2, 0.6, 0.8, 1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glLightModelf(GL_LIGHT_MODEL_AMBIENT, GL_TRUE);
glEnable(GL_COLOR_MATERIAL); // 使用颜色跟踪
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_NORMALIZE); // 自动法线单位化
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
}
void OnDraw()
{
SetViewPortSize();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
glEnable(GL_AUTO_NORMAL);
glTranslated(m_move[0], m_move[1], m_move[2]);
SetLight(); // 放在单位模型矩阵后面, 平移变换之后。gluLookAt放在平移之后,操作才更接近理想效果
glRotated(m_rotate[0], 1.0, 0.0, 0.0);
glRotated(m_rotate[1], 0.0, 1.0, 0.0);
glRotated(m_rotate[2], 0.0, 0.0, 1.0);
glScaled(m_scale, m_scale, m_scale);
m_stlObj.Draw();
glFlush();
SwapBuffers(m_hDC);
}