閱讀612 返回首頁    go 阿裏雲 go 技術社區[雲棲]


[Qt教程] 第48篇 進階(八) 3D繪圖簡介

[Qt教程] 第48篇 進階(八) 3D繪圖簡介

樓主
 發表於 2013-10-7 09:44:37 | 查看: 184| 回複: 0
3D繪圖簡介



版權聲明

該文章原創於作者yafeilinux,轉載請注明出處!




導語


OpenGL是一個跨平台的用來渲染3D圖形的標準API。在Qt中提供了QtOpenGL模塊,從而很輕鬆地實現了在Qt應用程序中使用OpenGL,這主要是在QGLWidget類中完成的。因為3D繪圖涉及到了專業方麵的內容,我們下麵隻是講解最簡單的使用,向大家演示在Qt中如何顯示3D圖形。如果大家想深入學習openGL繪圖,可以查看網上比較經典的nehe的OpenGL教程,為了方便大家下載,我們在網站上提供了下載連接。





環境:Windows Xp + Qt 4.8.5+QtCreator2.8.0




目錄


一、繪製簡單的圖形
二、添加顏色
三、實現3D效果





正文


一、繪製簡單的圖形

QGLWidget類是一個用來渲染OpenGL圖形的部件,它提供了在Qt應用程序中顯示OpenGL圖形的功能。我們隻需要繼承該類,然後像使用其他QWidget部件一樣來使用它。QGLWidget提供了三個虛函數,可以在子類中通過重新實現它們來執行典型的OpenGL任務:
initializeGL():設置OpenGL渲染環境,定義顯示列表等。該函數隻在第一次調用resizeGL()或paintGL()前被調用一次;
resizeGL():設置OpenGL的視口、投影等。每次部件改變大小時都會調用該函數;
paintGL():渲染OpenGL場景。每當部件需要更新時都會調用該函數。



下麵先來看一個簡單的例子。



1.新建空的Qt項目,項目名稱為myOpenGL,完成後向項目中添加新的C++ Class,類名為MyGLWidget,基類修改為QGLWidget,類型信息選擇“繼承自QWidget”。



2.完成後打開myOpenGL.pro,添加一行代碼:
QT += opengl
然後保存該文件。



3.打開myglwidget.h文件,添加函數聲明:
protected:
    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();



4. 再到myglwidget.cpp文件中先添加頭文件包含:
#include <GL/glu.h>

然後添加這三個函數的定義:
void MyGLWidget::initializeGL()
{
   glClearColor(0.0, 0.0, 0.0, 0.0);
   glShadeModel(GL_SMOOTH);
   glClearDepth(1.0);
   glEnable(GL_DEPTH_TEST);
}


       glClearColor()函數用來設置清除屏幕時使用的顏色,其四個參數分別用來設置紅、綠、藍顏色分量和Alpha值,它們的取值範圍都是0.01.0,這裏四個參數都為0,表示純黑色。然後設置了陰影平滑(smooth shading),這樣可以使色彩和光照更加精細。最後設置了深度緩存和啟用深度測試,用來記錄圖形在屏幕內的深度值。

