为什么 OpenGL 不渲染我的红色三角形?

Why isn't OpenGL rendering my red triangle?

经过几次测试我仍然没有看到我的红色三角形,我做错了什么?这很有趣,因为这不是我第一次使用 OpenGL,而且我很确定我没有错过任何设置步骤。这是一个代码片段:

GLFWwindow* window;
glfwSetErrorCallback(onError);

if ( !glfwInit() ) {
        std::cout << "glfwInit() failed." << std::endl;
        return;
}

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

window = glfwCreateWindow( GetWindowWidth(), GetWindowHeight(), "The Game", NULL, NULL );
if ( !window )
{
        std::cout << "couldn't create a proper window, exiting." << std::endl;
        glfwTerminate();
        return;
}

glfwSetKeyCallback( window, handleKeysEvents );

glfwMakeContextCurrent( window );
gladLoadGL(); // no glfwGetProcAddress required

glfwSwapInterval(1);



/// init opengl things ...

GLuint VAO, VBO, program;
GLuint VertexShader, FragmentShader;

VertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShader, 1, &vertex_shader_text, NULL);
glCompileShader(VertexShader);

GLint isCompiled = 0;
glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
        GLint maxLength = 0;
        glGetShaderiv(VertexShader, GL_INFO_LOG_LENGTH, &maxLength);
        std::cout << "ERROR IN COMPILING VERTEX SHADER." << std::endl;


        // The maxLength includes the NULL character
        std::vector<GLchar> errorLog(maxLength);

        glGetShaderInfoLog(VertexShader, maxLength, &maxLength, &errorLog[0]);
                                
        for ( int i = 0; i < errorLog.size(); ++i )
                std::cout << errorLog[i];

        glDeleteShader(VertexShader); // Don't leak the shader.
        return;
}

FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader, 1, &fragment_shader_text, NULL);
glCompileShader(FragmentShader);

isCompiled = 0;
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
        GLint maxLength = 0;
        glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
        std::cout << "ERROR IN COMPILING VERTEX SHADER." << std::endl;

        // The maxLength includes the NULL character
        std::vector<GLchar> errorLog(maxLength);

        glGetShaderInfoLog(FragmentShader, maxLength, &maxLength, &errorLog[0]);
                                
        for ( int i = 0; i < errorLog.size(); ++i )
                std::cout << errorLog[i];

        glDeleteShader(FragmentShader); // Don't leak the shader.
        return;
}

program = glCreateProgram();
glAttachShader(program, VertexShader);
glAttachShader(program, FragmentShader);
glLinkProgram(program);
                

// Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE)
{
        
        std::cout << "ERROR IN LINKING PROGRAM." << std::endl;

        GLint maxLength = 0;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);

        // The maxLength includes the NULL character
        std::vector<GLchar> infoLog(maxLength);
        glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
        
        // We don't need the program anymore.
        glDeleteProgram(program);
        // Don't leak shaders either.
        glDeleteShader(VertexShader);
        glDeleteShader(FragmentShader);

        // Use the infoLog as you see fit.
        for ( int i = 0; i < infoLog.size(); ++i )
                std::cout << infoLog[i];
        
        // In this simple program, we'll just leave
        return;
}

glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);

glGenBuffers(1, &VBO);

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_VERTEX_ARRAY, VBO);
glBufferData(GL_VERTEX_ARRAY, sizeof(vertices), reinterpret_cast<const void*>(vertices), GL_STATIC_DRAW);
glBindBuffer(GL_VERTEX_ARRAY, 0);

glBindBuffer(GL_VERTEX_ARRAY, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);

glBindBuffer(GL_VERTEX_ARRAY, 0);
glBindVertexArray(0);

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

while( !glfwWindowShouldClose(window) )
{
        Float wWidth = GetWindowWidth();
        Float wHeight = GetWindowHeight();

        glViewport(0, 0, (GLsizei)wWidth, (GLsizei)wHeight);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        

        glUseProgram(program);

        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glBindVertexArray(0);


        glfwSwapBuffers(window);
        glfwPollEvents();
}


glfwDestroyWindow(window);
glfwTerminate();

std::cout << "closing the game." << std::endl;
return;

这是着色器:
顶点着色器:

#version 460 core
layout (location = 0) in vec3 aPos;
void main()
{
    gl_Position = vec4(aPos, 1.0f);
}

和片段着色器:

#version 460 core

out vec4 FragCol;
void main()
{
    FragCol = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

创建了 OpenGL 上下文,实际上用特定颜色清除屏幕效果很好。我只是在屏幕上看不到我的三角形,有什么建议吗?

GL_VERTEX_ARRAY is not a valid buffer type. GL_VERTEX_ARRAY is a client-side capability (fixed function attribute, legacy OpenGL). The buffer type for vertex attributes is GL_ARRAY_BUFFER:

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), reinterpret_cast<const void*>(vertices), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);