15. Qt中OPenGL的参数传递问题

news2024/11/30 2:29:03

1. 说明

在OPenGL中,需要使用GLSL语言来编写着色器的函数,在顶点着色器和片段着色器之间需要参数值的传递,且在CPU中的数据也需要传递到顶点着色器中进行使用。本文简单介绍几种参数传递的方式:
(本文内容仅个人理解,有错请评论纠正…)
函数解读:
glVertexAttribPointer(参数一,参数二,参数三,参数四,参数五,参数六)
参数一:标号,和顶点着色器中layout(location=n)的location值对应,这样找到的数据就会自动传输给layout(location=n)对应的变量
参数二:连续寻找几个值,一般是3个(位置坐标/颜色rgb值)
参数三:数值的类型
参数四:一般都是GL_FALSE
参数五:寻找完需要的值的个数后,下一次在寻找需要跨越多少步长
参数六:起始寻找位置的指针偏移量(寻址起始位置
下文用到的形式含义说明:

glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,6*sizeof (float),(void*)0);//从第0个位置为起始位置开始找数据,每次找3个,查找结束后,跨6个位置当起始位置继续找
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,6*sizeof (float),(void*)(3*sizeof(float)));//从第3个位置为起始位置开始找数据,每次找3个,查找结束后,跨6个位置当起始位置继续找
//上面的起始位置是最后一个参数决定的,跨度是第五个参数决定的

2. 方式一:关键字 in / out

一般OPenGL的渲染流程是从CPU中拿到顶点数据,然后传输到顶点着色器中,经过顶点着色器的处理,会传输到片段着色器中进行再次处理。那么,顶点着色器和片段着色器之间的参数传递就可使用 in / out 关键字来传输。需要注意的是变量的名称要保证完全相同,这样OPenGL在底层遇到 in / out修饰的变量后,会自动将这两个同名变量连接到一起进行参数传输,示例代码如下:
顶点着色器代码:

#version 330 core
layout (location = 0) in vec3 aPos;	//in 修饰,说明是从外界传输过来的
out vec4 vertexColor; //out修饰,说明是需要传输到外部的
void main(){
	gl_Position = vec4(aPos,1.0);
	vertexColor = vec4(0.5,0.0,0.0,1.0);
}

片段着色器代码:

#version 330 core
out vec4 FragColor;  //out修饰,说明是需要传输到外部的
in vec4 vertexColor; //使用 in 修饰,定义同名变量,底层会将顶点着色器中的同名变量和这个变量进行连接,实现着色器间参数传递
void main(){
	FragColor = vertexColor;
}

3. 方式二:使用 layout 定位

layout一般是用在顶点着色器中定义变量的,比如当VAO通过定义的方式在VBO中拿到数据后,那么拿到的数据怎样传输给顶点着色器中进行使用呢?此时,就可以使用 layout 这个关键字。如下:

//加入有数据 vertices
float vertices[] = {	//每一行数据的前三个是位置坐标,后三个是颜色值
	0.5f,0.5f,0.5f,1.0f,0.0f,0.0f,
	0.5f,-0.5f,0.0f,0.0f,1.0f,0.0f,
	-0.5f,-0.5f,0.0f,0.0f,0.0f,1.0f,
	-0.5f,0.5f,0.0f,0.5f,0.5f,0.5f,
}
//下面代码的意思是:定义一个变量,这个变量的数据是从VAO中获取,以 location 为标记来确定是哪一个VAO
layout (location = 0) in vec3 aPos;

//在initializeGL()函数中,我们需要使用VAO通过某种方式在VBO缓存中拿数据,有可能是位置坐标数据,也有可能是纹理数据,所以可能会设置多个VAO来获取数据,那么上面的变量 aPos 怎么确定自己要在哪一个VAO中接收数据呢?就是通过上面 location 的值,比如:
//告诉VAO怎么在VBO中拿数据
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,6*sizeof (float),(void*)0);
//上行代码的第一个参数:指定VAO在VBO中取数据时的起始位置,同时也和顶点着色器中变量的 location 值对应,两者相同,则说明这个VAO后续查询获取的数据会传递到顶点着色器中并赋予对应变量,比如上述查询到的数据会赋值给 aPos;
//例2:
//顶点着色器中定义变量:
layout (location = 1) in vec3 aColor;
//在initializeGL()函数中:
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,6*sizeof (float),(void*)(3*sizeof(float)));
//上一行代码注意:第一个参数是1,和顶点着色器中变量 aColor 的 location = 1 是对应的
//例2中VAO查询到的数据会赋值给 aColor 变量

4. 方式三:使用 attributeLocation() 查询属性并定位

