Qt Opengl 画三角形

Qt Opengl 画三角形,第1张

Qt Opengl 画三角形

OpenGL ES 3.2 Reference Pages

先上代码再解析

widget.h 文件

在头文件中 widget 继承了 QOpenGLWidget, QOpenGLFunctions

可以看到 class Q_WIDGETS_EXPORT QOpenGLWidget : public QWidget

QOpenGLWidget 下面有这三个虚函数 

protected:
virtual void initializeGL();

virtual void resizeGL(int w, int h);

virtual void paintGL();

这三个虚函数实现 opengl 绘制 initializeGL在调用 paintGL 或者 resizeGL 前调用一次。

paintGL 和 resizeGL 根据需要多次调用

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QOpenGLWidget, public QOpenGLFunctions
{
    Q_OBJECT

public:
    Widget(QOpenGLWidget *parent = nullptr);
    ~Widget();

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

    QOpenGLShaderProgram program;
    GLuint programId;
    GLint matLocation;
    GLint vertexLocation;
    GLint colorLocation;

    QVector3D cameraLocation;

    GLuint vertexVbo;
    GLuint indexVbo;
    GLuint colorVbo;
    QMatrix4x4 projection;

    int vVerticesLen,triIndexLen,colorsLen;



};
#endif // WIDGET_H
widget.cpp
initializeOpenGLFunctions() 这一步不能漏掉
Initializes OpenGL function resolution for the current context.
为当前上下文 初始化 opengl 方法解析

QOpenGLShaderProgram  program 用来加载 shader

shader 文件加载 分四步 

program.addShaderFromSourceFile(QOpenGLShader::Vertex, "E:\wqs\OpenglQt\QtOpengLesson01\vertexshader.vert")

QOpenGLShader::Vertex 指定shader 类型 和 文件路径        

program.link()

program.bind() 将这个着色程序绑定到活动的QGLContext,并使其成为当前的着色程序。 任何以前绑定的着色程序被释放

释放

program.release()

GLint glGetUniformLocation(GLuint program, const GLchar *name);

获取 shader 中指定变量的 统一块的索引(个人理解,如有问题欢迎指正)

GLint glGetAttribLocation(GLuint program, const GLchar *name);

glGetAttribLocation查询由program指定的前面链接的程序对象,获取由name指定的属性变量,并返回绑定到该属性变量的通用顶点属性的索引。 如果name是一个矩阵属性变量,则返回矩阵第一列的索引。 如果指定的属性变量不是指定程序对象中的活动属性,或者如果name以保留的前缀“gl_”开头,则返回-1的值。  

void glGenBuffers(GLsizei n, GLuint *buffers);  生成缓冲区对象名称

glGenBuffers在buffer中返回n个buffer对象名称。

glBindBuffer — bind a named buffer object。 绑定一个命名的缓冲区对象

glBufferData — creates and initializes a buffer object's data store 创建并初始化一个缓冲区对象的数据存储  

void glBufferData(GLenum target,GLsizeiptr size,const void * data,GLenum usage);

glVertexAttribPointer — define an array of generic vertex attribute data 定义一个通用顶点属性数据的数组  

void glVertexAttribPointer(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const void * pointer);

glEnableVertexAttribArray -启用通用的顶点属性数组  

glDrawElements — render primitives from array data 从数组渲染原数据

void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void * indices);

mode 模式 count 数量 type 数据类型

indices 指定一个字节偏移量(转换为指针类型)到绑定到GL_ELEMENT_ARRAY_BUFFER的缓冲区中,以开始读取索引。 如果没有绑定缓冲区,则指定一个指向索引存储位置的指针。  

#include "widget.h"
#include "ui_widget.h"

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

Widget::~Widget()
{}

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

    if(!program.addShaderFromSourceFile(QOpenGLShader::Vertex, "E:\wqs\OpenglQt\QtOpengLesson01\vertexshader.vert"))
    {
        return;
    }
    if(!program.addShaderFromSourceFile(QOpenGLShader::Fragment, "E:\wqs\OpenglQt\QtOpengLesson01\fragmentshader.frag"))
    {
        return;
    }

    program.link();
    program.bind();
    programId = program.programId();
    matLocation = glGetUniformLocation(programId, "matrix");
    vertexLocation = glGetAttribLocation(programId, "vPosition");
    colorLocation = glGetAttribLocation(programId, "vColor");

    Q_ASSERT(matLocation != -1);
    Q_ASSERT(vertexLocation != -1);
    Q_ASSERT(colorLocation != -1);



    //三角形顶点坐标
    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,
                        1.0f, 1.0f, 0.0f, 1.0f,
                        1.0f, 0.0f, 1.0f, 1.0f,
                       };


    glGenBuffers(1, &vertexVbo);
    glBindBuffer(GL_ARRAY_BUFFER, vertexVbo);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof (GLfloat), vertex, GL_STATIC_DRAW);

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


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

}

void Widget::paintGL()
{
    //清除之前图形并将背景设置为黑色(设置为黑色纯粹个人爱好!)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.0f, 0.2f, 0.2f, 1.0f);


    // shader传入模型视图矩阵 projection可以理解为建立了一个坐标系空间,可以再这个空间内设置图形
    glUniformMatrix4fv(matLocation, 1, GL_FALSE, projection.data());
   // shader绑定并启用颜色数组buffer
    glBindBuffer(GL_ARRAY_BUFFER,colorVbo);
    glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(colorLocation);
    // shader绑定并启用顶点数组buffer
    glBindBuffer(GL_ARRAY_BUFFER, vertexVbo);
    glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(vertexLocation);

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

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

}

void Widget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
    projection.setToIdentity();
    float aspect = float(w)/ float(h?h:1);
    projection.perspective(60.0f, aspect, 1.0f, 100.f);
    projection.translate(0, 0.0, -2.0f);


}

glViewport 设置视口 

QMatrix4x4 projection; 
projection.setToIdentity  将这个矩阵设为单位矩阵。
projection.perspective(60.0f, aspect, 1.0f, 100.f);
将这个矩阵与另一个应用透视投影的矩阵相乘。 垂直视场将是一个具有确定水平视场的给定视场比的窗口内的垂直角度。 投影将有指定的nearPlane和farPlane剪切平面,它们是观察者到相应平面的距离。  

main.cpp

#include "widget.h"

#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

vertex.shader

#version 430 //版本号 必须指定
uniform mat4 matrix;
in vec4 vPosition;
in vec4 vColor;
out vec4 fColor;

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

fragment.shader

#version 430
in vec4 fColor;

void main(void)
{
    gl_FragColor = fColor;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5714250.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存