OpenGL 无法在启用深度缓冲区的情况下进行 3D 绘制

OpenGL not drawing in 3D with depth buffers enabled

我花了 2 周的时间试图让 OpenGL 在 3D 中绘制立方体,但无论我做什么,它从未真正绘制出立方体。如果我使用 glEnable(DEPTH_TEST) 启用深度测试,它根本不会呈现任何内容。如果我注释掉该函数,它会渲染所有顶点,就好像 z 值都为 0。我完全被卡住了,不知道我做错了什么。

这是我的主文件:https://pastebin.com/D8cEcJ4g

#include "Dependencies\glew\glew.h"
#include "Dependencies\freeglut\freeglut.h"
#include "Dependencies\soil\SOIL.h"
 
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
 
#include <iostream>
 
#include "ShaderLoader.h";
#include "Camera.h"
 
#define BUTTON_UP   0
#define BUTTON_DOWN 1
 
GLuint program;
GLuint vao, vbo, ebo;
GLuint texture, texture2;
 
unsigned char keyState[255];
 
 
glm::vec3 vPosTrans = glm::vec3(-0.50f, -0.50f, 0.0f);//source
glm::vec3 vPosInit = vPosTrans;
glm::vec3 vPosDest = glm::vec3(0.50f, 0.50f, 0.0f);//destination
glm::vec3 vCurrentPos = vPosTrans;
 
bool Dest1or2 = true;
 
const GLfloat WIDTH = 800.0f, HEIGHT = 600.0f;
 
Camera* camera;
 
