在获取模型视图矩阵方面,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))
一些附加说明:
- 我也尝试过,只是想看看会发生什么,将 (gl:get-float :modelview-matrix) 的打印输出更早地放在我的代码中的另一个文件的其他位置,实际上是在创建 OpenGL 上下文之后,我在其中应用一些随机的旋转和翻译调用——在那里它工作得很好,返回了我期望的矩阵!然而,在其他任何地方,它都会返回单位矩阵。我使用这个函数作为例子是因为它最容易理解,即使对于可能不熟悉 Lisp 的读者也是如此。
- 我只能在 2001 年初的某个时候在 OpenGL 论坛上通过 Google 搜索其他人在 Internet 上找到一个实例。不幸的是,该线程以我的编程理智的祸根结束 - “哈哈,没关系,我找到了"的结论。
- 我没有使用固定管道,但即使现代 OpenGL 最佳实践建议“在执行可编程管道时使用自己的矩阵”,我从未读过任何关于 OpenGL 禁用或以某种方式削弱与 OpenGL 相关的矩阵操作功能的某些部分的内容使用可编程流水线时拥有自己的矩阵。但是,为了确定起见,我还尝试了包装在一些代码中的 get-float 调用,它暂时禁用了可编程管道,并且在固定管道模式下它仍然返回单位矩阵。
- 为了确保这不是 nvidia OpenGL 驱动程序中的一些奇怪的错误,我设法在使用英特尔图形驱动程序的笔记本电脑上重现了这个奇怪的异常。结果相同。
- %gl:get-float-v 也会发生这种情况,它将输出转储到预先分配的外部数组中,而不是像 gl:get-float 那样返回 Lisp 数组。
- 另外,在上面的代码中,我之前在 translate+rotate 调用之后和 get-float 调用之前尝试了 gl:finish (glFinish) 和 gl:flush (glFlush),基于某种模糊的怀疑,也许,只是也许,有些东西是发生故障。但是这些添加没有效果。