簡體   English   中英

Qt 4/5和Opengl API之間的opengl速度差異

[英]Difference in opengl speed between Qt 4/5 and Opengl API

我已經閱讀了關於qt 4和5 opengl的所有關於SO的問題。 這是Qt 5中最接近的OpenGL vs QOpenGL / QtOpenGL:差異和局限? ,我不知道為什么它被關閉,因為它是一個很好的問題。 我看到它缺少的唯一方面是速度差異。

我也讀過這個https://qt-project.org/forums/viewthread/22921 ,它有類似的問題,但是來回約4比5,主要討論新功能。

我的問題是,使用QT5的內置方法比直接使用opengl API制作自定義小部件要快嗎? 如果我擔心性能,那么使用QT是一個糟糕的選擇

編輯:

更具體一點,我需要使用physx,tcp / ip通信,以及大量快速更新頂點和網格。 目標是盡可能接近實時。 像渲染這樣的東西不是一個問題,但qt的任何開銷都是有害的。 (一切都是使用C ++的3D)

我已經閱讀了關於qt 4和5 opengl的所有關於SO的問題。 這是Qt 5中最接近的OpenGL vs QOpenGL / QtOpenGL:差異和局限? ,我不知道為什么它被關閉,因為它是一個很好的問題。 我看到它缺少的唯一方面是速度差異。

更具體一點,我需要使用physx,tcp / ip通信,以及大量快速更新頂點和網格。 目標是盡可能接近實時。 像渲染這樣的東西不是一個問題,但qt的任何開銷都是有害的。 (一切都是使用C ++的3D)

您的問題中有多個問題。

“原始”OpenGL與“Qt”OpenGL

這個問題很糟糕,因為沒有“Qt OpenGL”這樣的東西。 OpenGL是Khronos標准擁有和發布的標准。 Qt只是使用它。

Qt可以為您做的是幫助您的應用程序管理多個事情。

窗口/上下文創建

你有沒有試過在Win32下創建一個OpenGL上下文? 它需要一堆樣板代碼(參見此處此處 ),其中包括創建臨時上下文以檢查WGL功能,然后最終創建實際上下文...

您是否嘗試過在X11下創建OpenGL上下文? 它需要一堆樣板代碼(見這里 ),它涉及檢查GLX_ARB_create_context存在,然后用它來創建上下文,或者回退到GLX 1.3代碼路徑和......

您是否曾嘗試在Mac OS X下創建OpenGL上下文?

您是否曾嘗試在Android下創建OpenGL上下文?

您是否嘗試過在QNX下創建OpenGL上下文?

您是否曾嘗試在DirectFB / EGLFS下創建OpenGL上下文?

等一下。 問:Qt:

class Window : public QWindow {
    QOpenGLContext *context;
public:
    Window() {
        QSurfaceFormat format;
        format.setVersion(3,3);
        format.setProfile(QSurfaceFormat::CoreProfile);

        setSurfaceType(OpenGLSurface);
        setFormat(format);
        create();

        context = new QOpenGLContext;
        context->setFormat(format);
        context->create();
    }
...

是的,就是這樣。 這創建了一個(頂級)OpenGL窗口和一個3.3核心配置文件上下文。 將它與QTimer結合使用,您就擁有了可行的渲染器。 這當然適用於所有上述平台:Win32,Mac,X11,Linux / EGLFS,QNX,iOS,Android


你需要支付所有這些費用嗎? 當然是。 但這絕對可以忽略不計; 並且您只需支付一次,即創建窗口和上下文時。

真正重要的東西來自OpenGL繪圖本身,它完全在您的控制之下: 您在窗口上創建上下文並開始發出原始OpenGL命令 Qt不在那里。 Qt和OpenGL再次見面的唯一時刻是交換緩沖時間; 但這是一項幾乎沒有成本的操作。

所以: Qt不會增加任何可衡量的開銷

窗口管理

當然,與上述捆綁在一起的事實是,您可以在任何這些平台上使用相同的代碼處理鍵盤和鼠標輸入。 或者調整窗口大小。 或者全屏。 或者關閉它。

OpenGL助手

Qt並不“只是”提供一種創建OpenGL表面和上下文的方法(以及相關操作:設置為當前,交換緩沖區等)。 它(更進一步),並提供了一整套輔助類和函數:

