GL_SPOT_CUTOFF的意外行为

时间:2014-08-16 15:23:03

标签: c++ opengl mfc

美好的一天,

我正在使用小型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 SPOT_CUTOFF is not set

这是GL_SPOT_CUTOFF设置为45.0时的情况 SPOT_CUTOFF is 45

白点表示light0的GL_POSITION。

2 个答案:

答案 0 :(得分:2)

要使聚光灯工作,你需要一些光线方向。然而,

GLfloat light0_direction[] = { 0.0, 0.0, 0.0}; //at the center of the cube

无法运作。你需要一个方向向量,而不是你想要光线指向的某个物体的位置。空向量根本就没有方向。

使用目标点和灯光位置之间的差异作为方向矢量。但要小心:灯光位置是在GL_MODELVIEW调用时由当前glLight()矩阵定义的局部对象空间中设置的。

如果您现在正在学习OpenGL,我强烈建议您来学习那些东西。 OpenGL照明是固定功能管道的一部分,自Ope​​nGL 3.0以来已弃用。您现在应该使用可编程管道("着色器")。

答案 1 :(得分:0)

通过将GL_SPOT_CUTOFF设置为定向聚光灯,您实际上是在定义一个光锥:

enter image description here

在您的应用程序中,您将聚光灯点设置为原点(0,0,0)。因此,如果您的聚光灯位置非常靠近具有GL_SPOT_CUTOFF约束的立方体,则只有正面(即面向光线的面)可以点亮。

默认情况下,GL_SPOT_CUTOFF180,即灯光向各个方向发出,这就是为什么在GL_SPOT_CUTOFF关闭时可以让灯光点亮的原因。< / p>

要解决此问题,请进一步移动聚光灯,或者只需关闭GL_SPOT_CUTOFF