OpenGL ES着色语言-UBO

    Uniform Buffer Objects(简称UBO)是OpenGL3.1引入的。UBO是显卡上的一块缓冲区,即GPU buffer。它允许将数据从客户端程序传送到GLSL程序中。

    使用UBO的最大好处是可以在各个shader之间共享数据。

    下面还是以OpenGL 4.0 shading language cookbook中的例子说明。

    在OpenGL的shader中,UBO是将分散的变量集中起来统一管理,有点类似于C/C++中的结构体,在Shader中叫做Uniform Block。

uniform BlobSettings {
  vec4 InnerColor;
  vec4 OuterColor;
  float RadiusInner;
  float RadiusOuter;
};

上面的的结构体用来存储一个环形的数据,InnerColor代表内环的颜色,OuterColor代表外环的颜色,RadiusInner代表内环的半径,RadiusOuter代表外环的半径,最终生成的图像是从内环到外环的过度颜色。


shader中定义了Uniform Block之后,客户端程序需要获得Uniform Block的相关信息以及生成UBO对象和Uniform Block


1、为UBO分配内存空间

	GLint blockSize;
	mProgram.GetActiveUniformBlockiv("BlobSettings",GL_UNIFORM_BLOCK_DATA_SIZE,&blockSize);
	GLubyte * blockBuffer;
	blockBuffer = (GLubyte *) malloc(blockSize);


2、查询每个Block相对于整个Block的偏移量

	const GLchar *names[] = { "InnerColor", "OuterColor",
		"RadiusInner", "RadiusOuter" };

	GLuint indices[4];
	mProgram.GetUniformIndices(4,names,indices);

	GLint offset[4];
	mProgram.GetActiveUniformsiv(4, indices, GL_UNIFORM_OFFSET, offset);

3、将数据存储到第一步生成的UBO缓冲区中

	GLfloat outerColor[] = {0.0f, 0.0f, 0.0f, 0.0f};
	GLfloat innerColor[] = {1.0f, 1.0f, 0.75f, 1.0f};
	GLfloat innerRadius = 0.25f, outerRadius = 0.45f;

	memcpy(blockBuffer + offset[0], innerColor, 4 * sizeof(GLfloat));
	memcpy(blockBuffer + offset[1], outerColor, 4 * sizeof(GLfloat));
	memcpy(blockBuffer + offset[2], &innerRadius, sizeof(GLfloat));
	memcpy(blockBuffer + offset[3], &outerRadius, sizeof(GLfloat));

4、生成UBO以及拷贝数据

	GLuint uboHandle;
	glGenBuffers( 1, &uboHandle );
	glBindBuffer( GL_UNIFORM_BUFFER, uboHandle );
	glBufferData( GL_UNIFORM_BUFFER, blockSize, blockBuffer, GL_DYNAMIC_DRAW );

5、绑定UBO和 Uniform Block

	GLuint blockIndex = mProgram.GetUniformBlockIndex("BlobSettings");
	glBindBufferBase( GL_UNIFORM_BUFFER, blockIndex, uboHandle );


上述就是整个UBO的使用过程,

GetActiveUniformBlockiv、

GetUniformIndices等函数就是GLSLProgram类的成员函数,只是OpenGL API的简单封装。





你可能感兴趣的:(OpenGL,OpenGL,ES着色语言)