【问题标题】:OpenGL Rotate, Translate, Push/Pop questionOpenGL Rotate, Translate, Push/Pop 问题
【发布时间】:2011-06-18 00:49:39
【问题描述】:

我对 openGL 还很陌生,但我一直在为为什么这行不通而苦苦挣扎(不一定要解决问题,而只是想了解基础知识)

所以基本上这会绘制一个旋转的三角形网格。我想了解的是是否/如何删除 Push 和 Pop 操作。当我把它们拿出来时,会出现随机散射。我尝试在绘图完成后反转旋转,切换平移和旋转命令。我想我看到的方式是我应该能够避免推送/弹出,而是每次使用旋转来比上次增加几度,但我显然错过了一些东西。

【问题讨论】:

  • 我相信你应该在一个单独的函数中旋转,比如 glutTimerFunc(如果你使用它作为你的框架)或你正在使用的 GUI 库提供的其他一些计时器函数。
  • 为什么要避免push/pop?
  • 我的推送弹出性能很差。当我移除推/弹出和旋转,并在实际位置绘制而不是平移时,速度快了 20 倍。

标签: opengl


【解决方案1】:

推送/弹出矩阵正在保存/恢复之前的矩阵。你无法避免这样做,因为你会累积平移和旋转。

记住:glTranslate 不定位东西。它构建一个平移矩阵并将其应用于 current 矩阵,无论是什么。所以如果你先平移,然后旋转,再平移,最后一次平移将在 rotated 空间中,而不是与旋转相同的空间。

【讨论】:

    【解决方案2】:

    OpenGL 保留一个内部转换矩阵堆栈。当您调用glPushMatrix() 时,它会将所有矩阵向下推一,复制列表顶部的矩阵。这使您可以将变换、旋转、缩放等应用到您的心脏内容,并且如果您在完成后调用 glPopMatrix() 来删除新调整的变换矩阵,那么 3D 世界的其余部分根本不会改变。

    请注意,当我说 3D 世界的其余部分时,这包括下次主循环循环时的对象。如果您不调用 glPushMatrix() 然后调用 glPopMatrix() 您将永久改变世界,它将对您的对象产生(不可预测的)影响。

    总而言之,请始终在转换的开始和结束时调用 glPushMatrix() 和 glPopMatrix(),除非您知道自己在做什么并希望对 3D 世界的其他部分产生影响。

    【讨论】:

    • 是的,我遇到了一些性能问题,在我正在搞砸的一些东西上使用大量推送弹出,并发现推送/弹出不是硬件加速导致我的问题,所以我很好奇如何在不使用两者的情况下完成。不过感谢您的解释,这对我慢慢增长的 openGL 知识来说是有意义的。
    • @rickJames 如果您有大量的推送/弹出,那么我假设您也有大量的 glBegin/glEnd,这更有可能是问题所在。 push/pop 没有硬件加速是有充分理由的,它们所做的只是改变一个指向不同矩阵的指针。
    • 有很多开始/结束(超过 30k),但我也搞砸了使用 vetexPointer/colorPointer/drawArray 而不是明显的区别。删除推送/弹出有很大的改进。
    • @rickJames 开始/结束了。如果您正在绘制粒子或其他东西,最好将预先转换的位置放入顶点数组并使用 vertexPointer 在一个开始/结束时撕裂它们,而不是执行 push/translate/rotate/begin/end/pop每个项目。顺便说一句,我怀疑简单地删除推送/弹出会产生如此显着的效果。在您上面的一个 cmets 中,您提到您“删除了推送/弹出 和旋转” - 现在删除了旋转,是的,这会让你加快速度。这是你的意思吗? ps 如果您回复,请使用@iforce2d,以便我收到通知。
    【解决方案3】:

    您需要反转 translate 和 rotate 命令(以相反的顺序):

    glTranslatef(xF, yF, 0);
    glRotatef(angle, 0.0f, 0.0f, 1.0f);                        
    
    // draw
    
    glRotatef(-angle, 0.0f, 0.0f, 1.0f);                        
    glTranslatef(-xF, -yF, 0);
    

    正如@Nicol 在下面指出的那样,使用glPushMatrix/glPopMatrix 可能会更快,因为glRotatef 需要建立一个包含正弦和余弦的旋转矩阵。

    更重要的是,由于浮点舍入错误,随后的旋转可能不是完全的标识。这意味着,如果您在内部循环中依赖此技术(如上所示),您可能会在整个绘图调用过程中累积一些大量浮点错误。

    【讨论】:

    • -1 如果 OP 的对象偏离中心,那么 OP 肯定要先旋转,然后平移 - 否则他将围绕非质心旋转。
    • @user407462,我只是在复制他的代码——他先翻译,然后旋转,所以要撤消它,你需要先旋转,然后再翻译。 (我假设他的代码按他的预期工作,他说确实如此。)
    • 那行得通。我想我现在应该学到的教训是这些操作中的许多应该成对执行。感谢您的帮助!
    • @rickJames 如果你只做 push 和 pop 可能会更快。 glRotatef 需要进行正弦和余弦运算。 glPushMatrix 和 glPopMatrix 只是移动一个堆栈指针。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 2014-06-22
    • 1970-01-01
    • 2020-03-27
    • 2022-01-17
    相关资源
    最近更新 更多