void init(){
    camera = new Camera(180.0f, WIDTH, HEIGHT, 0.0f, 100.0f);
 
    ShaderLoader shaderLoader;
    program = shaderLoader.CreateProgram("CoordSystem_Texture_QUAD.vs", "CoordSystem_Texture_QUAD.fs");
 
    glEnable(GL_DEPTH_TEST);
 
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 
    // Set up vertex data (and buffer(s)) and attribute pointers
    GLfloat vertices[] = {
 
        //position              //color                 //texture coord   //Normals
        -1.01f, -1.01f, -1.01f, 1.0f, 0.0f, 0.0f,       0.0f, 1.0f,
        -1.01f, 1.01f, -1.01f,      0.0f, 1.0f, -0.0f,      0.0f, 0.0f,
        1.01f, 1.01f, -1.01f,       1.0f, 0.0f, -0.0f,      1.0f, 0.0f,
        1.01f, -1.01f, -1.01f,      0.0f, 1.0f,  1.0f,      1.0f, 1.0f,
 
        // Fill in the back face vertex data.
        -1.01f, -1.01f, 1.01f,      0.0f, 1.0f, 1.0f,       1.0f, 1.0f,
        1.01f, -1.01f, 1.01f,       1.0f, 0.0f, 1.0f,       0.0f, 1.0f,
        1.01f, 1.01f, 1.01f,        1.0f, 0.0f, 1.0f,       0.0f, 0.0f,
        -1.01f, 1.01f, 1.01f,       1.0f, 1.0f, 0.0f,       1.0f, 0.0f,
 
        // Fill in the top face vertex data.
        -1.01f, 1.01f, -1.01f,      0.0f, 1.0f, 0.0f,       0.0f, 1.0f,
        -1.01f, 1.01f, 1.01f,       1.0f, 0.0f, 1.0f,       0.0f, 0.0f,
        1.01f, 1.01f, 1.01f,        0.0f, 1.0f, 1.0f,       1.0f, 0.0f,
        1.01f, 1.01f, -1.01f,       1.0f, 1.0f, 0.0f,       1.0f, 1.0f,
 
        // Fill in the bottom face vertex data.
        -1.01f, -1.01f, -1.01f, 1.0f,  1.0f, 0.0f,      1.0f, 1.0f,
        1.01f, -1.01f, -1.01f,      0.0f,  1.0f, 1.0f,      0.0f, 1.0f,
        1.01f, -1.01f, 1.01f,       0.0f,  1.0f, 0.0f,      0.0f, 0.0f,
        -1.01f, -1.01f, 1.01f,      1.0f,  1.0f, 0.0f,      1.0f, 0.0f,
 
        // Fill in the left face vertex data.
        -1.01f, -1.01f, 1.01f,       1.0f, 1.0f, 0.0f,      0.0f, 1.0f,
        -1.01f, 1.01f, 1.01f,        1.0f, 0.0f, 1.0f,      0.0f, 0.0f,
        -1.01f, 1.01f, -1.01f,       1.0f, 0.0f, 1.0f,      1.0f, 0.0f,
        -1.01f, -1.01f, -1.01f,  1.0f, 1.0f, 0.0f,      1.0f, 1.0f,
 
        // Fill in the right face vertex data.
        1.01f, -1.01f, -1.01f,      1.0f, 1.0f, 0.0f,       0.0f, 1.0f,
        1.01f, 1.01f, -1.01f,       0.0f, 1.0f, 1.0f,       0.0f, 0.0f,
        1.01f, 1.01f, 1.01f,        1.0f, 0.0f, 1.0f,       1.0f, 0.0f,
        1.01f, -1.01f, 1.01f,       0.0f, 1.0f, 1.0f,       1.0f, 1.0f,
    };
 
    GLuint indices[] = {
        // front
        0, 1, 2,
        0, 2, 3,
        // top
        4, 5, 6,
        4, 6, 7,
        // back
        8, 9, 10,
        8, 10, 11,
        // bottom
        12, 13, 14,
        12, 14, 15,
        // left
        16, 17, 18,
        16, 18, 19,
        // right
        20, 21, 22,
        20, 22, 23,
    };
 
    //** VAO **
    // Generate vertex arrow object
    glGenVertexArrays(1, &vao);
    // Bind the Vertex Array Object to openGl context
    glBindVertexArray(vao);//otherwise glVertexAttribPointer
 
    //** VBO **
    // Then bind and set vertex buffer(s).
    // First paramter is how many buffers we have to create
    glGenBuffers(1, &vbo);
 
    // bind VBO to binding point, here it is GL_ARRAY_BUFFER
    // there are other binding points
    glBindBuffer(GL_ARRAY_BUFFER, vbo);//bind to context
    glBufferData(GL_ARRAY_BUFFER,
        sizeof(vertices),// GPU need to know how much memory needs to be allocated
        vertices,//copy data to GPU
        GL_STATIC_DRAW);// How to use the buffer - buffer is created and modified once
 
    //** EBO **
    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
        sizeof(indices),
        indices,
        GL_STATIC_DRAW);
 
 
    // ** Attributes **
 
    //** Vertex Attribute **
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);
 
    //** Color Attribute **
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);
 
    //** TexCoord attribute **
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
    glEnableVertexAttribArray(2);
 
    // It's always a good thing to unbind any buffer/array to prevent strange bugs
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
 
    //** Load and bind texture 1 
    //--------------------------
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
 
 
    //** loadImage and create texture
    // Load image, create texture and generate mipmaps
    int width, height;
    unsigned char* image = SOIL_load_image("wall.jpg", &width, &height, 0, SOIL_LOAD_RGB);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
    glGenerateMipmap(GL_TEXTURE_2D);
    SOIL_free_image_data(image);
    glBindTexture(GL_TEXTURE_2D, 0);
 
 
    // ** Load and Bind Texture 2
    //---------------------------
    glGenTextures(1, &texture2);
    glBindTexture(GL_TEXTURE_2D, texture2);
 
 
    //** loadImage and create texture
    // Load image, create texture and generate mipmaps
    unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
    glGenerateMipmap(GL_TEXTURE_2D);
    SOIL_free_image_data(image2);
    glBindTexture(GL_TEXTURE_2D, 0);
 
 
    // Set texture wrapping to GL_REPEAT (usually basic wrapping method)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    // Set texture filtering parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
}
 
void render(){
 
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    // Draw our first triangle
    glUseProgram(program);
 
    //bind 
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glUniform1i(glGetUniformLocation(program, "Texture"), 0);
 
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texture2);
    glUniform1i(glGetUniformLocation(program, "Texture2"), 1);
 
    glBindVertexArray(vao);
 
    // Draw Elements intead of vertex array 
    glDrawArrays(GL_QUADS, 0, 24);
    //glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
 
    glutSwapBuffers();
}
 
void update(){
    GLfloat cameraSpeed = 0.05f;
    camera->setCameraSpeed(cameraSpeed);
 
    //currentTime uniform
    GLfloat currentTime = glutGet(GLUT_ELAPSED_TIME);
    currentTime = currentTime / 1000;
    GLint currentTimeLocation = glGetUniformLocation(program, "currentTime");
    glUniform1f(currentTimeLocation, currentTime);
 
    //transforms
    glm::mat4 transform = glm::mat4(1.0f);
    glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
 
    glm::mat4 model = glm::mat4(1.0);
 
    if (keyState[(unsigned char)'w'] == BUTTON_DOWN) {
        camera->moveForward();
        std::cout << "e";
    }
    if (keyState[(unsigned char)'s'] == BUTTON_DOWN) {
        camera->moveBack();
        std::cout << "A";
    }
 
    camera->Update();
 
    //glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
    glm::mat4 projection = camera->getProjectionMatrix();
 
    glm::mat4 view = glm::lookAt(camera->getCameraPos(), camera->getCameraPos() + camera->getCameraFront(), camera->getCameraUp());
 
    //glm::mat4 view = glm::lookAt(glm::vec3(1, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));
 
    GLfloat radius = 3.5f;
    GLfloat camX = sin(currentTime) * radius;
    GLfloat camZ = cos(currentTime) * radius;
 
    //glm::mat4 view = glm::lookAt(
    //     glm::vec3(camX, 0.0, camZ),
    //     glm::vec3(0.0, 0.0, 0.0),
    //     glm::vec3(0.0, 1.0, 0.0));
 
    transform = glm::scale(transform, vScaleVec);
    glm::vec3(0.65f, 0.65f, 0.65f);
    //transform = glm::rotate(transform, 90.0f, glm::vec3(0.0, 0.0, 1.0));
    if (vCurrentPos == vPosDest && Dest1or2 == true )
    {       
        Dest1or2 = false;
    }
    else if (vCurrentPos == vPosTrans && Dest1or2 == false)
    {
        Dest1or2 = true;
    }
    if(Dest1or2)
    vCurrentPos = glm::mix(vCurrentPos, vPosDest, currentTime * 0.01f);
    else 
    vCurrentPos = glm::mix(vCurrentPos, vPosTrans, currentTime*0.01f);
 
    //transform = glm::translate(transform, vCurrentPos);
    //transform = glm::translate(transform, glm::vec3(-0.51f, -0.51f, 0.0f));
    //transform = glm::rotate(transform, ((GLfloat)currentTime / 100) * 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
 
    // RTS
    GLuint transformLoc = glGetUniformLocation(program, "transform");
    glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
 
    GLint modelLoc = glGetUniformLocation(program, "model");
    GLint viewLoc = glGetUniformLocation(program, "view");
    GLint projLoc = glGetUniformLocation(program, "projection");
 
    // Pass them to the shaders
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(camera->getViewMatrix()));
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix()));
    //glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
    //glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
 
 
    glutPostRedisplay();
}
 
void keyboard(unsigned char key, int x, int y) {
    keyState[key] = BUTTON_DOWN;
 
    //printf("key pressed: %d \n", key);
}
 
void keyboard_up(unsigned char key, int x, int y) {
    keyState[key] = BUTTON_UP;
}
 
int main(int argc, char **argv){
 
    // init glut
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
 
    glutInitWindowPosition(300, 200);
    glutInitWindowSize(800, 600);
    glutCreateWindow("QUAD EBO");
 
    //init GLEW
    glewInit();
 
    init();
 
    //clear
    glClearColor(1.0, 0.0, 0.0, 1.0);//clear red
 
    // register callbacks
    glutDisplayFunc(render);
 
    glutKeyboardFunc(keyboard);
    glutKeyboardUpFunc(keyboard_up);
 
    glutIdleFunc(update);
 
    glutMainLoop();
 
    return 0;
}
 
 
RAW Paste Data
#include "Dependencies\glew\glew.h"
#include "Dependencies\freeglut\freeglut.h"
#include "Dependencies\soil\SOIL.h"

#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"

#include <iostream>

#include "ShaderLoader.h";
#include "Camera.h"

#define BUTTON_UP   0
#define BUTTON_DOWN 1

GLuint program;
GLuint vao, vbo, ebo;
GLuint texture, texture2;

unsigned char keyState[255];


glm::vec3 vPosTrans = glm::vec3(-0.50f, -0.50f, 0.0f);//source
glm::vec3 vPosInit = vPosTrans;
glm::vec3 vPosDest = glm::vec3(0.50f, 0.50f, 0.0f);//destination
glm::vec3 vCurrentPos = vPosTrans;

bool Dest1or2 = true;

const GLfloat WIDTH = 800.0f, HEIGHT = 600.0f;

Camera* camera;

void init(){
    camera = new Camera(180.0f, WIDTH, HEIGHT, 0.0f, 100.0f);

    ShaderLoader shaderLoader;
    program = shaderLoader.CreateProgram("CoordSystem_Texture_QUAD.vs", "CoordSystem_Texture_QUAD.fs");

    glEnable(GL_DEPTH_TEST);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    // Set up vertex data (and buffer(s)) and attribute pointers
    GLfloat vertices[] = {

        //position              //color                 //texture coord   //Normals
        -1.01f, -1.01f, -1.01f, 1.0f, 0.0f, 0.0f,       0.0f, 1.0f,
        -1.01f, 1.01f, -1.01f,      0.0f, 1.0f, -0.0f,      0.0f, 0.0f,
        1.01f, 1.01f, -1.01f,       1.0f, 0.0f, -0.0f,      1.0f, 0.0f,
        1.01f, -1.01f, -1.01f,      0.0f, 1.0f,  1.0f,      1.0f, 1.0f,

        // Fill in the back face vertex data.
        -1.01f, -1.01f, 1.01f,      0.0f, 1.0f, 1.0f,       1.0f, 1.0f,
        1.01f, -1.01f, 1.01f,       1.0f, 0.0f, 1.0f,       0.0f, 1.0f,
        1.01f, 1.01f, 1.01f,        1.0f, 0.0f, 1.0f,       0.0f, 0.0f,
        -1.01f, 1.01f, 1.01f,       1.0f, 1.0f, 0.0f,       1.0f, 0.0f,

        // Fill in the top face vertex data.
        -1.01f, 1.01f, -1.01f,      0.0f, 1.0f, 0.0f,       0.0f, 1.0f,
        -1.01f, 1.01f, 1.01f,       1.0f, 0.0f, 1.0f,       0.0f, 0.0f,
        1.01f, 1.01f, 1.01f,        0.0f, 1.0f, 1.0f,       1.0f, 0.0f,
        1.01f, 1.01f, -1.01f,       1.0f, 1.0f, 0.0f,       1.0f, 1.0f,

        // Fill in the bottom face vertex data.
        -1.01f, -1.01f, -1.01f, 1.0f,  1.0f, 0.0f,      1.0f, 1.0f,
        1.01f, -1.01f, -1.01f,      0.0f,  1.0f, 1.0f,      0.0f, 1.0f,
        1.01f, -1.01f, 1.01f,       0.0f,  1.0f, 0.0f,      0.0f, 0.0f,
        -1.01f, -1.01f, 1.01f,      1.0f,  1.0f, 0.0f,      1.0f, 0.0f,

        // Fill in the left face vertex data.
        -1.01f, -1.01f, 1.01f,       1.0f, 1.0f, 0.0f,      0.0f, 1.0f,
        -1.01f, 1.01f, 1.01f,        1.0f, 0.0f, 1.0f,      0.0f, 0.0f,
        -1.01f, 1.01f, -1.01f,       1.0f, 0.0f, 1.0f,      1.0f, 0.0f,
        -1.01f, -1.01f, -1.01f,  1.0f, 1.0f, 0.0f,      1.0f, 1.0f,

        // Fill in the right face vertex data.
        1.01f, -1.01f, -1.01f,      1.0f, 1.0f, 0.0f,       0.0f, 1.0f,
        1.01f, 1.01f, -1.01f,       0.0f, 1.0f, 1.0f,       0.0f, 0.0f,
        1.01f, 1.01f, 1.01f,        1.0f, 0.0f, 1.0f,       1.0f, 0.0f,
        1.01f, -1.01f, 1.01f,       0.0f, 1.0f, 1.0f,       1.0f, 1.0f,
    };

    GLuint indices[] = {
        // front
        0, 1, 2,
        0, 2, 3,
        // top
        4, 5, 6,
        4, 6, 7,
        // back
        8, 9, 10,
        8, 10, 11,
        // bottom
        12, 13, 14,
        12, 14, 15,
        // left
        16, 17, 18,
        16, 18, 19,
        // right
        20, 21, 22,
        20, 22, 23,
    };

    //** VAO **
    // Generate vertex arrow object
    glGenVertexArrays(1, &vao);
    // Bind the Vertex Array Object to openGl context
    glBindVertexArray(vao);//otherwise glVertexAttribPointer

    //** VBO **
    // Then bind and set vertex buffer(s).
    // First paramter is how many buffers we have to create
    glGenBuffers(1, &vbo);

    // bind VBO to binding point, here it is GL_ARRAY_BUFFER
    // there are other binding points
    glBindBuffer(GL_ARRAY_BUFFER, vbo);//bind to context
    glBufferData(GL_ARRAY_BUFFER,
        sizeof(vertices),// GPU need to know how much memory needs to be allocated
        vertices,//copy data to GPU
        GL_STATIC_DRAW);// How to use the buffer - buffer is created and modified once

    //** EBO **
    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
        sizeof(indices),
        indices,
        GL_STATIC_DRAW);


    // ** Attributes **

    //** Vertex Attribute **
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    //** Color Attribute **
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    //** TexCoord attribute **
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
    glEnableVertexAttribArray(2);

    // It's always a good thing to unbind any buffer/array to prevent strange bugs
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    //** Load and bind texture 1 
    //--------------------------
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);


    //** loadImage and create texture
    // Load image, create texture and generate mipmaps
    int width, height;
    unsigned char* image = SOIL_load_image("wall.jpg", &width, &height, 0, SOIL_LOAD_RGB);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
    glGenerateMipmap(GL_TEXTURE_2D);
    SOIL_free_image_data(image);
    glBindTexture(GL_TEXTURE_2D, 0);


    // ** Load and Bind Texture 2
    //---------------------------
    glGenTextures(1, &texture2);
    glBindTexture(GL_TEXTURE_2D, texture2);


    //** loadImage and create texture
    // Load image, create texture and generate mipmaps
    unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
    glGenerateMipmap(GL_TEXTURE_2D);
    SOIL_free_image_data(image2);
    glBindTexture(GL_TEXTURE_2D, 0);


    // Set texture wrapping to GL_REPEAT (usually basic wrapping method)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    // Set texture filtering parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

}

void render(){

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Draw our first triangle
    glUseProgram(program);

    //bind 
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glUniform1i(glGetUniformLocation(program, "Texture"), 0);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texture2);
    glUniform1i(glGetUniformLocation(program, "Texture2"), 1);

    glBindVertexArray(vao);

    // Draw Elements intead of vertex array 
    glDrawArrays(GL_QUADS, 0, 24);
    //glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

    glutSwapBuffers();
}

void update(){
    GLfloat cameraSpeed = 0.05f;
    camera->setCameraSpeed(cameraSpeed);

    //currentTime uniform
    GLfloat currentTime = glutGet(GLUT_ELAPSED_TIME);
    currentTime = currentTime / 1000;
    GLint currentTimeLocation = glGetUniformLocation(program, "currentTime");
    glUniform1f(currentTimeLocation, currentTime);

    //transforms
    glm::mat4 transform = glm::mat4(1.0f);
    glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);

    glm::mat4 model = glm::mat4(1.0);

    if (keyState[(unsigned char)'w'] == BUTTON_DOWN) {
        camera->moveForward();
        std::cout << "e";
    }
    if (keyState[(unsigned char)'s'] == BUTTON_DOWN) {
        camera->moveBack();
        std::cout << "A";
    }

    camera->Update();

    //glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
    glm::mat4 projection = camera->getProjectionMatrix();

    glm::mat4 view = glm::lookAt(camera->getCameraPos(), camera->getCameraPos() + camera->getCameraFront(), camera->getCameraUp());

    //glm::mat4 view = glm::lookAt(glm::vec3(1, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));

    GLfloat radius = 3.5f;
    GLfloat camX = sin(currentTime) * radius;
    GLfloat camZ = cos(currentTime) * radius;
     
    //glm::mat4 view = glm::lookAt(
    //     glm::vec3(camX, 0.0, camZ),
    //     glm::vec3(0.0, 0.0, 0.0),
    //     glm::vec3(0.0, 1.0, 0.0));

    transform = glm::scale(transform, vScaleVec);
    glm::vec3(0.65f, 0.65f, 0.65f);
    //transform = glm::rotate(transform, 90.0f, glm::vec3(0.0, 0.0, 1.0));
    if (vCurrentPos == vPosDest && Dest1or2 == true )
    {       
        Dest1or2 = false;
    }
    else if (vCurrentPos == vPosTrans && Dest1or2 == false)
    {
        Dest1or2 = true;
    }
    if(Dest1or2)
    vCurrentPos = glm::mix(vCurrentPos, vPosDest, currentTime * 0.01f);
    else 
    vCurrentPos = glm::mix(vCurrentPos, vPosTrans, currentTime*0.01f);
    
    //transform = glm::translate(transform, vCurrentPos);
    //transform = glm::translate(transform, glm::vec3(-0.51f, -0.51f, 0.0f));
    //transform = glm::rotate(transform, ((GLfloat)currentTime / 100) * 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));

    // RTS
    GLuint transformLoc = glGetUniformLocation(program, "transform");
    glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));

    GLint modelLoc = glGetUniformLocation(program, "model");
    GLint viewLoc = glGetUniformLocation(program, "view");
    GLint projLoc = glGetUniformLocation(program, "projection");

    // Pass them to the shaders
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(camera->getViewMatrix()));
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix()));
    //glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
    //glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));


    glutPostRedisplay();
}

void keyboard(unsigned char key, int x, int y) {
    keyState[key] = BUTTON_DOWN;

    //printf("key pressed: %d \n", key);
}

void keyboard_up(unsigned char key, int x, int y) {
    keyState[key] = BUTTON_UP;
}

int main(int argc, char **argv){

    // init glut
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

    glutInitWindowPosition(300, 200);
    glutInitWindowSize(800, 600);
    glutCreateWindow("QUAD EBO");

    //init GLEW
    glewInit();

    init();

    //clear
    glClearColor(1.0, 0.0, 0.0, 1.0);//clear red

    // register callbacks
    glutDisplayFunc(render);

    glutKeyboardFunc(keyboard);
    glutKeyboardUpFunc(keyboard_up);

    glutIdleFunc(update);

    glutMainLoop();

    return 0;
}

片段着色器:

#version 430 core

in vec3 outColor;
in vec2 TexCoord;

out vec4 color;

uniform sampler2D Texture;
uniform sampler2D Texture2;

uniform float currentTime;

void main()
{
    //vec3 colorTemp = outColor * abs(sin(currentTime));
    //color = vec4(colorTemp, 1.0f) ;
    //color = texture(ourTexture, TexCoord) * vec4(outColor, 1.0f) * abs(sin(currentTime))  ;
    
    color = mix(texture(Texture, TexCoord), texture(Texture2, TexCoord), 0.2) * vec4(outColor, 1.0f) * abs(sin(currentTime));
}

顶点着色器:

#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;

out vec3 outColor;
out vec2 TexCoord;
 
uniform mat4 transform;
 
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main(void)
{
    gl_Position = projection * view * model * transform * vec4(position, 1.0);
    outColor = color;
    TexCoord = vec2(texCoord.x, 1.0 - texCoord.y);
}

If I comment out that function, it renders all the vertices as if the z-values were all 0

嗯,那是因为......他们:

glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
[...]
transform = glm::scale(transform, vScaleVec);
[...]
gl_Position = projection * view * model * transform * vec4(position, 1.0);

您使用 z=0 进行缩放,这意味着您将所有顶点移动到 z = 0 平面中。所以在你的第一个转换步骤之后它已经是平坦的(这也意味着 transform 是一个奇异矩阵,第三行和第三列都是零)。您在代码中注释掉的额外变换步骤,以及着色器中应用的所有其他矩阵,不会改变其中任何一个,对象仍然是一个平面,无论您预先或 post-乘以它,他们只是移动那个平面。

我不知道你想要多少缩放,但按 0 缩放几乎不是一个好主意,1 是缩放操作的中性元素。

此外,为什么在着色器中将 modeltransform 作为单独的矩阵?在 3d 计算机图形学中,模型矩阵通常包含将对象从其自身的本地模型 space 映射到世界 space 所需的所有变换。即使您需要在内部跟踪转换的不同部分,在 gpu 上的实际渲染过程中通常不需要这些,并且应该在 CPU 上将所有这些相乘,然后将累积的转换作为model 矩阵到着色器。