首页 > 其他分享 >QT+OpenGL从顶点着色器传递颜色数据给片元着色器

QT+OpenGL从顶点着色器传递颜色数据给片元着色器

时间:2024-08-22 16:18:19浏览次数:5  
标签:QT OpenGL float mX programId 顶点 mY 着色器

一、概述

  目的:

    1.定义顶点数据和颜色数据,并将颜色数据通过顶点着色器传递给片元着色器

    2.对定义的三角形动态进行:平移、颠倒、镜像

  

  

二、示例代码

  1.定义顶点坐标和颜色值。此处颜色和顶点是放到一块的。需要告知GPU如何解析数据,如:哪些是顶点,哪些是颜色数据

float vertices[] = {
    // 位置              // 颜色
     0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,   // 右下
    -0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,   // 左下
     0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f    // 顶部
};

  2.定义顶点着色器和片元着色器

//顶点着色器
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
uniform float mX;
uniform float mY;
uniform float mXT;
out vec3 ourColor;
void main(void)
{
    gl_Position = vec4(aPos.x*mX+mXT,aPos.y*mY,aPos.z,1.0f);
    ourColor = aColor;
} 
//片元着色器
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
void main(void)
{
    FragColor = vec4(ourColor,1.0f);
}

  3.编译、链接顶点着色器及片元着色器

GLuint BaseOpenGLWindow::buildAttachShaderAndReturnProgramId(QString vertexResPath, QString fragmentResPath) {
    //编译顶点着色器和片元着色器
    GLuint vertexShader = getShaderId(GL_VERTEX_SHADER, vertexResPath);
    GLuint fragmentShader = getShaderId(GL_FRAGMENT_SHADER, fragmentResPath);
    GLuint programId = glCreateProgram();
    glAttachShader(programId, vertexShader);
    glAttachShader(programId, fragmentShader);
    glLinkProgram(programId);
    getLinkProgramErrorInfo(programId);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    return programId;
} 
//小程序
programId = buildAttachShaderAndReturnProgramId(":/QtForOpenCV4Tool/shader/vertex_color.vert",
    ":/QtForOpenCV4Tool/shader/vertex_color.frag");

  4.创建VAO、VBO,把VBO挂到VAO上,并将顶点数据一次性Copy到GPU中,方便后续使用(效率高)

glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);

//创建VBO并创建存放顶点数据的内存
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  5.告知显卡如何解析顶点数据(顶点和颜色)

//位置数据(参数1:位置对应aPos,参数2:顶点个数,参数3:顶点数据类型,参数4:是否标准化处理,false,参数5:步长,这里一行有6个数据交替,所以这里写6,参数6:偏移量)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);//启用第一个顶点,即aPos
//颜色数据(参数1:位置对应aColor,参数5:步长同上,参数6:偏移量,这里颜色数据和顶点数据之间隔了3个float,所以是3*sizeof(float))
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);//启用第二个顶点即aColor

  6.顶点着色器定义了三个uniform变量

uniform float mX;
uniform float mY;
uniform float mXT;

    可以通过这三个值从CPU把数据传递给GPU

GLint mLocation = glGetUniformLocation(programId, "mX");
glUniform1f(mLocation, mX);
GLint mLocation1 = glGetUniformLocation(programId, "mY");
glUniform1f(mLocation1, mY);
GLint mLocation2 = glGetUniformLocation(programId, "mXT");
glUniform1f(mLocation2, mXT);

  7.绘制出想要的三角形

