为什么我的 openGL 程序显示空白屏幕?

时间:2021-07-31 13:48:40

标签: c opengl shader

我从互联网示例中创建了这个简单的 hello triangle 程序,但无论我如何尝试,我总是得到一个空白屏幕。我将不胜感激。

开发环境是带有 CUDA 10 的 Windows 10 上的 Visual Studio。

显示回调处的 glGetError 返回 0。

这里是完整的源代码:

#pragma comment(lib, "C:\\GL\\GLUT\\lib\\x64\\freeglut.lib")

#define GLEW_STATIC

#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>

const char* vertexShaderSource = "#version 460 core\n"
"layout(location = 0) in vec3 aPos;\n"
"layout(location = 1) in vec3 aColor;\n"
"out vec4 vertexColor;\n"
"void main()\n"
"{\n"
"   gl_Position = vec4(aPos, 1.0);\n"
"   vertexColor = vec4(aColor, 1.0);\n"
"}\0";

unsigned int vertexShader;

const char* fragmentShaderSource = "#version 460 core\n"
    "in vec4 vertexColor;\n"
    "out vec4 FragColor;\n"
    "void main()\n"
    "{\n"
    "   FragColor = vertexColor;\n"
    "}\0";

unsigned int shaderProgram;
unsigned int VAO;

void keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
        /* Exit on escape key press */
    case '\x1B':
    {
        exit(EXIT_SUCCESS);
        break;
    }
    }
}

void display()
{
    glUseProgram(shaderProgram);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    printf("GL error=%d\n", glGetError()); fflush(stdout);
}

/* Main method */
int main(int argc, char** argv)
{
    glutInitContextVersion(4, 6);
    glutInit(&argc, argv);
    glutInitWindowSize(800, 600);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("Automaton");
    printf("%s\n", glGetString(GL_VERSION));
    glViewport(0, 0, 800, 600);
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        printf("glew init %s\n", glewGetErrorString(err)); fflush(stdout);
        return -1;
    }
    //
    // Create shaders
    //
    int success;
    char infoLog[512];
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        perror("Vertex shader failed.\n");
        return -1;
    }
    unsigned int fragmentShader;
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        perror("Vertex shader failed.\n");
        return -1;
    }
    //
    // Link shaders
    //
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success)
    {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        perror("Linking error.\n");
        return -1;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    //
    float vertices[] = 
    {
        -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
        1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f,  0.0f, 0.0f, 1.0f
    };
    GLuint attribPos = 0;
    GLuint attribCol = 1;
    //
    unsigned int VBO;
    glCreateBuffers(1, &VBO);
    glCreateVertexArrays(1, &VAO);
    glNamedBufferStorage(VBO, sizeof(vertices), vertices, GL_DYNAMIC_STORAGE_BIT);
    GLuint vaoBindingPoint = 0; 
    glVertexArrayVertexBuffer(VAO, vaoBindingPoint, VBO, 0, 6 * sizeof(float));
    glEnableVertexArrayAttrib(VAO, attribPos);
    glEnableVertexArrayAttrib(VAO, attribCol);
    glVertexArrayAttribFormat(VAO, attribPos, 3, GL_FLOAT, 0/*false*/, 0);
    glVertexArrayAttribFormat(VAO, attribCol, 3, GL_FLOAT, 0/*false*/, 3 * sizeof(float));
    glVertexArrayAttribBinding(VAO, attribPos, vaoBindingPoint);
    glVertexArrayAttribBinding(VAO, attribCol, vaoBindingPoint);
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glutKeyboardFunc(&keyboard);
    glutDisplayFunc(&display);
    glutMainLoop();
    return EXIT_SUCCESS;
}

该程序在配备 NVIDIA GPU 1050 的戴尔 PC 上运行。

1 个答案:

答案 0 :(得分:0)

您必须调用 glutSwapBuffers 来刷新显示,分别执行缓冲区交换:

void display()
{
    glUseProgram(shaderProgram);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    printf("GL error=%d\n", glGetError()); fflush(stdout);
    glutSwapBuffers();
}