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

OpenGL超级宝典学习笔记:原子计数器

前言
本篇在讲什么

本篇为蓝宝书学习笔记
原子计数器

本篇适合什么

适合初学Open的小白
本篇需要什么

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

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


★提高阅读体验★

👉 ♠ 一级标题 👈

👉 ♥ 二级标题 👈

👉 ♣ 三级标题 👈

👉 ♦ 四级标题 👈


目录

  • ♠ 原子计数器
  • ♠ 用法
    • ♥ 声明
    • ♥ 绑定
    • ♥ 重置
    • ♥ 计数
  • ♠ 案例
  • ♠ 推送
  • ♠ 结语


♠ 原子计数器

  • 什么是原子计数器

原子计数器是一种特殊的变量,表示的是多个着色器之间共享的存储,这个存储和一个缓冲对象关联,而且我们可以调用特定的函数进行原子内存操作

  • 原子计数器的作用

变量本身的功能是用于计数


♠ 用法

♥ 声明

layout (binding=3,offset=8) uniform atomic_uint my_variable;

声明了原子计数器my_variable,并绑定在3上,其中起始位置是8


♥ 绑定

GLuint buf;
glGenBuffers(1, &buf); 
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, buf); 
glBufferData(GL_ATOMIC_COUNTER_BUFFER, 16 * sizeof(GLuint), NULL, GL_DYNAMIC_COPY);
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 3, buf);

uniformbuffer相同,可以使用相同的方式将缓存对象绑定至绑定点上,特定参数GL_ATOMIC_COUNTER_BUFFER


♥ 重置

在使用前我们要重置计数器变量,书中提供了三种方式重设变量

  • glBufferSubData
const GLuint zero = 0; 
glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 2 * sizeof(GLuint), sizeof(GLuint), &zero);

通过glBufferSubData更新指定位置的数据

  • glMapBufferRange
GLuint * data = (GLuint *)glMapBufferRange(GL ATOMIC COUNTER BUFFER, 0, 16 * sizeof(GLuint), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
data[2] = 0;
glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);

通过glMapBufferRange获取变量地址后直接赋值

  • glClearBufferSubData
glClearBufferSubData(GL_ATOMIC_COUNTER_BUFFER, GL_R32UI, 2 * sizeof(GLuint), sizeof(GLuint), GL_RED_INTEGER, GL_UNSIGNED_INT, &zero);

通过glClearBufferSubData赋值


♥ 计数

OpenGL提供了三种用于计数的着色器函数

  • 加一
uint atomicCounterIncrement(atomic_uint a);
  • 减一
uint atomicCounterDecrement(atomic_uint a);
  • 获取值
uint atomicCounter(atomic_uint a);

♠ 案例

我们来看一个完整的演示示例吧,改例子将一个计数器绑定到缓存后并清零,通过计数器的数量来判断颜色的显示

注:该例子直接修改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""																   \n""layout (binding=0) uniform atomic_uint my_variable;	           \n""																   \n""out vec4 color;												   \n""																   \n""void main(void)                                                   \n""{																   \n""    uint counter = atomicCounterIncrement(my_variable);		   \n""	 if(counter>20000){										       \n""		 color = vec4(1.0, 0.8, 1.0, 1.0);						   \n""	 }else{														   \n""		 color = vec4(0.0, 0.8, 1.0, 1.0);						   \n""    }															   \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);// 绑定缓存GLuint buf;glGenBuffers(1, &buf);glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, buf);glBufferData(GL_ATOMIC_COUNTER_BUFFER, 16 * sizeof(GLuint), NULL, GL_DYNAMIC_COPY);glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, buf);// 清零计数器const GLuint zero = 0;glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 2 * sizeof(GLuint), sizeof(GLuint), &zero);
}

counter>20000下显示效果如下

在这里插入图片描述

counter<20000下显示效果如下

在这里插入图片描述


♠ 推送

  • Github
https://github.com/KingSun5

♠ 结语

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

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

相关文章:

OpenGL超级宝典学习笔记:原子计数器

前言 本篇在讲什么 本篇为蓝宝书学习笔记 原子计数器 本篇适合什么 适合初学Open的小白 本篇需要什么 对C语法有简单认知 对OpenGL有简单认知 最好是有OpenGL超级宝典蓝宝书 依赖Visual Studio编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#…...

深圳/东莞/惠州师资比较强的CPDA数据分析认证

深圳/东莞/惠州师资比较强的CPDA数据分析认证培训机构 CPDA数据分析师认证是中国大数据领域有一定权威度的中高端人才认证&#xff0c;它不仅是中国较早大数据专业技术人才认证、更是中国大数据时代先行者&#xff0c;具有广泛的社会认知度和权威性。 无论是地方政府引进人才、…...

LeetCodeHOT100热题02

写在前面 主要是题目太多&#xff0c;所以和前面的分开来记录。有很多思路的图都来源于力扣的题解&#xff0c;如侵权会及时删除。不过代码都是个人实现的&#xff0c;所以有一些值得记录的理解。之前的算法系列参看&#xff1a; 剑指offer算法题01剑指offer算法题02 七、动…...

