Qt实现 QOpenGL绘制彩色三角形

5 篇文章 1 订阅
1 篇文章 0 订阅

目录

1、QOpenGL介绍

2、效果

3、主要代码介绍:

4、全部代码:


1、QOpenGL介绍

QOpenGLWidget类封装了opengl,比起原生的opengl,使用起来很方便。只需要让子类继承QOpenGLWidget。

OpenGL(英语:Open Graphics Library,译名:开放图形库或者“开放式图形库”)是用于渲染2D3D矢量图形的跨语言跨平台应用程序编程接口(API)。这个接口由近350个不同的函数调用组成,用来从简单的图形比特绘制复杂的三维景象。而另一种程序接口系统是仅用于Microsoft Windows上的Direct3D。OpenGL常用于CAD虚拟现实、科学可视化程序和电子游戏开发。(摘自维基百科)

其实OpenGL是把图像数据和几何数据发送给电脑显卡,进行一系列处理后,把图形显示到屏幕上进行展示。

QOpenGLWidget允许在平台支持的情况下使用不同的OpenGL版本和配置文件,只需通过setFormat()设置请求的格式即可。

可以根据自己电脑所支持的opengl版本进行兼容性设置。

QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
this->setFormat(format);

QOpenGLWidget还提供了三个函数来方便我们处理业务。分别是
paintGL():绘制渲染opengl场景,update的时候会自动调用
resizeGL() :设置opengl的大小,resize的时候调用
initializeGL() :提供初始化opengl需要的环境的接口,在resizeGL或者paintGL之前会被调用一次。

2、效果

3、主要代码介绍:

1、着色器装载

void MyQOpengl::InitShader()
{
    //顶点着色器
    QOpenGLShader *vShader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vSrc =
            "in vec4 vPosition;                        \n"
            "in vec4 vColor;                           \n"
            "out vec4 color;                           \n"
            "void main() {                             \n"
            "   color = vColor;                        \n"
            "   gl_Position = vPosition;               \n"
            "}                                         \n";
    vShader->compileSourceCode(vSrc);

    //片段着色器
    QOpenGLShader *fShader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fSrc =
            "in vec4 color;                             \n"
            "out vec4 fColor;                           \n"
            "void main() {                              \n"
            "   fColor = color;                         \n"
            "}                                          \n";
    fShader->compileSourceCode(fSrc);

    //着色器程序
    _pShaderProgram = new QOpenGLShaderProgram;
    _pShaderProgram->addShader(vShader);
    _pShaderProgram->addShader(fShader);

    _pShaderProgram->link();
    _pShaderProgram->bind();
}

这里我们需要创建一个顶点着色器和片段着色器,然后通过addShader装载它们,所谓着色器就是像素被渲染时执行的程序,在GPU中执行的程序。const char *vSrc字符串是opengl着色器语言(OpenGL Shading Language)即GLSL。通过这些语言来描述给GPU。

而顶点就是我们图形的几个顶角,片段就是几个顶点包围起来的全部像素点,通过对以上进行渲染,就能得到我们需要的图形和颜色。

2、顶点描述

下面描述的是三角形的三个顶点

//顶点位置
GLfloat vertices[] = {
   -0.5f, -0.5f,   //left
   0.0f, 0.5f,     //top
   0.5f, -0.5f,    //right
};

如下图所示:

3、顶点颜色

对三个顶点进行颜色的描述,分别表示r、g、b,我们知道,通过r、g、b的组合可以组合出任何我们想要的颜色

GLfloat colors[] = {
   1.0f, 0.5f, 0.2f,   //r g b
   1.0f, 0.5f, 0.2f,
   1.0f, 0.5f, 0.2f,
};

4、QOpenGLBuffer _vbo用于管理OpenGL的缓存对象,流程是create()创建缓存对象--bind()绑定对象关联的缓存到OpenGL环境

--allocate()分配缓存空间--setAttributeBuffer()填充数据。

_vbo.create();
_vbo.bind();
_vbo.allocate(vertices, 18*sizeof(GLfloat));

GLuint vPosition = _pShaderProgram->attributeLocation("vPosition");
_pShaderProgram->setAttributeBuffer(vPosition, GL_FLOAT, 0, 2, 0);
glEnableVertexAttribArray(vPosition);

4、全部代码:

头文件:

#ifndef MYQOPENGL_H
#define MYQOPENGL_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>

class MyQOpengl : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    explicit MyQOpengl(QWidget *parent = 0);

    void InitShader();

protected:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;

private:
    QOpenGLShaderProgram *_pShaderProgram;
    QOpenGLBuffer _vbo;
};

#endif // MYQOPENGL_H

cpp

#include "myqopengl.h"
#include <QDebug>

MyQOpengl::MyQOpengl(QWidget *parent)
    : QOpenGLWidget(parent)
{
}

void MyQOpengl::initializeGL()
{
    // 为当前环境初始化OpenGL函数
    initializeOpenGLFunctions();

    InitShader();
}

void MyQOpengl::InitShader()
{
    //顶点着色器
    QOpenGLShader *vShader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vSrc =
            "in vec4 vPosition;                        \n"
            "in vec4 vColor;                           \n"
            "out vec4 color;                           \n"
            "void main() {                             \n"
            "   color = vColor;                        \n"
            "   gl_Position = vPosition;               \n"
            "}                                         \n";
    vShader->compileSourceCode(vSrc);

    //片段着色器
    QOpenGLShader *fShader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fSrc =
            "in vec4 color;                             \n"
            "out vec4 fColor;                           \n"
            "void main() {                              \n"
            "   fColor = color;                         \n"
            "}                                          \n";
    fShader->compileSourceCode(fSrc);

    //着色器程序
    _pShaderProgram = new QOpenGLShaderProgram;
    _pShaderProgram->addShader(vShader);
    _pShaderProgram->addShader(fShader);

    _pShaderProgram->link();
    _pShaderProgram->bind();
}
void MyQOpengl::resizeGL(int w, int h)
{
    glViewport(0,0,w,h);
}

void MyQOpengl::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(0.2f, 0.3f, 0.3f,1.0f);

    //顶点位置
    GLfloat vertices[] = {
        -0.5f, -0.5f,   //left
        0.0f, 0.5f,     //top
        0.5f, -0.5f,    //right
    };

    _vbo.create();
    _vbo.bind();
    _vbo.allocate(vertices, 18*sizeof(GLfloat));

    GLuint vPosition = _pShaderProgram->attributeLocation("vPosition");
    _pShaderProgram->setAttributeBuffer(vPosition, GL_FLOAT, 0, 2, 0);
    glEnableVertexAttribArray(vPosition);


    // 顶点颜色
    GLfloat colors[] = {
        1.0f, 0.5f, 0.2f,   //r g b
        1.0f, 0.5f, 0.2f,
        1.0f, 0.5f, 0.2f,
    };

    _vbo.write(6*sizeof(GLfloat), colors, 12*sizeof(GLfloat));
    GLuint vColor = _pShaderProgram->attributeLocation("vColor");
    _pShaderProgram->setAttributeBuffer(vColor, GL_FLOAT, 6*sizeof(GLfloat), 3, 0);
    glEnableVertexAttribArray(vColor);

    // 绘制
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

通过以上代码实现QOPenGL绘制了一个橘色的三角形,具体的API这里不进行过多讨论,主要是熟悉opengl的绘图流程,后面再专门对相关的接口进行探讨,以上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值