  • QMatrix4x4是一個... 4x4矩陣。 它具有OpenGL程序中所需的所有lookAt()功能: lookAt()ortho()perspective()normalMatrix()等。
  • QOpenGLContext :: hasExtensionQOpenGLContext :: getProcAddress是解決OpenGL入口點的獨立於平台的方法。
  • QOpenGLContext :: versionFunctions返回一個對象,其中包含已解析的給定版本/配置文件的所有OpenGL入口點。
  • QOpenGLBuffer包裝緩沖區對象。
  • QOpenGLVertexArrayObject包裝頂點數組對象(並具有RAII幫助程序以綁定和取消綁定VAO)。
  • QOpenGLTexture包裝紋理對象。
  • QOpenGLFrameBufferObject包裝幀緩沖區對象。
  • QOpenGLShaderQOpenGLShaderProgram包裝着色器和着色器程序,提供了將QMatrix4x4設置為統一變量的便捷方法。 因此,您可以使用上述方法計算CPU上給定網格的MVP,然后將其設置為統一。
  • QOpenGLDebugLogger包裝GL_KHR_debug以調試OpenGL應用程序。
  • 和另一堆我現在不記得的東西。

有開銷嗎? 是的,但它再次是最小的, 它不涉及如何在OpenGL代碼中使用這些對象 如果您的OpenGL代碼快速且結構良好,您會發現這些幫助程序對管理它很有用,並且它們不會使它運行得更慢。

(“有用於管理它”的示例:QOpenGLVertexArrayObject將允許您在OpenGL 3.0上使用VAO,或者在存在GL_ARB_vertex_array_object擴展的任何Desktop OpenGL版本上使用VAO,或者如果存在GL_OES_vertex_array_object則在OpenGL ES2上使用GL_OES_vertex_array_object 。您無需解析正確的功能集取決於運行時.Qt將為您執行此操作並提供用於創建,綁定,釋放和銷毀VAO的相同API。

一切都那么好嗎 不,我必須在這里說實話,有一點點可以從一些愛中受益。

例如,QOpenGLFrameBufferObject具有有限的API,不支持任何數量的顏色附件。 QOpenGLBuffer需要一些工作來支持更多的緩沖區類型/綁定目標。 仍然沒有對程序管道的支持。 仍然不支持統一緩沖區。

另一方面,你有像QOpenGLTexture這樣的東西,它支持最近的功能,如不可變存儲和紋理視圖。

這是否意味着您無法使用這些功能? 當然可以。 如果你需要功能,請回到原始的OpenGL代碼Qt現在沒有給你。 或者,考慮將這些功能貢獻給Qt

Qt的

當然,一旦你走Qt路徑,你就有了Qt。 這意味着,僅在QtCore和QtGui庫中:

  • 事件循環
  • 計時器
  • 信號和插槽
  • 線程
  • Unicode字符串+ i18n
  • 集裝箱
  • 常用表達
  • 文件處理
  • 插件加載
  • 設置
  • MIME類型
  • 輸入處理
  • 圖像I / O.
  • 使用光柵引擎進行2d命令式繪畫
  • JSON
  • XML
  • 和另一堆我現在不記得的東西。

當然,以上所有都是跨平台的。

順便說一句,Qt還有:

  • 用於跨平台2d小部件的QtWidgets
  • QtSql用於數據庫訪問
  • QtNetwork for TCP / UDP / SSL套接字,以及高級HTTP / FTP引擎
  • QtTest進行單元測試
  • 用於嵌入webkit的QtWebkit
  • 和另一堆我現在不記得的東西

Qt 4中的OpenGL與5

在Qt 4和Qt 5中如何處理OpenGL之間是否存在巨大差異? 並不是的...

在Qt 4中,用於進行OpenGL渲染的類是QGLWidget。 它存在於QtOpenGL模塊中(而不是QtGui中 - 請記住Qt 4中的小部件也存在於QtGui中)。 另外,我在上面列出的Qt 5 OpenGL助手的實際部分是QGLFoo名稱(fi QGLBuffer而不是QOpenGLBuffer )。

在Qt 5中,QtOpenGL模塊仍然用於保持舊應用程序的工作。 但:

  • QtGui和QtWidgets分道揚 .. QtGui現在包含處理WM的低級別位,創建GL上下文和曲面,2d繪畫,以及基本上我上面列出的內容。 相反,QtWidgets包含小部件本身。

  • QtOpenGL仍然包含QGL *類,但現在鏈接到QtWidgets(因為它包含QGLWidget)。 這意味着使用QGLWidget意味着即使您根本不使用小部件,也會鏈接到某個大型庫 (因為您的應用程序是純OpenGL)。

  • 正如我之前所展示的,QtGui足以創建一個頂級的OpenGL窗口。 但是如果你想將它嵌入基於小部件的應用程序中該怎么辦? 然后你仍然可以使用QGLWidget或通過QWidget::createWindowContainer嵌入QWindow。 除了QGLWidget之外,您不應該使用任何其他QtOpenGL(即QGL)類。 使用QtGui中的對應項(即QOpenGL類)。

  • 所有上面的QOpenGL *類都在QtGui中,而不在QtOpenGL中 ; 它們不僅僅是QGL *對應物(例如沒有QGLVertexArrayObject),它們有更多的功能(例如QOpenGLShader支持幾何和曲面細分着色器,QGLShader沒有),以及一般使用的(因為它們會看到錯誤修正和改進) ,QGL *不會)。

