相关疑难解决方法(0)

OpenGL:用于加载资源的辅助线程?

使用C和Win32,我想知道如何实现用于加载资源(纹理和VBO)的辅助OpenGL线程.

从我发现的,这应该用wglShareLists()来完成,但我不确定如何设置辅助线程:

我是否需要新的设备上下文或仅需要新的渲染上下文?

我需要调用哪些wgl函数?

c opengl winapi

11
推荐指数
1
解决办法
6470
查看次数

在 .net 对象的终结器中调用 glDeleteTextures 的正确方法

我即将围绕 OpenGL 纹理实现一个托管包装类,并且我希望对象终结器调用glDeleteTextures.

因此,调用终结器的线程(GC线程?)必须通过调用绑定到纹理所属的OpenGL渲染上下文wglMakeCurrent

wglMakeCurrent文档明确指出,一个OpenGL渲染上下文不能同时是多个线程的当前渲染上下文。

如果GC可以随时触发,我不能保证发生时没有其他线程正在使用上下文。

glDeleteTextures调用 .net 对象的终结器的正确方法是什么?

编辑

该包装类将用于“按需加载”场景图的复杂系统,并通过WeakReference等等实现缓存策略。因此,“手动处置”不是我想要考虑的选项:我真的希望 GC 能够处理这个问题。

.net opengl multithreading garbage-collection finalizer

5
推荐指数
2
解决办法
1124
查看次数

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 
}
Run Code Online (Sandbox Code Playgroud)

所以,换句话说,我创建一个像任何其他对象一样的对象

 opengl_object obj;
Run Code Online (Sandbox Code Playgroud)

然后,在其构造函数中,将自身置于由OpenGL上下文线程创建的OpenGL对象的队列中.然后,OpenGL上下文线程调用一个虚拟函数,该函数在所有OpenGL对象中实现,并包含必要的OpenGL调用以最终创建对象.

我真的认为,这种处理这个问题的方式会很好.但是,现在,我觉得我错了.

情况是,尽管上面的方法到目前为止工作得非常好,但是一旦类层次结构变深,我就会遇到麻烦.例如(这不完美,但它显示了我的问题):

比方说,我有一个名为sprite的类,显然代表了一个Sprite.它有自己的OpenGL线程创建函数,其中顶点和纹理坐标被加载到图形卡内存中等等.到目前为止,这没问题.让我们进一步说,我想有两种渲染精灵的方法.一个实例和另一个方式.所以,我最终会得到2个类,sprite_instanced和sprite_not_instanced.两者都是从sprite类派生的,因为它们都是sprite,它们只是以不同的方式呈现.但是,sprite_instanced和sprite_not_instanced在其create函数中需要进一步的OpenGL调用.

到目前为止我的解决方案(我觉得它非常糟糕!)

我对c ++中的对象生成如何工作以及它如何影响虚函数有一些了解.所以我决定只使用类精灵的虚拟创建函数将顶点数据等加载到图形内存中.然后,sprite_instanced的虚拟create方法将执行准备以呈现该实例的sprite.所以,如果我想写

sprite_instanced s;
Run Code Online (Sandbox Code Playgroud)

首先,调用sprite构造函数,在一些初始化之后,构造线程将对象传递给OpenGL线程.此时,传递的对象只是一个普通的精灵,所以将调用sprite :: create,OpenGL线程将创建一个普通的精灵.之后,构造线程将调用sprite_instanced的构造函数,再次进行一些初始化并将对象传递给OpenGL线程.但是这一次,它是一个sprite_instanced,因此将调用sprite_instanced :: create.

所以,如果我对上述假设是正确的,那么一切都应该完全按照我的情况发生,至少在我的情况下.我花了最后一小时阅读关于从构造函数调用虚函数以及如何构建v-table等等.我已经运行了一些测试来检查我的假设,但这可能是编译器特定的所以我不依赖它们100% .此外,它只是感觉很糟糕,像一个可怕的黑客.

另一种方案

另一种可能性是在OpenGL线程类中实现工厂方法来处理它.所以我可以在这些对象的构造函数中进行所有OpenGL调用.但是,在这种情况下,我需要很多函数(或者一种基于模板的方法),当OpenGL线程需要做的事情多于它需要时,感觉可能会丢失潜在的渲染时间......

我的问题

可以按照我上面描述的方式处理它吗?或者我应该抛弃那些东西并做其他事情?

c++ opengl inheritance

4
推荐指数
1
解决办法
2580
查看次数

多个上下文与不同的版本

我正在试验多个OpenGL上下文之间的列表共享.这是一个很棒的功能,因为它允许我执行并行渲染线程.

但由于我正在使用CreateContextAttribs,我提供了请求特定OpenGL实现的可能性.因此,可能会发生一些上下文正在实现版本3.2+而另一个正在实现版本2.1.

实际上工作得很好,但我怀疑这种作案手法隐藏了一些副作用.使用具有不同版本的上下文时可能出现的问题列表是什么?

除此之外,我查询每个上下文版本的已实现的扩展,因为我认为不同的版本可以支持不同的扩展,这是对的吗?那么函数指针呢?我必须为每个具有不同版本的上下文重新查询它们(实际上,指针根据版本而变化)?

opengl opengl-3

2
推荐指数
1
解决办法
1721
查看次数