OpenGL数据接口块

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zjz520yy/article/details/83662520

定义:OpenGL中接口块是用来对着色器中的变量进行统一管理。

声明:声明方式和C中的结构体的声明有点相像。声明伪代码如下:

限定符(可以为in,out,uniform或者buffer) 用户程序访问的块名称
{
	块中变量列表
}着色器代码中访问的块名称;

uniform接口块对象:当不同着色器中存在多个uniform变量时,管理和维护这些uniform变量会显得十分麻烦。另外当不同着色器中用到了同一个uniform变量时,对应的索引值是不一样的,这样导致用户程序设置这个uniform变量显得十分的麻烦。所以uniform接口块对象可以优化uniform变量访问,以及在不同的着色器间共享uniform数据。声明方式如下所示:

uniform UserBlockName
{
	float value;
    vec3 vector;
}ShaderBlockName;

uniform接口块布局:由于uniform接口块对象并不会保存具体类型的数据,所以我们还需要告诉OpenGL内存的哪一部分对应着接口块中的哪一个uniform变量。
常见的布局方式如下所示:

布局限制符 描述
binding = N 设置缓存的绑定位置,需要用到OpenGL API
shared 设置uniform块是多个程序间共享的,也是默认的布局方式
packed 设置uniform块占用最小的内存空间,但是这样会禁止程序间共享这个uniform块
std140 使用标准布局方式来设置uniform块或者buffer块
std430 使用标准布局方式来设置uniform块
offset = N 强制设置成员变量位于缓存的N字节偏移处
align= N 强制设置成员变量的偏移位置是N的倍数
row_major 使用行主序的方式来存储uniform块中的矩阵
column_major 使用列主序的方式来存储uniform块中的矩阵

std140布局规则如下所示:

类型 布局规则
标量,比如int和bool 每个标量的基准对齐量为N。
向量 2N或者4N。这意味着vec3的基准对齐量为4N。
标量或向量的数组 每个元素的基准对齐量与vec4的相同。
矩阵 储存为列向量的数组,每个向量的基准对齐量与vec4的相同。
结构体 等于所有元素根据规则计算后的大小,但会填充到vec4大小的倍数。

std140布局例子如下所示:

layout (std140) uniform UserBlockName
{
                     // 基准对齐量       // 对齐偏移量
    float value;     // 4               // 0 
    vec3 vector;     // 16              // 16  (必须是16的倍数,所以 4->16)
    mat4 matrix;     // 16              // 32  (列 0)
                     // 16              // 48  (列 1)
                     // 16              // 64  (列 2)
                     // 16              // 80  (列 3)
    float values[3]; // 16              // 96  (values[0])
                     // 16              // 112 (values[1])
                     // 16              // 128 (values[2])
    bool boolean;    // 4               // 144
    int integer;     // 4               // 148
}ShaderBlockName; 

uniform缓冲对象:就是使用glGenBuffers创建缓冲区对象,并使用glBindBuffer绑定到GL_UNIFORM_BUFFER上,然后通过glBufferData分配内存空间。创建代码如下所示:

unsigned int uboExampleBlock;
glGenBuffers(1, &uboExampleBlock);
glBindBuffer(GL_UNIFORM_BUFFER, uboExampleBlock);
glBufferData(GL_UNIFORM_BUFFER, 152, NULL, GL_STATIC_DRAW); // 分配152字节的内存
glBindBuffer(GL_UNIFORM_BUFFER, 0);

使用uniform缓冲:就是将uniform接口块对象和uniform缓冲区内存通过绑定点进行关联。当更新uniform缓冲区中的数据时,关联的uniform接口块对象数据也将同步的发生改变。
绑定关系如图所示:
在这里插入图片描述
具体使用流程如下:
1.绑定uniform接口块到绑定点上。
绑定代码如下所示:

// 使用相关接口进行分布操作来绑定
unsigned int lights_index = glGetUniformBlockIndex(shaderA.ID, "Lights");   
glUniformBlockBinding(shaderA.ID, lights_index, 2);

或者使用声明来单独绑定,如下所示:
layout(std140, binding = 2) uniform Lights { ... };

绑定接口如下所示:
GLuint glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName):获取uniform接口块索引。
.program代表着色器程序对象标志。
.uniformBlockName代表uniform接口块的名称。

void glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding):将指定uniform接口块绑定到一个特定的绑定点上。
.program代表着色器程序对象标志。
.uniformBlockIndex代表接口块索引值。
.uniformBlockBinding代表绑定点数值。

2.绑定uniform缓冲区内存到绑定点上。
绑定代码如下所示:

glBindBufferBase(GL_UNIFORM_BUFFER, 2, uboExampleBlock); 
// 或
glBindBufferRange(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152);

绑定接口如下所示:
void glBindBufferBase(GLenum target, GLuint index, GLuint buffer):将指定uniform缓冲区绑定到一个特定的绑定点上。
.target代表目标类型,这里应该使用GL_UNIFORM_BUFFER。
.index代表绑定点数值。
.buffer代表uniform缓冲区索引值。

void glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size):将指定uniform缓冲区中指定区间内存绑定到一个特定的绑定点中。
.target代表目标类型,这里应该使用GL_UNIFORM_BUFFER。
.index代表绑定点数值。
.buffer代表uniform缓冲区索引值。
.offset代表uniform缓冲区起始值。
.size代表需要绑定的内存大小。

3.更新uniform缓冲对象数据,进而更新uniform接口块中的uniform属性数据。
更新代码如下所示:

// 使用GL_UNIFORM_BUFFER缓冲区对象
glBindBuffer(GL_UNIFORM_BUFFER, uboExampleBlock);
// GLSL中的bool是4字节的,所以我们将它存为一个integer
int b = true; 
// 向GL_UNIFORM_BUFFER代表的uniform缓冲区对象中基准对齐量为4,偏移量为144处的成员赋值
glBufferSubData(GL_UNIFORM_BUFFER, 144, 4, &b); 
// 卸载GL_UNIFORM_BUFFER缓冲区对象
glBindBuffer(GL_UNIFORM_BUFFER, 0);

更新接口如下所示:
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data):将指定数据更新到指定缓冲区中指定位置处的内存上。
.target代表目标类型,这里应该使用GL_UNIFORM_BUFFER。
.offset代表缓冲区对象中的偏移位置。
.size代表要更新数据在缓冲区中占用的内存大小。
.data代表指定要更新的数据。

猜你喜欢

转载自blog.csdn.net/zjz520yy/article/details/83662520