欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Qt OpenGL 绘制三角形(一)

程序员文章站 2023-12-25 08:29:51
...

一、效果图
Qt OpenGL 绘制三角形(一)
二、代码

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDebug>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QMatrix4x4>

class Widget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int w, int h);

private:
    QOpenGLShaderProgram *program;
    GLuint programId;
    GLint matrixLocation,vertexLocation,clorLocation;
    int vVerticesLen,triIndexLen,colorsLen;
    GLuint verVbo,indexVbo,colorVbo;
    QMatrix4x4 projection;
};
#endif // WIDGET_H

#include "widget.h"

//三角形顶点坐标
GLfloat vertex[] = {
    -0.5f, 0.0f,
    0.5f, 0.0f,
    0.0f, 0.5f,
};

//三角形顶点索引
GLuint triIndexs[] = {0, 1, 2};

//三角形顶点颜色
GLfloat colors[] = {1.0f, 0.0f, 0.0f, 1.0f,
                    0.0f, 1.0f, 0.0f, 1.0f,
                    0.0f, 0.0f, 1.0f, 1.0f,
                   };

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

}

Widget::~Widget()
{

}

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

    program = new QOpenGLShaderProgram(this);

    if(!program->addShaderFromSourceFile(QOpenGLShader::Vertex, "E:/opengl/opengl/vertexshader.vert")){
        qDebug()<<"vert fail";
        return;
    }
    if(!program->addShaderFromSourceFile(QOpenGLShader::Fragment, "E:/opengl/opengl/fragmentshader.frag")){
        return;
    }
    if(!program->link()){
        return;
    }
    if(!program->bind()){
        return;
    }

    // 获取shaderprogram的id号,然后可以通过id号获取一些属性...
    programId = program->programId();

    // 从shaderprogram里面获取变量标识
    matrixLocation = glGetUniformLocation(programId, "matrix");
    vertexLocation = glGetAttribLocation(programId, "vPosition");
    clorLocation  = glGetAttribLocation(programId, "vColor");

    // 计算获得数组长度
    vVerticesLen = sizeof(vertex)/sizeof(GLfloat);
    triIndexLen = sizeof(triIndexs)/sizeof(GLuint);
    colorsLen = sizeof(colors)/sizeof(GLfloat);

    // 初始化顶点buffer并装载数据到显存
    glGenBuffers(1, &verVbo);
    glBindBuffer(GL_ARRAY_BUFFER, verVbo);
    glBufferData(GL_ARRAY_BUFFER, vVerticesLen * sizeof(GLfloat), vertex, GL_STATIC_DRAW);

    // 初始化索引buffer并装载数据到显存
    glGenBuffers(1, &indexVbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, triIndexLen * sizeof(GLuint), triIndexs, GL_STATIC_DRAW);

    // 初始化颜色buffer并装载数据到显存
    glGenBuffers(1, &colorVbo);
    glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
    glBufferData(GL_ARRAY_BUFFER, colorsLen * sizeof(GLfloat), colors, GL_STATIC_DRAW);
}

void Widget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    // shader传入模型视图矩阵 projection可以理解为建立了一个坐标系空间,可以再这个空间内设置图形
    glUniformMatrix4fv(matrixLocation, 1, GL_FALSE, projection.data());

    // shader绑定并启用颜色数组buffer
    glBindBuffer(GL_ARRAY_BUFFER,colorVbo);
    glVertexAttribPointer(clorLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(clorLocation);
    // 颜色值rgba,所以每四个float值作为一个颜色值,如果只是希望rgb,取三个值作为颜色值即可!


    // shader绑定并启用顶点数组buffer
    glBindBuffer(GL_ARRAY_BUFFER, verVbo);
    glVertexAttribPointer( vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(vertexLocation);

    // shader绑定并顶点索引数组buffer - 索引无需启用
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexVbo);
    glDrawElements(GL_TRIANGLES, triIndexLen, GL_UNSIGNED_INT,0);

    // 解绑buffer、关闭启用顶点、颜色数组
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(vertexLocation);
    glDisableVertexAttribArray(clorLocation);
}


void Widget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);

    // 模型矩阵重置
    projection.setToIdentity();
    // 透视投影
    qreal aspect = qreal(w) / qreal(h ? h : 1);
    projection.perspective(60.0f, aspect, 1.0f, 100.0f);
    // 增加了模型矩阵,需要做一定偏移量,保证物体刚开始渲染出来时可以被看到!
    projection.translate(0.0f, 0.0f, -2.0f);
}



vertexshader.vert

//vertexshader.vert
uniform mat4 matrix;
in vec4 vPosition;
in vec4 vColor;
out vec4 fColor;

void main(void)
{
    fColor = vColor;
    gl_Position = matrix * vPosition;
}

fragmentshader.frag

//fragmentshader.frag
in vec4 fColor;

void main(void)
{
    gl_FragColor = fColor;
}

Qt OpenGL 绘制三角形(一)

相关标签: Qt OpenGL

上一篇:

下一篇: