击败状态机

时间:2014-02-16 11:02:50

标签: opengl

我正在开发一个脚本语言插件,允许用户访问OpenGL 1.1命令集。最重要的是,脚本语言自己的gfx命令集的所有功能都被透明地重定向到适当的OpenGL调用。通常,用户应该使用 OpenGL命令集脚本语言的内置gfx命令集,它基本上只包含典型的2D绘图命令,如DrawLine(),{ {1}},DrawRectangle()

但是,在某些情况下,用户可能希望混合调用OpenGL 内置的gfx命令集。这导致我的OpenGL实现内置命令(如DrawPolygon()DrawLine()DrawRectangle()等必须能够处理OpenGL状态机当前可能处于的任何状态的问题。

因此,我的想法是首先在堆栈上保存所有状态信息,然后为我的DrawPolygon()等命令的实现准备一个干净的OpenGL上下文,然后恢复原始状态。例如。像这样的东西:

DrawLine()

然而,这样做会导致一些问题:

  1. glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); glPushMatrix(); ....prepare OpenGL context for my needs.... --> problem: see below #2 ....do drawing.... glPopMatrix(); glPopClientAttrib(); glPopAttrib(); 不会推送所有属性,例如保存像素包和解包状态,渲染模式状态以及选择和反馈状态都不会被推送。此外,不保存扩展状态。扩展状态并不重要,因为我的插件不支持扩展。可以使用glPushAttrib()手动实现保存和恢复其他信息(像素包和解包)。
  2. 大问题:在保存所有状态信息后,我应该如何准备OpenGL上下文?我可以在OpenGL初始化之后立即在堆栈上保存一个“干净”状态的副本然后尝试弹出这个堆栈但是为此我需要一个函数来移动堆栈内的数据,即我需要一个函数来复制或者将保存的状态从后面移动到堆栈顶部,以便我可以弹出它。但我没有看到能够实现这一目标的功能......
  3. 这可能会非常慢,但这是我可以忍受的,因为用户不应该混合OpenGL和内置的gfx调用。如果他这样做,他将不得不忍受非常糟糕的表现。
  4. 在这些介绍性考虑之后,我最后想提出一个问题:是否有可能以某种方式“击败”OpenGL状态机?通过“殴打”我的意思是:是否可以完全保存所有当前状态信息,然后恢复默认状态并根据我的需要进行准备并进行绘图,最后再次恢复完整的先前状态,以便一切都准确就像以前一样。例如,基于OpenGL的脚本语言版本的DrawLine()命令可以执行以下操作:

    glGet()

    这有可能吗?只要它100%保证将状态置于与之前完全相同的状态,它是否非常缓慢无关紧要。

1 个答案:

答案 0 :(得分:2)

您可以简单地使用不同的上下文,尤其是在您不关心性能的情况下。只需为你的内部gfx操作保留一个上下文,另一个用户可能会搞乱,只需将适当的一个绑定到你的窗口(和线程)。

你描述它的方式看起来好像你永远不想与用户的GL内容共享对象,所以简单的“非共享”上下文会很好。你似乎想要分享的是帧缓冲区 - 而GL帧缓冲区(包括后面和前面的颜色缓冲区,深度缓冲区,模板等等)是drawable / window的一部分,而不是上下文 - 所以你可以访问它在使上下文变为当前时,可以使用任何上下文在帧中改变上下文不是问题。