2016-09-16 67 views
0

我有一个RenderWidget类从QOpenGLWidget继承,它有以下两种方法,其中包括:如何仅在用户输入上设置统一变量?

RenderWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_3_Core { 
    // ... 
public slots: 
    void setSmthEnabled(bool enabled) { 
     float val = (enabled == true) ? 1.0f : 0.0f; 
     shader.setUniformValue("uniformUserInput", val); 
    } 

public: 
    void paintGL() { 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     // ... 
     shader.setUniformValue("uniform1", value1); 
     shader.setUniformValue("uniform2", value2); 
     // ... 
     mesh->draw(); 
    } 
}; 

paintGL被调用100次/秒,而setSmthEnabled是当用户在切换复选框仅称为UI,偶尔会发生。统一不需要设置每一帧,所以我尝试只在用户输入槽中设置它,但它不起作用。统一保留它的值,这是在初始化时设置的。

我想这是因为渲染是异步的,并且统一无法在管道忙时更新。这就是为什么我试图拨打glFinish()之前设置uniformUserInputsetSmthEnabled插槽,但它并没有帮助。我发现的唯一的解决办法是重写以下方式类:

RenderWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_3_Core { 
    // ... 
private: 
    float val = 1.0f; 

public slots: 
    void setSmthEnabled(bool enabled) { 
     val = (enabled == true) ? 1.0f : 0.0f; 
    } 

public: 
    void paintGL() { 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     // ... 
     shader.setUniformValue("uniform1", value1); 
     shader.setUniformValue("uniform2", value2); 
     // ... 
     shader.setUniformValue("uniformUserInput", val); 
     mesh->draw(); 
    } 
}; 

现实世界中的代码包含更多的用户输入的制服,所以我不希望更新所有的每一帧,并保持冗余为此目的的成员变量。如何仅更新用户输入的制服?

shader.setUniformValue在核心上面只呼叫QOpenGLShaderProgram::setUniformValue上有关的QOpenGLShaderProgram对象并返回。

回答

2

所以我尽量把它只有在用户输入插槽,但它不工作

这是可以预料的。 OpenGL是一个有状态的API,并且状态被封装在上下文中。单个程序中可能有多个上下文使用,必须绑定并且可以解除绑定。为了清楚起见,在Qt的编程模型中,OpenGL上下文仅在非常特定的情况下被绑定,即当在​​,paintGLresizeGL内时。您也可以通过QOpenGLContext::makeCurrent制作上下文。

只有在OpenGL上下文绑定的情况下,您才可以使用它。像设置统一的值。

我想这会发生是因为渲染是异步的,并且统一无法在管道忙时更新。

这不是原因。另外,OpenGL具有完美的能力,事实上,它已被指定,您可以随时拨打任何电话,一切都会排队等候。即使GPU仍在使用纹理对象进行渲染(驱动程序必须跟踪这些更改并推迟执行,直到所有受影响的资源都可以使用),您甚至可以替换纹理图像(即使通过PBO)。

+0

我不知道上下文在'paintGL'中是当前的,但不是我定义的其他方法。所以你的回答很有帮助,谢谢!但是,只有少数几种方法才能使上下文流畅起来,这是什么原因呢?是否在一个应用程序中管理多个上下文?它不会显着减慢渲染速度吗? – Sergey

+0

@Sergey:是的,这是关于在应用程序中有多个上下文的可能性。在默认的操作模式下,Qt为每个窗口创建一个单独的上下文(使用Qt5和新的OpenGL集成方式,您可以通过其他方式实现,但这不是非常简单)。所以如果围绕上下文有多个OpenGL窗口必须切换。除此之外,Qt5也可以使用OpenGL来渲染UI元素,而且您的小部件实际上已经结束于由Qt管理的FBO。 – datenwolf

相关问题