QT与OpenGL之三维旋转

QT与OpenGL之三维旋转

制作短暂的效果。

在这篇文章中,将要展现的效果是在3D场景中移动位图,得到简单的动画效果。便于大家共同学习,给出全部代码:

在开始前,你应该在pro中添加

LIBS += glut.lib glut32.lib

同时你也应该将这两个库加到QT的bin目录下。

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();  //初始化OpenGL窗口部件
    void paintGL();  //绘制整个OpenGL窗口,只要有更新发生,这个函数就会被调用
    void resizeGL(int width, int height); //处理窗口大小变化事件的,参数是新状态下的宽和高
    void keyPressEvent(QKeyEvent *e);  //鼠标处理函数
    void loadGLTextures();
    void timerEvent(QTimerEvent *);

protected:
    bool fullscreen;  //判断是否全屏的变量
    bool twinkle;  //闪烁的星星
    bool tp;  //"T" 按下了吗
    bool blend;
    GLfloat rotate_angle;
    double title;
    double zoom;
    double tilt;
    GLfloat spin;
    GLuint loop;
    GLuint texture[1];

private:
    Ui::GLWidget *ui;
};

#endif // GLWIDGET_H

glwidget.cpp

#include "glwidget.h"
#include "ui_glwidget.h"

#include <QtGui>
#include <QtCore>
#include <QtOpenGL>
#include <GL/GLU.h>

const int num = 50;

typedef struct
{
    int r, g, b;
    GLfloat dist;
    GLfloat angle;
}stars;
stars star[num];

GLfloat light_ambient[4]={0.5, 0.5, 0.5, 1.0};
GLfloat light_diffuse[4]={1.0, 1.0, 1.0, 1.0};
GLfloat light_position[4]={0.0, 0.0, 2.0, 0.0};

GLWidget::GLWidget(QGLWidget *parent) :
    QGLWidget(parent),
    ui(new Ui::GLWidget)
{
    ui->setupUi(this);
    fullscreen = false;
    rotate_angle = 0.0;
    zoom = -15.0;
    title = 90.0;
    spin = (GLfloat)0.1;
    loop = 0;
    twinkle = false;
    blend = false;
    startTimer(5);//开启5ms定时器
}

//这是对虚函数,这里是重写该函数
void GLWidget::initializeGL()
{
    setGeometry(300, 150, 500, 500);//设置窗口初始位置和大小
    loadGLTextures();
    glEnable(GL_TEXTURE_2D);//允许采用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);

/*为num个星星的数组结构体赋初值*/
    for(loop = 0; loop < num; loop++)
        {
            star[loop].angle = 0.0;
            star[loop].dist = (float(loop)/num)*5.0;//星星的离中心的距离越来越远,最大距离为5,接近屏幕的距离
            star[loop].r = rand()%256;
            star[loop].g = rand()%256;
            star[loop].b = rand()%256;
        }
}

void GLWidget::paintGL()
{
    //glClear()函数在这里就是对initializeGL()函数中设置的颜色和缓存深度等起作用
    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轴旋转了tilt度
            glRotatef(star[loop].angle, 0.0, 1.0, 0.0);//每个星星沿着y轴旋转自己的角度
            glTranslatef(star[loop].dist, 0.0, 0.0);
            glRotatef(-star[loop].angle, 0.0, 1.0, 0.0);//将沿着y轴旋转的角度又转回去
            glRotatef(-title, 1.0, 0.0, 0.0);//将沿着x轴旋转过的角度也转回去
            if(twinkle)//如果星星闪烁的话
                {
                    glColor4ub(star[num-loop-1].r, star[num-loop-1].g, star[num-loop-1].b, 255);//采用的是对称一头那边的星星的颜色
                    //将星星的纹理贴到一个小矩形上
                    glBegin(GL_QUADS);
                    glTexCoord2f(0.0, 0.0);
                    glVertex3f(-1.0, -1.0, 0.0);
                    glTexCoord2f(1.0, 0.0);
                    glVertex3f(1.0, -1.0, 0.0);
                    glTexCoord2f(1.0, 1.0);
                    glVertex3f(1.0, 1.0, 0.0);
                    glTexCoord2f(0.0, 1.0);
                    glVertex3f(-1.0, 1.0, 0.0);
                    glEnd();
                }
            /*不闪烁时*/
            glRotatef(spin, 0.0, 0.0, 1.0);//星星沿z轴自转spin度
            glColor4ub(star[loop].r, star[loop].g, star[loop].b, 255);//采用的是自己的颜色,完全不透明
            glBegin(GL_QUADS);
            glTexCoord2f(0.0, 0.0);
            glVertex3f(-1.0, -1.0, 0.0);
            glTexCoord2f(1.0, 0.0);
            glVertex3f(1.0, -1.0, 0.0);
            glTexCoord2f(1.0, 1.0);
            glVertex3f(1.0, 1.0, 0.0);
            glTexCoord2f(0.0, 1.0);
            glVertex3f(-1.0, 1.0, 0.0);
            glEnd();

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/6f8d80c1f83b8fd1708ab1d7f90411e4.html