当前位置: 首页 > news >正文

(第五章)OpenGL超级宝典学习:统一变量(uniform variable)

统一变量

前言
本篇在讲什么

本篇记录对glsl中的变量uniform的认知和学习
本篇适合什么

适合初学Open的小白
适合想要学习OpenGL中uniform的人

本篇需要什么

C++语法有简单认知
OpenGL有简单认知
最好是有OpenGL超级宝典蓝宝书
依赖Visual Studio编辑器
本篇的特色

具有全流程的图文教学
重实践,轻理论,快速上手
提供全流程的源码内容


★提高阅读体验★

👉 ♠ 一级标题 👈

👉 ♥ 二级标题 👈

👉 ♣ 三级标题 👈

👉 ♦ 四级标题 👈


目录

  • ♠ uniform
    • ♥ 什么是uniform
    • ♥ uniform的作用
    • ♥ 简单理解
    • ♥ 定义
      • ♣ 方式1
      • ♣ 方式2
      • ♣ 定义演示
    • ♥ 赋值
      • ♣ 获取位置赋值
      • ♣ 直接赋值
    • ♥ 实战演示
  • ♠ 一致区块
    • ♥ 定义
    • ♥ 数据布局
      • ♣ 标准布局
    • ♥ 数据缓冲
    • ♥ 完整示例
  • ♠ 推送
  • ♠ 结语


♠ uniform

♥ 什么是uniform

uniform在glsl是一种特殊变量的限定符,这种变量被称为统一变量


♥ uniform的作用

能够直接将数据从应有程序传递到着色器阶段


♥ 简单理解

简单理解,用uniform定义在着色器中的变量,类似代码中的静态变量


♥ 定义

♣ 方式1

uniform vec4 out_color;

可以直接通过uniform+类型+字段的方式定义在着色器内


♣ 方式2

layout(location = 0) uniform vec4 out_color;

可以在方式1的基础上加上layout位置限定符


♣ 定义演示

"#version 450 core                                                 \n"
"                                                                  \n"
"uniform vec4 out_color1;										   \n"
"                                                                  \n"
"layout(location = 0) uniform vec4 out_color2;					   \n"
"                                                                  \n"
"out vec4 color;                                                   \n"
"                                                                  \n"
"void main(void)                                                   \n"
"{                                                                 \n"
"    color = out_color1;										   \n"
"}                                                                 \n"

以上是一个片段着色器的代码,我们在其中按照方式1方式2定义了两个统一变量out_color1out_color2


♥ 赋值

定义uniform后,我们需要在外部给其赋值,根据不同的定义方式,赋值的方式也略有不同


♣ 获取位置赋值

第一种赋值方式针对根据方式1定义的变量,我们首先需要获取变量在程序中的位置,才可以通过接口赋值,看下述代码

int location = glGetUniformLocation(program, "out_color1");
glUniform4f(location, 1.0f, 1.0f, 1.0f, 1.0f)

要点1:glGetUniformLocation

该接口可以根据定义的变量名,来获取统一变量在程序中的位置,参数1是创建好的程序,参数2是自定义的变量名,out_color1是我们在上边定义代码中写的变量

要点2:glUniform4f

我们在获取到变量位置后,可以通过glUniform**类似的接口给不同类型的统一变量赋值,参数1是位置,后边是需要赋的值


♣ 直接赋值

在上述定义2的形式中,我们直接通过限定符layout给变量设定了位置,如此一来我们就不需要再获取位置了,可以直接赋值

glUniform4f(0, 1.0f, 1.0f, 1.0f, 1.0f)

类似的形式还有很多,比如直接定义数组的赋值方式

GLfloat outColor[4] = {1.0f, 1.0f, 1.0f, 1.0f };glUniform4fv(0, 1, outColor);

♥ 实战演示

我们已经知道了如何定义变量,还有如何赋值,下面我们就写一个简单的例子,画一个三角形,通过uniform变量给三角形上色

注:该例子直接修改OpenGl超级宝典官方示例singletri.cpp,只需修改片段着色器和render方法

  • 片段着色器
static const char * fs_source[] =
{"#version 450 core                                                 \n""                                                                  \n""uniform vec4 out_color1;										   \n""                                                                  \n""layout(location = 0) uniform vec4 out_color2;					   \n""                                                                  \n""out vec4 color;                                                   \n""                                                                  \n""void main(void)                                                   \n""{                                                                 \n""    color = out_color2;										   \n""}                                                                 \n"
};
  • render