  • 鑒於現在QtGui提供OpenGL支持,期望QGLWidget替換直接出現在QtWidgets中是很自然的。 事實上,它有望在5.4(准備工作進入5.3;但不幸的是,功能本身將錯過功能凍結)。


是否有理由期待Qt 4和Qt 5之間存在巨大的性能差異? 不,我希望您的GL代碼執行完全相同。 最后Qt並沒有真正妨礙你。

桌面GL / ES 2

您可以通過配置時間開關使用“Desktop GL”或“ES 2”支持編譯Qt 5。 它顯然會改變QtGui在編譯時將使用哪些頭文件,以及它將鏈接到哪些庫(libGL或libGLES2等)。 它還將改變默認的表面格式:上面的QWindow代碼將創建一個漂亮的OpenGL ES2表面(並且可能無法創建上下文,因為沒有OpenGL ES 3.3,哦,好吧)。

但是你明白了:使用相同的代碼你也可以支持ES2。

問題(在我看來)是它也將改變一些其他更微妙的東西:例如QOpenGLShader將插入一些宏,如

#define highp
#define mediump
#define lowp

如果您正在使用Desktop GL,請在所有着色器之前。 原因是它允許您在ES2和Desktop GL中重復使用相同的着色器 ,這些着色器缺少精度限定符; 因此它們會被擴展為空的宏擦除。

我認為這些小事並不是真正的收獲。 也許它們會減少非常小而簡單的着色器(以及僅由頂點和碎片着色器制作的程序)的維護。 如果Qt不會那么聰明,那會更好。

但您的Desktop GL代碼路徑可能正在使用更多着色器階段; 或者通常只使用ES2上沒有的功能。 最終,它將與您的ES2代碼路徑明顯不同。 (想想在3.3核心中你必須使用VAO,而ES2本身並不知道VAO是什么。)

個人咆哮:我討厭,討厭,討厭ES2不像OpenGL配置文件那樣的事實,而是自己獨立。 並且基本上必須有一個不同的代碼庫才能讓ES2滿意。 Bah bah bah。

視窗

進入痛苦的世界! 也稱為Windows下的OpenGL驅動程序狀態。

基本上,除NVIDIA之外的任何人都在Windows上發布破碎的OpenGL驅動程序。

至少,“開箱即用”。 升級驅動程序通常有效 ,但您並不總是要求用戶升級其驅動程序。 他們是最終用戶,而不是職業玩家。 也許他們甚至沒有管理員權限。

這對於OpenGL應用程序來說是一個問題,特別是對於Qt最強大的工具之一:Qt Quick 2. Qt試圖通過使用ANGLE解決這個問題,ANGLE是一個OpenGL ES2 - > Direct3D轉換層。 因此,在Windows下,您可以選擇

