试图在 OpenGL 中绘制一个带有两个三角形的正方形,但我只得到一个黑屏

Trying to draw a square with two triangles in OpenGL but I'm only getting a black screen

正如标题所说,我正在尝试从两个三角形中绘制一个正方形 class。我已经尝试了所有我能想到的方法,但我无法弄清楚为什么它只显示黑屏。到目前为止,这是我的代码。我已正确设置项目和库。我已经看了十几遍了,似乎找不到问题所在。

#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>


static unsigned int CompileShader(unsigned int type, const std::string& source) {
    unsigned int id = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(id, 1, &src, nullptr);
    glCompileShader(id);

    return id;
}

static unsigned int CreateShader(const std::string& vrtxShader, const std::string& fragShader) {
    unsigned int program = glCreateProgram();
    //compile shaders
    unsigned int vs = CompileShader(GL_VERTEX_SHADER, vrtxShader);
    unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragShader);

    //attach shaders to program 
    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    
    //delete shaders 
    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;
}



int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    //sets up GLFW
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Module 3", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    
    //Initialize GLEW 
    if (glewInit() != GLEW_OK)
        std::cout << "Error!" << std::endl;

    float vertPositions[] = {
        // index 0
       -0.5f, -0.5f, 0.0f,
       1.0f, 0.0f, 0.0f,

       // index 1
       -5.0f, 0.5f, 0.0f,
       0.0f, 0.0f, 1.0f,

       // index 2
       0.5f, -0.5f, 0.0f,
       0.0f, 1.0f, 0.0f,

       // index 3
       0.5f, 0.5f, 0.0f,
       1.0f, 0.0f, 0.0f,

    

    };

    float indices[] = { 0, 1, 2, 1, 2, 3 };

    //creates vertex buffer object
    unsigned int vbo;
    unsigned int ebo;
    glGenBuffers(1, &vbo);
    glGenBuffers(1, &ebo);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertPositions), vertPositions, GL_STATIC_DRAW);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);


    //attribute location and layout to gpu. 
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)0);
    

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
    

    // Vertex Shader Program Source Code
    std::string vertexShaderSource = "#version 440 core\n"
        "layout (location = 0) in vec4 aPos;\n"
        "layout (location = 1) in vec4 aColor;\n"
        "out vec4 colorOut;\n"
        "void main()\n"
        "{\n"
        "   gl_Position = aPos;\n"
        "   colorOut = aColor;\n"
        "}\n[=10=]";


    // Fragment Shader Program Source Code
    std::string fragmentShaderSource = "#version 440 core\n"
        "in vec4 colorOut;\n"
        "out vec4 fragColor;\n"
        "void main()\n"
        "{\n"
        "fragColor = colorOut;\n"
        "}\n[=10=]";
    
    unsigned int shader = CreateShader(vertexShaderSource, fragmentShaderSource);
    glUseProgram(shader);
   


    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        //draw the shapes 
        
        glDrawElements(GL_TRIANGLES, 6, GL_FLOAT, nullptr);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

为什么要使用核心配置文件 OpenGL Context (GLFW_OPENGL_CORE_PROFILE) it is mandatory to create a Vertex Array Object。使用核心配置文件时没有默认 VAO。

例如:

unsigned int vao, vbo, ebo;

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertPositions), vertPositions, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)0);    
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)(3 * sizeof(float)));

此外,索引的类型必须是整数。例如:

unsigned int indices[] = { 0, 1, 2, 1, 2, 3 };
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);