我正在按照David Wolff的一本书GLSL将数据发送到OpenGL中的统一块。
#ifdef LINUX
客户代码:
layout(std140) uniform BlobSettings {
vec4 InnerColor;
vec4 OuterColor;
float RadiusInner;
float RadiusOuter;
};
执行memcpy时程序出现分段错误。当我在那里设置断点时,我发现glGetActiveUniformsiv返回偏移量和索引错误。例如:
GLuint blockIndex = glGetUniformBlockIndex(programHandle, "BlobSettings");
// Allocate space for the buffer
GLint blockSize;
glGetActiveUniformBlockiv(programHandle, blockIndex,
GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
GLubyte* blockBuffer = (GLubyte *) malloc(blockSize);
// Query for the offsets of each block variable
const GLchar *names[] = { "BlobSettings.InnerColor", "BlobSettings.OuterColor",
"BlobSettings.RadiusInner", "BlobSettings.RadiusOuter" };
GLuint indices[4];
glGetUniformIndices(programHandle, 4, names, indices);
GLint offset[4];
glGetActiveUniformsiv(programHandle, 4, indices, GL_UNIFORM_OFFSET, offset);
// Store data within the buffer at the appropriate offsets
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));
虽然我期待它们是0,4,8,12等等或接近它的东西。如何解决此错误?
答案 0 :(得分:1)
我不得不想知道为什么在首先使用std140
时使用这种偏移机制?
我认为你的书没有提到std140
有非常具体的对齐规则,这意味着你可以在不查询它们的情况下找出所有这些成员的偏移量。这是一个重要的概念,如果跳过它根本不会帮助你。
遵循std140
规则,您已经拥有了正确对齐的数据结构。
layout(std140) uniform BlobSettings {
vec4 InnerColor; // 4N begins at 0
vec4 OuterColor; // 4N begins at 4 (divisible by 4 -- YES)
float RadiusInner; // 1N begins at 8 (divisible by 1 -- YES)
float RadiusOuter; // 1N begins at 9 (divisible by 1 -- YES)
};
此数据结构的偏移量为
0 (InnerColor),
16 (OuterColor), // 4x sizeof GLfloat (vec4)
32 (RadiusInner), // 8x sizeof GLfloat (vec4, vec4)
36 (RadiusOuter) // 8x sizeof GLfloat + sizeof GLfloat (vec4, vec4, float)
这里有一件事你需要记住,如果你要遵循std140
规则声明这个结构的数组,那么你需要在结尾添加一个额外的8个字节。正确对齐的结构。否则vec4 InnerColor
将在数组中的第一个元素之后的错误边界上开始(请参阅下面链接的文档中的规则10)。
这一点在OpenGL 4.5规范的7.6.2.2 Standard Uniform Block Layout中得到了更正式的讨论。