简体   繁体   English

如何在OpenGL中使用GLM?

[英]How to use GLM with OpenGL?

I am trying to render an object using GLM for matrix transformations, but I'm getting this: 我正在尝试使用GLM渲染对象以进行矩阵转换,但是我得到了这一点:

White rectangle is rendered instead of the object

EDIT: Forgot to mention that the object I'm trying to render is a simple Torus. 编辑:忘记提及我要渲染的对象是一个简单的Torus。

I did a lot of digging around and one thing I noticed is glGetUniformLocation(program, "mvp") returns -1 . 我做了很多研究,发现一件事是glGetUniformLocation(program, "mvp")返回-1 The docs says it will return -1 if the uniform variable isn't used in the shader, even if it is declared. 文档说如果着色器中没有使用统一变量,即使声明了它,它将返回-1 As you can see below, it has been declared and is being used in the vertex shader. 如下所示,它已被声明并在顶点着色器中使用。 I've checked against program to make sure it is valid, and such. 我检查了program以确保它是有效的,等等。

So my questions are: 所以我的问题是:

Question 1: 问题1:

Why is glGetUniformLocation(program, "mvp") returning -1 even though it is declared and is being used in the vertex shader? 为什么glGetUniformLocation(program, "mvp")返回-1即使它已被声明并在顶点着色器中使用?

Question 2: (Which I think may be related to Q1) 问题2 :(我认为可能与第一季度有关)

Another thing I'm not particularly clear on. 我还不太清楚的另一件事。 My GameObject class has a struct called Mesh with variables GLuint vao and GLuint[4] vbo (Vertex Array Object) and (Vertex Buffer Object). 我的GameObject类具有一个名为Mesh的结构,具有变量GLuint vaoGLuint[4] vbo (顶点数组对象)和(顶点缓冲区对象)。 I am using Assimp, and my GameObject class is based on this tutorial . 我正在使用Assimp,而我的GameObject类基于本教程 The meshes are rendered in the same way as the tutorial, using: 使用与教程相同的方式渲染网格。

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

I'm not sure how VAO's and VBO's work. 我不确定VAO和VBO的工作方式。 What I've found is that VAO's are used if you want access to the vertex arrays throughout your program, and VBO's are used if you just want to send it to the graphics card and not touch it again (Correct me if I'm wrong here). 我发现,如果要在整个程序中访问顶点数组,则使用VAO;如果只想将其发送到图形卡,而不要再次触摸它,则使用VBO(如果我错了,请纠正我)这里)。 So why does the tutorial mix them? 那么,为什么本教程将它们混合在一起呢? In the constructor for a mesh, it creates and binds a VAO then doesn't touch it for the rest of the constructor (unless creating and binding VBO's have an effect on the currently bound VAO). 在网格的构造函数中,它创建并绑定VAO,然后在其余构造函数中不使用它(除非创建和绑定VBO对当前绑定的VAO产生影响)。 It then goes on and creates and binds VBO's for the vertex buffer, normal buffer, texture coordinate buffer, and index buffer. 然后,它继续为顶点缓冲区,法线缓冲区,纹理坐标缓冲区和索引缓冲区创建并绑定VBO。 To render the object it binds the VAO and calls glDrawElements . 为了渲染对象,它绑定了VAO并调用glDrawElements What I'm confused about is how/where does OpenGL access the VBO's, and if it can't with the setup in the tutorial, which I'm pretty sure it can, what needs to change? 我感到困惑的是OpenGL如何/在何处访问VBO,如果不能通过本教程中的设置进行访问(我很确​​定可以),则需要更改什么?

Source 资源

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
    }
}

Vertex shader (simple unlit red color): 顶点着色器(简单的未点亮红色):

#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);
}

Fragment shader: 片段着色器:

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

void main(void) {
    color = vertColor;
}

Question 1 问题1

You've pretty much answered this one yourself. 您已经亲自回答了这个问题。 glGetUniformLocation(program, name) gets the location of the uniform "mvp" in the shader program program and returns -1 if the uniform is not declared (or not used: if you don't use it, it doesn't get compiled in). glGetUniformLocation(program, name)获取着色器程序program中的统一"mvp"的位置,如果未声明(或不使用)统一,则返回-1:如果不使用它,则不会对其进行编译)。 Your shader does declare and use mvp, which strongly suggests there is an issue with compiling the program. 您的着色器确实声明并使用了mvp,这强烈表明编译程序存在问题。 Are you sure you are using this shader in the program? 确定在程序中使用此着色器吗?

Question 2 问题2

A VBO stores the data values that the GPU will use. VBO存储GPU将使用的数据值。 These could be colour values, normals, texture coordinates, whatever you like. 这些可以是颜色值,法线,纹理坐标,无论您喜欢什么。 A VAO is used to express the layout of your VBOs - think of it like a map, indicating to your program where to find the data in the VBOs. VAO用于表示VBO的布局-将其视为地图,向您的程序指示在VBO中可以找到数据的位置。

The example program does touch the VAO whenever it calls glVertexAttribPointer , eg 该示例程序在调用glVertexAttribPointer时确实会触摸VAO,例如

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

This is not related to your missing uniform. 这与您丢失的制服无关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM