2016-09-16 22 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

相關問題