virtual void render(double currentTime)
{static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };glClearBufferfv(GL_COLOR, 0, green);// 赋值方式1//int  location = glGetUniformLocation(program, "out_color1");//glUniform4f(location, 1.0f, 1.0f, 1.0f, 1.0f);// 赋值方式2//glUniform4f(0, 1.0f, 1.0f, 1.0f, 1.0f);// 赋值数组GLfloat outColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };glUniform4fv(0, 1, outColor);glUseProgram(program);glDrawArrays(GL_TRIANGLES, 0, 3);
}

在这里插入图片描述

很简单的一个例子,我们通过glUniform4fglUniform4fv方法,给outColor赋值,得以给三角形绘制指定颜色


♠ 一致区块

我们已经了解到统一变量的定义、赋值和使用,但是仅仅是单一变量,还有种高级点的用法,可以将很多的统一变量组合成一个区块,称之为一致区块


♥ 定义

以下声明了一个名为TransformBlock的一致区块

uniform TransformBlock{float scale;vec3 translation;float rotation[3];mat4 projection_matrix;
};			

♥ 数据布局

命名好的区块会被写入到缓冲当中,在缓冲中,区块的数据布局可能不同,有两种数据布局

  • 标准的、共识的数据布局(标准布局)

由于区块中的数据不同,占用的空间不同,该布局会根据每个统一变量的空间占用去存储

  • OpenGL自己决定数据的布局方式(shared布局)

OpenGL自己决定存储方式,用之前并不知道各个数据位置,运行的时候需要先查询数据布局格式


♣ 标准布局

推荐使用标准布局,以下是标准布局的声明方式,需要用到限定符std140去声明一致区块

layout uniform (std140) TransformBlock{	float scale;vec4 color;
};							

使用标准布局最重要的一点是我们需要知道区块内的统一变量,在缓存中的数据位置,我们简单理解一下数据的分布规则

  • 每个类型都有固定长度
  • 数据的起始点必须是其固定长度的倍数

我们以上边声明的TransformBlock为例来简单介绍一下

  • 类型float的长度是4,起始点是0,scale需要四个字节,所以结束位置4
  • 类型vec4的长度是16,因为前4位已被占用,并且4不是16的倍数,所以translation在缓冲的起始点只能是16,需要16个字节,在32结束

♥ 数据缓冲

区块的缓冲和我们之前学习的缓冲类似,结构基本一致,分为以下几个步骤

  • 创建和绑定缓冲
unsigned int ubo;
glGenBuffers(1, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
  • 分配内存
glBufferData(GL_UNIFORM_BUFFER, 4*8, NULL, GL_STATIC_DRAW);
  • 将缓冲区对象内的范围绑定到索引的缓冲区目标
glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo, 0, 4 * 8);
  • 更新数据
glBufferSubData(GL_UNIFORM_BUFFER, 0, 4 * 4, sColor);

♥ 完整示例

我们来看一个完整的演示示例吧,很简单,我们只通过区块内的统一变量去给三角形上色

注:该例子直接修改OpenGl超级宝典官方示例singletri.cpp,只需修改startup方法即可

virtual void startup()
{static const char * vs_source[] ={"#version 450 core                                                 \n""                                                                  \n"" 																   \n""void main(void)                                                   \n""{                                                                 \n""    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  \n""                                   vec4(-0.25, -0.25, 0.5, 1.0),  \n""                                   vec4( 0.25,  0.25, 0.5, 1.0)); \n""                                                                  \n""    gl_Position = vertices[gl_VertexID];                          \n""}                                                                 \n"};static const char * fs_source[] ={"#version 450 core                                                 \n""                                                                  \n""layout (std140) uniform color_block							   \n""{                                                                 \n""    vec4 out_color;                                               \n""};                                                                \n""                                                                  \n""out vec4 color;                                                   \n""                                                                  \n""void main(void)                                                   \n""{                                                                 \n""    color = out_color;										       \n""}                                                                 \n"};program = glCreateProgram();GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fs, 1, fs_source, NULL);glCompileShader(fs);GLuint vs = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vs, 1, vs_source, NULL);glCompileShader(vs);glAttachShader(program, vs);glAttachShader(program, fs);glLinkProgram(program);glGenVertexArrays(1, &vao);glBindVertexArray(vao);GLfloat sColor[] = { 1.0f, 0.5f, 0.0f, 1.0f };unsigned int ubo;glGenBuffers(1, &ubo);glBindBuffer(GL_UNIFORM_BUFFER, ubo);glBufferData(GL_UNIFORM_BUFFER, 4*8, NULL, GL_STATIC_DRAW);glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo, 0, 4 * 8);glBufferSubData(GL_UNIFORM_BUFFER, 0, 4 * 4, sColor);
}

