OpenGL 总是在 cl-opengl(Common Lisp)中为 glGetFloatv GL_MODELVIEW_MATRIX 返回单位矩阵

标签 opengl matrix common-lisp

我似乎在使用 glGetFloatv 获取模型 View 矩阵时遇到了一些意想不到的麻烦(这也发生在尝试获取投影矩阵时)。

会发生什么?好吧,不管矩阵实际是什么,函数都会返回单位矩阵,甚至在平移和旋转之后立即返回!我知道这两个矩阵都不是单位矩阵,因为在游戏世界中移动时屏幕上的视觉效果完全符合预期。

我的函数是一小段 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 论坛上的某个时候在 Internet 上的 Google 搜索中找到一个其他人遇到这个问题的例子。不幸的是,那个线程以我的编程理智的祸根结束 - “LOL NEVERMIND,我找到了”这样的结论。
  • 我没有使用固定的管道,但即使现代 OpenGL 最佳实践建议“在进行可编程管道时使用您自己的矩阵”,我也从未读过任何有关 OpenGL 禁用或以某种方式削弱矩阵操作功能的某些部分的信息当使用可编程管道时,关于 OpenGL 自己的矩阵。但是,为确保万无一失,我还尝试了将 get-float 调用包裹在一些暂时禁用可编程管道的代码中,并且在固定管道模式下它仍然返回单位矩阵。
  • 为了确保这不是 nvidia OpenGL 驱动程序中的一些奇怪错误,我设法在使用 Intel 图形驱动程序的笔记本电脑上重现了这个奇怪的异常现象。结果相同。
  • %gl:get-float-v 也会发生这种情况,它将输出转储到预先分配的外部数组中,而不是像 gl:get-float 那样返回 Lisp 数组。
  • 此外,在上面的代码中,我之前尝试过 gl:finish (glFinish) 和 gl:flush (glFlush) 在 translate+rotate 调用之后和 get-float 调用之前,基于一些模糊的怀疑,也许,只是也许,有些事情发生了故障。但这些添加没有任何效果。

最佳答案

我找到了,我真的很尴尬,因为我发布了这个关于我的一个非常愚蠢的疏忽的大问题。但也许像我一样,将问题大声说出来,最终帮助我的大脑在睡了一夜之后理清第二天早上下一步该做什么。

所以发生了什么:它正在返回单位矩阵,因为我忘记了,很多个月前,我在我的代码中其他地方的一个更广泛的外壳中调用了 apply-camera-gl 函数,在它正在构建的另一个文件中一个显示列表,旋转和平移作为显示列表本身的一部分(如果这对任何人来说听起来很奇怪,该游戏是一个逐步移动的游戏,与飞行模拟或 FPS 不同)。

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

我重新安排了另一个文件中的代码,以便在任何显示列表构造外壳之外调用 apply-camera-gl... 现在它得到了预期的矩阵,因为平移和旋转是立即调用而不是延迟直到每当 (gl:call-list ...) 发生。从现在开始,我将专门为几何使用显示列表——或者更好的是,完全停止使用它们并为几何使用 VBO。

这也解释了为什么它在项目的其他地方返回单位矩阵,我把它放在 apply-camera-gl 以外的地方——它们都恰好在显示列表构造 block 下,我上次甚至没有意识到夜晚(故事的寓意:“隧道视野”是真实存在的)

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

关于OpenGL 总是在 cl-opengl(Common Lisp)中为 glGetFloatv GL_MODELVIEW_MATRIX 返回单位矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14250616/

相关文章:

macos - 如何在共享上下文中渲染到 FBO?

python - 每个元素的高效 numpy 欧氏距离计算

将 nil 参数解释为空字符串而不是 "NIL"的 Lisp 格式指令

c++ - opengl 台球数组

python - python 中的 Kivy 模块

python - MatLab 和 numpy 中 Hermitian 矩阵特征值的差异

sockets - 如何使用 usocket 创建连接? (普通口齿不清)

lisp - Lisp首次搜索下的正向链接

c++ - 实现行进立方体算法?

r - 函数 "if "应用于每个单元格