【问题标题】:How to keep track of OpenGL state across function calls?如何跨函数调用跟踪 OpenGL 状态?
【发布时间】:2009-08-06 20:35:12
【问题描述】:

由于 OpenGL 是一个状态机,我经常在我的程序中使用 glEnable() 和 glDisable() 的东西。我只在开始时进行了少数调用(例如 glClearColor),但大多数其他调用我都会打开和关闭(例如照明,取决于我是在渲染模型还是 3d 文本或 gui)。

您如何跟踪事物的状态?您是否经常在每个功能的顶部设置/重置这些东西?这不是很多不必要的开销吗?

例如,当我编写一个新函数时,有时我知道调用该函数时事物将处于什么状态,而我在函数顶部省略了 glEnable 或 glDisable 或其他相关的状态切换调用。其他时候,我只是提前编写函数并添加这些东西。所以我的函数最终变得非常混乱,其中一些修改了 OpenGL 状态,而另一些只是做出假设(后来被打破了,然后我必须回去弄清楚为什么有些东西变黄了,或者为什么另一个东西是颠倒的,等等。 )。

如何在面向对象的环境中跨函数跟踪 OpenGL?


与这个问题也相关的是,如何知道何时使用 push 和 pop,以及何时只设置值。

例如,假设您有一个程序先绘制一些 3D 内容,然后再绘制一些 2D 内容。显然,投影矩阵在每种情况下都是不同的。你也是:

  1. 设置 3d 投影矩阵,绘制 3D,设置 2d 投影矩阵,绘制 2d,循环
  2. 在程序中设置3d投影矩阵;然后绘制 3d,推送矩阵,绘制 2d,弹出矩阵,循环

为什么?

【问题讨论】:

    标签: opengl oop


    【解决方案1】:

    很好的问题。想想纹理是如何工作的。 OpenGL 有大量的纹理可供切换,您需要在 每个 对象被绘制后启用/禁用纹理。您通常会尝试通过一次绘制具有相同纹理的所有对象来优化这一点,但仍然存在大量的状态切换。由于这个事实,我尽我所能一次绘制具有相同状态的所有内容,但我不确定按照您的想法优化它是否非常重要。

    对于 3D 和 2D 投影模式之间的推送和弹出,推送和弹出旨在用于分层建模。如果您需要 2D 投影位于相对于 3D 对象的位置,请务必按下矩阵并切换到 2D 投影模式,然后在完成后弹出。但是,如果您正在编写一个在屏幕上具有恒定位置的 2D GUI 叠加层,我看不出为什么推送和弹出很重要。

    【讨论】:

    • 嗯,我不确定你的第一段是否真的解决了这个问题,但我确信这主要是因为我没有很好地解释自己。当我对我要问的问题有更清晰的了解时,我需要回到这个问题。感谢您对 push/pop 的见解,我喜欢这种解释。
    【解决方案2】:

    您可能有兴趣阅读有关场景图形库的更多信息。它们旨在从更高级别管理您的图形。他们不能很好地处理所有事情,但他们擅长组织几何体以优化渲染。它们还可以用于根据 OpenGL 状态对场景进行排序,尽管很多人不这样做。通过按状态排序,您可以按导致较少状态转换的顺序渲染几何图形。下面是关于场景图形库的一个很好的概述:

    http://www.realityprime.com/articles/scenegraphs-past-present-and-future

    【讨论】:

    • 是的,我对它们很熟悉。我使用的是 Java,所以有 Xith3D 和 jMonkeyEngine。问题是我沉迷于这些引擎,实际上并没有做出任何值得的事情。既然我一直在编写纯 OpenGL,我实际上正在完成一些工作。不过还是谢谢。
    • 您似乎在重新发明轮子。您已经完成的工作中有多少是由场景图库管理的?
    • .ms3d 文件加载器,带有边界框计算。大概就是这样。我不能用场景图库做的,至少很容易,是我的特殊高度图(有计划的动态加载)和我的自定义 GUI 功能。所以是的,这是一个折衷,但我更容易编写场景图形库可以做的事情,然后做其他它不能做的事情,而不是使用一个并试图找出解决方法和黑客只是为了能够绘制屏幕上的二维形状或其他东西。
    【解决方案3】:

    我认为最简单的方法是编写您自己的渲染类,包装您正在使用的所有 OpenGL 状态操作函数并记录您设置的状态。您需要考虑到更改屏幕分辨率或切换全屏模式将使您当前的 OpenGL 渲染上下文的状态和数据无效,这意味着在此类事件之后您必须设置所有状态,重新上传所有纹理和着色器程序等.

    【讨论】:

      猜你喜欢
      • 2010-09-26
      • 2018-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-02
      • 2020-08-28
      相关资源
      最近更新 更多