2.第一个三角形程序

 顶点着色器 out vec3 Color是为了给片段着色器传参

#version 130
in vec3 VertexPosition;
in vec3 VertexColor;

out vec3 Color;

void main()
{
    Color = VertexColor;
    gl_Position = vec4( VertexPosition, 1.0 );
}

片段着色器

#version 130
in vec3 Color;
out vec4 FragColor;

void main()
{
    FragColor = vec4( Color, 1.0);
}

头文件

#include "ui_OpenGL1.h"
//Qt
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLFunctions_3_3_Core>


class OpenGL1 : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
    Q_OBJECT

public:
    OpenGL1(QWidget *parent = Q_NULLPTR);
    ~OpenGL1();

private:
    Ui::OpenGL1Class* ui;
    void init();
    virtual void initializeGL() override;
    virtual void paintGL()override;
    virtual void resizeGL(int w, int h)override;
    //三角形的三点坐标
    GLfloat triangle[9] = {
        -1.0, -1.0, 0.0,
        1.0, -1.0,0.0,
        0.0, 1.0,0.0
    };

    //三角形三个顶点的颜色值
    GLfloat color[9] = {
        1.0,0.0,0.0,
        0.0,1.0,0.0,
        0.0,0.0,1.0,
    };
    QOpenGLShaderProgram* _shaderProgram;
    
};

源文件

#include "OpenGL1.h"
#include <QOpenGLWidget>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QDebug>
#include <QOpenGLFunctions>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLFunctions_3_3_Core>
OpenGL1::OpenGL1(QWidget *parent):QOpenGLWidget(parent), ui(new Ui::OpenGL1Class)
{
    ui->setupUi(this);
    
}
OpenGL1::~OpenGL1() {
    delete ui;
}

void OpenGL1::init() {
    //顶点着色器
    QOpenGLShader* vertShader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    vertShader->compileSourceFile("test.vert");

    //片段着色器
    QOpenGLShader* fragShader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    fragShader->compileSourceFile("test.frag");

    _shaderProgram = new QOpenGLShaderProgram;
    //添加着色器
    _shaderProgram->addShader(vertShader);
    _shaderProgram->addShader(fragShader);

    //对着色器进行链接
    _shaderProgram->link();
    //把着色器绑定到上下文
    _shaderProgram->bind();
}
void OpenGL1::initializeGL() {
    
    initializeOpenGLFunctions();//死代码
    glClearColor(1.0, 0.0, 0.0, 0.5);//清除的背景颜色
    init();
}

void OpenGL1::paintGL() {
    QOpenGLBuffer buffer;
    //创建缓存区对象
    buffer.create();
    //绑定上下文
    buffer.bind();
    //动态分配 
    buffer.allocate(triangle, 2*sizeof(triangle));//在服务器上为缓冲区分配空间 这里的空间要同时分配两个数组的空间
    GLuint vPosition = _shaderProgram->attributeLocation("VertexPosition");//返回属性名在该着色器程序参数列表中的位置。如果名称不是此着色器程序的有效属性,则返回-1。
    //location指定着色程序中变量的地址索引
    //type指定缓冲区中变量的类型
    //offset指定要读取的数据到缓冲区开始位置的偏移值,这里是0,因为顶点的位置是从缓冲区开始进行存储的
    //tupleSize指定变量的维数
    //stride指定每个变量(这里是3个数值)到下一个变量之间的跨度值,这里因为是连续存储的,所以跨度是0
    _shaderProgram->setAttributeBuffer(vPosition, GL_FLOAT, 0, 3, 0);//找到着色程序中的输入变量VertexPosition对应的位置,再将其和缓冲区中的数据进行绑定
    glEnableVertexAttribArray(vPosition);//调用glEnableVertexAttribArray()是开启顶点属性,这里提供的索引是位置索引,所以开启的顶点属性是位置属性

    //不需要再用allocate()分配新的空间了,而是直接调用write()函数将数据写到缓冲区中
    //wirte()函数的第一个参数是偏移值,因为前9个GLfloat大小的空间写入了位置信息
    //所以就要偏移9个GLfloat大小的空间
    //(offset,数组,数组大小)
    buffer.write(9 * sizeof(GLfloat), color, 9 * sizeof(GLfloat));
    GLuint vColor = _shaderProgram->attributeLocation("VertexColor");
    _shaderProgram->setAttributeBuffer(vColor, GL_FLOAT, 9 * sizeof(GLfloat), 3, 0);//setAttributeBuffer()函数中的偏移值也同样需要设置成9*sizeof(GLfloat)
    glEnableVertexAttribArray(vColor);//开启颜色属性
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

void OpenGL1::resizeGL(int w, int h) {
}

效果如图

小结一下每个函数干的事情

初始化函数InitializeGL:

顾名思义是要初始化

1.需要开启openglFunction函数,为当前上下文初始化OpenGL函数解析,只能与当前上下文以及与其共享的其他上下文一起使用。再次调用initializeOpenGLFunctions()以更改对象的上下文关联。

2.选择清除的背景颜色

3.初始化着色器,包括连接顶点着色器和片段着色器的文件,初始化QOpenGLShaderProgram类的指针,并且添加两个着色器,链接并且绑定到上下文

绘画函数paintGL

1.首先对缓存区对象buffer进行操作,需要先创建再绑定上下文,通过allocate函数进行顶点数组和颜色数组的内存分配,将着色器程序中的变量和缓冲区的数据进行绑定,开启顶点属性

2. 使用write指定偏移量,颜色数组,大小来操作刚刚的内存,绑定片段着色器中的变量和缓冲区中的数据,开启颜色属性,调用glDrawArrays进行绘制

3.对最后一个函数做出解释:

glDrawArrays(GL_TRIANGLES, 0, 3);//用来绘制缓冲区中的数据,其第1个参数指定需要绘制的图元的类型;第2个参数制定了图元的第一个点在缓冲区中的索引;
//第3个参数是要绘制的顶点的数据,要绘制三角形,其数目必然是3的倍数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值