void GLColorDataFromVertexWindow::paintGL() {
    glUseProgram(programId);
    GLint mLocation = glGetUniformLocation(programId, "mX");
    glUniform1f(mLocation, mX);
    GLint mLocation1 = glGetUniformLocation(programId, "mY");
    glUniform1f(mLocation1, mY);
    GLint mLocation2 = glGetUniformLocation(programId, "mXT");
    glUniform1f(mLocation2, mXT);
    switch (type) {
    case 1: {
        mX = -1.0f;
        GLint mLocation = glGetUniformLocation(programId, "mX");
        glUniform1f(mLocation, mX);
        break;
    }
    case 2: {
        mY = -1.0f;
        GLint mLocation = glGetUniformLocation(programId, "mY");
        glUniform1f(mLocation, mY);
    }
          break;
    case 3: {
        mXT = 0.25f;
        GLint mLocation = glGetUniformLocation(programId, "mXT");
        glUniform1f(mLocation, mXT);
    }
          break;
    }
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

  8.增加点击事件动态给mX、mY、mXT赋值,从而改变三角形的状态

void GLColorDataFromVertexWindow::changeTriStatus(int type) {
    this->type = type;
    mY = 1.0f;
    mX = 1.0f;
    mXT = 0.0f;
    update();
}
QHBoxLayout* hLayout = new QHBoxLayout(this);
QPushButton* btnRed = new QPushButton(this);
btnRed->setText("Y轴颠倒");
QPushButton* btnGreen = new QPushButton(this);
btnGreen->setText("X轴颠倒");
QPushButton* btnBlue = new QPushButton(this);
btnBlue->setText("X轴平移");
hLayout->addWidget(btnRed);
hLayout->addWidget(btnGreen);
hLayout->addWidget(btnBlue);
hLayout->setAlignment(Qt::AlignTop);

connect(btnRed, &QPushButton::clicked, [=]() {
    changeTriStatus(1);
    });

connect(btnGreen, &QPushButton::clicked, [=]() {
    changeTriStatus(2);
    });

connect(btnBlue, &QPushButton::clicked, [=]() {
    changeTriStatus(3);
    });

 

标签:QT,OpenGL,float,mX,programId,顶点,mY,着色器
From: https://www.cnblogs.com/tony-yang-flutter/p/18374123

相关文章

  • Qt键盘事件检测不到方向键|阻止控件截取键盘事件
    做项目二次开发的时候遇到一个问题,在自己新建的界面中放了很多控件,需要通过键盘方向键来控制焦点在不同控件间的转移,之前用键盘事件检测上下键没有问题,后来加上左右键发现没有反应,查了资料了解到是控件吞掉了左右方向键的信号,因为Qt中本身就有一些处理事件的函数,控件会获取键盘左......
  • QT+OpenGL通过两个VAO来管理两个三角形
    一、概述需求:通过两个VAO来管理VBO,从而控制两个三角形此需求和单独通过VAO绘制一个三角形有较大的不同,此处创建两个VAO,同时需要管理两个VBO。在绘制图形的时候需要分别绑定这两个VAO才能正确的绘制出三角形。效果:二、代码示例1.定义顶点数据(两个三角形......
  • QT+OpenGL使用一组顶点绘制两个三角形
    一、概述需求:使用一组顶点坐标绘制两个三角形。ps:此需求和绘制一个三角形并没有什么不同,只是把顶点坐标由三个改成了6个。依次类推,如果想要绘制多边形或者更多的三角形,只需要定义不同的顶点就行了。效果:二、代码示例1.定义顶点floatvertices[18]={......
  • QT自定义结构体的传递
    方法1:使用Q_DECLARE_METATYPE(TestResult)进行声明1.1声明#ifndefTESTRESULT_H#defineTESTRESULT_H#include<QDateTime>#include<QString>#include<QMetaType>//用于测试时更新内容,作为结果导出的依据classTestResult{public:int_nid=0;int_coun......
  • 【python】PyQt5中的QFrame控件,控制图形的边框样式、阴影效果、形状等属性
    ✨✨欢迎大家来到景天科技苑✨✨......
  • qt静态编译 全自动编译qt静态库 qt5 windows安装qt (2024.2.23)
    全自动编译qt5静态库(2024.2.23)本教程是从无到有配置qt.io和vcpkg实现全自动编译qt5的静态库,使得您可以静态编译qt项目0.安装VisualStudio2022这个我就不多解释了,直接去官网下载社区版本,勾选使用C++的桌面开发安装好就行1.安装qt.io的开发环境1.1下载在线安装包并且配......
  • 【嵌入式裸机开发】智能家居入门7:最新ONENET,MQTT协议接入,最全最新(微信小程序、MQTT协
    智能家居入门7前言一、ONENET云平台创建产品与设备二、STM32端连接服务器前的准备三、STM32端实现四、微信小程序端连接服务器前的准备五、微信小程序端实现六、最终测试前言本篇文章介绍最新ONENET云平台的MQTT协议接入方法,在STM32上实现数据上云与服务器下发数据......
  • VS2022+QT6.7.2 定时器的使用(两种方法)
    目录一、继承QObject定时器事件二、QTimer类三、具体实现一、继承QObject定时器事件  所有继承自QObject的类,都会有一个timerEvent(QTimerEvent*event)的纯虚函数,startTimer()设定定时间隔并启动,再重载这个函数以处理自己的定时任务,多个定时任务用timeId区分,结束后......
  • 解决lazarus 3.xx后在linux编译为Qt出错方法
    今天用lazarus3.4在银河麒麟将应用编译为Qt5出现以下错误信息:Warning:linker:/usr/bin/ld.bfd:/home/lb/fpcupdeluxe34/lazarus/lcl/units/aarch64-linux/qt5/qtint.o:infunction`QTINT$_$TQTWIDGETSET_$__$$_CREATE$$TQTWIDGETSET':Error:qtint.pp:(.text.n_qtint$_$t......
  • PyQt5实现置顶、位置固定、透明度设置
    在PyQt5中,要实现一个始终置顶、位置固定、透明度设置、去除关闭按钮且无法通过常规方式关闭的对话框窗口,需要对QDialog进行一系列的自定义设置。以下是一个详细的示例代码,展示了如何实现这些功能:importsysfromPyQt5.QtWidgetsimportQApplication,QDialog,QVBoxLayou......