2016-06-28 93 views
2

我目前正在嘗試使用GleW來獲得Qt 5窗口並且使用QOpenGLContext。是的,我知道Qt 5爲OpenGL提供了自己的函數包裝,但由於我的渲染引擎依賴於GLEW並支持其他窗口庫,所以Qt內置的東西不是一種選擇。與Qt 5.x一起使用GLEW

現在,這裏是我站了起來,至今運行:

  1. 我子類QWindow並用QOpenGLContext裝備吧。上下文已成功初始化。

  2. 初始化QOpenGLContext後,I(再次成功)調用glewInit()初始化GLEW。

  3. 我現在能夠以與我爲其他窗口框架(GLFW,更加精確)完全相同的方式將幾何體呈現爲默認幀緩衝區。

這裏有一個棘手的部分:我使用OpenGL的統一緩衝區對象之一將光數據傳輸到GPU。一旦我打電話給glBufferData()開始填充它,我會得到一個分段錯誤。當使用我的基於GLFW的實現和上下文初始化時,一切正常。我知道這種行爲可能會導致OpenGL上下文初始化不充分,但再次設置QOpenGLContext並調用glewInit()似乎工作得很好。

下面是一些代碼來證明什麼,我試圖做...

QtWindow::QtWindow(QWindow *parent) 
: QWindow(parent) { 

    setSurfaceType(QWindow::OpenGLSurface); 

    QSurfaceFormat format; 
    format.setVersion(4,5); 
    format.setOption(QSurfaceFormat::DeprecatedFunctions); 
    format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); 
    format.setProfile(QSurfaceFormat::CoreProfile); 

    setFormat(format); 

} 

這應該足以後來得到我想要的格式的內容。現在,第一幀渲染之前,我建立的背景和GLEW ...

void QtWindow::init_context() { 

    if (!initialized_) { 
    context_handler_.init(this); 
    initialized_ = true; 

    glewExperimental = GL_TRUE; 
    auto e = glewInit(); 
    if (e != GLEW_OK) { 
     std::cout << "Failed to initialize glew: " 
       << glewGetErrorString(e) << std::endl; 
    } 

    glGetError(); 

    } 

} 

我用一個小的輔助類初始化QOpenGLContext,因爲我需要防止的Qt來自聯合國定義GLEW宏:

void QtContextHandler::init(QWindow* parent) { 
    if (!qt_context_) { 
    qt_context_ = new QOpenGLContext(parent); 
    qt_context_->setFormat(parent->requestedFormat()); 

    if (qt_context_->create()) { 
     auto format(qt_context_->format()); 
     std::cout << "Initialized Qt OpenGL context " 
       << format.majorVersion() << "." 
       << format.minorVersion() << " successfully." 
       << std::endl; 


     qt_context_->makeCurrent(parent); 
    } else { 
     std::cout << "Failed to initialize Qt OpenGL context!" 
       << std::endl; 
    } 

    } 
} 

下面是我設置光線UBO和OpenGL初始化時發生的崩潰事件,如上所示。我使用oglplus作爲GL的包裝,但因爲它包裹OpenGL的功能相當緊密,你應該明白我的意思:

ubo_.Bind(ogl::Buffer::Target::Uniform); 

oglplus::Buffer::Data(oglplus::Buffer::Target::Uniform, sizeof(data), &data, oglplus::BufferUsage::DynamicDraw); 

有沒有人嘗試過類似的方法,並可以分享他們的經驗?我會很感激任何幫助,因爲我一直在試圖弄清楚我做錯了什麼。再說一遍:初始化似乎運行順利,我甚至可以創建VBOs/VAOs/IBOs來渲染網格!只有創建UBO纔會導致分段錯誤。

編輯:

好了,這裏有一些新的見解。首先,如果上傳的數據超過一定的大小(〜90字節),分段錯誤纔會發生。換句話說,我可以使用恰好一個自定義光源渲染Qt創建的上下文場景。當查詢GL_MAX_UNIFORM_BLOCK_SIZE時,驅動程序告訴我,統一塊有64KB可用(GLFW創建的上下文同樣適用)。有沒有人有可能出錯的想法?

+1

你說,只要你使用'glBufferData'就會出現seg錯誤。你檢查過那個時候'glBufferData'是否非空? –

+0

@ G.M。是的,我查了一下。奇怪的是,我嘗試上傳一些虛擬數據,例如'std :: array d = {0,1,2,3,4,5,6,7,8,9}'和'ogl :: Buffer :: Data (ogl :: Buffer :: Target :: Uniform,sizeof(d),&d,ogl :: BufferUsage :: DynamicDraw);'它工作得很好(除了意想不到的着色器端行爲,顯然)。我感覺到我用於光照數據的數據類型越來越亂了。 –

回答

1

好的,萬一任何人遇到類似的困難:我設法通過使用glBufferStorage而不是glBufferData上傳UBO數據來得到它的工作。前者用於創建不可變大小的緩衝區,這對我的目的來說已經足夠了。不過,我不知道glBufferData出了什麼問題,並且它是否是Qt中的錯誤,或者我錯誤地初始化了上下文。

+0

到目前爲止,您是否嘗試過使用Qt的更高版本? (這個帖子寫於一年前(2016年)現在是2017年)。 –