一、概述
需求:
绘制一个正方形,可以控制正方形的颜色、可以切换正方形为线框模式/填充模式
绘制流程:
1.定义一个顶点着色器和片元着色器shader
2.Qt创建一个Widget并继承QOpenGLWidget、QOpenGLFunctions,并重写initializeGL()、resizeGL(w,h)、paintGL()
3.定义顶点坐标数组、元素索引数组、创建VAO、VBO、EBO并给其分配相应的内存
4.告知显卡如何解析顶点
5.创建shader、编译shader、关联shader、链接shader
6.绑定VAO、使用program、绘制正方形
二、代码示例
1.定义一个顶点着色器和片元着色器shader
a.顶点着色器代码
#version 330 core layout (location = 0) in vec3 aPos; void main() { gl_Position = vec4(aPos, 1.0); }
b.片元着色器代码
#version 330 core out vec4 FragColor; uniform vec4 ourColor; void main() { FragColor = ourColor; }
2.Qt创建一个Widget并继承QOpenGLWidget、QOpenGLFunctions,并重写initializeGL()、resizeGL(w,h)、paintGL()
class GLSquareWindow : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core { Q_OBJECT public: GLSquareWindow(QWidget *parent = nullptr); ~GLSquareWindow(); protected: virtual void initializeGL();//初始化OpenGL virtual void resizeGL(int w, int h);//ResizeWindow大小 virtual void paintGL();//绘制OpenGL
3.定义顶点坐标数组、元素索引数组、创建VAO、VBO、EBO并给其分配相应的内存
//创建四边形的顶点 GLfloat vertices[] = { // 位置 0.5f, 0.5f, 0.0f,// 右上角 0.5f, -0.5f, 0.0f,// 右下角 -0.5f, -0.5f, 0.0f,// 左下角 -0.5f, 0.5f, 0.0f, // 左上角 //0.0f, -0.5f, 0.0f, // left //0.9f, -0.5f, 0.0f, // right //0.45f, 0.5f, 0.0f // top }; glGenVertexArrays(1, &VAO);//创建VAO:顶点数组对象 glGenBuffers(1, &VBO);//创建VBO:顶点数组缓冲 //绑定VAO和VBO对象 glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); //把顶点数据放入缓冲区 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //告知显卡如何解析缓冲中的属性 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); //开启VAO管理第一个属性 glEnableVertexAttribArray(0);
//EBO创建与绑定
glGenBuffers(1, &EBO);//EBO元素索引缓冲,用来指定顶点应该如何排列和绘制
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
4.告知显卡如何解析顶点
//告知显卡如何解析缓冲中的属性 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); //开启VAO管理第一个属性 glEnableVertexAttribArray(0);
5.创建shader、编译shader、关联shader、链接shader
//创建顶点着色器 unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); QFile vertexShaderFile(":/QtForOpenCV4Tool/shader/square.vert"); if (!vertexShaderFile.open(QIODevice::ReadOnly)) { qDebug() << "Cannot open vertex shader file for reading"; } QString verQStr = vertexShaderFile.readAll(); std::string verStdStr = verQStr.toStdString(); const char* vertexStr = verStdStr.c_str(); qDebug() << "vertexStr-------------" << vertexStr; vertexShaderFile.close(); glShaderSource(vertexShader, 1, &vertexStr, NULL); glCompileShader(vertexShader); //创建片元着色器 QFile fragShaderFile(":/QtForOpenCV4Tool/shader/square.frag"); if (!fragShaderFile.open(QIODevice::ReadOnly)) { qDebug() << "Cannot open frag shader file for reading"; } QString fragQStr = fragShaderFile.readAll(); std::string fragStdStr = fragQStr.toStdString(); const char* fragmentStr = fragStdStr.c_str(); qDebug() << "fragmentStr-------------" << fragmentStr; unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentStr, NULL); fragShaderFile.close(); glCompileShader(fragmentShader); //创建program programShaderNative = glCreateProgram(); //将着色器和显卡程序关联 glAttachShader(programShaderNative, vertexShader); glAttachShader(programShaderNative, fragmentShader); glLinkProgram(programShaderNative);//链接程序 //着色器使用后删除掉 glDeleteShader(vertexShader); glDeleteShader(fragmentShader);
6.绑定VAO、使用program、绘制正方形
void GLSquareWindow::paintGL() { if (isFullMode) {//切换线框模式 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } //原生绘制 glUseProgram(programShaderNative); //找到ourColor的位置 GLint colorLocation = glGetUniformLocation(programShaderNative, "ourColor"); switch (mColor) { case SquareColor::RED2: glUniform4f(colorLocation, 1.0f, 0.0f, 0.0f, 1.0f);//给ourColor赋值 break; case SquareColor::GREEN2: glUniform4f(colorLocation, 0.0f, 1.0f, 0.0f, 1.0f);//给ourColor赋值 break; case SquareColor::BLUE2: glUniform4f(colorLocation, 0.0f, 0.0f, 1.0f, 1.0f);//给ourColor赋值 break; } glBindVertexArray(VAO);//说明要使用VAO配置的顶点属性及对应的VBO及EBO glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, /*indices*/0); }
标签:QT,OpenGL,0.0,EBO,0.5,shader,顶点,GL,VAO From: https://www.cnblogs.com/tony-yang-flutter/p/18371307