c++ - OpenGL对象创建

标签 c++ inheritance opengl

现在,我正在对某种小OpenGL库进行建模,以愚弄图形编程等。因此,我正在使用类来包装特定的OpenGL函数调用,例如纹理创建,着色器创建等,到目前为止,效果很好。

我的问题:

所有OpenGL调用必须由拥有已创建的OpenGL上下文的线程完成(至少在Windows下,每个其他线程将不执行任何操作并产生OpenGL错误)。因此,为了获得OpenGL上下文,我首先创建一个窗口类的实例(只是Win API调用的另一个包装器),最后为该窗口创建OpenGL上下文。这对我来说听起来很合乎逻辑。 (如果我的设计中已经存在一个让您尖叫的缺陷,请告诉我...)

如果要创建纹理或需要OpenGL调用的任何其他对象来进行创建,则基本上可以这样做(例如,称为OpenGL对象的构造函数):

opengl_object()
{
    //do necessary stuff for object initialisation
    //pass object to the OpenGL thread for final contruction
    //wait until object is constructed by the OpenGL thread 
}

因此,换句话说,我使用
 opengl_object obj;

然后,它在其构造器中将自己放入要由OpenGL上下文线程创建的OpenGL对象队列。 OpenGL上下文线程然后调用一个在所有OpenGL对象中实现的虚函数,该虚函数包含最终创建该对象所需的OpenGL调用。

我真的认为,以这种方式处理该问题会很好。但是,现在,我认为我错了。

情况是,即使到目前为止上述方法都可以很好地工作,但随着类层次结构的深入,我会遇到麻烦。例如(这不是很完美,但它显示了我的问题):

假设,我有一个名为sprite的类,显然,它代表一个Sprite。它具有OpenGL线程自己的创建功能,其中顶点和纹理坐标被加载到图形卡的内存中,依此类推。到目前为止没有问题。
进一步说,我想有两种渲染 Sprite 的方法。一个实例,一个实例。因此,我将得到2个类,sprite_instanced和sprite_not_instanced。两者都是从sprite类派生的,因为它们都是仅以不同方式呈现的sprite。但是,sprite_instanced和sprite_not_instanced在其create函数中需要进一步的OpenGL调用。

到目前为止,我的解决方案(我对此感到非常恐惧!)

我对C++中的对象生成如何工作以及它如何影响虚函数有某种理解。因此,我决定仅使用类Sprite的虚拟创建功能将顶点数据等加载到图形内存中。然后,sprite_instanced的虚拟创建方法将进行准备以渲染该实例实例。
所以,如果我想写
sprite_instanced s;

首先,调用sprite构造函数,并在进行一些初始化之后,构造线程将对象传递给OpenGL线程。此时,传递的对象仅仅是普通的 Sprite ,因此将调用sprite::create,而OpenGL线程将创建普通的 Sprite 。之后,构造线程将调用sprite_instanced的构造函数,再次进行一些初始化,然后将该对象传递给OpenGL线程。但是这次是sprite_instanced,因此将调用sprite_instanced::create。

因此,如果我对上述假设是正确的,那么至少在我的情况下,一切都会按预期进行。我花了最后一个小时来阅读有关从构造函数调用虚拟函数以及v表如何构建等的信息。我已经进行了一些测试来检验我的假设,但这可能是特定于编译器的,因此我不完全依赖它们。此外,它感觉就像可怕的骇客一样可怕。

另一个解决方案

另一种可能性是在OpenGL线程类中实现工厂方法来解决这一问题。因此,我可以在这些对象的构造函数中进行所有OpenGL调用。但是,在那种情况下,我将需要很多功能(或一种基于模板的方法),并且当OpenGL线程要做的事情比需要做的更多时,感觉就像是潜在的渲染时间损失。

我的问题

可以按照我上面描述的方式来处理吗?还是我应该扔掉那些东西然后做其他事情?

最佳答案

  • 在构造函数中调用任何虚函数始终是错误的形式。虚拟调用将无法正常完成。
  • 您的数据结构非常困惑。您应该研究Factory对象的概念。这些是用于构造其他对象的对象。您应该有一个SpriteFactory,它会被推送到某种队列或其他任何队列中。该SpriteFactory应该是创建Sprite对象本身的东西。这样,您就不会有部分构造的对象的概念,在其中创建它会把自己插入队列,依此类推。

    确实,无论何时您开始写“Objectname::Create”,都停下来思考:“我真的应该使用Factory对象。”
  • 关于c++ - OpenGL对象创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7590646/

    相关文章:

    python - 无法在子初始化器的列表理解中调用父方法,但显式循环有效

    c++ - 用于桌面 Gui 应用程序的 Qt 4.x/5.x 和 OpenGL : What module to choose?

    c++ - c_str() == NULL 不工作

    c++ - 多个默认可选值

    objective-c - 子类可以在继承方法的参数中的 block 中添加参数吗?

    c++ - 在 OpenGL 中启用深度测试后,我的整个屏幕都是空白的(恢复为清晰的颜色)——为什么?

    linux - 如何通过 drm (Linux) 创建 opengl 上下文

    c++ - Qt - 在 Linux DE 上将窗口提升到当前桌面/工作区

    c++ - 在 NodeJS 中将 Raw 流转换为 Wav 流

    database-design - 设计带或不带继承的数据库