1、安裝必要的庫linux
sudo apt-get install libxt-dev libmotif-dev libxext-dev libxaw7-dev libxmu-dev libgl1-mesa-dev freeglut3-dev libglu1-mesa-dev libqt4-dev libqt4-opengl-dev
2、項目openglQt(目錄下)的文件:緩存
$ cat openglQt.probash
###################################################################### # Automatically generated by qmake (2.01a) ?? 11? 19 22:49:56 2014 ###################################################################### QT += opengl TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . LIBS += -lGLU -lglut # Input HEADERS += nehewidget.h SOURCES += main.cpp nehewidget.cpp
$ cat nehewidget.happ
/* NeHeWidget類 * 這就是咱們繼承QGLWidget類獲得的OpenGL窗口部件類。 * 由nehewidget.h 展開。 */ #include <QtOpenGL/QtOpenGL> class NeHeWidget : public QGLWidget { /*由於QGLWidget類被包含在qgl.h頭文件中,因此咱們的類就須要包含這個頭文件。Q_OBJECT是Qt中的一 *個專用的宏,具體說明請參見Qt的文檔。 */ Q_OBJECT public: NeHeWidget( QWidget* parent = 0, bool fs = false ); ~NeHeWidget(); protected: void initializeGL(); void paintGL(); /*由於QGLWidget類已經內置了對OpenGL的處理,就是經過對initializeGL()、paintGL()和resizeGL() *這個三個函數實現的,具體狀況能夠參考QGLWidget類的文檔。由於咱們的這個Qt OpenGL教程取材於 *NeHe OpenGL教程,因此這裏就用這個NeHeWidget類來繼承QGLWidget類來使用相關OpenGL的功能。 *initializeGL()是用來初始化這個OpenGL窗口部件的,能夠在裏面設定一些有關選項。paintGL()就是用 *來繪製OpenGL的窗口了,只要有更新發生,這個函數就會被調用。resizeGL()就是用來處理窗口大小變化這 *一事件的,width和height就是新的大小狀態下的寬和高了,另外resizeGL()在處理完後會自動刷新屏幕。 */ void resizeGL( int width, int height ); /*這是Qt裏面的鼠標按下事件處理函數。*/ void keyPressEvent( QKeyEvent *e ); protected: /*用來保存窗口是否處於全屏狀態的變量。*/ bool fullscreen; };
$ cat nehewidget.cpp函數
/* 由nehewidget.cpp 展開。 */ #include "nehewidget.h" #include <GL/glut.h> /*這個是構造函數,parent就是父窗口部件的指針,fs就是窗口是否最大化。*/ NeHeWidget::NeHeWidget( QWidget* parent,bool fs ) : QGLWidget( parent) { /*保存窗口是否爲全屏的狀態。*/ fullscreen = fs; /*設置窗口的位置,即左上角爲(0,0)點,大小爲640*480。*/ setGeometry( 0, 0, 640, 480 ); /*設置窗口的標題爲「NeHe's OpenGL Framework」。*/ setWindowTitle(tr("NeHe's OpenGL Framework")); /*若是fullscreen爲真,那麼就全屏顯示這個窗口。*/ if ( fullscreen ) showFullScreen(); } /*這個是析構函數。*/ NeHeWidget::~NeHeWidget() { } /*這個函數中,咱們對OpenGL進行全部的設置。咱們設置清除屏幕所用的顏色,打開深度緩存,啓用smooth * shading(陰影平滑),等等。這個例程直到OpenGL窗口建立以後纔會被調用。 */ void NeHeWidget::initializeGL() { /*這一行啓用smooth shading(陰影平滑)。陰影平滑經過多邊形精細的混合色彩,並對外部光進行平滑。 *我將在另外一個教程中更詳細的解釋陰影平滑。 */ glShadeModel( GL_SMOOTH ); /*這一行設置清除屏幕時所用的顏色。若是您對色彩的工做原理不清楚的話,我快速解釋一下。 *色彩值的範圍從0.0到1.0。0.0表明最黑的狀況,1.0就是最亮的狀況。glClearColor後的 *第一個參數是紅色,第二個是綠色,第三個是藍色。最大值也是1.0,表明特定顏色份量的最亮狀況。 *最後一個參數是Alpha值。當它用來清除屏幕的時候,咱們不用關心第四個數字。如今讓它爲0.0。 *我會用另外一個教程來解釋這個參數。經過混合三種原色(紅、綠、藍),您能夠獲得不一樣的色彩。 *但願您在學校裏學過這些。所以當您使用glClearColor(0.0, 0.0, 1.0, 0.0 ),您將用亮藍色清除 *屏幕。若是用glClearColor(0.5, 0.0, 0.0, 0.0 ) *的話,您將使用中紅色來清除屏幕。 *不是最亮(1.0),也不是最暗 (0.0)。要獲得白色背景,您應該將全部的 *顏色設成最亮(1.0)。要黑色背景的話,您該將全部的顏色設爲最暗(0.0)。 */ glClearColor( 0.0, 0.0, 0.0, 0.0 ); /*設置深度緩存。*/ glClearDepth( 1.0 ); /*啓用深度測試。*/ glEnable( GL_DEPTH_TEST ); /*所做深度測試的類型。*/ /*上面這三行必須作的是關於depth buffer(深度緩存)的。將深度緩存設想爲屏幕後面的層。深度緩存 *不斷的對物體進入屏幕內部有多深進行跟蹤。咱們本節的程序其實沒有真正使用深度緩存,但幾乎全部在 *屏幕上顯示3D場景OpenGL程序都使用深度緩存。它的排序決定那個物體先畫。這樣您就不會將一個圓形 *後面的正方形畫到圓形上來。深度緩存是OpenGL十分重要的部分。 */ glDepthFunc( GL_LEQUAL ); /*真正精細的透視修正。這一行告訴OpenGL咱們但願進行最好的透視修正。這會十分輕微的影響性能。 *但使得透視圖看起來好一點。 */ glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); } /*這個函數中包括了全部的繪圖代碼。任何您所想在屏幕上顯示的東東都將在此段代碼中出現。之後的 *每一個教程中我都會在例程的此處增長新的代碼。若是您對 OpenGL已經有所瞭解的話,您能夠在 *glLoadIdentity()調用以後,函數返回以前,試着添加一些OpenGL代碼來建立基本的形。若是您是 *OpenGL新手,等着個人下個教程。目前咱們所做的所有就是將屏幕清除成咱們前面所決定的顏色, *清除深度緩存而且重置場景。咱們仍沒有繪製任何東東。 */ void NeHeWidget::paintGL() { /*清楚屏幕和深度緩存。*/ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); /*重置當前的模型觀察矩陣。*/ glLoadIdentity(); } /*透視圖設置屏幕。意味着越遠的東西看起來越小。這麼作建立了一個現實外觀的場景。此處透 *視按照基於窗口寬度和高度的45度視角來計算。0.1,100.0是咱們在場景中所能繪製深度的起點和終點。 *glMatrixMode(GL_PROJECTION)指明接下來的兩行代碼將影響projection matrix(投影矩陣)。投影 *矩陣負責爲咱們的場景增長透視。 glLoadIdentity()近似於重置。它將所選的矩陣狀態恢復成其原始狀態。 *調用glLoadIdentity()以後咱們爲場景設置透視圖。glMatrixMode(GL_MODELVIEW)指明任何新的變換 *將會影響modelview matrix(模型觀察矩陣)。模型觀察矩陣中存放了咱們的物體訊息。最後咱們重置 *模型觀察矩陣。若是您還不能理解這些術語的含義,請彆着急。在之後的教程裏,我會向你們解釋。只要 *知道若是您想得到一個精彩的透視場景的話,必須這麼作。這個函數的做用是從新設置OpenGL場景的 *大小,而無論窗口的大小是否已經改變(假定您沒有使用全屏模式)。甚至您沒法改變窗口的大小時 *(例如您在全屏模式下),它至少仍將運行一次——在程序開始時設置咱們的透視圖。OpenGL場景的尺寸 *將被設置成它顯示時所在窗口的大小。 */ void NeHeWidget::resizeGL( int width, int height ) { /*防止height爲0。*/ if ( height == 0 ) height = 1; /*重置當前的視口(Viewport)。*/ glViewport( 0, 0, (GLint)width, (GLint)height ); /*選擇投影矩陣.*/ glMatrixMode( GL_PROJECTION ); /*重置投影矩陣。*/ glLoadIdentity(); /*創建透視投影矩陣。*/ gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 ); /*選擇模型觀察矩陣。*/ glMatrixMode( GL_MODELVIEW ); /*重置模型觀察矩陣。*/ glLoadIdentity(); } void NeHeWidget::keyPressEvent( QKeyEvent *e ) { switch ( e->key() ) { /*若是按下了F2鍵,那麼屏幕是否全屏的狀態就切換一次。而後再根據須要,顯示所要的 *全屏窗口或者普通窗口。 */ case Qt::Key_F2: fullscreen = !fullscreen; if ( fullscreen ) showFullScreen(); else { showNormal(); setGeometry( 0, 0, 640, 480 ); } update(); break; /*若是按下了Escape鍵,程序退出。*/ case Qt::Key_Escape: close(); } }
$ cat main.cpp性能
/* main.cpp * 由main.cpp 展開。 */ /* Qt的應用程序直接使用QtGui模塊,直接包含QtGui就能夠了。*/ #include <QtGui> #include "nehewidget.h" int main( int argc, char **argv ) { /*咱們把這個布爾型變量的初始值設置爲false。*/ bool fs = false; /*每個Qt應用程序都使用QApplication類。*/ QApplication a(argc,argv); /*使用當前字符編碼。*/ QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); /*這裏彈出一個消息對話框,讓用戶選擇是否使用全屏模式。*/ switch( QMessageBox::information( 0, "Start FullScreen?", "Would You Like To Run In Fullscreen Mode?", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default ) ) { case QMessageBox::Yes: fs = true; break; case QMessageBox::No: fs = false; break; } /*設置應用程序的主窗口部件爲w。*/ NeHeWidget w( 0, fs ); /*顯示w。*/ w.show(); /*程序返回。*/ return a.exec(); }
3、編譯測試
$ qmake $ make g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I. -I/usr/X11R6/include -I. -o main.o main.cpp g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I. -I/usr/X11R6/include -I. -o nehewidget.o nehewidget.cpp /usr/lib/x86_64-linux-gnu/qt4/bin/moc -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I. -I/usr/X11R6/include -I. nehewidget.h -o moc_nehewidget.cpp g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I. -I/usr/X11R6/include -I. -o moc_nehewidget.o moc_nehewidget.cpp g++ -m64 -Wl,-O1 -o openglQt main.o nehewidget.o moc_nehewidget.o -L/usr/lib/x86_64-linux-gnu -L/usr/X11R6/lib64 -lGLU -lglut -lQtOpenGL -lQtGui -lQtCore -lGL -lpthread