3. 线框三角形平移
colortriangle.vert
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aColor; out vec3 ourColor; uniform float xOffset; void main(){ gl_Position = vec4(aPos.x + xOffset, aPos.y, aPos.z, 1.0); ourColor = aColor; }
colortriangle.frag
#version 330 core out vec4 FragColor; in vec3 ourColor; void main(void) { FragColor = vec4(ourColor, 1.0f); }
头文件
#pragma once #include <QOpenGLWidget> #include <QOpenGLExtraFunctions> #include <QOpenGLFunctions_3_3_Core> #include <QOpenGLShader> #include <QOpenGLShaderProgram> class CoreFunctionWidget : public QOpenGLWidget , protected /*QOpenGLExtraFunctions*/QOpenGLFunctions_3_3_Core { Q_OBJECT public: explicit CoreFunctionWidget(QWidget *parent = nullptr); ~CoreFunctionWidget(); protected: virtual void initializeGL(); virtual void resizeGL(int w, int h); virtual void paintGL(); private: QOpenGLShaderProgram shaderProgram; QTimer* m_pTimer = nullptr; float m_uniformValue = 0.0f;//控制偏移量 };
源文件
#include "CoreFunctionWidget.h" #include <QDebug> #include <QTimer> static GLuint VBO, VAO; CoreFunctionWidget::CoreFunctionWidget(QWidget *parent) : QOpenGLWidget(parent) { m_pTimer = new QTimer(this); m_pTimer->setInterval(200); connect(m_pTimer, &QTimer::timeout, this, [=] { m_uniformValue += 0.1f; if (m_uniformValue > 1.5f) { m_uniformValue = -1.5f; } update();//计时器触发更新 }); m_pTimer->start(); } CoreFunctionWidget::~CoreFunctionWidget() { glDeleteVertexArrays(1, &VAO);//第一个参数是指定要删除的顶点数组对象的数量,第二个是要删除对象的n个名称的数组地址 glDeleteBuffers(1, &VBO); //glDeleteBuffers(1, &EBO);//用于索引 } void CoreFunctionWidget::initializeGL() { this->initializeOpenGLFunctions();//初始化函数 //读入编译两个求解器文件,出错则打印日志 bool success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "colortriangle.vert"); if (!success) { qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log(); return; } success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "colortriangle.frag"); if (!success) { qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log(); return; } //链接着色器 success = shaderProgram.link(); if (!success) { qDebug() << "shaderProgram link failed!" << shaderProgram.log(); } //VAO,VBO数据部分 float vertices[] = { // positions // colors 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom right -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // top }; glGenVertexArrays(1, &VAO);//生成顶点数组对象名称 (指定数量,指定一个数组-储存的是顶点数组对象名称) glGenBuffers(1, &VBO);//生成缓冲区对象名称 glBindVertexArray(VAO);//绑定一个顶点数组对象 指定要绑定的顶点数组的名称。 //(target 指定缓冲区对象绑定的目标必须为GL_ARRAY_BUFFER或GL_ELEMENT_ARRAY_BUFFER,指定缓冲区对象的名称ID) glBindBuffer(GL_ARRAY_BUFFER, VBO);//绑定一个命名(ID)的缓冲区对象 //(target,指定缓冲区对象的新数据存储的大小,数组,指定数据存储的预期使用模式(GL_STREAM_DRAW,GL_STATIC_DRAW或GL_DYNAMIC_DRAW)) glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //顶点数据复制到缓冲 //定义通用顶点属性数据的数组 //给出具体参数 //修改通用顶点属性的索引location //指定每个属性的组件数比如这里为3,那么就阅读3个数据,0.5f, -0.5f, 0.0f //数据类型 //如果设置为true将被标准化映射成有符号值的(-1,1)无符号值的(0,1), //步长, //偏移量 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0); glEnableVertexAttribArray(0);//指定要启用的通用顶点属性的索引 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, 0);//取消VBO的绑定, glVertexAttribPointer已经把顶点属性关联到顶点缓冲对象了 glBindVertexArray(0); //取消VAO绑定 //线框模式 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } void CoreFunctionWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h);//设置视口 } void CoreFunctionWidget::paintGL() { glClearColor(0.23, 0.37, 0.51, 1.00);//指定颜色缓冲区清除时的RGBA值 //使用掩码的按位异或运算来表示要清除的缓冲区。 三个掩码是GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //把着色器绑定到上下文 shaderProgram.bind(); { int xOffsetLocation = shaderProgram.uniformLocation("xOffset");//提取着色器中的全局变量 //指定当前程序对象的统一变量的值 //参数一:指定要修改的统一变量的位置。 参数二:指定要用于指定统一变量的新值。 glUniform1f(xOffsetLocation, m_uniformValue);//每触发一次timeout信号,m_uniformValue的值就增加0.1 //绑定一个顶点数组对象,每次重绘都要重新绑定 glBindVertexArray(VAO); //用来绘制缓冲区中的数据,其第1个参数指定需要绘制的图元的类型;第2个参数制定了图元的第一个点在缓冲区中的索引; //第3个参数是要绘制的顶点的数据,要绘制三角形,其数目必然是3的倍数 glDrawArrays(GL_TRIANGLES, 0, 3); } //解绑 shaderProgram.release(); }