主要講解知識點:
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