要点1:在该片段着色器中我们声明了一个标准区块color_block,其存有唯一变量out_color,该变量会作为三角形颜色被赋值

要点2:自定义颜色sColor,作为数值通过glBufferSubData接口更新到了区块内,以下是最终显示效果

在这里插入图片描述


♠ 推送

  • Github
https://github.com/KingSun5

♠ 结语

若是觉得博主的文章写的不错,不妨关注一下博主,点赞一下博文,另博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。

👉 本文属于原创文章,转载请评论留言,并在转载文章头部著名作者出处👈

相关文章:

(第五章)OpenGL超级宝典学习:统一变量(uniform variable)

统一变量 前言 本篇在讲什么 本篇记录对glsl中的变量uniform的认知和学习 本篇适合什么 适合初学Open的小白 适合想要学习OpenGL中uniform的人 本篇需要什么 对C语法有简单认知 对OpenGL有简单认知 最好是有OpenGL超级宝典蓝宝书 依赖Visual Studio编辑器 本篇的特色 …...

数据存储技术复习(四)未完

1.什么是NAS。一般用途服务器与NAS设备之间有何不同。NAS是一个基于IP的专用高性能文件共享和存储设备。—般用途服务器可用于托管任何应用程序,因为它运行的是一般用途操作系统NAS设备专用于文件服务。它具有专门的操作系统,专用于通过使用行业标准协议…...

Rust编码的信息窃取恶意软件源代码公布,专家警告已被利用

黑客论坛上发布了一个 用Rust编码的信息窃取恶意软件源代码 ,安全分析师警告,该恶意软件已被积极用于攻击。 该恶意软件的开发者称,仅用6个小时就开发完成,相当隐蔽, VirusTotal的检测率约为22% 。 恶意软件开发者在…...

diffusers编写自己的推理管道

英文文献:Stable Diffusion with 🧨 Diffusers 编写自己的推理管道 最后,我们展示了如何使用diffusers. 编写自定义推理管道是对diffusers库的高级使用,可用于切换某些组件,例如上面解释的 VAE 或调度程序。 例如&a…...

计算机操作系统 左万利 第二章课后习题答案

计算机操作系统 左万利 第二章课后习题答案 1、为何引进多道程序设计,在多道程序设计中,内存中作业的道数是否越多越好?说明原因。 引入多道程序设计技术是为了提高计算机系统资源的利用率。在多道程序系统中,内存中作业的道数并…...

CODESYS开发教程10-文件读写(SysFile库)

今天继续我们的小白教程,老鸟就不要在这浪费时间了😊。 前面一期我们介绍了CODESYS的文件操作库CAA File。这一期主要介绍CODESYS的SysFile库所包含的文件读写功能块,主要包括文件路径、名称、大小的获取以及文件的创建、打开、读、写、拷贝…...

Linux安装redis

Linux安装redis一.下载二.解压配置1.创建文件夹2.上传文件3.解压4.编译配置三.启动测试1.启动2.防火墙配置3.测试四.设置开机自启1.配置脚本2.添加服务3.测试一.下载 redis官网:https://redis.io/ redis官方下载地址:http://download.redis.io/releases…...

计算机组成与体系结构 性能设计 William Stallings 第2章 性能问题

2.1 优化性能设计例如,当前需要微处理器强大功能的桌面应用程序包括:图像处理、三维渲染、语音识别、视频会议、多媒体创作、文件的声音和视频注释、仿真建模从计算机组成与体系结构的角度来看,一方面,现代计算机的基本组成与50多…...

anaconda详细介绍、安装及使用(python)

anaconda详细介绍、安装及使用1 介绍1.1 简介1.2 特点1.3 版本下载2 Anaconda管理Python包命令3 安装3.1 windows安装4 操作4.1 Conda 操作4.2 Anaconda Navigator 操作4.3 Spyder 操作4.4 Jupyter Notebook 操作5 示例参考1 介绍 1.1 简介 Anaconda是用于科学计算&#xff08…...

雅思经验(6)

反正我是希望遇到的雅思听力section 4.里面填空的地方多一些,之后单选的部分少一些。练了一下剑9 test3 的section 4,感觉还是不难的,都是在复现,而且绕的弯子也不是很多。本次考试的目标就是先弄一个六分,也就是说&am…...

CentOS9源码编译libvirtd工具

