【问题标题】:OpenGL ModelView ConfusionOpenGL 模型视图混淆
【发布时间】:2023-03-28 00:20:01
【问题描述】:

我正在使用带有固定功能管道的 opengl 2.0。似乎在opengl 2.0中 他们通过模型视图堆栈推动顶点,该堆栈基本上是(视图矩阵*模型矩阵),其中模型矩阵不提供任何转换,实际上它带来了一个对象,比如一个立方体,中心位于(0,0,0 ) 如果模型视图矩阵加载了单位矩阵。此外,它自身的相机将位于 (0,0,0) 处,向下看负 z 轴。

所以,如果我对立方体使用 translate 调用,我真的是在移动眼睛空间中的立方体吗?

据我所知,广义的查看管道是

顶点->建模矩阵->世界空间,世界空间中的对象->查看矩阵->眼睛空间,眼睛空间对象->投影矩阵->裁剪空间,然后归一化等

所以如果我切换到 模型视图矩阵堆栈() 加载身份() gltranslate(在负 z 方向上增加 5 个单位) gldrawcube()

它会根据翻译将立方体从眼睛空间的中心移动?

我认为我的困惑是我不知道程序启动时加载到模型视图矩阵堆栈中的是什么,我假设它是一个单位矩阵,将所有内容都带到眼睛空间的中心。

【问题讨论】:

    标签: opengl graphics


    【解决方案1】:

    在一个新创建的 OpenGL 上下文中,所有矩阵都是恒等的,即向量未经转换。在固定函数中,OpenGL 顶点变换跳过“世界”步骤,将对象→世界和世界→眼睛折叠成一个单独的变换。然而,这没什么大不了的。无论如何,照明计算在眼睛空间中是最容易的。并且由于固定函数 OpenGL 不知道着色器(扩展除外),因此无需在世界空间中做任何事情。

    glTranslate、glRotate、glScale 不变换对象。他们操纵堆栈顶部的矩阵以进行操纵。所以最终它们有助于转换,但不是在对象上,而是在顶点(位置)级别。

    它会根据平移将立方体从眼睛空间的中心移动?

    确实,但是“移动”(实际上是变换)的是立方体的顶点;它可能不仅仅是翻译。

    因评论而编辑

    要理解的关键是转换组合。首先,转换是映射

    T: R^4 -> R^4, v' = v |-> T(v)
    

    有一个变换的子集,即可以用矩阵乘法表示的线性变换:

    v' = T * v
    

    一个可以连接转换,即v = v |-> T'○T (v)再次用于线性转换的子集,以矩阵形式编写,您可以将其扩展为

    v' = T * v
    v'' = T' * v'
    
    =>
    
    v'' = T' * T * v
    

    现在让V 表示查看变换,W 表示世界变换。所以总的变换是

    M = V * W
    

    矩阵乘法的顺序很重要(即矩阵乘法不可交换):

    ∃ M, N ∊ {Matrices}: M * N ≠ N * M
    

    视图变换V 是整个世界的变换,因此它以某种方式移动,世界中的相机最终位于原点,向下查看负 Z 轴。因此,让V' 成为将“相机”从原点移动到它在世界中的位置的变换,该运动的逆以相机停止在原点的方式移动世界。所以

    V = inv(V')
    

    最后但并非最不重要的一点是给出了一些矩阵 A、B、C 的成立

    A = B * C
    

    然后

    inv(A) = inv(C) * inv(B)
    

    即操作顺序颠倒了。因此,如果您使用逆 OpenGL 矩阵运算“定位”您的“相机”,则必须颠倒操作的顺序。而且由于操作的整体顺序很重要,因此查看转换必须在模型转换之前发生。

    【讨论】:

    • 我只是发现模型视图在红皮书中确实令人困惑,它说“因此,逆时针旋转对象的建模转换相当于顺时针旋转相机的查看转换。最后,请记住必须在执行任何建模转换之前调用查看转换命令,以便建模转换首先对对象生效。“为什么必须先执行它们?在我的脑海中,我在想(View Mat *(Model Mat * Vertex)),它们的意思是不是例如 glMatrixMode(GL_MODELVIEW) loadIdentity()
    • glMatrixMode(GL_MODELVIEW) loadIdentity() //move "Camera here" glpushmatrix() gltranslate() gldrawcube() glpopmatrix() 有没有很好的教程来解释这个模型视图矩阵?这对我来说是一个困难的概念
    • 好吧,除了我想知道 opengl modelview 在堆栈上默认有什么之外,所有这些都是有道理的?视图矩阵(将相机移动到原点,以便视点是相机的)* 身份(建模矩阵)?所以理论上我必须乘以 invviewing 矩阵来获得世界空间,在应用程序级别然后一旦我这样做我使用平移和旋转移动相机然后应用再次居中相机的观察矩阵所以我在眼睛空间吗?
    • 你知道我的困惑是什么吗?模型视图只是矩阵堆栈的名称,因此该堆栈实际上以单位矩阵开头,由于 MV = V * M,我必须首先应用查看变换,其中应用建模变换是可选的。如果我确实想应用建模转换,那么我必须确保先进行查看,然后进行建模矩阵转换,以便顶点乘以建模然后查看,否则顶点只是乘以查看另一种情况。
    • 所以最初的 MV = I * I = I 所以顶点只会穿过眼睛空间,确保一切都在原点结束,所以技术上的查看和建模是一样的,取决于你如何考虑一下
    猜你喜欢
    • 1970-01-01
    • 2015-09-20
    • 2012-05-08
    • 2011-11-22
    • 1970-01-01
    • 2013-07-05
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多