小白学opengl 第一课

第一课:创建一个OpenGL窗口

选择空项目

![0_1526345895281_QQ截图20180515084615.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDU5NDQvY2xvdW5kaW5hcnkvbTJ6MGZ1c2lhZjBidDdxbWNxbWcucG5n?x-oss-process=image/format ,png)

输入项目名称和位置

![0_1526345931933_QQ截图20180515084648.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDU5ODEvY2xvdW5kaW5hcnkvaTFwajB1aHBtamppcGRjemR4enIucG5n?x-oss-process=image/format ,png)

选择编译器

![0_1526345958327_QQ截图20180515084656.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDYwMDgvY2xvdW5kaW5hcnkvZDFqaHR6Ync2a3F1eHVna3FuaWsucG5n?x-oss-process=image/format ,png)

创建成功后,首先添加pri文件,pri文件可以管理我们的类文件,类似一个小项目的感觉

![在这里插入图片描述]( https://img-blog.csdnimg.cn/2020070715174581.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5fMjI3,size_16,color_FFFFFF,t_70)

输入pri名字

![0_1526346029022_QQ截图20180515084949.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDYwNzgvY2xvdW5kaW5hcnkvd21qZnVieWJzamhvanlyYzdweXQucG5n?x-oss-process=image/format ,png)

此时项目结构,只有pro项目文件,和pri文件

![0_1526346106557_QQ截图20180515085040.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDYxNTUvY2xvdW5kaW5hcnkvbXhrbmt2azZob2Fsc3VibDB4ZjYucG5n?x-oss-process=image/format ,png)

修改pro代码,改变项目结构

![0_1526346152132_QQ截图20180515085115.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDYyMDEvY2xvdW5kaW5hcnkvcTFocG94dGh6ZDFmdWp2d3Q1cTUucG5n?x-oss-process=image/format ,png)

右键pri文件,在pri下创建窗口类

![0_1526346188098_QQ截图20180515085147.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDYyMzcvY2xvdW5kaW5hcnkvd2R3MTUyYzNyeG1zbDZ0Ynp6b3MucG5n?x-oss-process=image/format ,png)

输入窗口名

![0_1526346216835_QQ截图20180515085222.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDYyNjUvY2xvdW5kaW5hcnkvamY0M21heGNlemMzdWd1ZXJ0ZXkucG5n?x-oss-process=image/format ,png)

创建完毕的项目结构

![0_1526346239009_QQ截图20180515085248.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDYyODgvY2xvdW5kaW5hcnkvcWdkMGFwb2d3d2o4dXdscnYya2EucG5n?x-oss-process=image/format ,png)

为项目添加main.cpp

![0_1526346285326_QQ截图20180515085426.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDYzMzYvY2xvdW5kaW5hcnkvZGM5ZDhxbmsxZjdlbGQyZGxwd2IucG5n?x-oss-process=image/format ,png)

输入main.cpp

![0_1526346314449_QQ截图20180515085436.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDYzNjQvY2xvdW5kaW5hcnkvanJoN21yb29nYnh3aTVuZXc0eXAucG5n?x-oss-process=image/format ,png)

openglwindow.h代码

#ifndef OPENGLWINDOW_H
#define OPENGLWINDOW_H

#include <QtGui/QWindow>
#include <QtGui/QOpenGLFunctions>

QT_BEGIN_NAMESPACE
class QPainter;
class QOpenGLContext;
class QOpenGLPaintDevice;
QT_END_NAMESPACE

class Openglwindow : public QWindow, protected QOpenGLFunctions
{
    Q_OBJECT
public:
    explicit Openglwindow(QWindow *parent=0);
    ~Openglwindow();

    //基于QPainter渲染
    virtual void render(QPainter *parent);
    //基于opengl渲染
    virtual void render();
    //初始化
    virtual void initialize();
    //设置动画
    void setAnimating(bool animating);

public slots:
    //手动刷新一次
    void renderLater();
    //立刻渲染
    void renderNow();

protected:
    //监听事件
    bool event(QEvent *event) override;
    //监听暴露事件
    void exposeEvent(QExposeEvent *event) override;

private:
    //动画状态位
    bool m_animating;

    //OpenGL 上下文
    QOpenGLContext *m_context;
    //OpenGL画笔设备,能使用QPainter在上下文里画东西
    QOpenGLPaintDevice *m_device;
};

#endif // OPENGLWINDOW_H

openglwindow.cpp代码

#include "openglwindow.h"
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLPaintDevice>
#include <QtGui/QPainter>

Openglwindow::Openglwindow(QWindow *parent)
    :QWindow(parent)
    ,m_animating(false)
    ,m_context(0)
    ,m_device(0)
{
    //设置使用OpenGL上下文渲染OpenGL
    setSurfaceType(QWindow::OpenGLSurface);
}
Openglwindow::~Openglwindow()
{
    //删除设备
    delete m_device;
}
void Openglwindow::render(QPainter *painter)
{
    Q_UNUSED(painter);
}

void Openglwindow::initialize()
{
}
void Openglwindow::render()
{
    //第一次没有画笔设备,需要创建画笔设备
    if (!m_device)
        m_device = new QOpenGLPaintDevice;

    //清除屏幕, 颜色缓冲区和深度缓冲区和模板缓冲区
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    //设置大小
    m_device->setSize(size());

    //创建画笔
    QPainter painter(m_device);
    //用QPainter渲染一次
    render(&painter);
}
void Openglwindow::renderLater()
{
    //请求刷新,窗口会收到UpdateRequest事件
    requestUpdate();
}
bool Openglwindow::event(QEvent *event)
{
    switch (event->type()) {
    case QEvent::UpdateRequest:
        renderNow();
        return true;
    default:
        return QWindow::event(event);
    }
}
void Openglwindow::exposeEvent(QExposeEvent *event)
{
    Q_UNUSED(event);

    //如果窗口暴露,显示,立刻渲染画面
    if (isExposed())
        renderNow();
}
void Openglwindow::renderNow()
{
    if (!isExposed())
        return;

    bool needsInitialize = false;

    //没有上下文就创建上下文
    if (!m_context) {
        m_context = new QOpenGLContext(this);
        //设置格式
        m_context->setFormat(requestedFormat());
        //创建
        m_context->create();

        needsInitialize = true;
    }

    //激活上下文
    m_context->makeCurrent(this);

    if (needsInitialize) {
        //初始化当前上下文的OpenGL函数解析
        initializeOpenGLFunctions();
        initialize();
    }

    render();

    //交换前后缓冲区,完成一帧渲染
    m_context->swapBuffers(this);

    if (m_animating)
        renderLater();
}
void Openglwindow::setAnimating(bool animating)
{
    m_animating = animating;

    if (animating)
        renderLater();
}

main.cpp代码

#include <QtGui/QGuiApplication>
#include "openglwindow.h"

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);

    QSurfaceFormat format;
    //设置采样率
    format.setSamples(16);

    Openglwindow window;
    window.setTitle(QStringLiteral("第一个OpenGLFunctions例子"));
    window.setFormat(format);
    window.resize(640, 480);
    window.show();

    return app.exec();
}

运行

![0_1526349599163_QQ截图20180515095818.png]( https://imgconvert.csdnimg.cn/aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vcXRkcmVhbS9pbWFnZS91cGxvYWQvdjE1MjYzNDk2NDkvY2xvdW5kaW5hcnkvZHpwY2EwZTlkOG5pMWxlYmdmeXkucG5n?x-oss-process=image/format ,png)

源代码下载

https://gitee.com/chen227/opengl_OpenGLFunctions

posted @ 2021-11-01 13:55  踏月清风  阅读(66)  评论(0)    收藏  举报