OpenGL 4.6中glGetUniformLocation返回-1的问题求助
问题描述
我正在编写一个小型渲染引擎,现在要实现变换功能,但调用glGetUniformLocation时返回-1。以下是相关代码:
渲染方法代码
void GFXRenderer::submit(EntityBase* _entity, GPUProgram _program) { if(_entity->mesh.has_value()) { mat4 mod_mat(1.0); //mod_mat = translate(mod_mat, _entity->transform.position); /* mod_mat = scale(mod_mat, _entity->transform.scale); mod_mat = rotate(mod_mat, radians(_entity->transform.rotation.x), vec3(1.0, 0.0, 0.0)); mod_mat = rotate(mod_mat, radians(_entity->transform.rotation.y), vec3(0.0, 1.0, 0.0)); mod_mat = rotate(mod_mat, radians(_entity->transform.rotation.z), vec3(0.0, 0.0, 1.0)); */ mod_mat = translate(mod_mat, vec3(0.5f, -0.5f, 0.0f)); //mod_mat = glm::rotate(mod_mat, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f)); glUseProgram(_program.id); int transform = glGetUniformLocation(_program.vsh.id, "transform"); std::cout << transform << std::endl; glUniformMatrix4fv(transform, 1, GL_FALSE, value_ptr(mod_mat)); glUseProgram(_program.id); glBindTexture(GL_TEXTURE_2D, _entity->mesh->tex_id); glBindVertexArray(_entity->mesh->vao); glDrawElements(GL_TRIANGLES, _entity->mesh->indices.size(), GL_UNSIGNED_INT, 0); glUseProgram(0); glBindVertexArray(0); } }
Transform类定义
class Transform { public: vec3 position; vec3 rotation; vec3 scale; quat q_rot; mat4x4 matrix; };
可忽略四元数和matrix成员,另外说明:不做变换时渲染完全正常。
顶点着色器代码
#version 460 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec2 aTex; out vec2 tex_coord; out mat4 f_tr_opt; // for stopping optimization uniform mat4 transform; void main() { tex_coord = aTex; f_tr_opt = transform; gl_Position = transform * vec4(aPos, 1.0); }
片段着色器代码
#version 460 core in vec2 tex_coord; in mat4 f_tr_opt; // again, same thing out vec4 FragColor; uniform sampler2D texture0; void main() { mat4 garbage = f_tr_opt * f_tr_opt; // named garbage for easier recognition FragColor = texture(texture0, tex_coord); }
我检查过编译和链接错误,均无问题,请问我哪里出错了?
问题排查与解决
问题出在glGetUniformLocation的调用参数上:
glGetUniformLocation要求传入链接完成的完整程序对象ID,但你传入的是顶点着色器单独的ID(_program.vsh.id),这不符合API要求。- 正确做法是使用你调用
glUseProgram时用到的_program.id,也就是整个着色器程序的ID。
修改后的关键代码行:
int transform = glGetUniformLocation(_program.id, "transform");
另外,代码里重复调用了glUseProgram(_program.id),属于冗余操作,可以删除一次,优化后的代码片段:
glUseProgram(_program.id); int transform = glGetUniformLocation(_program.id, "transform"); std::cout << transform << std::endl; glUniformMatrix4fv(transform, 1, GL_FALSE, value_ptr(mod_mat)); // 移除重复的glUseProgram调用 glBindTexture(GL_TEXTURE_2D, _entity->mesh->tex_id); glBindVertexArray(_entity->mesh->vao); glDrawElements(GL_TRIANGLES, _entity->mesh->indices.size(), GL_UNSIGNED_INT, 0);
内容的提问来源于stack exchange,提问作者Moosa
相关产品推荐
相关产品推荐

