2

我目前正在使用 OpenGL 开发一个小玩具程序,该程序在剪辑空间视图中显示场景,即它绘制一个立方体以可视化规范视图体积,并在立方体内部绘制投影变换模型。要显示模型图的代码片段:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(projectionMat);
glMultMatrixd(modelviewMat);
glEnable(GL_LIGHTING);
draw_model();
glDisable(GL_LIGHTING);

因此,自然地,绘制的模型是“扭曲的”(这是所需的行为)。然而,照明是错误的,因为表面法线也被投影矩阵变换,因此在变换后与它们的表面不正交。我想要完成的是“正确”的照明,即扭曲模型的表面具有正确的法线。

问题是 - 我该怎么做?我正在使用通常的法线转置逆矩阵规则,但据我所知,这就是 OGL 默认情况下对其法线所做的事情。我想在用模型视图矩阵转换表面之后,我必须重新计算表面法线,但是该怎么做呢?还是有其他方法?

4

2 回答 2

1
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(projectionMat);

投影矩阵进入glMatrixMode(GL_PROJECTION);。变换法线发生在模型视图的逆转置中。如果模型视图中有一个投影组件,它会破坏您的正常转换。

正确的代码是

glMatrixMode(GL_PROJECTION);
glLoadMatrixd(projectionMat);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(modelviewMat);
glEnable(GL_LIGHTING);
draw_model();
glDisable(GL_LIGHTING);
于 2012-11-22T18:53:16.677 回答
0

如果您使用的是固定函数,则必须将所有这些都放在投影矩阵中。包括投影后发生的缩放、平移和旋转:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(projectionMat);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixd(modelviewMat);
glEnable(GL_LIGHTING);
draw_model();
glDisable(GL_LIGHTING);

这是因为位置(即:您所看到的)由投影和模型视图矩阵转换,但固定功能照明仅在视图空间中完成(即:在模型视图之后但投影之前)。

事实上,这正是固定函数 GL 在两个矩阵之间存在区别的原因。

于 2012-11-22T19:08:08.660 回答