  • 桌面OpenGL構建
  • 通過ANGLE構建OpenGL ES2

選擇不相同 - ES2當然意味着忘記做任何嚴肅的現代GL。 但除此之外, 這里提供一種或另一種方式的原因。

Qt Quick 2

這很重要,我認為值得一提。

但首先讓我們澄清一下:您是否需要使用Qt Quick 2在Qt下構建OpenGL應用程序? 不,不,不。 Qt Quick 2是一種完全獨立的技術,它也利用OpenGL進行渲染。 因此,您可以忽略它,只需構建您的OpenGL應用程序。

但Qt Quick 2究竟是什么? 它是一個建立在QML語言之上的庫,一種用於創建動態UI的聲明性語言(現在用於構建系統 ......哦)。

請記住區別:QML是語言 ,Qt Quick 2是一個包含一組可視項目(以及用於創建自己的C ++ API)的庫,您可以使用QML編程。

Qt Quick 2使用OpenGL來繪制那些視覺項目。 這可以保證60 FPS的無撕裂效果,非常低的CPU使用率,各種基於着色器的視覺效果,等等。

所以呢? 好吧,你可能有興趣給它一個踢。 例如,API允許它疊加到您繪制的任何純OpenGL內容上。 所以你可以考慮使用Qt Quick 2來處理更傳統的UI位 - 按鈕,滑塊等,同時你可以控制主要內容的渲染。

或者,您可以忽略它存在的事實並繼續使用OpenGL。

我認為你的問題和收到的評論中存在很多誤解。 問題的根源是“Qt”一詞的使用非常松散。

Qt是一個很大的跨平台應用程序開發框架。 它結合了許多獨立框架提供的功能。 它提供了許多完全不與gui相關的功能。 即跨平台容器,線程,變體,具有內省的元對象系統,定時器,網絡,使用qtscript或javascript(通過qml),xml,json,狀態機等編寫腳本。 Qt用於編寫Web服務,例如,在任何地方都沒有單行UI代碼。

在用戶界面方面,Qt為您提供了四個UI工具包 完全由您選擇最終使用的工具包。 您還可以混合搭配所有這些 - 您可以在一個工具包中實現UI的一部分,在另一個工具包中實現部分。 一切都取決於您的要求。

我認為“Qt5”是指Qt Quick 2,它是使用QML作為描述/腳本平台的場景圖和UI工具包的實現。 如果你只需要一個2D,基於場景圖的工具包,那么Qt Quick 2就是一個不錯的選擇。 它不提供任何3D功能,因此對於3D功能,您可以自己動手。 Qt不會妨礙你 - 事實上,它會對你有所幫助,因為它為OpenGL提供了一個可移植的包裝器API,它隱藏了訪問OpenGL的一些平台差異。 它還提供ANGLE,一個在Direct3D之上的OpenGL捆綁實現。 這使您可以在OpenGL中進行開發,同時仍然在Windows上定位Direct3D。

對於TCP / IP和一般非ui功能,您應該使用Qt - 它使生活變得非常簡單。 對於3D,您將通過Qt提供的包裝器直接使用OpenGL。 然后,您可以在Qt的OpenGL和ANGLE構建之間進行選擇,以決定是直接使用平台OpenGL驅動程序,還是使用在DirectX(ANGLE)之上實現的OpenGL。 既然你使用了physx,那么你已經有了很好的nvidia驅動程序,以及一個不錯的OpenGL實現,所以不首選使用ANGLE。 這就是我看到它的方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM