如何在openGL中显示2个或更多对象(模型 - 视图 - 投影矩阵和着色器)

Ian*_*ess 6 opengl shader glsl

当我想绘制一个对象时,一切都好,例如一个立方体.我为立方体创建顶点,我创建缓冲区,我创建MVP矩阵并将其发送到着色器,它工作得很好.

但是,当我想要绘制2个或更多个对象时,该怎么办,例如立方体和三角形?我认为三角形和立方体的视图和投影矩阵应该相同,我只需要不同的模型矩阵,对吧?这意味着我将有两个MVP?

//Example (using GLM):

glm::mat4 MVPC = Projection * View * ModelCube; 
glm::mat4 MVPT = Projection * View * ModelTriangle; 
Run Code Online (Sandbox Code Playgroud)

那我现在怎么办这两个呢?这是适用于立方体的顶点着色器

//vertex shader
#version 330 core

layout(location = 0) in vec3 verticesCube;

uniform mat4 MVPC;

void main(){

     gl_Position =  MVPC * vec4(verticesCube,1);

}
Run Code Online (Sandbox Code Playgroud)

我应该如何处理着色器中的MVPT(三角形),我尝试搞乱不同的东西,但我无法让它工作,我无法同时显示立方体和三角形.

cod*_*p3r 7

混淆来自于认为着色器一次控制多个顶点数组,它应该被认为是一个通用实体.将顶点数组传递给着色器,然后绘制对象.然后重复这个过程.

例如,假设我们将变量matrixID分配给统一的MVP:

    // get handle for our "MVP" uniform
    GLuint matrixID = glGetUniformLocation(programID, "MVP");
Run Code Online (Sandbox Code Playgroud)

当我们准备绘制对象时,我们将matrixID设置为对象的MVP:

    glUniformMatrix4fv(matrixID, 1, GL_FALSE, &cubeMVP[0][0]);
Run Code Online (Sandbox Code Playgroud)

然后绑定顶点缓冲区,设置属性指针,并绘制它:

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, cubeVerteciesBuffer);

    glVertexAttribPointer(
            0,      // shader layout location
            3,
            GL_FLOAT,
            GL_FALSE,
            0,
            (void *)0
    );
    glDrawArrays(GL_TRIANGLES, 0, 12*3);    // draw cube
Run Code Online (Sandbox Code Playgroud)

现在我们继续三角形并重复该过程 - 将matrixID设置为对象的MVP,绑定顶点缓冲区,设置属性指针并绘制它:

    glUniformMatrix4fv(matrixID, 1, GL_FALSE, &triMVP[0][0]);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, triangleVerteciesBuffer);

    glVertexAttribPointer(
            0,      // shader layout location
            3,
            GL_FLOAT,
            GL_FALSE,
            0,
            (void *)0
    );
    glDrawArrays(GL_TRIANGLES, 0, 3);   // draw triangle
Run Code Online (Sandbox Code Playgroud)

相应的顶点着色器代码:

#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertecies_modelspace;

uniform mat4 MVP;

void main(){
    gl_Position = MVP * vec4(vertecies_modelspace, 1);
}
Run Code Online (Sandbox Code Playgroud)


dat*_*olf 6

OpenGL 不是场景图。它根据当前状态绘制事物,然后忘记它。

因此,如果您想使用不同的变换绘制不同的几何图形,只需设置相应的变换矩阵(统一),绘制对象并对每个要绘制的对象重复此操作。绘制几何图形后,除了可能会透支之外,后续操作不会对其产生进一步影响。