opengl GL_SPOT_CUTOFF的意外行为

ffscu2ro  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(147)

大家好
我正在使用一个小型MFC应用程序探索OpenGL中的照明,该应用程序绘制了一个以(0,0,0)为中心的立方体和一个光源。
然而,当我设置GL_SPOT_CUTOFF时,光源(如果我可以说-出乎意料地)关闭。
这是cube的代码:

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),light 0都会熄灭。有什么线索吗?我对OpenGL很陌生,所以我相信我的代码缺少了什么或者做错了什么。
这是在不设置GL_SPOT_CUTOFF x1c 0d1x的情况下进行的
此时GL_SPOT_CUTOFF设置为45.0

白色点表示light 0的GL_POSITION。

ncecgwcz

ncecgwcz1#

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

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

字符串
你需要一个方向向量,而不是你想让光线指向的物体的位置,空向量根本就没有方向。
使用目标点和灯光位置之间的差值作为方向向量。但要注意:灯光位置是在调用glLight()时在当前GL_MODELVIEW矩阵定义的局部对象空间中设置的。
如果你现在正在学习OpenGL,我强烈建议你不要学那些东西。OpenGL光照是 * 固定函数管道 * 的一部分,从OpenGL 3.0开始就不推荐了。你现在应该使用 * 可编程管道 *(“着色器”)。

bfrts1fy

bfrts1fy2#

通过将GL_SPOT_CUTOFF设置为平行聚光灯,实际上是在定义照明圆锥体:


的数据
在您的应用程序中,您可以将聚光灯点设定为原点(0,0,0)。因此,如果聚光灯位置非常接近具有GL_SPOT_CUTOFF约束的立方体,则只有正面(即,面向光源的面)可以被照亮。
默认情况下,GL_SPOT_CUTOFF180,即灯光向所有方向发射,这就是为什么在GL_SPOT_CUTOFF关闭时可以点亮立方体的原因。
若要解决此问题,请将聚光灯移远一点,或直接关闭GL_SPOT_CUTOFF

相关问题