opengl 光照位置问题??急!!! 10
在做一个opengl程序的时候,想设置一个固定位置光源,但是不管我怎么改变光源位置,光源始终跑到远点,并且旋转物体时物体的颜色会发生明暗变化???...
在做一个opengl程序的时候,想设置一个固定位置光源,但是不管我怎么改变光源位置,光源始终跑到远点,并且旋转物体时物体的颜色会发生明暗变化???
展开
4个回答
展开全部
光源的位置就应该是其在世界坐标系中的位置,不管经过什么变换,光源和场景中物体的相对位置是不应该变的。openGL中的这个现象是openGL的一个bug,跟坐标变换没有关系。
在openGL中,顶点每被提交一次,就被模型视图矩阵变换一次,而变换后的坐标,即,眼脊清睛坐标系中的坐标,被存储起来,用以绘图。所谓“提交”就是指调用说明顶点坐标的函数,比如glVertex3d。对于光源,这个提交函数就是glLightfv函数。如饥耐果在MyInit函数中指定光源位置,提交的坐标值就是世界坐标值。如果在此之后才调用gluLookAt函数,则在提交光源坐标时,模型视图矩阵是单位阵。经此单位阵变换后的光源坐标被存储起来。假如在MyDisplay函数中不再设置光源的位置,也就是不再“提交”光源的位置,则openGL不会再重新计算光源的眼睛坐标值,仍然使用MyInit中计算出来的值。那么,就会出现这种现象:在MyInit后,调用gluLookAt设置了眼睛坐标系,从而也修改了模型视图矩阵,按道理来讲,光源的眼睛坐标值应该随着模型视图矩阵而变,但因为没有再次“提交”光源坐标,openGL仍然沿用使用单位矩阵计算出来的光源位置,这就造成了眼睛(坐标系)移动,光源也移动的现象发生。因为openGL中存储的光源坐标不随着眼睛位置的变化而被重新计算,总是一个定值。在绘图时,不管眼睛在哪里,openGL总是在当时的眼睛坐标系中按照一个固定的坐标值安置光源,所以,光源就随着眼睛移动了。
而,网上流行的什么光源随眼睛移动是因为被模型视图矩阵变换了坐标值的说法是完全错误的。试想,世界坐标系中的一个有固定坐标的点,不论经过了怎样的坐标变换,只是对这个点的位置的描述变了,但这个点在空间中的位置不会变。而引起大家疑惑的现象是:光源的位置在空间中发生了变化,这决不是模型视图矩阵能够做到的。
我前边说了一句:“在glLightfv之后,调用gluLookAt”,好像这个顺序有什么要紧,其实
无所谓。我这次特地来说明这点。
其实,不管是在gluLookAt之前还是之后调用glLightfv函数,只要是程序中在MyDisplay()
之外指定了光源位置,那么光源位置都会按照当时的模型视图矩阵的值被计算为一个固定的
值。那么当眼睛位置变换时,光源总会按照这个固定坐标值被绘制到当前的眼睛坐标系中,
因此光源就会随着眼睛移动了。而MyDisplay函数由于会被不断地调用,因此如果在该函数
中制定光源位置,则每次光源坐标都会被重新提交,与之对应的眼睛坐标也会被重新计算,
这就可以反映当前最新的模型视图矩阵的变化。烂野春因此光源位置就固定了。
总之:光源位置是以视觉坐标存储的,弄清这一点,问题就解决了
在openGL中,顶点每被提交一次,就被模型视图矩阵变换一次,而变换后的坐标,即,眼脊清睛坐标系中的坐标,被存储起来,用以绘图。所谓“提交”就是指调用说明顶点坐标的函数,比如glVertex3d。对于光源,这个提交函数就是glLightfv函数。如饥耐果在MyInit函数中指定光源位置,提交的坐标值就是世界坐标值。如果在此之后才调用gluLookAt函数,则在提交光源坐标时,模型视图矩阵是单位阵。经此单位阵变换后的光源坐标被存储起来。假如在MyDisplay函数中不再设置光源的位置,也就是不再“提交”光源的位置,则openGL不会再重新计算光源的眼睛坐标值,仍然使用MyInit中计算出来的值。那么,就会出现这种现象:在MyInit后,调用gluLookAt设置了眼睛坐标系,从而也修改了模型视图矩阵,按道理来讲,光源的眼睛坐标值应该随着模型视图矩阵而变,但因为没有再次“提交”光源坐标,openGL仍然沿用使用单位矩阵计算出来的光源位置,这就造成了眼睛(坐标系)移动,光源也移动的现象发生。因为openGL中存储的光源坐标不随着眼睛位置的变化而被重新计算,总是一个定值。在绘图时,不管眼睛在哪里,openGL总是在当时的眼睛坐标系中按照一个固定的坐标值安置光源,所以,光源就随着眼睛移动了。
而,网上流行的什么光源随眼睛移动是因为被模型视图矩阵变换了坐标值的说法是完全错误的。试想,世界坐标系中的一个有固定坐标的点,不论经过了怎样的坐标变换,只是对这个点的位置的描述变了,但这个点在空间中的位置不会变。而引起大家疑惑的现象是:光源的位置在空间中发生了变化,这决不是模型视图矩阵能够做到的。
我前边说了一句:“在glLightfv之后,调用gluLookAt”,好像这个顺序有什么要紧,其实
无所谓。我这次特地来说明这点。
其实,不管是在gluLookAt之前还是之后调用glLightfv函数,只要是程序中在MyDisplay()
之外指定了光源位置,那么光源位置都会按照当时的模型视图矩阵的值被计算为一个固定的
值。那么当眼睛位置变换时,光源总会按照这个固定坐标值被绘制到当前的眼睛坐标系中,
因此光源就会随着眼睛移动了。而MyDisplay函数由于会被不断地调用,因此如果在该函数
中制定光源位置,则每次光源坐标都会被重新提交,与之对应的眼睛坐标也会被重新计算,
这就可以反映当前最新的模型视图矩阵的变化。烂野春因此光源位置就固定了。
总之:光源位置是以视觉坐标存储的,弄清这一点,问题就解决了
展开全部
这个是你坐标系没有控制好,你可以把你想画的图形和光源的位置放在不同棚迟逗的坐链卖标系里面处理,这样想怎么移动都可以,这里使用到glPushMatrix(保存当前状态的坐标系)和glPopMatrix(重置当前坐标系,也就是把保存的旦运坐标系拿出来作为当前坐标系)函数
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你要对设置光源的那些参数熟悉才行。建议你看看OpenGL的一个光源参数实时教厅谨程,直接改变参数就可以看到光照的变化。这个程序在C3DN论坛有。在论坛里搜索“7个经典的改卖OpenGL教学程序”就能扮歼基找到你想要的资源了。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
光照等功能,模型者毁载入是用Explor3D转成C++的头文件,旋转什么的都没有出现问题,但加光照后就出现了你旋转时把首厅备光伏野源的位置也进行了旋转,比如你光源的
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询