主要讲解知识点:
1.GL_ATOMIC_COUNTER_BUFFER 使用。
2.采用原子计数器记录片元中的红色通道分量大于绿色分量的个数。
效果验证图:
可以看到统计结果,并且得出当我们放大图片的时候,处理的片元数量是增大的,缩小的时候GPU处理的片元数量减少。
实现:
初始化原子缓存对象
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLuint *counters;
glGenBuffers(1, &_actomCounterBuf);
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, _actomCounterBuf);
glBufferData(GL_ATOMIC_COUNTER_BUFFER, 2 * sizeof(GLuint), NULL, GL_DYNAMIC_COPY);
counters = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY);
counters[0] = 0;
counters[1] = 1;
glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
//将原子缓存对象,与原子换成指定目标点进行绑定。
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _actomCounterBuf);
每次渲染完成后对统计结果进行回读(从GPU读取到CPU)
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, _actomCounterBuf);
GLuint * cont = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY);
char buffer[50];
sprintf(buffer, "red_texels: %d \n green_texels: %d\n", cont[0],cont[1]);
_m_simpleStats->SetString(buffer);
glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
原子计数器片元着色器的实现
//glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _actomCounterBuf);
//这里对应绑定点0 ,这里的偏移量指定的为字节偏移量大小
layout(binding = 0, offset = 0) uniform atomic_uint red_texels;
layout(binding = 0, offset = 4) uniform atomic_uint green_texels;
layout(binding = 0) uniform sampler2D my_texture;
#UNIFORMS
layout(location = 1) in block{
vec2 texCoord;
} In;
layout(location = 0) out vec4 fragment_color;
void main(void)
{
vec4 texel_color = texture(my_texture, In.texCoord);
if (texel_color.r > texel_color.g)
{
//采用高效的原子计数,目的是防止不同的片源在同一个时刻访问或修改同一块显存位置。
atomicCounterIncrement(red_texels);
}
else
{
atomicCounterIncrement(green_texels);
}
fragment_color = texel_color;
}
总结:
我们可以利用原子计数器做一些片源统计方面的工作。或是其它一些用途。
完整源码文件下载:
https://t.zsxq.com/qrvJiYB