是否有任何计划或现有项目将 OpenGL API 移植到 C++?

2021-12-19 00:00:00 opengl c++

OpenGL 标准页面声明 OpenGL 可从 C 和 C++调用.然而,API 当然是纯 C 语言.例如,由于 OpenGL 使用了大量枚举,因此使用枚举类(来自 C++11)可以大大减少错误数量并使 API 更适合初学者.可以看出,创建了很多像 OpenTK(对于 C#)这样的绑定;创建好的 C++ API 不应该难.

The OpenGL standard pages states that the OpenGL is callable from C and C++. The API, however, is of course in pure C. As the OpenGL uses for example a lot of enumerations, using enum-classes (from C++11) could greatly reduce number of errors and make the API more feasible for beginners. It could be seen that lot of the bindings like OpenTK (for C#) are created; creating good C++ API shouldn't be much harder.

除了晦涩的包装外,我找不到任何东西,因此我的问题是:

I weren't able to find anything that was more than an obscure wrapper, hence my questions:

  1. 是否有著名的 C++ 包装器使用用于 OpenGL 的 C++11 设施?如果没有,
  2. 有没有知名人士(尤其是 Khronos)计划这样的事情?

推荐答案

OpenGL 的整个工作方式并没有很好地映射到 OOP:http://www.opengl.org/wiki/Common_Mistakes#The_Object_Oriented_Language_Problem

The whole way OpenGL works does not really well map to OOP: http://www.opengl.org/wiki/Common_Mistakes#The_Object_Oriented_Language_Problem

本文中没有说明的是上下文关联问题.在 OpenGL 中,一切都发生在上下文中,因此Texture"类正确地说只不过是与上下文一起使用的荣耀句柄.

What's not stated in this article is the context affinity problem. In OpenGL everything happens on the context, so a class "Texture", to be correct would be nothing more than a glorifed handle to be used with the context.

这是错误的:

class Texture {
/* ... */

public:
    void bind();
}

只有当纹理是当前活动上下文的一部分时才有效.

It would only work if the texture was part of the currently active context.

这也好不到哪里去:

class Texture {
/* ... */

public:
    void bind(Context &ctx);
}

纹理仍然必须是上下文 ctx 的一部分,并且只有在 ctx 此刻处于活动状态时它才会起作用.

The texture still must be part of the context ctx, and it would only work, if ctx was active at the moment.

那么这个呢:

class Context {
/* ... */
public:
    void bindTextureToUnit(TextureUnit &tu, Texture &t);
};

更好,但仍然不正确,因为上下文必须是当前线程中当前活动的上下文.您可能会想哦,如果上下文不活动,我只会抛出异常".请不要这样做.

Better, but still not correct as the context must be the one currently active in the current thread. You may think "oh, I'll just throw an exception if context is not active". Please don't do this.

那怎么办

class ActiveContext : Context {
/* ... */
public:
    void bindTextureToUnit(TextureUnit &tu, Texture &t);

}

现在您已经确定每个线程只能有一个 ActiveContext 实例.最终你会陷入各种奇怪的线程单例混乱.

Now you've ended up with making sure that there can be only one ActiveContext instance per thread. Which ends you up in all kinds of weird thread singleton mess.

事实上,我曾多次尝试实现从 OpenGL 状态和对象到一组 C++ 类的清晰而合理的映射,但总有一些情况根本无法解决或以可怕的代码混乱告终.

In fact I numerously tried to implement a clean and sane mapping from OpenGL state and objects into a set of C++ classes, but there are always cases where is simply doesn't work out or ends up in horrible code mess.

恕我直言,最好不要尝试将 OpenGL API 映射到一组 C++ 类中(这不能正常完成),而是使用来自专门类的常规 OpenGL API.任何 OpenGL 上下文管理都非常依赖于问题程序,因此必须专门针对该程序进行定制.

IMHO it's far better to not try mapping the OpenGL API into a set of C++ classes (it can't be done sanely), but instead use the regular OpenGL API from specialized classes. Any OpenGL context management is so dependent in the program in questions, that it must be tailored specifically to said program.

相关文章