OpenGL总是返回cl-opengl中的glGetFloatv GL_MODELVIEW_MATRIX的标识矩阵(Common Lisp)

时间:2013-01-10 03:59:00

标签: opengl matrix common-lisp

对于获取模型视图矩阵,我似乎在使用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论坛上找到一个关于互联网上其他人的谷歌搜索实例。不幸的是,那个线程以我的编程理智的祸根结束 - “LOL NEVERMIND,我发现它“有点结论。
  • 我没有使用固定管道,但即使现代OpenGL最佳实践建议“在进行可编程管道时使用自己的矩阵”,我也从未读过任何关于OpenGL禁用或以某种方式削弱矩阵操作功能的某些部分的内容。在使用可编程管道时,请考虑OpenGL自己的矩阵。但是,为了确定,我还尝试将get-float调用包含在一些暂时禁用可编程管道的代码中,并且在处于固定管道模式时它仍然返回单位矩阵。
  • 为了确保这不是nvidia OpenGL驱动程序中的一些奇怪的错误,我设法在我的笔记本电脑上使用英特尔图形驱动程序重现这个奇怪的异常。相同的结果。
  • 这也发生在%gl:get-float-v中,它将输出转储到预先分配的外部数组中,而不是像gl:get-float那样返回一个Lisp数组。
  • 另外,在上面的代码中,我之前尝试了gl:finish(glFinish)以及gl:flush(glFlush),在翻译+旋转调用之后和get-float调用之前,对某些模糊的怀疑,也许,只是也许,事情发生了故障。但这些补充没有效果。

2 个答案:

答案 0 :(得分:2)

我找到了,而且我真的很尴尬,因为我发布了一个关于我的非常愚蠢的监督的大问题。但也许正如我所说的那样,大声地将这个问题大胆地用语言表达出来,最后帮助我的大脑在第二天早上睡了一觉后理清下一步该做什么。

所发生的事情是:它正在返回单位矩阵,因为我忘记了,几个月前,我在我的代码中的另一个文件中的更广泛的机箱内调用了apply-camera-gl函数一个显示列表,旋转和翻译作为显示列表本身的一部分(如果对任何人来说听起来很奇怪,游戏就是一个逐步移动的游戏,不像飞行模拟或FPS)。

在显示列表构造块中,不立即执行OpenGL命令。

我在其他文件中重新安排了代码,只需在任何显示列表构造机箱外调用apply-camera-gl ...现在它获得了预期的矩阵,因为翻译和旋转立即被调用而不是被延迟直到每当(gl:call-list ...)发生。从现在开始,我将专门为几何使用显示列表 - 或者更好的是,完全停止使用它们并将VBO用于几何体。

这也解释了为什么它在我把它放在除了apply-camera-gl以外的项目中的其他地方返回了单位矩阵 - 它们都碰巧在显示列表构造块之下,我甚至没有意识到晚上(故事的道德:“隧道视觉”是一个真实的东西)

道歉,这个问题可能会被关闭。

答案 1 :(得分:0)

嗯,我无法重现这个问题,但我会展示我做了什么,所以你可以看到。 我正在使用sbcl,quicklisp(获取cl-opengl)并运行以下

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!