Сейчас я пытаюсь передать массив int в фрагментный шейдер и делаю это через единый массив:
uniform int myArray[300];
И заполняя его вне шейдера glUniform1iv
,
К сожалению, однородные массивы больше, чем ~400
потерпеть поражение. Я понимаю, что вместо этого могу использовать «единый буфер», но не могу найти полного примера передачи большого 1D-массива в фрагментный шейдер с буферами или другим способом.
Кто-нибудь может привести такой пример?
Это должно помочь вам начать использовать объект Uniform Buffer для хранения массива. Обратите внимание, что GL требует, чтобы UBO имели минимальную емкость 16 КиБ, максимальная емкость может быть запрошена через 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));
}
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);
Я, наверное, что-то забыл, есть причина, по которой я не пишу учебники. Если у вас возникли проблемы с реализацией этого, оставьте комментарий.
Обратите внимание, что 0 используется в glUniformBlockBinding (...)
а также glBindBufferBase (...)
является глобальным идентификатором для точки привязки. При использовании в сочетании с std140
компоновка, это означает, что вы можете использовать этот UBO в любой программе GLSL, где вы привязываете один из его унифицированных блоков к этому месту привязки (0). Это на самом деле очень удобно, когда вы хотите поделиться чем-то вроде ваших таблиц ModelView и Projection между десятками различных программ GLSL.
Других решений пока нет …