OPenGL笔记--多边形旋转

该博客介绍了如何在OpenGL环境中使用glRotatef函数实现3D图形的旋转。通过一个实例展示了如何围绕Y轴旋转三角形以及围绕X轴旋转正方形,动态更新旋转角度实现连续旋转效果。关键代码包括glTranslatef和glRotatef的使用,以及利用QTimer更新GL场景。

一、前置知识

OPenGL中使用glRotatef(Angle, Xvector, Yvector, Zvector)来让对象绕某个轴旋转

  • Angle:通常是个变量,导表对象转过的角度;
  • Xvector, Yvector, Zvector:共同决定对象旋转的方向;
  • (1,0,0)表示绕着X轴旋转、 (0,1,0)表示绕着Y轴旋转、 (0,0,1)表示绕着Z轴旋转;

二、运行效果

在这里插入图片描述


三、关键代码

void GL_Test::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存

    //-----------------------------------------
    glLoadIdentity();   //重置当前的模型观察矩阵

    glTranslatef(-1.5, 0.0, -6.0);

    glRotatef(rTri, 0.0, 1.0, 0.0); //绕Y轴旋转rTri度

    //开始绘制三角形
    glBegin(GL_TRIANGLES);

    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(0.0, 1.0, 0.0);      //上顶点

    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(-1.0, -1.0, 0.0);    //左下顶点

    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(1.0, -1.0, 0.0);     //右下顶点

    glEnd();
    //绘制三角形结束

    //-----------------------------------------
    glLoadIdentity();   //重置当前的模型观察矩阵

    glTranslatef(-1.5, 0.0, -6.0);

    glRotatef(rQuad, 1.0, 0.0, 0.0);    //绕X轴旋转rQuad度

    //开始绘制正方形
    glTranslatef(3.0, 0.0, 0.0);

    glBegin(GL_QUADS);

    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(-1.0, 1.0, 0.0);     //左上顶点

    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(1.0, 1.0, 0.0);      //右上顶点

    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(1.0, -1.0, 0.0);     //右下顶点

    glColor3f(1.0, 1.0, 0.0);
    glVertex3f(-1.0, -1.0, 0.0);    //左下顶点

    glEnd();
    //绘制正方形结束

    //-----------------------------------------
    rTri += 5;
    rQuad += 5;
}

四、完整代码

#ifndef GL_TEST_H
#define GL_TEST_H

#include <qgl.h>        //因为QGLWidget类被包含在qgl.h头文件中
#include <glut.h>       //使用glut库中的API
#include <QKeyEvent>
#include <QTimer>

//继承QGLWidget得到OPenGL窗口部件类
class GL_Test : public QGLWidget
{
public:
    GL_Test(QWidget* parent = 0, bool fs = false);
    ~GL_Test();

protected:
    /*************************************************************************************************
    QGLWidget 类已经内置了对 OpenGL 的处理,就是通过对 initializeGL()、 paintGL()和 resizeGL()这个三个函数实现
    *************************************************************************************************/
    void initializeGL() override;           //用来初始化OPenGL窗口,可以在里面设定一些有关选项
    void paintGL() override;                //用来绘制OPenGL的窗口,只要有更新发生,这个函数就会被调用
    void resizeGL(int w, int h) override;   //用来处理窗口大小变换这一事件,resizeGL()在处理完后会自动刷新屏幕

    void keyPressEvent(QKeyEvent* e) override;  //Qt键盘事件处理函数

protected:
    bool fullscreen;    //用来保存窗口是否处于全屏状态的变量
    GLfloat rTri;       //用来旋转三角形
    GLfloat rQuad;      //用来旋转正方形
};

#endif // GL_TEST_H

#include "gl_test.h"

GL_Test::GL_Test(QWidget* parent, bool fs)
    : QGLWidget(parent)
{
    fullscreen = fs;

    rTri = 0.0;

    rQuad = 0.0;

    setGeometry(500,500,640,480);               //设置窗口大小、位置

    setWindowTitle("The first OpenGL Window");  //设置窗口标题

    if(fullscreen) {
        showFullScreen();
    }

    QTimer* timer = new QTimer(this);
    connect(timer,&QTimer::timeout,[=]{
        updateGL();
    });
    timer->start(50);
}

GL_Test::~GL_Test()
{

}

void GL_Test::initializeGL()
{
    glShadeModel(GL_SMOOTH);    //启用smooth shading(阴影平滑)

    glClearColor(0.0, 0.0, 0.0, 0.0);   //清除屏幕时所用的颜色,rgba【0.0(最黑)~1.0(最亮)】

    glClearDepth(1.0);  //设置深度缓存

    glEnable(GL_DEPTH_TEST);    //启动深度测试

    glDepthFunc(GL_LEQUAL); //所作深度测试的类型

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  //真正精细的透视修正,告诉OPenGL我们希望进行最好的透视修正,这会十分轻微的影响性能,但使得透视图看起来好一点
}

void GL_Test::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存

    //-----------------------------------------
    glLoadIdentity();   //重置当前的模型观察矩阵

    glTranslatef(-1.5, 0.0, -6.0);

    glRotatef(rTri, 0.0, 1.0, 0.0); //绕Y轴旋转rTri度

    //开始绘制三角形
    glBegin(GL_TRIANGLES);

    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(0.0, 1.0, 0.0);      //上顶点

    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(-1.0, -1.0, 0.0);    //左下顶点

    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(1.0, -1.0, 0.0);     //右下顶点

    glEnd();
    //绘制三角形结束

    //-----------------------------------------
    glLoadIdentity();   //重置当前的模型观察矩阵

    glTranslatef(-1.5, 0.0, -6.0);

    glRotatef(rQuad, 1.0, 0.0, 0.0);    //绕X轴旋转rQuad度

    //开始绘制正方形
    glTranslatef(3.0, 0.0, 0.0);

    glBegin(GL_QUADS);

    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(-1.0, 1.0, 0.0);     //左上顶点

    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(1.0, 1.0, 0.0);      //右上顶点

    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(1.0, -1.0, 0.0);     //右下顶点

    glColor3f(1.0, 1.0, 0.0);
    glVertex3f(-1.0, -1.0, 0.0);    //左下顶点

    glEnd();
    //绘制正方形结束

    //-----------------------------------------
    rTri += 5;
    rQuad += 5;
}

void GL_Test::resizeGL(int w, int h)
{
    if(h == 0) {    //防止h为0
        h = 1;
    }

    glViewport(0, 0, (GLint)w, (GLint)h);   //重置当前的视口(Viewport)

    glMatrixMode(GL_PROJECTION);    //选择投影矩阵

    glLoadIdentity();   //重置投影矩阵

    gluPerspective( 45.0, (GLfloat)w/(GLfloat)h, 0.1, 100.0 );  //建立透视投影矩阵

    glMatrixMode(GL_MODELVIEW); //选择模型观察矩阵

    glLoadIdentity();   //重置模型观察矩阵
}

void GL_Test::keyPressEvent(QKeyEvent* e)
{
    switch (e->key()) {
        case Qt::Key_Q: {
            fullscreen = !fullscreen;
            if(fullscreen) {
                showFullScreen();
            }else {
                showNormal();
                setGeometry(500,500,640,480);
            }
            updateGL();
            break;
        }//case Qt::Key_Q

        case Qt::Key_Escape: {
            close();
        }//Qt::Key_Escape

    }//switch (e->key())
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝勒里恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值