OpenGL学习(二)绘制三维图形 固定管线

一.简单步骤

  • 考虑顶点数据
  • 上色
  • 旋转

二.完整代码

myopenglwidget.h

// An highlighted block
#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QtNetwork/QHostInfo>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QNetworkInterface>
#include <QFile>
#include <QDir>
#include <QImage>
#include <QBuffer>
#include <QKeyEvent>
#include <QTimer>
#include <GL/glu.h>
#include <QMouseEvent>

class MyOpenGLWidget : public QOpenGLWidget,protected QOpenGLFunctions  // 可直接使用QOpenGLFunctions中的OpenGL函数
{
    Q_OBJECT
public:
    explicit MyOpenGLWidget (QWidget * parent = 0);



protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int width,int height);
    void keyPressEvent(QKeyEvent* e) override;  //Qt键盘事件处理函数
    void mousePressEvent(QMouseEvent *event) override
    {
        if (event->button() == Qt::LeftButton)
        {
            m_lastPos = event->globalPos() - frameGeometry().topLeft();
//            qDebug() << "Clicked at position: " << m_lastPos;
        }
    }
    void mouseMoveEvent(QMouseEvent *event) override
        {
            if (event->buttons() & Qt::LeftButton)
            {
                QPoint newpos = event->globalPos() - m_lastPos;
                move(newpos);
            }
        }

private slots:
    void rotate() {
        update();
    }
private:
    GLfloat angle;
    double size_t;
    bool flag=true;
    bool fullscreen=false;
    QPoint m_lastPos;




};

#endif // MYOPENGLWIDGET_H

 

 myopenglwidget.cpp

#include "myopenglwidget.h"

MyOpenGLWidget::MyOpenGLWidget(QWidget *parent)
    : QOpenGLWidget(parent)
{

    setGeometry(1550,0,100,100);               //设置窗口大小、位置
    resize(50,50);

    // 去掉当前窗口的标题栏
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);//隐藏标题栏并且设置窗口悬浮在所有程序之上
    setAttribute(Qt::WA_TranslucentBackground);//设置背景透明
//    setWindowFlags(Qt::WindowStaysOnTopHint);
    angle = 0;
    size_t=0;

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(rotate()));
    timer->start(20);


    foreach(const QHostAddress& hostAddress,QNetworkInterface::allAddresses())//对于所有检测到的地址
        if ( hostAddress != QHostAddress::LocalHost && hostAddress.toIPv4Address() )//如果格式为IPv4则输出
            qDebug()<<hostAddress.toString();





}

void MyOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();

//    glClearColor(0.5, 0.5, 0.5, 0.0);

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

    glEnable(GL_DEPTH_TEST);    //启动深度测试
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

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

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

void MyOpenGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//用于清除颜色缓冲区和深度缓冲区,以便开始绘制新的帧。
    glLoadIdentity();//用于将当前矩阵重置为单位矩阵,即将模型视图矩阵设置为初始状态。
    glScalef(size_t,size_t,size_t);//进行缩放变换,将物体的大小缩小为原来的0.2倍。
    glRotatef(angle, 0.0f, 1.0f, 0.0f);//是进行旋转变换,围绕Y轴旋转angle度。其中,angle是一个变量,可以控制旋转的角度。

    // 启用混合
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // 启用Alpha测试
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0.0f);

    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, 1.0);    //左下顶点

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

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

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

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

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

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

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

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

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

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

    //后侧面
    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, -1.0);    //左下顶点

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

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

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

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

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

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

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

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

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

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

    glEnd();

    if(size_t>=0.5)
    {
        flag=false;
    }
    else if(size_t==0)
    {
        flag=true;
    }

    angle += 2;

    if(flag)
    {
        size_t+=0.001;
    }
    else
    {
        size_t-=0.001;
    }
}

void MyOpenGLWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);//使用当前屏幕的宽和高来设置视口
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

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

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

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

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值