//比如我们在顶点着色器中定义变量:
in vec3 aPos;	//未用关键字修饰,in仅表示此变量是外界输入进来的
//在initializeGL()函数中:
//先初始化着色器并绑定:
//添加着色器
shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shaders/Shaders/shape.vert");//注意:此处的路径最好用相对路径,绝对路径可能会打不开文件
shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shaders/Shaders/shape.frag");
shaderProgram.link();	//将两个着色器文件连接到一起
//查询着色器中变量位置:
GLint posLocation = shaderProgram.attributeLocation("aPos");//里面的参数是需要查找的变量名称
//后面设置VAO时使用上面这个变量:(即可将获取到的数据传递给指定位置的变量)
glVertexAttribPointer(posLocation,3,GL_FLOAT,GL_FALSE,6*sizeof (float),(void*)(3*sizeof(float)));

5. 方式四:使用 bindAttributeLocation() 直接绑定属性位置

方式三类似,唯一不同的是此方式自己定义位置,并绑定到指定属性上,不需要去查找属性的位置。

//比如我们在顶点着色器中定义变量:
in vec3 aPos;	//未用关键字修饰,in仅表示此变量是外界输入进来的
//在initializeGL()函数中:
//先初始化着色器并绑定:
//添加着色器
shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shaders/Shaders/shape.vert");//注意:此处的路径最好用相对路径,绝对路径可能会打不开文件
shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shaders/Shaders/shape.frag");
shaderProgram.link();	//将两个着色器文件连接到一起
//查询着色器中变量位置:
GLint posLocation = 1;
shaderProgram.bindAttributeLocation("aPos",posLocation);//直接随意设置个标志绑定到属性上
//后面设置VAO时使用上面这个变量:(即可将获取到的数据传递给指定位置的变量)
glVertexAttribPointer(posLocation,3,GL_FLOAT,GL_FALSE,6*sizeof (float),(void*)(3*sizeof(float)));

6. 方式五:使用 uniform 定义全局属性

上面的方式一到方式四一般是用在顶点着色器中,而使用 uniform 修饰的变量可以定义在任意着色器中,可以在任意着色器程序在任意阶段进行访问。
比如:在片段着色器中定义一个变量 ourColor,如下图所示:
在这里插入图片描述
上面片段着色器中的变量 ourColor 是可以在外界传入的,比如在 initializeGL() 函数中进行设置:

shaderProgram.setUniformValue("ourColor",0.0f,0.5f,0.0f,1.0f);//注意变量名要写正确

持续更新中,请大家多多关注…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/363690.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学校节能减排实施方案-浅析高校能耗及节能管理

摘要:高校能源管理是高校治理体系和高校后勤保障的重要组成部分。利用数据统计等手段对蚌埠医学院近年来的能源使用情况进行统计分析,通过横向及纵向对比,结合国家相关政策法规及同类高校能耗情况,对该校能源消耗现状进行了综合分析&#xff…

Web3中文|2023年zk赛道爆发,即将推出的Polygon zkEVM有多重要?

Crypto行业被广泛关注的零知识证明(Zero—Knowledge Proof)技术,在1980年就被数学家S.Goldwasser、S.Micali及C.Rackoff提出。 零知识证明涉及一系列步骤,可以实现密码学中的「可用而不可知」。 而区块链有着公开透明、不可篡改…

Nginx之反向代理、负载均衡、动静分离。

Nginx之反向代理、负载均衡、动静分离。 1、Nginx是啥? 轻量级Web服务器、反向代理服务器、电子邮件(IMAP/POP3)代理服务器 在 BSD-like 协议下发行、占内存少、并发高(同时处理请求能力)。 2、安装 官网&#xf…

【Python】序列与列表(列表元素的增删改查,求之,列表推导式、列表的拷贝)

