Возникли проблемы с отображением треугольника в современном OpenGL

#c #opengl

#c #opengl

Вопрос:

Я ожидал, что программа отобразит простой треугольник поверх серого фона, но вместо этого он отображает фон, но не треугольник.

Мой компилятор не показывает никаких предупреждений или ошибок, как и SDL2 или GLAD. Я пришел к выводу, что причина такого поведения содержится в любом из этих двух фрагментов кода. Просто в качестве ссылки я программирую это на C и использую OpenGL 4.2.

внутри shader.h

 #ifndef SHADER_H
#define SHADER_H

// vertex shader
const char* vertexShaderSrc = 
    "#version 420 coren"
    "layout (location = 0) in vec3 aPos;n"
    "void main()n"
    "{n"
    "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);n"
    "}";

unsigned int vShader;



// fragment shader
const char* fragmentShaderSrc =
    "#version 420 coren"
    "out vec4 FragColor;n"
    "void main()n"
    "{n"
    "   FragColor = vec4(1.0, 1.0, 1.0, 1.0);n"
    "}n";

unsigned int fShader;

// shader program
unsigned int sProgram;

#endif // SHADER_H
  

внутри main.c

     // SETUP TRIANGLE
    float triVertices[] = {
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f, -0.5f, 0.0f
    };

    // vertex buffer object / vertex array object
    unsigned int vbo, vao;
    glGenVertexArrays(1, amp;vao);
    glGenBuffers(1, amp;vbo);

    // vao
    glBindVertexArray(vao);

    // vbo
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(triVertices), triVertices, GL_STATIC_DRAW);

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

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


    // vertex shader
    vShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShader, 1, amp;vertexShaderSrc, NULL);
    glCompileShader(vShader);

    glGetShaderiv(vShader, GL_COMPILE_STATUS, amp;success);
    if(!success) {
        glGetShaderInfoLog(vShader, 512, NULL, infoLog);
        printf("vertex shader error: %sn", infoLog);
        isRunning = false;
    }


    // fragment shader
    fShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShader, 1, amp;fragmentShaderSrc, NULL);
    glCompileShader(fShader);

    glGetShaderiv(fShader, GL_COMPILE_STATUS, amp;success);
    if(!success) {
        glGetShaderInfoLog(fShader, 512, NULL, infoLog);
        printf("fragment shader error: %sn", infoLog);
        isRunning = false;
    }


    // shader program
    sProgram = glCreateProgram();

    glAttachShader(sProgram, vShader);
    glAttachShader(sProgram, fShader);
    glLinkProgram(sProgram);

    glGetProgramiv(sProgram, GL_LINK_STATUS, amp;success);
    if(!success) {
        glGetProgramInfoLog(sProgram, 512, NULL, infoLog);
        printf("shader program errror: %sn", infoLog);
        isRunning = false;
    }

    glDeleteShader(vShader);
    glDeleteShader(fShader);



    // APPLICATION LOOP
    while(isRunning) {
        while(SDL_PollEvent(amp;event)) {
            switch(event.type) {
                case SDL_QUIT:
                    isRunning = false; 
                    break;
                default: 
                    break;
            }
        }

        // display
        glClearColor(0.15f, 0.15f, 0.15f, 1.0f);
        glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

        glUseProgram(sProgram);
        glBindVertexArray(vao);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        SDL_GL_SwapWindow(window);
    }
  

Я попытался решить свою проблему, изменив порядок размещения числовых функций, присвоив этим функциям разные значения и изменив исходный код моих шейдеров. Ни одно из этих действий, похоже, не сработало, и поэтому я вернул свой код в исходное состояние. Я оглянулся на свою ссылку, чтобы посмотреть, не пропустил ли я что-нибудь, но я ничего не смог отследить.

Комментарии:

1. Я чувствую тебя, братан, у меня была такая же проблема. По крайней мере, один час, чтобы понять, что я делал неправильно. Я не думаю, что кто-нибудь сядет, чтобы прочитать 100 строк кода, чтобы понять, что вы делаете не так. Я порекомендую вам вместо этого это видео , если вы хотите продолжать использовать ту же версию OpenGL, что и в учебном пособии. Или, если вам нужен более простой способ, я бы порекомендовал вам изучить glDebugMessageCallback .

2. Эта книга учит вас отлаживать программу до главы 47. Я думаю, это должно быть первое, чему вы должны научиться. Итак, вы можете взглянуть на эти ссылки. Мы изучаем это вместе, чувак, это мой результат, если это поможет вам сравнить . Я только что сделал это на прошлой неделе

Ответ №1:

Похоже, что вершины вашего треугольника имеют одинаковую координату Y

 float triVertices[] = {
    -0.5f, -0.5f, 0.0f,
     0.5f, -0.5f, 0.0f,
     0.0f, -0.5f, 0.0f
};
  

должно быть

 float triVertices[] = {
    -0.5f, -0.5f, 0.0f,
     0.5f, -0.5f, 0.0f,
     0.0f,  0.5f, 0.0f    // here I have changed -0.5 to  0.5
};
  

Небольшое обновление: я просмотрел ссылку после публикации этого, и это подтверждает мою догадку. Треугольник имеет то же значение Y для третьей вершины.

Остальная часть программы выглядит нормально, если SDL и шейдерный компилятор OpenGL не выдают никаких предупреждений.

Комментарии:

1. Большое вам спасибо! Наверное, я был прав, когда сказал, что я идиот, когда дело доходит до этого… я не могу поверить, что заставил вас пройти весь этот код, чтобы я понял, что это была просто проблема с моими вершинами, мне так жаль! Тем не менее, вы герой.

2. У меня было только два предположения: настройка буфера глубины (но все было в порядке) и опечатки в данных. У меня также есть большой «послужной список» подобных ошибок, обнаруженных моими коллегами) Другим распространенным источником ошибок в OpenGL, когда «все черное», является настройка режима наложения и ошибки в матрицах.