我必须从ASE文件中读取3D对象。对于我必须创建的世界来说,这个对象变得太大了,因此,我必须缩小它。
原始尺寸适当照明。
然而,一旦我缩小它,就会变得过饱和。
世界以(0,0,0)为中心,它是100 米长( y 轴)和50 米宽( x 轴),我的 upVector 是(0,0,1)。在(-20,-35,750)中有两个灯, light0 (20,35,750)和 light1 。
代码的相关部分:
void init(void){
glClearColor(0.827, 0.925, 0.949, 0.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
GLfloat difusa[] = { 1.0f, 1.0f, 1.0f, 1.0f}; // white light
glLightfv(GL_LIGHT0, GL_DIFFUSE, difusa);
glLightfv(GL_LIGHT1, GL_DIFFUSE, difusa);
loadObjectFromFile("objeto.ASE");
}
void display ( void ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eyeX, eyeY, eyeZ, atX, atY, atZ, 0.0, 0.0, 1.0);
GLfloat posicion0[] = { 20.0f, 35.0f, 750.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, posicion0);
GLfloat posicion1[] = { -20.0f, -35.0f, 750.0f, 1.0f};
glLightfv(GL_LIGHT1, GL_POSITION, posicion1);
glColor3f(0.749, 0.918, 0.278);
glPushMatrix();
glTranslatef(0.0, 0.0, 1.5);
//Here comes the problem
glScalef(0.08, 0.08, 0.08);
glBegin(GL_TRIANGLES);
for(int i = 0; i < numFaces; i++){
glNormal3d(faces3D[i].n.nx, faces3D[i].n.ny, faces3D[i].n.nz);
glVertex3d(vertex[faces3D[i].s.A].x, vertex[faces3D[i].s.A].y, vertex[faces3D[i].s.A].z);
glVertex3d(vertex[faces3D[i].s.B].x, vertex[faces3D[i].s.B].y, vertex[faces3D[i].s.B].z);
glVertex3d(vertex[faces3D[i].s.C].x, vertex[faces3D[i].s.C].y, vertex[faces3D[i].s.C].z);
}
glEnd();
glPopMatrix();
glutSwapBuffers();
}
为什么在缩小对象时光线会失效?
答案 0 :(得分:5)
您遇到的问题是,缩放模型视图矩阵也会影响“正常矩阵”法线的转换。 “正常矩阵”实际上是模型视图矩阵的逆的转置。因此,通过缩小模型视图矩阵,您可以放大普通矩阵(因为用于获取它的模型视图反转步骤)。
因为必须重新调整转换的法线,或者如果模型视图矩阵的比例不是单一的,则标准化。在固定功能OpenGL中有两种方法可以做到这一点:正常规范化(听起来很有趣,我知道)和正常的重新缩放。您可以使用
启用glEnable(GL_NORMALIZE);
glEnable(GL_RESCALE_NORMALS);
在着色器中,您只需将转换后的法线
标准化#version ...
uniform mat3 mat_normal;
in vec3 vertex_normal;
void main()
{
...
vec3 view_normal = normalize( mat_normal * vertex_normal );
...
}
答案 1 :(得分:3)
根据GL_NORMALIZE和GL_RESCALE_NORMALS的设置,您的法线可以通过OpenGL-Pipeline进行转换。
从glEnable(GL_NORMALIZE)
开始,看看是否能解决您的问题