一、序列序列的概念:按照某种顺序排列的数据类型就叫做序列,比如字符串,列表,元组,集合序列的共同点是都有下标,支持index()方法和count(),也支持切片处理(等同于字符串序列的切片处理)l1 [0, …

Leetcode(每日一题)——1140. 石子游戏 II

摘要 ​​​​​​1140. 石子游戏 II 877. 石子游戏 1406. 石子游戏 III 375. 猜数字大小 II 464. 我能赢吗 486. 预测赢家 1025. 除数博弈 一、动态规划解析 Alice一开始有两个选择:拿前一堆/前两堆石子。如果 Alice 拿前一堆,那么轮到 Bob 时…

Propargyl-PEG1-SS-PEG1-PFP ester,1817735-30-0,炔基应用于生物标记

【中文名称】丙炔-单乙二醇-二硫键-单乙二醇-五氟苯酚酯【英文名称】 Propargyl-PEG1-SS-PEG1-PFP ester【结 构 式】【CAS号】1817735-30-0【分子式】C16H15F5O4S2【分子量】430.4【基团部分】炔基基团【纯度标准】95%【包装规格】1g,5g,10g&#xff0c…

互联网行业中,哪些岗位越老越吃香?

你是不是也想转行IT行业,找一门适合自己学习,能拿高薪的技术,最好还越老越吃香?或许先应该看看对应岗位,老资格的同行们可以拿到的薪资数再做判断。整体上看,大部分岗位的起薪水平相差不大,但随…

matplotlib绘制三维图

目录线状堆积图 PolygonPlot三维表面图 SurfacePlot散点图ScatterPlot柱形图 BarPlot三维直方图螺旋曲线图 LinePlotContourPlot轮廓图网状图 WireframePlot箭头图二维三维合并文本图Text三维多个子图线状堆积图 PolygonPlot Axes3D.add_collection3d(col, zs0, zdir‘z’)  …

(考研湖科大教书匠计算机网络)第六章应用层-第一、二节:应用层概述和C/S及P2P

获取pdf:密码7281专栏目录首页:【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一:应用层概述二:客户/服务器(C/S)和对等(P2P)方式(1)客户/服务器&…

Vue页面组成及常用属性

一、Vue页面组成 目前的项目中,Vue页面都是采用组件套娃的形式,由一个一个的组件拼接而成整个页面。一个组件就是一个.vue文件。组件通常由template和script两部分组成: template部分:页面展示的具体元素内容,比如文字…

Type-c诱骗取电芯片大全

随着Type-C的普及和推广,目前市面上的电子设备正在慢慢淘汰micro-USB接口,逐渐都更新成了Type-C接口,micro-USB接口从2007年上市,已经陪伴我们走过十多个年头,如今也慢慢退出舞台。 今天我们评测的产品是市面上Type-C…

【OJ】最小字典序游戏

&#x1f4da;Description: 牌王和图王在玩一个游戏。 他们需要轮流移动字符串上的L&#xff0c;R指针&#xff0c;最后一位无法移动的人会输掉游戏。 给定一个字符串 s &#xff0c;起初有两个指针 L 和 R 都指向字符串的下标为k的位置(1 < k < | s |&#xff0c;|s…

CCNP350-401学习笔记(501-550题)

501、Refer to the exhibit. What is the effect of the configuration? A. The device will allow users at 192.168.0.202 to connect to vty lines 0 through 4 using the password ciscotestkey B. The device will allow only users at 192 168.0.202 to connect to vty …

Mybatis-Plus入门系列(20) -兼容多种数据库

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言方案分析1. 分页2. XML自定义SQL案例演示1. 配置2. 简单分页查询3. 带方言的分页查询参考前言 在我们实际开发软件产品过程中&#xff0c;数据库的类型可能不是确定的&#xff0c;也有客户…

PHP面试题

PHP相关 php7新特性 1.类型的声明 php7可以声明函数传参的类型和返回值的类型&#xff0c;比如可以用int&#xff0c;string声明参数和返回值的类型&#xff0c;如下&#xff1a; 代码&#xff1a;declare(strict_types1); function add(int $a,int $b):int{ return $a$b;…

深入浅出C++ ——手撕AVL树

文章目录前言一、AVL 树介绍二、AVL树节点的定义三、AVL树的插入四、AVL树的旋转五、AVL树的验证六、AVL树的删除七、AVL树的性能八、AVL树的实现前言 在前面的文章中介绍了map / multimap / set / multiset 容器&#xff0c;这几个容器的底层都是按照二叉搜索树来实现的。但是…

paddlepaddle目标检测

目录 1 参考链接 2 环境 3 数据集准备 4 训练 train.py 5 导出预测模型 6 预测 源码来自作者 夜雨飘零1&#xff0c;我对参考链接的代码略有修改&#xff0c;网盘地址 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;ipl5 1 参考链接 博客地址 基…

Linux 实现鼠标侧边键实现代码与网页的前进、后退

前言 之前一直是使用windows进行开发&#xff0c;最近转到linux后使用VsCode编写代码。 但是不像在win环境下&#xff0c;使用鼠标侧边键可以实现代码的前向、后向跳转。浏览网页时也不行&#xff08;使用Alt Left可以后退&#xff09;。 修改键盘映射实在没有那么方便&…

文案女王彭芳如何转变为“百万发售系统”创始人?我们来探个究竟!

智多星老师 她的输出跟智多星老师几乎毫无二致&#xff0c;是抄袭还是纯属巧合呢&#xff1f; 你们问的这个问题我也想知道&#xff0c;为了了解真相&#xff0c;我让我的一个学生把那个叫“彭芳老师”的视频给我看&#xff0c;当看到她的简介时&#xff0c;我非常震惊&#…

启智社区“我为开源狂”第六期活动小白教程之基础活跃榜

一、写在前面 春天来啦~启智社区第六期活动也来啦&#xff01; 有奖金的哦~~ 基础活跃榜奖金根据用户活跃程度进行100-300元的激励。 挑战升级榜需要用户完成相应任务&#xff0c;达标者可获得300-1000元的激励。 邀请助力榜根据用户邀请情况进行积分累加&#xff0c;按实际达…