美好的一天,
我正在使用小型MFC应用程序在OpenGL中探索Lighting,该应用程序绘制以(0,0,0)为中心的立方体和单个光源。
然而,当我设置GL_SPOT_CUTOFF时,光源(如果我可能会说 - 意外地)会关闭。
这是立方体的代码:
void CGLRenderer::DrawCube(float a)
{
GLfloat mat_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat mat_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_emission[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_shininess = 64.0;
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
//glShadeModel(GL_FLAT);
glEnable(GL_NORMALIZE);
glBegin(GL_QUAD_STRIP);
//front
glColor3f(1.0, 0.0, 0.0);
glNormal3f(0.0, 0.0, 1.0);
glVertex3f(-a / 2, -a / 2, a / 2);
glVertex3f(-a / 2, a / 2, a / 2);
glVertex3f(a / 2, -a / 2, a / 2);
glVertex3f(a / 2, a / 2, a / 2);
//right
glColor3f(0.0, 1.0, 0.0);
glNormal3f(1.0, 0.0, 0.0);
glVertex3f(a / 2, -a / 2, -a / 2);
glVertex3f(a / 2, a / 2, -a / 2);
//back
glColor3f(0.0, 0.0, 1.0);
glNormal3f(0.0, 0.0, -1.0);
glVertex3f(-a / 2, -a / 2, -a / 2);
glVertex3f(-a / 2, a / 2, -a / 2);
//left
glColor3f(0.0, 1.0, 1.0);
glNormal3f(-1.0, 0.0, 0.0);
glVertex3f(-a / 2, -a / 2, a / 2);
glVertex3f(-a / 2, a / 2, a / 2);
glEnd();
glBegin(GL_QUADS);
//top
glColor3f(1.0, 1.0, 0.0);
glNormal3f(0.0, 1.0, 0.0);
glVertex3f(-a / 2, a / 2, a / 2);
glVertex3f(a / 2, a / 2, a / 2);
glVertex3f(a / 2, a / 2, -a / 2);
glVertex3f(-a / 2, a / 2, -a / 2);
//bottom
glColor3f(1.0, 0.0, 1.0);
glNormal3f(0.0, -1.0, 0.0);
glVertex3f(-a / 2, -a / 2, a / 2);
glVertex3f(a / 2, -a / 2, a / 2);
glVertex3f(a / 2, -a / 2, -a / 2);
glVertex3f(-a / 2, -a / 2, -a / 2);
glEnd();
}
对于光明:
void CGLRenderer::SetUpLight()
{
GLfloat mod_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, mod_ambient);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
GLfloat light0_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat light0_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light0_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light0_position[] = { mLight0_x, mLight0_y, mLight0_z, 1.0 };
GLfloat light0_direction[] = { 0.0, 0.0, 0.0}; //at the center of the cube
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0_direction);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);
//glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
无论我为GL_SPOT_CUTOFF设置了什么值(0.0-90.0),light0都会熄灭。 任何线索为什么会发生这种情况?我是OpenGL的新手,所以我相信我的代码缺失或者做错了。
没有设置GL_SPOT_CUTOFF
这是GL_SPOT_CUTOFF设置为45.0时的情况
白点表示light0的GL_POSITION。
答案 0 :(得分:2)
要使聚光灯工作,你需要一些光线方向。然而,
GLfloat light0_direction[] = { 0.0, 0.0, 0.0}; //at the center of the cube
无法运作。你需要一个方向向量,而不是你想要光线指向的某个物体的位置。空向量根本就没有方向。
使用目标点和灯光位置之间的差异作为方向矢量。但要小心:灯光位置是在GL_MODELVIEW
调用时由当前glLight()
矩阵定义的局部对象空间中设置的。
如果您现在正在学习OpenGL,我强烈建议您不来学习那些东西。 OpenGL照明是固定功能管道的一部分,自OpenGL 3.0以来已弃用。您现在应该使用可编程管道("着色器")。
答案 1 :(得分:0)
通过将GL_SPOT_CUTOFF
设置为定向聚光灯,您实际上是在定义一个光锥:
在您的应用程序中,您将聚光灯点设置为原点(0,0,0)。因此,如果您的聚光灯位置非常靠近具有GL_SPOT_CUTOFF
约束的立方体,则只有正面(即面向光线的面)可以点亮。
默认情况下,GL_SPOT_CUTOFF
为180
,即灯光向各个方向发出,这就是为什么在GL_SPOT_CUTOFF
关闭时可以让灯光点亮的原因。< / p>
要解决此问题,请进一步移动聚光灯,或者只需关闭GL_SPOT_CUTOFF
。