虹科Dimetix激光测距仪在锯切系统中的应用

HK-Dimetix激光测距仪——锯切系统应用 许多生产设施&#xff0c;例如金属服务中心&#xff0c;使用切割锯将每个客户的订单切割成一定长度。定长切割过程通常涉及卷尺和慢跑锯的传送带。但更简单的替代方法是使用虹科Dimetix非接触式激光距离传感器。 为了切断大长度的棒材&…...

FreeRTOS入门(02):任务基础使用与说明

文章目录目的创建任务任务调度任务控制延时函数任务句柄获取与修改任务优先级删除任务挂起与恢复任务强制任务离开阻塞状态空闲任务总结目的 任务&#xff08;Task&#xff09;是FreeRTOS中供用户使用的最核心的功能&#xff0c;本文将介绍任务创建与使用相关的基础内容。 本…...

ESP通过乐为物联控制灯,微信发送数值,ESP上传传感器数据

暂时放个程序 //ME->>{“method”: “update”,“gatewayNo”: “01”,“userkey”: “2b64c489d5f94237bcf2e23151bb7d01”}&^! //Ser->>{“f”:“message”,“p1”:“ok”}&^! //ME->>{“method”: “upload”,“data”:[{“Name”:“A1C”,“Val…...

Linux:共享内存api使用

代码&#xff1a; #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <arpa/inet.h> #include <sys/un.h> #include <sys/ipc.h…...

android9.0 java静态库操作JNI实例 动态注册

一、java层 源码 目录&#xff1a;/Demo/java/com/android/simpleini/SimpleJNI.java package com.example.simplejni;import android.app.Activity; import android.os.Bundle; import android.widget.TextView;public class SimpleJNI {private IpoManagerService(Context …...

自定义复杂图片水印

我的社交能力还不如5岁儿童和狗。 文章目录前言一、主要工具类总结前言 之前写过一些简单的图片压缩和图片加水印&#xff1a;JAVA实现图片质量压缩和加水印 本次主要是针对图片加水印进行一个升级&#xff0c;图片水印自定义&#xff0c;自适应大小。 来&#xff0c;先看几…...

文章读后感——《人间清醒,内容为王》

观后感 人间清醒&#xff0c;内容为王 - 技术er究竟该如何写博客&#xff1f;1024上海嘉年华之敖丙演讲观后感。 致敬愿意带领后生的前辈——哈哥 哈哥&#xff0c;《人间清醒&#xff0c;内容为王》这篇&#xff0c;我的鱼获&#xff0c; 是里面传递出来写技术博客的思维与想法…...

51单片机入门 - 驱动多位数码管

我使用的是普中51单片机开发板A2套件&#xff08;2022&#xff09;&#xff0c;驱动数码管可能需要参考电路原理图。开发环境的搭建教程在本专栏的 51单片机开发环境搭建 - VS Code 从编写到烧录 有过介绍。 关于我的软硬件环境信息&#xff1a; Windows 10STC89C52RCSDCC &am…...

Java进击框架:Spring(一)

Java进击框架&#xff1a;Spring&#xff08;一&#xff09;前言创建Spring项目Spring IoC容器和Beans介绍Bean的概述Spring IoC配置元数据实例化Bean依赖注入循环依赖详细配置生命周期回调Bean定义继承基于注解的容器配置Component和进一步的原型注解自动检测类和注册Bean定义…...

Java笔记(18)

目录 什么是mvc? 什么是SpringMVC Spring MVC的特点: 原理: 什么是Thymeleaf? thymeleaf依赖包:...

【免费教程】地下水环境监测技术规范HJ/T164-2020解读使用教程

地下水环境监测技术规范依据《中华人民共和国环境保护法》第十一条“国务院环境保护行政主管部门建立监测制度、制订监测规范”和《中华人民共和国水污染防治法》的要求&#xff0c;积极开展地下水环境监测&#xff0c;掌握地下水环境质量&#xff0c;保护地下水水质&#xff0…...

Html 代码学习

场景:在页面中插入音频 代码 常见属性: src 音频的路径 controls 显示播放的控件 autoplay 自动播放 loop 循环播放 场景:在页面中插入视频 代码 常见属性: src 路径 controls 显示播放的控件 autoplay 自动播放 要配合muted 例如 autoplay muted loop 循环播放 链接 /…...

如何通过IP找到地址?

在我们印象中&#xff0c;我们都知道可以通过 IP 地址找到某个人。但当我们细想一下&#xff0c;我们会发现其实 IP 地址与地理位置并不是直接相关的。那我们到底是如何通过 IP 地址找到地址的呢&#xff1f;答案是&#xff1a;通过自治系统&#xff08;Autonomous System&…...

业务单据堆积如山?如何提升会计做账效率?

某集团以“创建现代能源体系、提高人民生活品质”为使命&#xff0c;形成了贯通下游分销、中游贸易储运、上游生产的清洁能源产业链和涵盖健康、文化、旅游、置业的生命健康产品链。目前&#xff0c;某集团在全国21个省&#xff0c;为超过2681万个家庭用户、21万家企业提供能源…...

