OpenGL_Qt學習筆記之_01(創建一個OpenGL窗口)


很早就想學opengl的,一直沒時間,今天心血來潮初步了解了下opengl。

Opengl是對2D和3D圖形支持很好,有非常多的優化函數,因為opengl的主要目標是圖形功能函數上,所以它對圖形界面的支持並不完善。當然了,作為一個跨平台的開源庫,這是能理解的,因為每個平台開發界面用的工具不同,如果它只支持其一,那么私心也太重了,還不如節省精力放在核心的代碼上。

Qt的UI函數很多,它的Opengl封裝很好,將opengl的函數和Qt的界面結合了起來,這主要是通過Qt中QGLWidget這個類來實現。所以一般我們開發opengl,且要用到Qt的界面時,這些類都可以從QGLWidget繼承過來。

本次試驗是按照網絡上NeHe寫的最著名的opengl英文教程:http://nehe.gamedev.net/ 和對應的中文教程:http://www.owlei.com/DancingWind/ 的第一講來學習的。當然也參考了網上對Nehe教程改編的Qt版:http://wenku.baidu.com/view/835b29fd941ea76e58fa04a2.html 

 

本次試驗的目的很簡單,只是顯示一個窗口,可以通過F1鍵值來切換全屏顯示和普通屏顯示,並當按下ESE鍵時退出程序。窗口的顏色背景和透視效果(其實該試驗都沒用上)等用opengl來實現,主要是為后面的學習寫了個框架,其實這里主要是重寫了3個函數:initializeGL();paintGL();resizeGL();這3個函數都是QGLWidget內部的虛函數。

 

程序運行時效果如下:

  

 

程序代碼如下:

glwidget.h:

復制代碼
#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <QtOpenGL>
#include <QWidget>

namespace Ui {
class GLWidget;
}

class GLWidget : public QGLWidget
{
    Q_OBJECT
    
public:
    explicit GLWidget(QGLWidget *parent = 0);
    ~GLWidget();

protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int width, int height);
    void keyPressEvent(QKeyEvent *e);
    bool fullscreen;
    
private:
    Ui::GLWidget *ui;
};

#endif // GLWIDGET_H
復制代碼

 

glwidget.cpp:

復制代碼
#include "glwidget.h"
#include "ui_glwidget.h"

#include <QtGui>
#include <QtCore>
#include <QtOpenGL>

GLWidget::GLWidget(QGLWidget *parent) :
    QGLWidget(parent),
    ui(new Ui::GLWidget)
{
    ui->setupUi(this);
    fullscreen = false;

}

//這是對虛函數,這里是重寫該函數
void GLWidget::initializeGL()
{
    setGeometry(300, 150, 640, 480);//設置窗口初始位置和大小
    glShadeModel(GL_FLAT);//設置陰影平滑模式
    glClearColor(0.5, 1.0, 0.2, 0);//改變窗口的背景顏色,不過我這里貌似設置后並沒有什么效果
    glClearDepth(1.0);//設置深度緩存
    glEnable(GL_DEPTH_TEST);//允許深度測試
    glDepthFunc(GL_LEQUAL);//設置深度測試類型
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//進行透視校正
}

void GLWidget::paintGL()
{
    //glClear()函數在這里就是對initializeGL()函數中設置的顏色和緩存深度等起作用
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();//重置當前的模型觀察矩陣?不是很理解!
}

//該程序是設置opengl場景透視圖,程序中至少被執行一次(程序啟動時).
void GLWidget::resizeGL(int width, int height)
{
    if(0 == height)
        height = 1;//防止一條邊為0
    glViewport(0, 0, (GLint)width, (GLint)height);//重置當前視口,本身不是重置窗口的,只不過是這里被Qt給封裝好了
    glMatrixMode(GL_PROJECTION);//選擇投影矩陣
    glLoadIdentity();//重置選擇好的投影矩陣
   // gluPerspective(45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0);//建立透視投影矩陣
    //glMatirxMode(GL_MODELVIEW);//以下2句和上面出現的解釋一樣
    glLoadIdentity();


}
void GLWidget::keyPressEvent(QKeyEvent *e)
{
    switch(e->key())
    {
        //F1鍵為全屏和普通屏顯示切換鍵
        case Qt::Key_F1:
            fullscreen = !fullscreen;
            if(fullscreen)
                showFullScreen();
            else
            {
                setGeometry(300, 150, 640, 480);
                showNormal();
            }
            updateGL();
            break;
        //Ese為退出程序鍵
        case Qt::Key_Escape:
            close();
    }
}

GLWidget::~GLWidget()
{
    delete ui;
}
復制代碼

 

  程序里面有很多opengl的函數暫時還用不到,因為圖形學領域不熟,有些函數功能暫時也不理解,以后慢慢會懂的。

  編譯時,gluPerspective處如下錯誤:

  C:\Users\Administrator\Desktop\tornadomeet\opengl\opengl_nehe_01\glwidget.cpp:46: error: C3861: “gluPerspective”: 找不到標識符。

  網上不少人都遇到過,貌似是Qt4.8以后的高級版本都不支持glu開頭的函數了,是Nokia弄的bug,還是有什么原因故意這么弄的?據說Qt4.7.4還支持。對於我這種初學者,反正還沒用到那個函數,可以不管,實在要用到時切換到4.7.4也行,還有,5.0據說9月份就要發行了,很期待。

 

附錄一

因為是初學,可能有些同學不懂改怎樣建立於opengl有關的工程,是用QtGUI工程,還是Qt控制台工程,或者是Qt空工程?網上貌似還沒有找到比較好的介紹。下面我把我建立該工程的過程記下來(也許步驟不對,不過我這次就是這么弄的)。

開發環境:windows+Qt4.8.2+QtCreator2.5.1

1.  打開QtCreator軟件,進入File-->New File or Project,左邊Projects選擇Application,中間選擇Qt Gui Application,如下圖所示:

  

 

2. 單擊choose,進入下一個界面,自己填入工程名和目錄(不能包含空格和中文路徑)。

3. 單擊next,進入下一界面,繼續單擊next,進入Class Information界面。類的名字自己設置,注意Base class(基類)一欄選擇QWidget,不要選擇QMainWidget或者QDialog,貌似我那2種試過,在本程序中修改比較大。如下圖所示:

  

 

4. 單擊next進入下一界面,單擊Finish完成操作。

5. 打開glwidget.h文件,因為生成的文件該類是從QWidget類繼承過來的,而我們是需要從QGLWidget中繼承過來,所以把代碼更改后如下:

復制代碼
#ifndef GLWIDGET_H

#define GLWIDGET_H

 

#include <QtOpenGL/QtOpenGL>

#include <QWidget>

 

namespace Ui {

class GLWidget;

}

 

class GLWidget : public QGLWidget

{

  Q_OBJECT

  

public:

  explicit GLWidget(QGLWidget *parent = 0);

  ~GLWidget();

  

private:

  Ui::GLWidget *ui;

};

 

#endif // GLWIDGET_H
復制代碼

 

6. 同理,glwidget.cpp文件也更改后如下:

復制代碼
#include "glwidget.h"

#include "ui_glwidget.h"

 

GLWidget::GLWidget(QGLWidget *parent) :

  QGLWidget(parent),

  ui(new Ui::GLWidget)

{

  ui->setupUi(this);

}

 

GLWidget::~GLWidget()

{

  delete ui;

 

http://www.pdfxs.com/search?q=abp-466


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM