我目前正在尝试使用opengl和过剩。 因为我不知道我在做什么,所以我完全搞砸了灯光。 完整的可编辑文件可在此处找到:main.c
我有一个显示循环,目前的操作如下:
glutDisplayFunc(also idle func)
:
glClear
GL_COLOR_BUFFER_BIT
和GL_DEPTH_BUFFER_BIT
- 切换到modelview矩阵
- 加载标识
- 首先根据相机的键盘和鼠标输入旋转然后翻译
- 在正面和背面画一个
封装glNormal
0,1,0和glMaterial
的地面, 由push / popmatrix- pushmatrix
- 翻译
glutSolidTeapod
- popmatrix
- 做照明相关的事情,glEnable GL_LIGHTING和LIGHT0并通过
float pos [] = {0.1,0.1,-0.1,0.1}; glLightfv(GL_LIGHT0,GL_POSITION,pos);- 交换缓冲区
醇>
与之相关的功能
glutReshapeFunc
运行(这来自lighthouse3d.com过量教程):
- 计算屏幕的比例
- 切换到投影矩阵
- loadidentity
- 设置视口
- 设置视角
- 切换到modelview矩阵
醇>
然而这一切似乎都以某种方式起作用, 但是当我启用照明时,法线似乎完全陷入困境。
我的GL_LIGHT0似乎保持原样,因为我可以看到地面上的光点 我不动,因为我四处走动
如果我移动相机,Teapods纹理似乎会移动, teapod本身静止不动。
这是一些解释它的视觉材料, 我为我糟糕的英语道歉:/
答案 0 :(得分:2)
您的代码中存在一系列错误:
您没有正确设置OpenGL窗口的属性:
glutCreateWindow (WINTITLE);
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitDisplayMode
只会影响您在之后创建的所有窗口。你应该交换这两行。
您永远不会启用深度测试。您应该在创建窗口后添加glEnable(GL_DEPTH_TEST)
。不使用深度测试会使用茶壶获得奇怪的“透视”效果。
您有以下代码
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茶壶就是这样定义的。有趣的是,您的地板也按照该规则绘制,因此它适合您的整个场景。至少现在(是。
您还没有完全理解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();
通过这些更改,我实际上可以在我的系统上获得点燃茶壶的预期效果。但正如我所说,我觉得有必要警告你几乎所有的代码都依赖于OpenGL的弃用的功能。这些东西已从现代版本的OpenGL中删除。如果你现在开始学习OpenGL,你应该考虑学习现代可编程管道,而不是几十年前过时的东西。