OpenGL:程序呈现纯白色正方形而不是变形后的正方形

OpenGL: Program renders plain white square instead of a transformed square

我正在尝试渲染一个具有颜色并因 4x4 矩阵而变换的 2D 正方形。输出应该如下所示:

但是,我得到的是:

这很令人沮丧,因为我在另一个项目中遇到了这个问题。我的教授向我介绍了如何解决它,我们所做的只是到处玩弄一些东西,它神奇地起作用了,没有更改代码。现在我再次遇到这个问题,并且没有关于为什么会发生这种情况的线索。我正确地逐字输入了教程代码,但没有正确呈现。然而,它确实在我教授的计算机上正确呈现。

代码如下:

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>

#define WINDOW_TITLE "Modern OpenGL"

#ifndef GLSL
#define GLSL(Version, Source) "#version" #Version "\n" #Source
#endif

GLint shaderProgram, windowWidth = 800, windowHeight = 600;
GLuint VBO, VAO, EBO, texture;

void uResizeWindow(int, int);
void uRenderGraphics();
void uCreateShader();
void uCreateBuffers();



//Vertex shader source code
const GLchar* vertexShaderSource = GLSL(330,
    layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color;

out vec3 mobileColor;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main() {
    gl_Position = projection * view * model * vec4(position, 1.0f); //transforms vertices to clip coordinates
    mobileColor = color; //references incoming color data
});

//Fragment shader source code
const GLchar* fragmentShaderSource = GLSL(330,
    in vec3 mobileColor;

out vec4 gpuColor;

void main() {
    gpuColor = vec4(mobileColor, 1.0f);
});



int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(windowWidth, windowHeight);
    glutCreateWindow(WINDOW_TITLE);
    glutReshapeFunc(uResizeWindow);
    glewExperimental = GL_TRUE;

    if (glewInit() != GLEW_OK) {
        std::cout << "Failed to initialize GLEW" << std::endl;
    }

    uCreateShader();
    uCreateBuffers();

    glUseProgram(shaderProgram);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    glutDisplayFunc(uRenderGraphics);

    glutMainLoop();

    //Destroys buffer objects once used
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);

    return 0;
}

void uResizeWindow(int w, int h) {
    windowWidth = w;
    windowHeight = h;
    glViewport(0, 0, windowWidth, windowHeight);
}

void uRenderGraphics() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    
    glBindVertexArray(VAO);

    glm::mat4 model(1.0f);
    model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); //place object at center of viewport
    model = glm::rotate(model, 15.0f, glm::vec3(1.0f, 0.0f, 0.0f)); //rotate object 15 degrees on x-axis
    model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f)); //increase object size by factor of 2

    //transforms the camera
    glm::mat4 view(1.0f);

    view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f)); //moves camera backwards -3 units in z

    //creates perspective projection
    glm::mat4 projection(1.0f);
    projection = glm::perspective(45.0f, (GLfloat)windowWidth / (GLfloat)windowHeight, 0.1f, 100.0f);

    //retrieves and passes transform matrices to shader program
    GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
    GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
    GLint projLoc = glGetUniformLocation(shaderProgram, "projection");

    //draws the triangles
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0); //deactive the vertex array object

    glutSwapBuffers();
}

void uCreateShader() {
    //vertex
    GLint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    //fragment
    GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

void uCreateBuffers() {
    GLfloat vertices[] = {
        0.5f, 0.5f, 0.0f,     1.0f, 0.0f, 0.0f, //top right vertex 0
        0.5f, -0.5f, 0.0f,    0.0f, 1.0f, 0.0f, //bottom right vertex 1
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f, //bottom left vertex 2
        -0.5f, 0.5f, 0.0f,    1.0f, 0.0f, 1.0f  //top left vertex 3
    };

    GLuint indices[] = {
        0, 1, 3, //triangle 1
        1, 2, 3 //triangle 2
    };

    //gen buffer ids
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);
    
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //set attrib pointer 0 to hold pos data
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);
    //set attrib pointer 1 to hold color data
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    glBindVertexArray(0); //deactivate VAO
}

无法编译顶点着色器和片段着色器,因为 GLSL 宏中缺少 space(在 #version 之后):

#define GLSL(Version, Source) "#version" #Version "\n" #Source

#define GLSL(Version, Source) "#version " #Version "\n" #Source

我建议检查着色器编译是否成功以及程序对象是否链接成功。
可以通过glGetShaderiv and the parameter GL_COMPILE_STATUS. If the linking of a program was successful can be checked by glGetProgramiv和参数GL_LINK_STATUS.
检查shader是否编译成功 查看 .

的答案

glm::perspective is radian的角度参数的单位:

projection = glm::perspective(45.0f, (GLfloat)windowWidth / (GLfloat)windowHeight, 0.1f, 100.0f);

projection = glm::perspective(glm::radians(45.0f),
    (GLfloat)windowWidth / (GLfloat)windowHeight, 0.1f, 100.0f);

你错过了设置矩阵制服:

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

glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));