nbu*_*bis 8 c++ opengl fragment-shader
现在我正在尝试将一个int数组传递给片段着色器,并通过统一数组执行此操作:
uniform int myArray[300];
Run Code Online (Sandbox Code Playgroud)
并在着色器外面填充它glUniform1iv.
不幸的是,大于~400失败的统一阵列.我知道我可以使用"统一缓冲区",但似乎无法找到将大型1D数组传递到带缓冲区或其他方式的片段着色器的完整示例.
谁能提供这样的例子?
这应该让您开始使用Uniform Buffer Object来存储数组.请注意,GL要求UBO的最小容量为16 KiB,可以查询最大容量GL_MAX_UNIFORM_BLOCK_SIZE.
#version 140 // GL 3.1
// Arrays in a UBO must use a constant expression for their size.
const int MY_ARRAY_SIZE = 512;
// The name of the block is used for finding the index location only
layout (std140) uniform myArrayBlock {
int myArray [MY_ARRAY_SIZE]; // This is the important name (in the shader).
};
void main (void) {
gl_FragColor = vec4 ((float)myArray [0] * 0.1, vec3 (1.0));
}
Run Code Online (Sandbox Code Playgroud)
const int MY_ARRAY_SIZE = 512;
GLuint myArrayUBO;
glGenBuffers (1, &myArrayUBO);
// Allocate storage for the UBO
glBindBuffer (GL_UNIFORM_BUFFER, myArrayUBO);
glBufferData (GL_UNIFORM_BUFFER, sizeof (GLint) * MY_ARRAY_SIZE,
NULL, GL_DYNAMIC_DRAW);
[...]
// When you want to update the data in your UBO, you do it like you would any
// other buffer object.
glBufferSubData (GL_UNIFORM_BUFFER, ...);
[...]
GLuint myArrayBlockIdx = glGetUniformBlockIndex (GLSLProgramID, "myArrayBlock");
glUniformBlockBinding (GLSLProgramID, myArrayBlockIdx, 0);
glBindBufferBase (GL_UNIFORM_BUFFER, 0, myArrayUBO);
Run Code Online (Sandbox Code Playgroud)
我可能忘了什么,有一个原因我不写教程.如果您在执行此操作时遇到任何问题,请发表评论.
注意0中使用glUniformBlockBinding (...),并glBindBufferBase (...)为绑定点全局标识符.当与std140布局结合使用时,这意味着您可以在任何GLSL程序中使用此UBO,在该程序中将其统一块之一绑定到该绑定位置(0).当你想在几十个不同的GLSL程序之间共享类似你的ModelView和Projection矩阵时,这实际上非常方便.