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_OBJECT public: 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(); }
//运行结果截图:
时间: 2024-12-29 11:20:27