I'm currently passing an array of bone positions to GLSL for a skeletal animation shader; the positions are passing successfully but producing a GL_INVALID_OPERATION error.
I'm passing the matrices in the following line:
std::vector<glm::mat4x4> bpos;
...
glUniformMatrix4fv(shader.uniform("bpos"), 50, GL_FALSE, &bpos.at(0)[0][0]);
Where the shader.uniform("bpos")
position has been assigned earlier as:
this->m_uniforms["bpos"] = glGetUniformLocation(this->m_program, "uniform_bpos");
I'm getting the following output:
GL CALLBACK: ** GL ERROR ** type = 0x824c, severity = 0x9146, message = GL_INVALID_OPERATION in glUniform3(uniform "uniform_bpos"@1 is matrix)
Has anyone here encountered this error or does anyone here see what I'm doing incorrectly?
EDIT:
The vertex shader:
#version 330 core
layout(location = 0) in vec3 vert_ms;
layout(location = 1) in vec3 norm_ms;
layout(location = 2) in ivec4 bone_ids;
layout(location = 3) in vec4 bone_weights;
out vec3 norm_ws;
out vec3 pos_ws;
uniform mat4 uniform_mvp;
uniform mat4 uniform_bpos[50];
void main(){
mat4 bone = uniform_bpos[bone_ids[0]] * bone_weights[0];
bone += uniform_bpos[bone_ids[1]] * bone_weights[1];
bone += uniform_bpos[bone_ids[2]] * bone_weights[2];
bone += uniform_bpos[bone_ids[3]] * bone_weights[3];
gl_Position = uniform_mvp * bone * vec4(vert_ms, 1);
norm_ws = (uniform_mvp * bone * vec4 (norm_ms, 0)).xyz;
pos_ws = vec3(gl_Position);
}
the function getting the uniform locations:
Shader::Shader(GLuint shader_program)
{
this->m_program = shader_program;
this->m_uniforms["mvp"] = glGetUniformLocation(this->m_program, "uniform_mvp");
this->m_uniforms["bpos"] = glGetUniformLocation(this->m_program, "uniform_bpos");
this->m_uniforms["eye"] = glGetUniformLocation(this->m_program, "uniform_eye");
}
from this file: https://github.com/EricJIsaac/opengl-engine/blob/feature/pb-materials/src/graphics/shader.cpp
uploading the vertex data:
void SkeletonMeshBuffer::predraw()
{
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, this->m_vbo);
// Vertices
std::size_t stride = sizeof(graphics::data::SkeletonMesh_Vertex);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0);
// Normals
char* offset = (char*)0 + 3 * sizeof(float);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, stride, (void*)offset);
// Bone Ids
offset = (char*)0 + 6 * sizeof(float);
glVertexAttribIPointer(2, 4, GL_UNSIGNED_SHORT, stride, (void*)offset);
// Bone Weights
offset = (char*)0 + 6 * sizeof(float) + 4 * sizeof(unsigned short);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, stride, (void*)offset);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->m_ele);
}
void SkeletonMeshBuffer::draw(std::size_t id)
{
if(id < 0 || id > this->m_entries.size())
{
printf("Invalid skeleton mesh id %lu requested\n", id);
return;
}
char* offset = (char*)0 +
this->m_entries[id].index_offset * sizeof(unsigned short);
glDrawElementsBaseVertex(
GL_TRIANGLES,
this->m_entries[id].index_count,
GL_UNSIGNED_SHORT,
(void*)offset,
this->m_entries[id].vertex_offset / 3);
}
void SkeletonMeshBuffer::postdraw()
{
glDisableVertexAttribArray(0);
}
from this file: https://github.com/EricJIsaac/opengl-engine/blob/feature/pb-materials/src/graphics/skeleton_mesh_buffer.cpp
The meshes being loaded: https://github.com/EricJIsaac/opengl-engine/tree/master/data/geometry/skeletonMeshes
glUniform*
calls to upload to UBOs. $\endgroup$glUniform3
. $\endgroup$glUniform3
looks suspicious. Throw an exception from your callback function if an error occurs. This way you can use your debugger to activate a breakpoint and traverse the call stack to find out which API call actually causes the error. It might be another function and not the one you expected. $\endgroup$