如何在OpenGL中使用GLM?

时间:2015-01-28 09:34:00

标签: c++ opengl glfw glew glm-math

我正在尝试使用GLM渲染一个对象进行矩阵变换,但我得到了这个:

White rectangle is rendered instead of the object

编辑:忘记提及我试图呈现的对象是一个简单的圆环。

我做了很多挖掘,我发现有一件事是glGetUniformLocation(program, "mvp")返回-1。如果统一变量未在着色器中使用,即使声明了变量,文档也会返回-1。如下所示,它已被声明并正在顶点着色器中使用。我已经对program进行了检查,以确保其有效,等等。

所以我的问题是:

问题1:

为什么glGetUniformLocation(program, "mvp")返回-1,即使它已被声明并且正在顶点着色器中使用?

问题2 :(我认为可能与Q1有关)

另一件我不太清楚的事情。我的GameObject类有一个名为Mesh的结构,包含变量GLuint vaoGLuint[4] vbo(顶点数组对象)和(顶点缓冲区对象)。我正在使用Assimp,我的GameObject类基于this tutorial。使用以下命令以与教程相同的方式呈现网格:

glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, NULL);

我不确定VAO和VBO是如何工作的。我发现如果您希望在整个程序中访问顶点阵列,则使用VAO,如果您只是想将其发送到显卡而不是触摸,则使用VBO它再次(纠正我,如果我在这里错了)。那么为什么教程会混合它们呢?在网格的构造函数中,它创建并绑定VAO,然后不为构造函数的其余部分触摸它(除非创建和绑定VBO对当前绑定的VAO有影响)。然后继续为顶点缓冲区,普通缓冲区,纹理坐标缓冲区和索引缓冲区创建和绑定VBO。要渲染对象,它会绑定VAO并调用glDrawElements。我感到困惑的是OpenGL如何/在何处访问VBO,如果它不能用于教程中的设置,我很确定它可以,需要什么改变?

来源

void GameObject::render() {
    GLuint program = material->shader->program;
    glUseProgram(program);
    glm::mat4 mvp = Game::camera->mvpMatrix(this->position);

    GLuint mvpLoc = glGetUniformLocation(program, "mvp");
    printf("MVP Location: %d\n", mvpLoc); // prints -1
    glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, &mvp[0][0]);
    for (unsigned int i = 0; i < meshes.size(); i++) {
        meshes.at(i)->render(); // renders element array for each mesh in the GameObject
    }
}

顶点着色器(简单的未点亮红色):

#version 330 core
layout(location = 0) in vec3 position;
uniform mat4 mvp;

out vec3 vertColor;

void main(void) {
    gl_Position = mvp * vec4(position, 1);
    vertColor = vec3(1, 0, 0);
}

片段着色器:

#version 330 core
in vec3 vertColor;
out vec3 color;

void main(void) {
    color = vertColor;
}

1 个答案:

答案 0 :(得分:1)

问题1

你自己几乎已经回答了这个问题。 glGetUniformLocation(program, name)获取着色程序"mvp"中统一program的位置,如果未宣布制服(或未使用,则返回-1):如果您不使用它,它没有被编译)。您的着色器确实声明并使用mvp,这强烈表明编译程序存在问题。你确定你在程序中使用这个着色器吗?

问题2

VBO存储GPU将使用的数据值。这些可以是颜色值,法线,纹理坐标,无论你喜欢什么。 VAO用于表达您的VBO的布局 - 将其视为地图,向您的程序指示在哪里可以找到VBO中的数据。

示例程序在调用glVertexAttribPointer时会触摸VAO,例如

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

这与你失踪的制服无关。