卸载原有版本libvirt [rootcentos9 ~]# yum remove libvirt Centos9配置网络源 [rootcentos9 ~]# dnf config-manager --set-enabled crb [rootcentos9 ~]# dnf install epel-release epel-next-release 安装依赖包 [rootcentos9 ~]# yum install -y libtirpc-devel libxml2-de…...

搭建内网穿透

文章目录摘要npsfrp服务提供商摘要 内网穿透是一种方便的技术,可以让用户随时随地访问内网设备。有两种方式可以使用内网穿透:自己搭建,使用nps/frps软件;购买服务,快速享受内网穿透带来的便利。 nps 内网穿透。参考…...

vue3组件库项目学习笔记(八):Git 使用总结

目前组件库的开发已经接近尾声,因为这次是使用 git 进行协作的开发模式,在团队协作的时候遇到很多的问题,开发过程中发现小伙伴们对于 git 的使用还不是很熟练,这里就简单总结一下常用的 git 的操作,大致有&#xff1a…...

ISO7320FCQDRQ1数字隔离器LMG1025QDEETQ1半桥GaN驱动器

1、数字隔离器 DGTL ISO 3000VRMS 2CH 8SOIC型号:ISO7320FCQDRQ1批次:新技术:容性耦合类型:通用隔离式电源:无通道数:2输入 - 侧 1/侧 2:2/0通道类型:单向电压 - 隔离:30…...

openmmlab 语义分割算法基础

本文是openmmlab AI实战营的第六次课程的笔记,以下是我比较关注的部分。简要介绍语义分割:如下图,左边原图,右边语义分割图,对每个像数进行分类应用语义分割在个各种场景下都非常重要,特别是在自动驾驶和医…...

2023年深圳/东莞/惠州CPDA数据分析师认证报名入口

CPDA数据分析师认证是中国大数据领域有一定权威度的中高端人才认证,它不仅是中国较早大数据专业技术人才认证、更是中国大数据时代先行者,具有广泛的社会认知度和权威性。 无论是地方政府引进人才、公务员报考、各大企业选聘人才,还是招投标加…...

RabbitMQ-客户端源码之AMQChannel