void MyGLWidget::resizeGL(int w, int h)
{
   glViewport(0, 0, (GLint)w, (GLint)h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(45.0, (GLfloat)w/(GLfloat)h, 0.1, 100.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}


       glViewport()函數用來設置視口的大小。然後使用glMatrixMode()設置了投影矩陣,投影矩陣用來為場景增加**,後麵使用了glLoadIdentity()重置投影矩陣,這樣可以將投影矩陣恢複到初始狀態。gluPerspective()用來設置**投影矩陣,這裏設置視角為45度,縱橫比為窗口的縱橫比,最近的位置為0.1,最遠的位置為100,這兩個值是場景中所能繪製的深度的臨界值。大家可以想象,離我們眼睛比較近的東西看起來比較大,而比較遠的東西看起來就比較小。最後設置並重置了模型視圖矩陣。

void MyGLWidget::paintGL()
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glLoadIdentity();
   // 繪製三角形
   glTranslatef(-2.0, 0.0, -6.0);
   glBegin(GL_TRIANGLES);  
   glVertex3f(0.0, 1.0, 0.0);
   glVertex3f(-1.0, -1.0, 0.0);
   glVertex3f(1.0, -1.0, 0.0);
   glEnd();
   // 繪製四邊形
   glTranslatef(4.0, 0.0, 0.0);
   glBegin(GL_QUADS);   
   glVertex3f(-1.0, 1.0, 0.0);
   glVertex3f(1.0, 1.0, 0.0);
   glVertex3f(1.0, -1.0, 0.0);
   glVertex3f(-1.0, -1.0, 0.0);
   glEnd();
}


       在開始繪製以前,先要使用glClear()清除屏幕和深度緩存。然後重置了模型視圖矩陣,這樣便將當前點移動到了窗口的中心,現在窗口中心即為坐標原點,X軸從左到右,Y軸從下到上,Z軸從裏到外。完成這兩步以後就可以進行圖形的繪製了,在圖形繪製開始時,一般會使用glTranslatef()來移動坐標原點,它是相對於當前點來移動的,比如這裏先將坐標原點左移2.0,向裏移6.0,然後繪製了三角形(TRIANGLES)。繪製從glBegin()開始,到glEnd()結束,使用glVertex3f()來設置各個頂點的坐標,頂點的繪製順序可以是順時針,也可以是逆時針。要注意逆時針繪製出來的是正麵,而順時針繪製出來的是反麵,這一點在後麵的紋理貼圖部分會顯示出來。當繪製完三角形以後,又將原點相對於當前點向右移動了4.0,然後繪製了一個四邊形(QUADS)。



5.最後再向項目中添加main.cpp文件,更改內容如下:


#include <QApplication>
#include "myglwidget.h"
int main(int argc, char *argv[])
{
   QApplication app(argc,argv);
   MyGLWidget w;
   w.resize(400, 300);
   w.show();
   return app.exec();
}


       現在運行程序,效果如下圖所示。



01.jpg



       可以看到,在Qt中隻需要實現這三個函數就可以進行OpenGL繪圖了。



二、添加顏色

       上麵的例子中圖形都是白色的,可以使用glColor3f()函數來設置繪製時使用的顏色,它的三個參數用來指定RGB(紅綠藍)顏色分量,取值範圍為0.01.0。我們可以在繪製一個頂點時指定使用的顏色,如果後麵不再設置其他顏色,那麼所有的頂點都將使用同樣的顏色。
       下麵我們將圖形的繪製代碼更改如下:



void MyGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(-2.0, 0.0, -6.0);
    glBegin(GL_TRIANGLES);
    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(0.0, 1.0, 0.0);
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(-1.0, -1.0, 0.0);
    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(1.0, -1.0, 0.0);
    glEnd();
    glTranslatef(4.0, 0.0, 0.0);
    glBegin(GL_QUADS);
    glColor3f(1.0, 1.0, 0.0);
    glVertex3f(-1.0, 1.0, 0.0);
    glVertex3f(1.0, 1.0, 0.0);
    glVertex3f(1.0, -1.0, 0.0);
    glVertex3f(-1.0, -1.0, 0.0);
    glEnd();
}



可以看到三角形的三個角分別是紅色、綠色和藍色,而正方形是純黃色的。如下圖所示。


02.jpg




三、實現3D效果



       前麵的圖形都還是平麵圖形,下麵添加代碼來實現三維立體效果。將程序中繪製圖形的代碼更改為:

void MyGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -6.0);
    glRotatef(45, 0.0, 1.0, 0.0);
    glBegin(GL_QUADS);
    // 上麵
    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(1.0, 1.0, 1.0);
    glVertex3f(1.0, 1.0, -1.0);
    glVertex3f(-1.0, 1.0, -1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    // 下麵
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(1.0, -1.0, 1.0);
    glVertex3f(1.0, -1.0, -1.0);
    glVertex3f(-1.0, -1.0, -1.0);
    glVertex3f(-1.0, -1.0, 1.0);
    // 前麵
    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(1.0, 1.0, 1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glVertex3f(1.0, -1.0, 1.0);
    glEnd();
}



這裏使用了glRotatef(angle, x, y, z)函數來對坐標軸進行旋轉,它的第一個參數是旋轉的角度,後麵三個參數用來確定旋轉軸向量。旋轉軸經過原點,指向(x,y,z)點。圖形的旋轉滿足右手定則,就是用右手握住旋轉軸,大拇指指向旋轉軸所指的方向,然後其他四個手指所指的方向就是要旋轉的方向。再往下麵,分別繪製了三個正方形作為正方體的三個麵,大家還可以再補充上其他幾個麵。運行程序,效果如下圖所示。


03.jpg





結語

       這一節隻是向大家簡單演示了如何在Qt中進行openGL編程來實現3D繪圖,目的隻是讓大家看到在Qt中進行3D繪圖是非常簡單的。如果想進一步應實現更炫酷的效果,就需要擁有openGL的專業知識了。




涉及到的代碼:  myOpenGL.rar (1.38 KB, 下載次數: 1) 

最後更新:2017-04-03 14:54:11

  上一篇:go Linux下TTY驅動程序分析
  下一篇:go 【進階】關於宏定義和內聯函數