opengl GL_SPOT_CUTOFF的意外行为

ffscu2ro  于 2024-01-07  发布在  其他
关注(0)|答案(2)|浏览(234)

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

  1. void CGLRenderer::DrawCube(float a)
  2. {
  3. GLfloat mat_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
  4. GLfloat mat_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
  5. GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  6. GLfloat mat_emission[] = { 0.0, 0.0, 0.0, 1.0 };
  7. GLfloat mat_shininess = 64.0;
  8. glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
  9. glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
  10. glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
  11. glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
  12. glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
  13. //glShadeModel(GL_FLAT);
  14. glEnable(GL_NORMALIZE);
  15. glBegin(GL_QUAD_STRIP);
  16. //front
  17. glColor3f(1.0, 0.0, 0.0);
  18. glNormal3f(0.0, 0.0, 1.0);
  19. glVertex3f(-a / 2, -a / 2, a / 2);
  20. glVertex3f(-a / 2, a / 2, a / 2);
  21. glVertex3f(a / 2, -a / 2, a / 2);
  22. glVertex3f(a / 2, a / 2, a / 2);
  23. //right
  24. glColor3f(0.0, 1.0, 0.0);
  25. glNormal3f(1.0, 0.0, 0.0);
  26. glVertex3f(a / 2, -a / 2, -a / 2);
  27. glVertex3f(a / 2, a / 2, -a / 2);
  28. //back
  29. glColor3f(0.0, 0.0, 1.0);
  30. glNormal3f(0.0, 0.0, -1.0);
  31. glVertex3f(-a / 2, -a / 2, -a / 2);
  32. glVertex3f(-a / 2, a / 2, -a / 2);
  33. //left
  34. glColor3f(0.0, 1.0, 1.0);
  35. glNormal3f(-1.0, 0.0, 0.0);
  36. glVertex3f(-a / 2, -a / 2, a / 2);
  37. glVertex3f(-a / 2, a / 2, a / 2);
  38. glEnd();
  39. glBegin(GL_QUADS);
  40. //top
  41. glColor3f(1.0, 1.0, 0.0);
  42. glNormal3f(0.0, 1.0, 0.0);
  43. glVertex3f(-a / 2, a / 2, a / 2);
  44. glVertex3f(a / 2, a / 2, a / 2);
  45. glVertex3f(a / 2, a / 2, -a / 2);
  46. glVertex3f(-a / 2, a / 2, -a / 2);
  47. //bottom
  48. glColor3f(1.0, 0.0, 1.0);
  49. glNormal3f(0.0, -1.0, 0.0);
  50. glVertex3f(-a / 2, -a / 2, a / 2);
  51. glVertex3f(a / 2, -a / 2, a / 2);
  52. glVertex3f(a / 2, -a / 2, -a / 2);
  53. glVertex3f(-a / 2, -a / 2, -a / 2);
  54. glEnd();
  55. }

字符串
对于光:

  1. void CGLRenderer::SetUpLight()
  2. {
  3. GLfloat mod_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
  4. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, mod_ambient);
  5. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
  6. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
  7. GLfloat light0_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
  8. GLfloat light0_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  9. GLfloat light0_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
  10. GLfloat light0_position[] = { mLight0_x, mLight0_y, mLight0_z, 1.0 };
  11. GLfloat light0_direction[] = { 0.0, 0.0, 0.0}; //at the center of the cube
  12. glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
  13. glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
  14. glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
  15. glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
  16. glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0_direction);
  17. glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);
  18. //glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.0);
  19. glEnable(GL_LIGHTING);
  20. glEnable(GL_LIGHT0);
  21. }


无论我为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#

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

  1. 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

相关问题