华为OD机试题,用 Java 解【VLAN 资源池】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…...

面试加分项:JVM 锁优化和逃逸分析详解

1 锁优化JVM 在加锁的过程中&#xff0c;会采用自旋、自适应、锁消除、锁粗化等优化手段来提升代码执行效率。1.1 自旋锁和自适应自旋现在大多的处理器都是多核处理器 &#xff0c;如果在多核心处理器&#xff0c;有让两个或者以上的线程并行执行&#xff0c;我们可以让一个等待…...

C++继承、构造函数和析构函数

构造函数 与 析构函数 构造函数代表一个对象的生成&#xff0c;主要作用是初始化类的成员变量&#xff0c;可以被重载 如果没有显式构造函数&#xff0c;则实例化对象时&#xff0c;系统会自动生成一个无参的构造函数 构造函数的名称与类名相同 析构函数代表的是一个对象的销…...

Python如何实现异步并发之async(1)

前言 本文是该专栏的第14篇,后面会持续分享python的各种干货知识,值得关注。 在python中使用async方式,实现异步并发,而本文笔者提到的代码案例仅支持python3.7及以上版本,这主要在于不同的版本之间都更新了异步的使用方法,这点暂时不详述了。 而所谓的异步,通常就是程…...

震撼!阿里首次开源 Java 10万字题库,Github仅一天星标就超60K

程序员面试 现在是程序员找工作、跳槽最重要的月份。随着行业的发展程序员面试也越来越难&#xff0c;面试中都是7分的能力&#xff0c;再加上3分的技巧&#xff1b; 对于应聘者&#xff0c;重中之重的就是简历&#xff0c;面试前一定要将最拿手和最能吸引面试官的技能在简历…...

十三、RESTful API

RESTful API 什么是RESTful REST一词&#xff0c;是Roy Thomas Fielding在他2000年的博士论文中提出的。 Fielding是一个非常重要的人&#xff0c;他是HTTP协议&#xff08;1.0版和1.1版&#xff09;的主要设计者、Apache服务器软件的作者之一、Apache基金会的第一任主席。所…...

路由器防火墙配置(14)

实验目的 通过本实验&#xff0c;理解路由器的防火墙工作原理&#xff0c;掌握路由器的防火墙功能配置方法&#xff0c;主要包括网络地址转换功能和数据包过滤功能的配置。 培养根据具体环境与实际需求进行网络地址转换及数据包过滤的能力。 预备知识网络地址转换 网络地址转…...

灰狼算法优化VMD对时序信号分析python

VMD算法变分模态分解(VMD)算法是一种根据变分方程计算,将信号分析过程转换成求解变分方程的过程,具体分析过程可见前面写的另外一篇博客VMD,这里不多介绍。 VMD算法在进行信号分析时,将一段时序信号分解成不同频段的几个子信号,但其分解效果的好坏由其两个参数影响较大—…...

微服务架构中的多级缓存设计还有人不懂?

今天我们来聊聊缓存这个话题&#xff0c;看看在微服务环境下如何设计有效的多级缓存架构。主要涉及三方面内容&#xff1a; Web 应用的客户端缓存&#xff1b;应用层静态资源缓存&#xff1b;服务层多级缓存。 首先&#xff0c;咱们先讲解微服务架构的多级缓存设计。 微服务…...

【图神经网络 医学/药物/目标/分子/(结构/相互作用)预测】用于药物-目标相互作用预测的元集合(Metapath)异构图神经网络(MHGNN)

May the immensity of the universe, guide us to meet again. 我个人觉得这篇Paper很好。哈哈! 本次学习的Paper于2023年1月15日索引于 Web of Science,是比较新的。 作者:中国天津,南开大学计算机科学学院。 本篇Paper的研究方向(类别/分类):生物化学 & 分子生物学…...

《Java核心技术》笔记——第六章

文章目录CH6.接口、lambda表达式与内部类1.接口基本2.常用接口3.lambda表达式4.内部类5.服务加载器与代理前章&#xff1a; 第三章~第五章的学习笔记CH6.接口、lambda表达式与内部类 1.接口基本 接口基本——interface声明&#xff0c;方法无需指明public&#xff08;默认都是…...

假设检验的基本思想

假设检验 首先了解参数估计&#xff0c;比如有服从正态分布的数据集X∼N(μ,σ2)X\sim N(\mu,\sigma^{2})X∼N(μ,σ2)&#xff0c;我们希望根据样本x1,...xnx_{1},...x_{n}x1​,...xn​估计出参数μ,σ\mu,\sigmaμ,σ&#xff0c;这些参数可以是一个具体值&#xff0c;也可以…...

c语言机试练习

1.打印日期 给出年分m和一年中的第n天&#xff0c;算出第n天是几月几号。 输入描述&#xff1a; 输入包括两个整数y(1<y<3000)&#xff0c;n(1<n<366)。 输出描述&#xff1a; 可能有多组测试数据&#xff0c;对于每组数据&#xff0c; 按 yyyy-mm-dd的格式将输入中…...