您好,登錄后才能下訂單哦!
雖然Qt不以效率著稱,但是事實上有足夠的優化,最最典型的就是默認的圖形雙緩沖,按照Windows下的編程慣例是需要手動開啟,并通過額外的接口調用才能使用的,這一點在以前簡單圖形編程學習時比較過Qt,Win32 GDI時感受特別深刻,在沒有額外處理的時候,Win32動畫程序那個閃阿,而Qt程序非常穩定。事實上,我想,Qt的其他問題比效率嚴重多了,比如個人感覺Qt程序在Windows下刷新的感知明顯沒有Windows原生程序快,這點倒是值得改進。
OpenGL只處理與3D圖形的繪制,基本上不提供創建用戶界面的功能,所以為OpenGL應用程序創建用戶界面必須使用其它的圖形工其包(如Motif、MFC等)。而Qt的OpenGL模塊很好的解決了這個問題,它提供了一個繼承自Qwidget的OpenGL部件類QGLWidget,使得該部件類能夠像Qt其它部件那樣使用,還可以在繪制窗口部件時直接使用OpenGL的API接口。在Qt中為OpenGL提供支持的類主要有以下幾個:
QGLWidget:用于渲染OpenGL場景的易于使用的Qt部件。
QGLColormap:用于在QGLWidget中安裝用戶自定義的顏×××。
QGLContext:封裝了用于OpenGL渲染的場景。
QGLFormat:指定OpenGL演染場景的顯示模式。
QGLFrameBufferObject和QGLPixelBuffer分別提供了對GL幀緩沖對象和GL像素緩沖的支持。
QGLPaintEngine:QPaintEngine的派生類,為QPainter提供了OpenGL繪圖引擎。
initializeGL() 注冊函數,在此設置GL的渲染繪制屬性、定義顯示列表、載入固定紋理等初始化工作。在initializeGL()在調用paintGL()之前只被調用一次,之后不再調用。
paintGL() 繪制函數,在此使用OpenGL中的接口進行場景繪制,QGLWidget的paintEvent( QPaintEvent* )將會自動調用 paintGL()進行部件的顯示繪制。也可在需要重繪時通過updateGL()時調用paintGL()。
resizeGL() 該函數用于處理當部件大小發生改變時,對OpenGL繪圖管線各矩陣需要進行的操作。該函數paintGL()第一次調用之前,initializeGL()調用之后被第一次被調用, 之后每當QGLWidget的不見大小發生改變時,都將調用該函數來對視圖、投影矩陣等進行相應的設置。
學習OpenGL很久了,也是時候在Qt的框架下感受一下OpenGL了,這也是學習OpenGL的好處,學習D3D的話就沒有這么Happy了,事實上這也導致我老實東學西學-_-!真不知是好是壞。。。只是作為程序員的感覺,要是世界只剩下Windows,那么實在失去了太多的色彩。
這樣就完成了一個利用OpenGL繪制矩形的任務,paintGL中調用的完全是普通的OpenGL函數,一如我們學過的普通OpenGL函數,沒有區別。其中最主要的代碼就在OpenGL::paintGL()中,這一點需要額外注意,那就是此處與普通的Qt程序是不同的,普通的Qt程序將重繪的工作放在paintEvent中進行,但是,可以想像的是,其實paintGL不過是QGLWidget中paintEvent中調用的一個虛接口,Qt可以在外面做好足夠的OpenGL準備工作。initializeGL,resizeGL,paintGL 3個額外的虛接口就構成了一個簡單但是強大的OpenGL框架,一如GLUT抽象出的框架及我在Win32 OpenGL學習時建立的框架一樣,知道這些以后,可以將OpenGL在Qt中的編程分成兩個部分,一個部分就是由initializeGL,resizeGL,paintGL三個虛接口構成的OpenGL的領域,我們可以在其中進行我們習慣的OpenGL操作,而程序的輸入等其他GUI相關的處理則還是交由Qt原來的框架去完成。
OpenGL從Win32到Qt
實際上,在進行二維圖形的繪制中,完全可以不使用OpenGL的原生接口而使用更為方便的QPainter。QPainter只是個API,實際的渲染是由QPaintEngine來執行的。Qt自帶有QGLPaintEngine,為QPainter提供了OpenGL后臺。在QGLWidget基礎上創建的QPainter,自動將QGLPaintEngine作為繪畫引擎。這樣,任何使用此QPainter類型繪制的2D圖形都會自動解析至OpenGL,間接以GL的原生接口來實現二維圖形的繪制。使用QPainter而不是OpenGL命令的優勢是可輕易將渲染在平臺默認引擎和OpenGL之間切換。這樣不僅可以充分利用二者各自的優勢,同時還可以直接使用Qt二維繪圖系統所提供的眾多高級功能。
Qt 提供了QtOpenGL模塊來支持三維圖形功能的OpenGL模塊。在使用QtOpengl模塊時,必須在對應的工程文件(*.pro)中加入:
QT += opengl
來聲明使用QtOpengl模塊,以便 qmake 在利用*.pro生成編譯器所需的makefile時添加所需的opengl庫。
在Qt下使用創建Opengl繪圖組件主要通過繼承QGLWidget并重現相關繪制函數來實現,QGLWidget派生自QWidget,故絕大多數情況下QGLWidget可以像QWidget一樣使用,只是使用OpenGL的函數替代QPainter實現繪制。通常通過子類化QGLWidget來實現OpenGL的使用,QGLWidget提供了三個虛函數用以重載來實現OpenGL的繪制:
可在任何需要刷新場景繪制的地方通過調用updateGL()來通知OpenGL進行重繪,但updateGL()自身不用實現。與QWidget相同,鼠標和鍵盤事件是通過mousePressEvent()和keyPressEvent()等事件處理函數進行處理的。要創建動畫,只需啟動QTimer,然后調用updateGL()。但應注意,如果需要在QGLWidget派生類之外的其他函數中進行paintGL()相同功能的繪制,需要先使用makeCurrent()接口將后面繪制的上下文對象(Context)標記為當前上下文對象(Current Context)。
如果本地OpenGL支持疊置繪制(Overlay Paint)(windows的WGL和X11的GLX都支持)QGLWidget還可以通過與前述類似的initializeOverlayGL()、resizeOverlayGL()、 paintOverlayGL()和updateOverlayGL()進行疊置層的繪制。makeoverlayCurrent()函數可以用于將疊置標記為當前上下文對象.
除了對OpenGL原生接口的支持,QGLWidget還為OpenGL在多個操作系統平臺上的應用進行了淺層封裝。Qt提供加載圖像并將其與紋理綁定的使用功能。可使用 GLuint bindTexture(Qp_w_picpath&, GLenum target, GLint format, QGLContext::BindOptions)等接口將圖像與所申請的OpenGL紋理索引進行綁定,并使用 deleteTexture ( GLuint id )來刪除已申請的紋理索引。Qt在內部對己與紋理綁定的像素圖/圖像進行跟蹤,這樣就可在使用相同的圖像文件或像素圖時重新使用紋理。由于QImage是獨立于硬件的,因此可以在另一個線程中對紋理圖片進行繪制,在繪制完成之后再載入OpenGL中作為紋理,而不需要OpenGL渲染線程中處理,因此可以很大幅度提高OpenGL繪圖部件的響應速度。
Qt還提供了在OpenGL三維繪圖場景中任意三維位置處按照給定的QFont字體格式繪制任意字符(包漢字等非ASCII碼字符),大大簡化了在三維場景中繪制字符的操作
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。