1.Uniform buffer object(ubo)是一种buffer object,所以也可以支持dma方式的数据传输,从而可以提高cpu端执行命令的效率
2.Uniform buffer object扩展提供了一种机制,一次可以绑定多个uniform param到program,并且可以在多个program或者shader stage之间共享数据3.Uniform buffer object不是像uniform param一样直接绑定到program,而是类似传统纹理单元管理纹理的方式一样,先将ubo绑定到所谓的binding point,然后program指定某个uniform block使用某个binding point
4.在shader源码中可以定义一个uniform block,方式类似struct定义,实例如下
layout([packed, shared(default),std140,std430]) uniform
{
[uniform] mat4 WorldMatrix;
[uniform] mat4 ViewMatrix;
};
也可以给一个uniform block增加一个名字,相当于定义了一个struct作为一个uniform block
5.packed适用于不在多个program或者shader stage之间共享数据的情况,编译器会把用不到的uniform param去掉,把数据尽量对齐,去掉空隙,从而提高内存利用率
6.shared方式适用于在多个program或者shader stage之间共享数据的情况,编译器不会去掉无用的uniform param,从而保证在所有program中使用的内存布局完全一致
7.std140和std430使用预先定义的对齐和排列方式,从而可以在C语言端定义一个struct对应uniform block
8.ubo使用GL_UNIFORM_BUFFER绑定点,所有的创建和更新操作与vbo完全一样
9.一个ubo可以包含多个uniform block的数据,但是每个uniform block必须对齐到GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,这个值可能很大,比如256、512。没有对齐到GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT的uniform block无法绑定到binding point
10.ubo提供了glBindBufferRange函数将ubo的一部分绑定到某个binding point,对应一个uniform block,要注意9条中说明的对齐问题
11.对于不是std140和std430布局的uniform block,只能从program中获得布局,大致是一下流程:
1.使用glGetProgramiv,GL_ACTIVE_UNIFORM_BLOCKS获得uniform block数量;
2.使用glGetProgramiv,GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH获得uniform block名称长度
3.依次处理索引为[0, GL_ACTIVE_UNIFORM_BLOCKS)的uniform block
4.使用glGetActiveUniformBlockName获得名称
5.使用glGetActiveUniformBlockiv,GL_UNIFORM_BLOCK_DATA_SIZE获得uniform block的大小
6.使用glGetActiveUniformBlockiv,GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS获得uniform block中的uniform数量
7.使用glGetActiveUniformBlockiv,GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES,获取一个uniform block中的所有uniform在program中的索引,uniform的其他属性都需要用这个索引获取
8.使用glGetActiveUniformName获得uniform名称
9.使用glGetActiveUniformsiv,GL_UNIFORM_OFFSET获得全部uniform偏移
10.使用glGetActiveUniformsiv,GL_UNIFORM_SIZE获得全部uniform的元素数量,不是数组类型的应当是1
11.使用glGetActiveUniformsiv,GL_UNIFORM_TYPE获得全部uniform类型
12.应该还需要获得元素数组类型uniform对齐方式
12.切记,binding point是针对整个context的,而不是针对program的。