之前提到过OGL中纹理缓存是作为输入缓存存在的,这使得输入缓存能够读取但是不能够改写。为了突破这一限制,在OGL中提出了Image的概念,这使得程序员能够有效的操作texture缓存——对背后的texture缓存进行读写操作。但是,这样的操作打破了原有的pipeline流水线,使得原本应该被OGL自身进行管理的缓存需要程序员自身来进行处理,因此提供了方便的同时也增加了程序员的编程负担。
为了对texture缓存进行写操作,需要将对应的纹理数据给绑定到相应的image uint中,需要注意的是image uint和texture uint是两个不同的区域,因此两者的ID号码计数是分离开的。由于image图像是和texture纹理绑定的,因此image的类型和texture的图像类型类似,其次每一个image里都有一个对应的存储类型,这个存储类型和image在内存中的分割以及图像像素的格式是相关的。
为了加载image中的数据,需要利用imageLoad内置函数,该函数需要两个参数,对应的输入图像以及相应的坐标信息,该函数会读取对应坐标处的图像的像素值。反过来,imageStore函数则会将相应的数据存入到对应的图像的对应的坐标位置处。下面是一个利用image进行存储和读取的实例。
首先创建两个纹理缓存,其中image_palette_buffer作为背后的缓存提供存储支持,该函数会分配相应的内存,但是并不进行数据的初始化,同时也不会将这个纹理缓存绑定到对应的texture uint中,真正被绑定到OGL管理的纹理缓存的数据是image_palette_texture。
glGenBuffers(1, &image_palette_buffer);//创建调色板缓存(提供内存)
glBindBuffer(GL_TEXTURE_BUFFER, image_palette_buffer);
glBufferData(GL_TEXTURE_BUFFER, 256 * 4 * sizeof(float), NULL, GL_STATIC_DRAW);
glGenTextures(1, &image_palette_texture);//创建调色板纹理,用于和片元着色器交互
glBindTexture(GL_TEXTURE_BUFFER, image_palette_texture);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, image_palette_buffer);
vmath::vec4 * data = (vmath::vec4 *)glMapBuffer(GL_TEXTURE_BUFFER, GL_WRITE_ONLY);
for (int i = 0; i < 256; i++)
{
data[i] = vmath::vec4((float)i);
}
glUnmapBuffer(GL_TEXTURE_BUFFER);
首先调用纹理激活函数切换纹理缓存,同时创建新的纹理对象output_texture,这个对象作为输出图像来接收输出的数据。同时设置对应的纹理参数,紧接着将其绑定到第0号图像单元上。注意这里的第0号图像单元和第0号纹理单元不是同一个对象。glBindImageTexture函数的第一个参数用于指定image单元的索引号,第二个参数用于指定纹理的