我指的是OpenGL SuperBible。我使用他们的框架来创建自己的程序。我想对接口块(特别是统一块)做一些事情。如果我打电话
glGetActiveUniformsiv(program, 1, uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets);
我得到一个错误,即GL_INVALID_VALUE
。
但是,如果我用0而不是1调用同一函数,则不会发生该错误。当时我以为我没有活动制服。我应该有3个。
如何激活它们?这是我的着色器:
#version 450 core
layout (location = 0) in vec4 position;
layout (location = 1) in vec4 color;
out vec4 vs_color;
uniform TransformBlock {
mat4 translation;
mat4 rotation;
mat4 projection_matrix;
};
void main(void)
{
mat4 mvp = projection_matrix * translation * rotation ;
gl_Position = mvp * position;
vs_color = color;
}
在这里,我将通过“启动”方法为您提供一个基本的代码段:
/////////////////////////////////
vmath::mat4 transl_matrix = vmath::translate(0.0f, 0.0f, -3.0f);
vmath::mat4 rot_matrix = vmath::rotate( 30.0f, 0.0f, 0.5f, 1.0f);
vmath::mat4 proj_matrix = vmath::perspective(60.0f, (float)info.windowWidth / (float)info.windowHeight, 0.1f, 10.0f);
//////////////////
static const GLchar * uniformNames[3] = {
"TransformBlock.translation",
"TransformBlock.rotation",
"TransformBlock.projection_matrix",
};
GLuint uniformIndices[3];
glUseProgram(program);
glGetUniformIndices(program, 3, uniformNames, uniformIndices);
GLint uniformOffsets[3];
GLint matrixStrides[3];
glGetActiveUniformsiv(program, 3, uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets);
glGetActiveUniformsiv(program, 3, uniformIndices, GL_UNIFORM_MATRIX_STRIDE, matrixStrides);
unsigned char * buffer1 = (unsigned char*)malloc(4096);
//GLuint * buffer1 = (GLuint *) malloc(4096);
int j;
for (int i = 0; i < 4; ++i) {
GLuint offset = uniformOffsets[0] + matrixStrides[0] * i;
for (j = 0; j < 4; ++j) {
*((float *)(buffer1 + offset)) = transl_matrix[i][j];//
offset += sizeof(GLfloat);
}
}
for (int i = 0; i < 4; ++i) {
GLuint offset = uniformOffsets[1] + matrixStrides[1] * i;
for (j = 0; j < 4; ++j) {
*((float *)(buffer1 + offset)) = rot_matrix[i][j];
offset += sizeof(GLfloat);
}
}
for (int i = 0; i < 4; ++i) {
GLuint offset = uniformOffsets[2] + matrixStrides[2] * i;
for (j = 0; j < 4; ++j) {
*((float *)(buffer1 + offset)) = proj_matrix[i][j];
offset += sizeof(GLfloat);
}
}
GLuint block_index = glGetUniformBlockIndex(program, "TransformBlock");
glUniformBlockBinding(program, block_index, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, (GLuint)buffer1);
free(buffer1);
在此,我指的是上述《 SuperBible》的第5章(称为“数据”)。
但是,由于函数返回GL_INVALID_VALUE
,因此调用出现错误:
*((float *)(buffer1 + offset)) = ...
,整个程序中断。不添加offset
,我在这里没有收到错误,因此我认为第二个错误取决于第一个错误。
谢谢您的回答。
编辑:
我给您解决的任务现在可以正常工作。我已经更改了uniformNames
变量。我现在有没有TransformBlock
关键字的它们。但是,现在在我的render()函数中,使用glDrawArrays
时出现了另一个错误。我将在此处显示我的render()函数:
virtual void render(double currentTime) {
const GLfloat color[] = {(float)sin(currentTime)*0.5f + 0.5f, (float)cos(currentTime)*0.5f + 0.5f, 0.0f, 1.0f};
glClearBufferfv(GL_COLOR, 0, color);
glUseProgram(program);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
错误消息是这样的:
Access violation by reading at position 0x00000125.
那是因为不是所有其他东西都在工作,还是我必须调用其他绘图函数而不是glDrawArrays
吗?
答案 0 :(得分:1)
我认为glGetUniformIndices
出了问题,因为您在统一名称前加上了TransformBlock
。您也不会使用它来访问GLSL代码中带有该前缀的制服。如果需要,您必须为统一块设置实例名称,而块名称与访问/命名统一根本无关。如果将访问同一接口块的多个着色器链接在一起,则仅用于匹配接口。