背景:
我的c ++ / OpenGL3.1 / GLSL / Qt程序中有一个Shader类。我的程序使用基于不同GLSL源文件的几个着色器。
我的应用程序可以基于QGLWidget实现运行许多不同的3D渲染器,每个渲染器都会创建自己的着色器。
当我创建第一个3d渲染器并初始化着色器时,在glCreateShader&amp ;;的帮助下生成着色器ID。 glCreateProgram,没有任何问题。
问题:
但是当我创建第二个3d渲染器时,检索ID的OGL函数给出完全相同但我期望有新的。这意味着我的两个渲染器会将数据发送到同一个GPU程序......
很明显,在GPU程序中,统一变量是混合的,当运行第二个渲染器时,第一个渲染器会显示一个奇怪的渲染。
实际上,当我关闭两个渲染器中的一个时,所有着色器都被杀死了......第二个渲染器无法显示任何内容。
想法?
我完全迷失了,我的逻辑演绎是glCreateShader& glCreateProgram根据自己的线程ID给出ID。 QGLWidget可能运行自己的线程来调用渲染函数,这可能会给持久性问题带来麻烦......
如何解决这个问题?
答案 0 :(得分:3)
如果您的QOpenGLWidget共享同一个父窗口,则默认情况下它们共享相同的上下文。如果你不想要那个,那么用你的第二个QOpenGLWidget创建一个新的顶级小部件(任何没有父级的QWidget)就更容易了。
请注意,这与旧的QGLWidget类不同。 From Qt documentation:
当多个QOpenGLWidgets作为子项添加到同一个顶级窗口小部件时,它们的上下文将相互共享。这不适用于属于不同窗口的QOpenGLWidget实例。
这意味着同一窗口中的所有QOpenGLWidgets都可以访问彼此的可共享资源,如纹理,并且不需要额外的全局共享"上下文,就像QGLWidget一样。
答案 1 :(得分:2)
没有问题需要解决。
每个QGLWidget都有自己的OpenGL context。并且,除非您明确在它们之间共享对象,否则每个上下文都有自己独立的对象列表。
您只能将OpenGL对象与创建它的OpenGL上下文一起使用。只要你将对象分开,并且仅将它们与创建它的上下文一起使用,你应该没问题。