OpenGL超级宝典(第7版)笔记22 原子计数器 清单5.31-5.34

这篇博客介绍了OpenGL原子计数器的使用,包括声明、初始化和计数操作。通过示例展示了如何利用原子计数器计算绘制像素的数量,以及如何根据计数结果改变图案的明暗。同时讨论了同步访问原子计数器时可能遇到的问题和解决方案,并强调了同步屏障的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenGL超级宝典(第7版)笔记22 原子计数器 清单5.31-5.34


前言

上一篇我们介绍了着色器存储区块的相关内容(包括了和uniform块的对比),还介绍了原子内存操作和屏障的实用问题。这一篇我们将介绍原子计数器,我们将通过它来进行计数,并通过它计算图形的面积。

1 原子计数器初介绍

原子计数器是一种特殊的变量,表示的是多个着色器之间共享的存储(即大家都可以对该变量进行修改),而且我们可以调用特定的函数进行原子内存操作。变量本身的功能是用于计数。

1.1 原子计数器的声明

layout (binding=2,offset=8) uniform atomic_uint mycounter;

这里声明了原子计数器mycounter,并绑定在2上,其中起始位置是8。

1.2 原子计数器准备缓冲

首先为原子计数器变量准备一些内存,以便其使用:

GLuint Atomic_counter_buffer;
	glCreateBuffers(1, &Atomic_counter_buffer);
	glNamedBufferStorage(Atomic_counter_buffer, 16*sizeof(GLuint), NULL, GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT );
	glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER,2,Atomic_counter_buffer);

我们要将缓冲中清零:

	GLuint atomic_counter_data=0;
	glClearNamedBufferSubData(Atomic_counter_buffer,GL_R32UI,2*sizeof(GLuint),sizeof(GLuint),GL_RED_INTEGER,GL_UNSIGNED_INT,&atomic_counter_data);

当然你可以才用书上的其他方法也可以把它清零(使用glNamedBufferSubData或是使用glMapBufferRange的指针来进行清零也可以)

1.3 使用原子计数器计数

我们现在在着色器中已经声明了原子计数器,并且在我们的程序中为该原子计数器安排了内存并做了初始化,现在我们要在着色器内部用原子计数器进行计数。OpenGL提供了三种用于计数的着色器函数:

uint atomicCounterIncrement(atomic_uint a);//让计数器加一
uint atomicCounterDecrement(atomic_uint a);//让计数器减一
uint atomicCounter(atomic_uint a);//返回计数器的值

我们现在改写一下片段着色器:

#version 450 core         
layout (binding=2,offset=8) uniform atomic_uint mycounter;
in vec4 fscolor;
out vec4 color;
void main(void){
   
   
	atomicCounterIncrement(mycounter);
	color = fscolor;
}

我们的想法是在每次运行片段着色器的时候都对计数器进行加一,这样我们在运算完一帧画面后计数器的数字就是所绘制的像素数,如果我们绘制的图像充满了整个窗口,那么计数

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值