Opengl照明和法线

时间:2014-09-13 12:25:22

标签: c opengl

我目前正在尝试使用opengl和过剩。 因为我不知道我在做什么,所以我完全搞砸了灯光。 完整的可编辑文件可在此处找到:main.c

我有一个显示循环,目前的操作如下:

glutDisplayFunc(also idle func)

  
      
  1. glClear GL_COLOR_BUFFER_BITGL_DEPTH_BUFFER_BIT
  2.   
  3. 切换到modelview矩阵
  4.   
  5. 加载标识
  6.   
  7. 首先根据相机的键盘和鼠标输入旋转然后翻译
  8.   
  9. 在正面和背面画一个glNormal 0,1,0和glMaterial的地面,   由push / popmatrix
  10. 封装   
  11. pushmatrix
  12.   
  13. 翻译
  14.   
  15. glutSolidTeapod
  16.   
  17. popmatrix
  18.   
  19. 做照明相关的事情,glEnable GL_LIGHTING和LIGHT0并通过
      float pos [] = {0.1,0.1,-0.1,0.1};       glLightfv(GL_LIGHT0,GL_POSITION,pos);
  20.   
  21. 交换缓冲区
  22.   

与之相关的功能 glutReshapeFunc运行(这来自lighthouse3d.com过量教程):

  
      
  1. 计算屏幕的比例
  2.   
  3. 切换到投影矩阵
  4.   
  5. loadidentity
  6.   
  7. 设置视口
  8.   
  9. 设置视角
  10.   
  11. 切换到modelview矩阵
  12.   

然而这一切似乎都以某种方式起作用, 但是当我启用照明时,法线似乎完全陷入困境。 gl_lighting1

我的GL_LIGHT0似乎保持原样,因为我可以看到地面上的光点 我不动,因为我四处走动 gl_lighting2

如果我移动相机,Teapods纹理似乎会移动, teapod本身静止不动。

这是一些解释它的视觉材料, 我为我糟糕的英语道歉:/

Link to YouTube video describing visually

1 个答案:

答案 0 :(得分:2)

您的代码中存在一系列错误:

  1. 您没有正确设置OpenGL窗口的属性:

    glutCreateWindow (WINTITLE);
    glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    

    glutInitDisplayMode只会影响您在之后创建的所有窗口。你应该交换这两行。

  2. 您永远不会启用深度测试。您应该在创建窗口后添加glEnable(GL_DEPTH_TEST)。不使用深度测试会使用茶壶获得奇怪的“透视”效果。

  3. 您有以下代码

    glEnable (GL_CULL_FACE | GL_CULL_FACE_MODE);
    

    这在两个方面是错误的:GLenums不是单个位,而只是值。你不能将它们组合在一起并期望发生任何有用的事情。我不知道这个特定的调用是否会启用你不期望的东西,或者只是产生错误。

    这里的第二个问题是GL_CULL_FACE_MODE甚至不是启用的有效枚举。

    在你的情况下,你要么完全跳过CULL_FACE,要么你应该写

    glEnable (GL_CULL_FACE);
    glFrontFace(GL_CW);
    

    后者调用将面部方向从OpenGL的默认 counterclokcwise 规则更改为顺时针规则,因为GLUT茶壶就是这样定义的。有趣的是,您的地板也按照该规则绘制,因此它适合您的整个场景。至少现在(是。

  4. 您还没有完全理解GL的状态机是如何工作的。您绘制场景并然后设置光照。但这不会对已绘制的对象产生影响。它只会在下次绘制内容时产生影响,这将在下一帧中显示。现在,固定功能管道的照明在眼睛空间中起作用。这意味着如果您想要一个位于世界固定位置的光源,而不是相对于相机的固定位置,则必须使用更新的模型视图矩阵重新指定灯光位置,每次相机移动。在您的情况下,当相机移动时,光源将落后于一帧。这可能不明显,但原则上仍然是错误的。您应该将display()功能重新排序为

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity();
    control (WALKSPEED, MOUSESPEED, mousein);
    lightHandler();
    drawhelpgrid(1, 20);
    drawTeapod();
    glutSwapBuffers();
    
  5. 通过这些更改,我实际上可以在我的系统上获得点燃茶壶的预期效果。但正如我所说,我觉得有必要警告你几乎所有的代码都依赖于OpenGL的弃用的功能。这些东西已从现代版本的OpenGL中删除。如果你现在开始学习OpenGL,你应该考虑学习现代可编程管道,而不是几十年前过时的东西。