Qt+OpenGL之紋理貼圖
阿新 • • 發佈:2019-02-19
NeNe的程式碼中是載入到了一個正方體當中,程式碼很長。其實單純的想要紋理貼圖是很方便的。具體的紋理貼圖技術在NeNe的書中的有很詳細的介紹。
.h檔案:
#ifndef PICGLWIDGET_H #define PICGLWIDGET_H #include <QtGui/QWidget> #include <QWidget> #include <QtOpenGL> #include <GL/GLU.h> #include <gl/gl.h> class PicGLWidget : public QGLWidget { Q_OBJECT public: explicit PicGLWidget(QWidget *parent = 0); ~PicGLWidget(); protected: void loadGLTextures (); void initializeGL(); //初始化OpenGL視窗部件 void paintGL(); //繪製整個OpenGL視窗,只要有更新發生,這個函式就會被呼叫 void resizeGL(int width, int height); //處理視窗大小變化事件的,引數是新狀態下的寬和高 void keyPressEvent(QKeyEvent *e); //滑鼠處理函式 protected: bool fullscreen; //判斷是否全屏的變數 float Zyot; GLuint texture[1]; }; #endif // PICGLWIDGET_H
.cpp檔案:
#include "picglwidget.h" PicGLWidget::PicGLWidget(QWidget *parent) : QGLWidget(parent) { fullscreen = false; Zyot = -10.0f; } void PicGLWidget::initializeGL() { setGeometry(300, 150, 500, 500);//設定視窗初始位置和大小 loadGLTextures(); glEnable(GL_TEXTURE_2D);//啟用紋理 glShadeModel(GL_SMOOTH);//設定陰影平滑模式 glClearColor(0.0, 0.0, 0.0, 0.5);//改變視窗的背景顏色 glClearDepth(1.0);//設定深度快取 glEnable(GL_DEPTH_TEST);//允許深度測試 glDepthFunc(GL_LEQUAL);//設定深度測試型別 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//進行透視校正 glBlendFunc(GL_SRC_ALPHA, GL_ONE);//源畫素因子採用alpha通道值,目標畫素因子採用1.0 glEnable(GL_BLEND); } void PicGLWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0, 0.0, Zyot); glBindTexture(GL_TEXTURE_2D, texture[0]);//繫結紋理目標 glBegin(GL_QUADS); glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 1.0, 1.0 ); glEnd(); } void PicGLWidget::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);//建立透視投影矩陣 glColor4f(1.0f, 1.0f, 1.0f, 0.5f); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glMatrixMode(GL_MODELVIEW);//以下2句和上面出現的解釋一樣 glLoadIdentity(); } void PicGLWidget::keyPressEvent(QKeyEvent *e) { switch(e->key()) { /*F1鍵為全屏和普通屏顯示切換鍵*/ case Qt::Key_F1: fullscreen = !fullscreen; if(fullscreen) showFullScreen(); else { setGeometry(300, 150, 500, 500); showNormal(); } updateGL(); break; /*Ese為退出程式鍵*/ case Qt::Key_Escape: close(); } } void PicGLWidget::loadGLTextures() { QImage tex, buf; if(!buf.load("./images/2.bmp"))//這個時候因為debug沒有在外面,所以圖片資料夾就是本目錄了 { qWarning("Cannot open the image..."); QImage dummy(128, 128, QImage::Format_RGB32);//當沒找到所需開啟的圖片時,建立一副128*128大小,深度為32位的點陣圖 dummy.fill(Qt::green); buf = dummy; } tex = convertToGLFormat(buf);//將Qt圖片的格式buf轉換成opengl的圖片格式tex glGenTextures(1, &texture[0]);//開闢3個紋理記憶體,索引指向texture[0] /*建立第一個紋理*/ glBindTexture(GL_TEXTURE_2D, texture[0]);//將建立的紋理記憶體指向的內容繫結到紋理物件GL_TEXTURE_2D上,經過這句程式碼後,以後對 //GL_TEXTURE_2D的操作的任何操作都同時對應與它所繫結的紋理物件 glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());//開始真正建立紋理資料 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//當所顯示的紋理比載入進來的紋理小時,採用GL_NEAREST的方法來處理 //GL_NEAREST方式速度非常快,因為它不是真正的濾波,所以佔用記憶體非常 // 小,速度就快了 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//當所顯示的紋理比載入進來的紋理大時,採用GL_NEAREST的方法來處理 } PicGLWidget::~PicGLWidget() { }
當然,你需要在pro檔案中新增opengl。