【问题标题】:OpenGL 4.0+ and 'immediate mode'-GUIOpenGL 4.0+ 和“即时模式”-GUI
【发布时间】:2012-11-17 10:33:06
【问题描述】:

我用按钮、菜单、列表等简单的小部件制作了一个 GUI 框架。 它应该在现代 PC 和带有板载图形的笔记本电脑上运行(通常只支持 GL 1.4)。为了实现这一点,我在 opengl 1.x 中进行绘图('立即模式',显示列表,...)。

现在我有几个问题:

1) 如果我想创建一个使用 OpenGL 4.0+ 函数/着色器绘制的画布小部件,有什么问题吗?我可以将 OpenGL 4.0+ 与 OpenGL 1.x 混合使用吗?

2) 其他 OpenGL-GUI-API 是如何在那里绘制内容的?他们是否都使用 OpenGL 1.x 来支持尽可能多的 PC/笔记本电脑?我知道 Blender-GUI 使用 OpenGL 1.x,但这是最好的解决方案吗?

【问题讨论】:

  • 我想提一下,我使用顶点/颜色/纹理数组来绘制不是显示列表或“立即模式”。

标签: opengl versions


【解决方案1】:

如果我想创建一个使用 OpenGL 4.0+ 函数/着色器绘制的画布小部件,有什么问题吗?我可以将 OpenGL 4.0+ 与 OpenGL 1.x 混合使用吗?

假设您创建了一个 OpenGL 4.x compatibility 上下文,是的。 NVIDIA、AMD 和 Intel 支持兼容性配置文件(达到 Intel 完全“支持”OpenGL 的程度)。

其他 OpenGL-GUI-API 是如何在那里绘制内容的?他们是否都使用 OpenGL 1.x 来支持尽可能多的 PC/笔记本电脑?我知道 Blender-GUI 使用 OpenGL 1.x,但这是最好的解决方案吗?

最佳是一个主观术语。您可以在网上找到很多(任何 类型的)OpenGL 代码都是旧的;向后兼容的缺点之一是人们永远不会觉得需要升级他们的旧代码或教程。

但没有什么阻止您在核心 OpenGL 4.x 中渲染 GUI。毕竟,这就是每个 D3D10 游戏渲染其 GUI 的有效方式(因为它们在 D3D10 中不再具有固定功能)。

【讨论】:

  • "但是没有什么可以阻止您在核心 OpenGL 4.x 中渲染 GUI。"如果我的应用程序使用 OpenGL 4.x(例如在画布中绘制 3d 对象),那么您是对的。但在某些情况下,我只想使用 OpenGL 进行 gui 渲染,因此我使用 OpenGL 1.x 来支持带有 OnBoard-Graphic 的旧 PC 或笔记本电脑。将 OpenGL 4.x 和 OpenGL 1.x 中的渲染代码拆分为“datenwolf”指出接缝对我来说是正确的答案。
【解决方案2】:

我可以将 OpenGL 4.0+ 与 OpenGL 1.x 混合使用吗?

没有。 OpenGL-1/2 兼容性配置文件仅适用于 OpenGL-3

实际上,从技术上讲,有一个可用的兼容性配置文件。但是,我看不出有人想使用它的任何合理理由。如果要使用 OpenGL-4 的特性,那么程序的内部结构就会发生很大变化,兼容性配置文件就不再重要了。

我知道 Blender-GUI 使用 OpenGL 1.x

目前正在进行大量开发以使其与 OpenGL-4 兼容。

为了实现这一点,我在 opengl 1.x 中进行绘图('立即模式',显示列表,...)。

显示列表和即时模式对您来说都是巨大的障碍。顶点数组从 OpenGL-1.1 开始可用。一旦你设置了顶点数组,它只需要最少的代码来支持 OpenGL-4。基本上,您需要做的就是通过提供正确的着色器来复制固定功能管道,并将顶点数组关联到正确的属性中。对于 OpenGL-4,您还需要一个顶点数组对象来保存顶点数组状态。

只要着色器不是强制性的,即你只做固定功能也可能的事情,你可以用它支持 OpenGL-1.1 到 OpenGL-4.x 的全部范围的方式编写它,只有非常您的代码中很少有运行时条件。


因评论而更新:

我正在考虑这样的事情:让我们假设一个源文件guiGL.c

#if GLPATH==2
#define GLPREFIX(x) glpath2_#x
#elif GLPATH==3
#define GLPREFIX(x) glpath3_#x
#endif

void GLPREFIX(draw_button)
{
#if GLPATH==2
    /* OpenGL 2 code here */
#endif

#if GLPATH==3
    /* OpenGL 3 code here */
#endif

    /* common code here */

}

调度员guiGLcommon.c

void draw_button()
{
    if(opengl_major_version <= 2) {
        glpath2_draw_button();
    } else {
        glpath3_draw_button();
    }
}

还有一个Makefile

guiGL_glpath2.o: guiGL.c
    $(CC) -DGLPATH=2 -o guiGL_glpath2.o -c guiGL.c

guiGL_glpath3.o: guiGL.c
    $(CC) -DGLPATH=3 -o guiGL_glpath2.o -c guiGL.c

guiGL.o: guiGLcommon.c 
    $(CC) -o guiGL.o -c guiGLcommon.c

# ...

target: ...
    $(CC) -o target guiGL.o guiGL_path2.o guiGL_path3.o ...

【讨论】:

  • 感谢您的回答。我已经使用了顶点数组,也许我只是添加了一个宏来在 GL 1.4 和 4.0 之间切换。幸运的是,我的框架只需要 4 个绘图例程(矩形、线条、图标、文本),所以工作量不大。
  • @pani00:您最好使用两个代码路径,它们在某个根点分支。也许在其他名称相同的函数前面加上_path_gl3__path_gl3rore_——你可以使用宏编译同一个编译单元两次,生成两个代码路径。从根调度程序函数调用结果。
  • 我无法理解您最后的评论。您的意思是我应该将 gl1/gl4 代码拆分为不同的文件吗?你能发布一个简短的伪代码/sn-p 吗?
  • -1:“OpenGL-1/2 兼容性配置文件仅适用于 OpenGL-3”不正确。 Here, for example, is the OpenGL 4.3 compatibility specification。你会发现similar specs for 4.2, 4.1, and 4.0.
  • @NicolBolas:感谢您的提醒。但是,我严重怀疑在 4 中具有兼容性配置文件的意义。我理解在 3 中需要它,以使过渡更容易。无论如何,我编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多