AMQChannel是一个抽象类,是ChannelN的父类。其中包含唯一的抽象方法: /*** Protected API - called by nextCommand to check possibly handle an incoming Command before it is returned to the caller of nextCommand. If this method* returns true…...

注意力机制(SE,ECA,CBAM) Pytorch代码

注意力机制1 SENet2 ECANet3 CBAM3.1 通道注意力3.2 空间注意力3.3 CBAM4 展示网络层具体信息1 SENet SE注意力机制(Squeeze-and-Excitation Networks):是一种通道类型的注意力机制,就是在通道维度上增加注意力机制,主要内容是是…...

Vue2笔记03 脚手架(项目结构),常用属性配置,ToDoList(本地存储,组件通信)

Vue脚手架 vue-cli 向下兼容可以选择较高版本 初始化 全局安装脚手架 npm install -g vue/cli 创建项目:切换到项目所在目录 vue create xxx 按照指引选择vue版本 创建成功 根据指引依次输入上面指令即可运行项目 也可使用vue ui在界面上完成创建&…...

Java程序的执行顺序、简述对线程池的理解

点个关注,必回关 文章目录一、Java程序是如何执行的二、合理利用线程池能够带来三个好处一、Java程序是如何执行的 我们日常的工作中都使用开发工具(IntelliJ IDEA 或 Eclipse 等)可以很方便的调试程序,或者是通 过打包工具把项目…...

【前言】嵌入式系统简介

随手拍拍💁‍♂️📷 日期: 2022.12.01 地点: 杭州 介绍: 2022.11.30下午两点时,杭州下了一场特别大的雪。隔天的12月路过食堂时,边上的井盖上发现了这个小雪人。此时边上的雪已经融化殆尽,只有这个雪人依旧维持着原状⛄…...

React设计原理—1框架原理

阅读前须知 本文是笔者学习卡颂的《React设计原理》的读书笔记,对书中有价值内容以Q&A方式进行呈现,同时结合了自己的理解🤔阅读时推荐先看问题,想想自己的答案,再和答案比对一下本文属于前端框架科普,…...

(C00034)基于Springboot+html前后端分离技术的宿舍管理系统-有文档

基于Springboothtml技术的宿舍管理系统-有文档项目简介项目获取开发环境项目技术运行截图项目简介 基于Springboothtml的前后端分离技术的宿舍管理系统项目为了方便对学生宿舍进行管理而设计,分为后勤、宿管、学生三种用户,后勤对整体宿舍进行管理、宿管…...

Flink面试题

一 基础篇Flink的执行图有哪几种?分别有什么作用Flink中的执行图一般是可以分为四类,按照生成顺序分别为:StreamGraph-> JobGraph-> ExecutionGraph->物理执行图。1)StreamGraph顾名思义,这里代表的是我们编写…...

Python学习笔记

前言:又从仓库翻出来了一些以前总结的文档,以下内容是我初学Python时网上找的或是图书馆借书抄写的笔记,现在再看有点零散不成体系,但是也还是纪念一下子吧。 Python学习笔记 对于初学编程的人来说,Python可以缩短编…...

最适合入门的100个深度学习实战项目

🚨注意🚨:最近经粉丝反馈,发现有些订阅者将此专栏内容进行二次售卖,特在此声明,本专栏内容仅供学习,不得以任何方式进行售卖,未经作者许可不得对本专栏内容行使发表权、署名权、修改…...

AssertionError: 618 columns passed, passed data had 508 columns【已解决】

问题描述 程序中断,报错如下AssertionError: 618 columns passed, passed data had 508 columns Exception has occurred: ValueError 618 columns passed, passed data had 508 columns AssertionError: 618 columns passed, passed data had 508 columnsThe abo…...

166_技巧_Power BI 窗口函数处理连续发生业务问题

166_技巧_Power BI 窗口函数处理连续发生业务问题 一、背景 在生产经营的数据监控中,会有一类指标需要监控是否连续发生,从而根据其在设定区间中的连续频次来评价业务。 例如: 员工连续迟到天数。销售金额连续上升或者下降。用户连续登陆…...

电子科技大学人工智能期末复习笔记(五):机器学习

目录 前言 监督学习 vs 无监督学习 回归 vs 分类 Regression vs Classification 训练集 vs 测试集 vs 验证集 泛化和过拟合 Generalization & Overfitting 线性分类器 Linear Classifiers 激活函数 - 概率决策 ⚠线性回归 决策树 Decision Trees 决策树构建递归…...

使用DDD指导业务设计的总结思考

领域驱动设计(DDD) 是 Eric Evans 提出的一种软件设计方法和思想,主要解决业务系统的设计和建模。DDD 有大量难以理解的概念,尤其是翻译的原因,某些词汇非常生涩,例如:模型、限界上下文、聚合、…...

江苏连云港网站建设公司/牡丹江seo

会有如题的思考,是因为我一直有一个疑问java文件的编码会影响字符串的编码嘛? 因此自然而然就想到了java编译后的文件的编码。 1 javac在控制台编译java类文件 手动建立一个java文件Demo.java,并保存。 此时Demo.java文件的编码为ANSI,中…...

网站按域名跳转不同的页面/短视频营销策划方案

如果访问存储器时使用bp寻址,则默认的段寄存器是“SS”,即堆栈段。SS堆栈段通常是指采用堆栈方式工作的一段内存区域;在采用段式内存管理方式进行程序内存分配的架构中,堆栈段用来存放局部变量和函数返回地址。段寄存器是因为对内…...

武汉搭建网站/品牌策划运营公司

文章目录开篇问题简介各种锁简介源码分析成员属性构造方法添加元素初始化桶数组判断是否需要扩容协助扩容(迁移元素)迁移元素删除元素获取元素获取元素个数总结开篇问题 (1)ConcurrentHashMap与HashMap的数据结构是否一样&#x…...

移动应用开发大专出来做什么/seo优化方案策划书

试题编号: 201703-1试题名称: 分蛋糕时间限制: 1.0s内存限制: 256.0MB问题描述:问题描述小明今天生日,他有n块蛋糕要分给朋友们吃,这n块蛋糕(编号为1到n)的重量分别为a1, a2, …, a…...

做彩票网站代理/淘宝大数据查询平台

如何玩转iPhone手机?最近手机连接投影仪被大家关注,那么苹果手机是如何连接投影仪的呢?新出的iPhone8可以连接吗?跟随小编一起来了解一下详细的步骤教程吧。苹果手机与投影仪连接的方法教程(步骤) 1、第一次…...

建设什么网站/官网优化 报价

图论涉及的内容广泛,复杂,综合性较强。我在学习《算法竞赛进阶指南》图论部分后,为了方便日后复习让自己感觉学了东西,写下这篇大杂汇,内容主要源自我自己对《算法竞赛进阶指南》图论部分概括以及学习做题的经验。 一、…...