对于获取模型视图矩阵,我似乎在使用glGetFloatv遇到了一些意想不到的麻烦(这也是在尝试捕获投影矩阵时也会发生的。)
会发生什么?好吧,无论矩阵实际上是什么,函数都会返回单位矩阵,即使在翻译和旋转后也是如此!我知道矩阵都不是单位矩阵,因为屏幕上的视觉效果与在游戏世界中移动时完全一样。
我的函数是Common Lisp代码的一小部分(修改了一个语句,用于在为了调试目的而立即更改矩阵之后打印矩阵),并在下面进一步说明:
(defun apply-camera-gl (camera)
(declare (type scene-camera camera))
(declare (optimize (speed 3) (safety 1) (debug 3) (space 0)))
"Passes the necessary OpenGL commands to apply the position and fov for the camera."
(let ((pos (scene-camera-position camera))
(rot (scene-camera-rot camera))
(fov (scene-camera-fov camera)))
(declare (type single-float rot fov)
(type vec3 pos))
(gl:matrix-mode :projection)
(gl:load-identity)
(set-perspective fov +sr+ 0.1 24.0)
(gl:matrix-mode :modelview)
(gl:load-identity)
(gl:rotate -90.0 1.0 0.0 0.0)
(gl:rotate rot 0.0 0.0 1.0)
(gl:translate (- (the single-float (vec3-x pos)))
(- (the single-float (vec3-y pos)))
(- (the single-float (vec3-z pos))))
;; this always returns the following:
;; mv = #(1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0)
(format t "mv = ~a~%" (gl:get-float :modelview-matrix))
nil))
一些补充说明:
答案 0 :(得分:2)
我找到了,而且我真的很尴尬,因为我发布了一个关于我的非常愚蠢的监督的大问题。但也许正如我所说的那样,大声地将这个问题大胆地用语言表达出来,最后帮助我的大脑在第二天早上睡了一觉后理清下一步该做什么。
所发生的事情是:它正在返回单位矩阵,因为我忘记了,几个月前,我在我的代码中的另一个文件中的更广泛的机箱内调用了apply-camera-gl函数一个显示列表,旋转和翻译作为显示列表本身的一部分(如果对任何人来说听起来很奇怪,游戏就是一个逐步移动的游戏,不像飞行模拟或FPS)。
在显示列表构造块中,不立即执行OpenGL命令。
我在其他文件中重新安排了代码,只需在任何显示列表构造机箱外调用apply-camera-gl ...现在它获得了预期的矩阵,因为翻译和旋转立即被调用而不是被延迟直到每当(gl:call-list ...)发生。从现在开始,我将专门为几何使用显示列表 - 或者更好的是,完全停止使用它们并将VBO用于几何体。
这也解释了为什么它在我把它放在除了apply-camera-gl以外的项目中的其他地方返回了单位矩阵 - 它们都碰巧在显示列表构造块之下,我甚至没有意识到晚上(故事的道德:“隧道视觉”是一个真实的东西)
道歉,这个问题可能会被关闭。
答案 1 :(得分:0)
CL-USER> (ql:quickload :cl-opengl)
To load "cl-opengl":
Load 1 ASDF system:
cl-opengl
; Loading "cl-opengl"
....
(:CL-OPENGL)
CL-USER> (ql:quickload :cl-glut)
To load "cl-glut":
Load 1 ASDF system:
cl-glut
; Loading "cl-glut"
(:CL-GLUT)
CL-USER> (defclass smooth-window (glut:window)
()
(:default-initargs :width 500 :height 500 :pos-x 100 :pos-y 100
:mode '(:single :rgb) :title "smooth.lisp"))
#<STANDARD-CLASS SMOOTH-WINDOW>
CL-USER> (defmethod glut:idle ((w smooth-window))
(sleep 2)
(gl:matrix-mode :modelview)
(format t "~%~%(~{~5,3f~^ ~})" (coerce (gl:get-float :modelview-matrix) 'list))
(gl:rotate 10 1.0 0.0 0.0)
(format t "~%~%(~{~5,3f~^ ~})" (coerce (gl:get-float :modelview-matrix) 'list)))
STYLE-WARNING:
redefining CL-GLUT:IDLE (#<STANDARD-CLASS SMOOTH-WINDOW>) in DEFMETHOD
#<STANDARD-METHOD CL-GLUT:IDLE (SMOOTH-WINDOW) {1005CB9363}>
CL-USER> (glut:display-window (make-instance 'smooth-window))
(1.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 1.000)
(1.000 0.000 0.000 0.000 0.000 0.985 0.174 0.000 0.000 -.174 0.985 0.000 0.000 0.000 0.000 1.000)
(1.000 0.000 0.000 0.000 0.000 0.985 0.174 0.000 0.000 -.174 0.985 0.000 0.000 0.000 0.000 1.000)
(1.000 0.000 0.000 0.000 0.000 0.940 0.342 0.000 0.000 -.342 0.940 0.000 0.000 0.000 0.000 1.000)
(1.000 0.000 0.000 0.000 0.000 0.940 0.342 0.000 0.000 -.342 0.940 0.000 0.000 0.000 0.000 1.000)
(1.000 0.000 0.000 0.000 0.000 0.866 0.500 0.000 0.000 -.500 0.866 0.000 0.000 0.000 0.000 1.000)
(1.000 0.000 0.000 0.000 0.000 0.866 0.500 0.000 0.000 -.500 0.866 0.000 0.000 0.000 0.000 1.000)
(1.000 0.000 0.000 0.000 0.000 0.766 0.643 0.000 0.000 -.643 0.766 0.000 0.000 0.000 0.000 1.000)
(1.000 0.000 0.000 0.000 0.000 0.766 0.643 0.000 0.000 -.643 0.766 0.000 0.000 0.000 0.000 1.000)
(1.000 0.000 0.000 0.000 0.000 0.643 0.766 0.000 0.000 -.766 0.643 0.000 0.000 0.000 0.000 1.000)
; No value
如果这个简单的例子有效,那么必须有(gl:rotate rot 0.0 0.0 1.0)...我有没有机会撤消旋转,所以它又回到了身份?
抱歉,我无法更精确,希望其他人可以填写我错过的位。快乐的Lisping!