Xlib 的 `Window` 与 GLX 的 `GLXWindow` 混淆

Xlib's `Window` vs. GLX's `GLXWindow` confusion

我正在查看使用 GLX 创建 OpenGL 上下文的各种示例代码,我对这两种类型感到困惑window 个对象:WindowXlib 使用,GLXWindowGLX 使用,因为在某些示例中他们的代码直接使用 Xlib 的 windows 进行渲染,而在其他代码中他们另外创建 GLX 的 windows.
我的问题是:

  1. 这两者有什么区别?
  2. 我需要同时创建两者,还是 Window 就可以?

GLX 1.4 文档(有更新的文档吗?)告诉我使用 glXCreateWindow 创建 GLXWindow,这个文档将 Window 作为其第三个参数。我不确定这是否应该是 GLXWindow 的父 window,或者 Window 是由 GLXWindow 得到的 "wrapped",文档似乎不清楚这一点。有谁知道这应该如何工作以及背后的基本原理?为什么有些示例使用 GLXWindows,而有些示例不使用,但它们似乎仍然工作得很好?

另一件让我感到困惑的事情是一些示例使用 glXCreateContext 来创建它们的 OpenGL 上下文,而其他示例(包括 GLX 1.4 规范)使用 glXCreateNewContext。两者似乎都在我的库版本中可用,但我不太明白它们之间有什么区别。

还有 glXMakeCurrentglXMakeContextCurrent – 另一个让我感到困惑的来源。

任何人都可以向我解释这些拼写略有不同的函数/类型之间的区别,或者将我发送到一些我可以自己了解的在线资源吗?

哦,还有一件事:这些东西是否仍然与现代 OpenGL(3.0+,可编程管道之一)相关?或者只是一些我不应该抨击我可怜的小马头的遗留垃圾? :q

因为我从未听说过 GLXWindow,所以我很好奇它是什么。大多数讨论,do not clarify 为什么这个是必要的,并且只传播猜测,包括我的回答。

首先要澄清的是,GLXWindow已经在GLX 1.3. Older versions, including GLX 1.2中引入定义如下GLXDrawable 列表:{Window, GLXPixmap},其中 GLXPixmap 从 off- 创建屏幕 X 像素图。 Specs 没有说明为什么在 X Pixmap 之上需要 GLXPixmap,而 X Window 可以直接使用,但猜测是 X Pixmap 定义中缺少某些东西,GLX 需要将其存储在 GLXPixmap 中...

GLX 1.3GLXDrawable 的定义扩展为 { GLXWindow , GLXPixmap, GLXPbuffer, Window }。这样你就可以看到一个新项目GLXPbuffer,这是在OpenGL本身引入Frame Buffer Objects (FBO)之前改进离屏渲染的尝试。与像素图和 windows 不同,GLXPbuffer 是从头创建的,在 X 中没有关系。还有一个新的 GLXWindow 附注:

For backwards compatibility with GLX versions 1.2 and earlier, a rendering context can also be used to render into a Window.

因此 GLXWindow 看起来更像是在所有 GLXDrawable[= 中统一 API(和内部逻辑)的尝试70=],而不是修复某些东西的工具,因为乍一看它没有扩展 X Window 的功能。

GLXWindow有没有引入新的东西?事实上,确实如此! GLX 1.3 还引入了一个新函数 glXSelectEvent(),它允许在 X11 流中处理 GLX 特定事件。因此该函数适用于 GLXWindow 和 GLXPbuffer,但不适用于 X Window(因为它是专门为区分 GLX 事件和普通事件而创建的)。令人困惑的是,规范定义的唯一 GLX 特定事件是 GLXPbufferClobberEvent 类型,这似乎与过时的 PBuffers 和 Window 辅助缓冲区(现在在核心 OpenGL 规范中被 FBO 取代)更相关).

因此,我个人认为没有任何实际理由创建 GLXWindow 而不是使用 X Window 本身 而不是仅仅遵循 GLX 规范建议(声明使用 X Window 只是为了与针对旧 GLX 版本编写的应用程序兼容)并使用 "cleaned up" API.

关于glXCreateNewContext() vs glXCreateContext(),这与引入GLXFBConfig[=70=有关],因为发现 X Visual 定义不足以表示所有必要的细节。来自规格:

Calling glXCreateContext(dpy, visual, share list, direct) is equivalent to calling glXCreateNewContext(dpy, config, render type, share list, direct) where config is the GLXFBConfig identified by the GLX_FBCONFIG_ID attribute of visual.

关于 glXMakeCurrent()glXMakeContextCurrent(),后者由较新的 GLX 版本引入,允许在中使用不同的可绘制和可读缓冲区与现代 FBO 允许的类似方式,这在规范中也很清楚:

Calling glXMakeCurrent(dpy, draw, ctx) is equivalent to calling glXMakeContextCurrent(dpy, draw, draw, ctx). Note that draw will be used for both the draw and read drawable.

关于现代 OpenGL 3+ 的使用,GLX 在这里没有问题 - 只需使用像 GLX_ARB_create_context_profile 这样的 GLX 扩展来创建上下文(当前的 Mesa 库实现提供更高的 OpenGL 版本在创建 Core Profile 时,但在专有驱动程序的情况下通常没有这种差异)。

当然,您可以考虑使用 EGL(但它会限制 OpenGL 上下文能力,因为与 GLX 相比缺少某些选项)或 Wayland/Mir 东西,如果你对新的显示服务器很狂热,想从依赖中摆脱 X(Wayland 实现了 Xlib 兼容层,所以它现在不是一个显示停止器)。