首页 > 其他分享 >QT+OpenGL 使用VAO、VBO、EBO结合绘制一个正方形

QT+OpenGL 使用VAO、VBO、EBO结合绘制一个正方形

时间:2024-08-21 11:49:39浏览次数:11  
标签:QT OpenGL 0.0 EBO 0.5 shader 顶点 GL VAO

一、概述

  需求:

    绘制一个正方形,可以控制正方形的颜色、可以切换正方形为线框模式/填充模式

  绘制流程:

    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

相关文章

  • OpenGL中的VAO、VBO、EBO
    一、概述目的:简单介绍一下VAO、VBO、EBO,使用他们能提高opengl的渲染效率VAO:顶点数组对象(VertexArrayObject)VAO就相当于一个管理者的角色,在GPU中创建一个VAO对象用于管理VBO、EBO。VBO和EBO创建绑定好后会自动挂到VAO下。VBO:顶点缓冲对象(VertexBuffe......
  • QT+OpenGL创建一个三角形并动态改变三角形颜色
    一、概述需求:1.使用QT+OpenGL创建一个三角形2.默认三角形为黑色3.可以通过点击按钮改变三角形颜色值(红绿蓝)4.如下图所示ps:这一篇用的是QT封装好的opengl相关帮助类,下一篇会用原生的来写。 二、代码示例1.让......
  • lazarus 编译时切换QT5/GTK2的方法
    lazarus编译时可以随时切换QT5/GTK2,方法如下:在project菜单-->options-->compileroptions-->additionsandoverrides点Set"LCLWidgetType"选择QT5或其他然后重新编译应用就可以。带menu、combobox等控件(在银河麒麟)的应用,用GTK2时有深灰的背景,QT5编译的整体会好点。注意:fastrepor......
  • Facebook广告投放指南:精准触达全球目标受众
    引言:在这个数字化时代,Facebook不仅是连接全球数十亿用户的社交纽带,更是品牌与企业触达全球目标受众的强大营销平台。本文将带您深入了解Facebook广告的投放策略,从广告类型选择到精准定位,再到预算管理,助您在全球市场中占据一席之地。Facebook广告的全球影响力作为全球最大......
  • Qt_ui生成界面原理
    QtUI界面生成原理在使用Qt开发图形用户界面(GUI)时,我们可以使用QtDesigner创建.ui文件,这个文件描述了界面的布局和组件信息。在编译项目时,这些信息会被转换为实际的代码,生成一个可视化的界面。下面是详细的步骤解释:1.创建.ui界面文件本质:.ui文件是一个XML......
  • Qt+ffmpeg环境搭建
    Qt+ffmpeg环境搭建各平台常见视频开发库举例:iOS:AVFoundationAudioUnitAndroid:MediaPlayer,MediaCodecWindows:DirectShowLinux:GStreamerFFmpeg库是一个跨平台的视频开发库,还有libVLC也是一个跨平台的视频开发库掌握了其中一个库,也能很快上手其它库,因为音视频解......
  • QTday4
    思维导图 第二题 widget.h#ifndefWIDGET_H#defineWIDGET_H#include<QWidget>#include<QTime>#include<QTimerEvent>#include<QTextToSpeech>QT_BEGIN_NAMESPACEnamespaceUi{classWidget;}QT_END_NAMESPACEclassWidget:public......
  • QTabWidget自定义样式(仿DotNetBar)
    QSS如下,若需要tab栏背景色需要添加ui->tabWidget->setAttribute(Qt::WA_StyledBackground);语句使background-color生效,这个时候qtdesigner中仍然看不到背景色,但是不要担心它是生效的,只需在属性中勾上autofillbackground即可在designer中预览(该属性在QWidget属性组中,实际上勾不勾......
  • 【Qt】 对象树 与 乱码问题
    文章目录1.对象树在堆上开辟空间并管理栈上开辟与堆上开辟的区别2.乱码问题的解释编码方式的区分出现乱码的原因查看当前文件的编码方式如何处理文件与终端编码方式不统一1.对象树在堆上开辟空间并管理该代码只进行new(在堆上开辟空间)而没有delete......
  • MQTT
    目录mosquitto搭建本地服务器下载配置启动订阅主题发布消息mosquitto搭建本地服务器下载配置启动mosquitto.exe-cmosquitto.conf-v订阅主题发布消息mosquito_pub-hlocalhost-t"topic"-i"client"-m"message"......