標籤:qt opengl 3d空間中移動映像
Qt_OpenGL:3D空間中移動映像
//.h
#ifndef GLWIDGET_H#define GLWIDGET_H#include <QGLWidget>#include <QtOpenGL>class QGLWidget;class QTimer;typedef struct Stars{public: int r, g, b; GLfloat dist, angle;}Stars;class GLWidget : public QGLWidget{ Q_OBJECTpublic: GLWidget(QWidget *parent = 0); ~GLWidget();protected: void initializeGL(); void paintGL(); void resizeGL(int w, int h); void keyPressEvent(QKeyEvent*); void timerEvent(QTimerEvent*);private: bool fullscreen; GLfloat rotate_angle; GLfloat zoom; GLfloat title; GLfloat spin; GLuint loop; bool twinkle; GLfloat blend;private: void loadTextures(); GLuint texture[1];};#endif // GLWIDGET_H
//.cpp
#include "glwidget.h"#include <glut.h>#include <QtGui>#include <QtCore>//好吧我承認全部變數不好GLfloat light_ambient[4] = {0.5,0.5,0.5,1.0};GLfloat light_diffiuse[4] = {1.0,1.0,1.0,1.0};GLfloat light_position[4] = {0.0,0.0,2.0,0.0};static const int num = 50;static Stars stars[num];GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent){ fullscreen = false; rotate_angle = 0.0; zoom = -15.0; title = 90.0; spin = 0.1; loop = 0; twinkle = false; blend = false; startTimer(5);}void GLWidget::initializeGL(){ setGeometry(300,150,500,500); loadTextures(); 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); glEnable(GL_BLEND); //為num個星星對象賦初值 for(loop = 0; loop < num; ++loop){ stars[loop].angle = 0.0; stars[loop].dist = (float(loop)/num) * 5.0; stars[loop].r = rand() % 256; stars[loop].g = rand() % 256; stars[loop].b = rand() % 256; }}void GLWidget::paintGL(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, texture[0]); for(loop = 0; loop < num; ++loop){ glLoadIdentity(); glTranslatef(0.0, 0.0, zoom); //移向螢幕裡面 glRotatef(title, 1.0, 0.0, 0.0); //沿x軸旋轉title glRotatef(stars[loop].angle, 0.0, 1.0, 0.0); //每個星星沿y軸旋轉自己的角度 glTranslatef(stars[loop].dist, 0.0, 0.0); //平移 glRotatef(-stars[loop].angle, 0.0, 1.0, 0.0); //沿y軸反轉 glRotatef(-title, 1.0, 0.0, 0.0); //沿x軸反轉 if(twinkle){ //如果星星閃爍 glColor4ub(stars[num-loop-1].r, stars[num-loop-1].g, stars[num-loop-1].b, 255); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glEnd(); } //如果星星不閃爍 glRotatef(spin, 0.0f, 0.0f, 1.0f); //沿z軸自轉spin glColor4ub(stars[loop].r, stars[loop].g, stars[loop].b, 255); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glEnd(); spin += 0.01f; stars[loop].angle += float(loop)/num; stars[loop].dist -= 0.01f; //距離逐漸減小,即越來越靠近螢幕 if(stars[loop].dist < 0){ stars[loop].dist += 5.0f; stars[loop].r = rand() % 256; stars[loop].g = rand() % 256; stars[loop].b = rand() % 256; } }}void GLWidget::resizeGL(int w, int h){ if( 0 == h){ h = 1; } glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLdouble)w/(GLdouble)h, 0.1, 100.0); glColor4f(1.0f, 1.0f, 1.0f, 0.5f); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}void GLWidget::keyPressEvent(QKeyEvent *event){ switch(event->key()){ case Qt::Key_T:{ twinkle = !twinkle; updateGL(); break; } case Qt::Key_B:{ blend = !blend; if(blend){ glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); }else{ glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); //色彩混合和深度緩衝不能同時開啟 } updateGL(); break; } case Qt::Key_PageUp:{ //移向螢幕 zoom -= 0.2; updateGL(); break; } case Qt::Key_PageDown:{ //移向螢幕外 zoom += 0.2; updateGL(); break; } case Qt::Key_Up:{ //加快旋轉速度 title += 0.5; updateGL(); break; } case Qt::Key_Down:{ title -= 0.5; updateGL(); break; } case Qt::Key_F1:{ fullscreen = !fullscreen; if(fullscreen){ showFullScreen(); }else{ setGeometry(300,150,500,500); showNormal(); } updateGL(); break; } case Qt::Key_Escape:{ close(); } }}void GLWidget::loadTextures(){ QImage tex, buf; if(!buf.load(":Star.bmp")){ qWarning("Cannot open the image..."); QImage dummy(128, 128, QImage::Format_RGB32); dummy.fill(Qt::green); buf = dummy; } tex = convertToGLFormat(buf); glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); 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); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);}void GLWidget::timerEvent(QTimerEvent *){ updateGL();}GLWidget::~GLWidget(){}
//main.cpp
#include "glwidget.h"#include <QApplication>int main(int argc, char *argv[]){ QApplication a(argc, argv); GLWidget w; w.show(); return a.exec();}
//運行結果:
Qt_OpenGL:3D空間中移動映像