Ничего не появляется на экране в OpenGL (GLFW/GLEW)

Недавно я переходил от LWJGL (с которым у меня есть опыт работы) к C++ OpenGL API. Я использовал этот учебник, так как не мог заставить мои классы VBO работать правильно. Код ниже:

#include "GL/glew.h"
#include "GLFW/glfw3.h"

#include <stdlib.h>
#include <stdio.h>

using namespace std;

GLFWwindow* window;

void init()
{

}

static const GLfloat g_vertex_buffer_data[] =
{
    -1.0f, -1.0f, 0.0f,
    1.0f, -1.0f, 0.0f,
    0.0f,  1.0f, 0.0f,
};

void render()
{
    glViewport(0, 0, 640, 480);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glDisableVertexAttribArray(0);
    glDeleteBuffers(1, &vertexbuffer);

    glfwSwapBuffers(window);
    glfwPollEvents();
}

static void errorCallback(int error, const char* desc)
{
    fputs(desc, stderr);
}

static void keyCallback(GLFWwindow* window, int key, int scanCode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
        glfwSetWindowShouldClose(window, GL_TRUE);
}

void initWindow()
{
    glfwSetErrorCallback(errorCallback);
    if (!glfwInit())
        exit(EXIT_FAILURE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    window = glfwCreateWindow(640, 480, "Hello, world!", NULL, NULL);

    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);
    glfwSetKeyCallback(window, keyCallback);

    glewExperimental = true;
    if (glewInit() != GLEW_OK)
        exit(EXIT_FAILURE);
}

void destroyWindow()
{
    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

int main(int argCount, char **args)
{
    initWindow();
    init();
    while (!glfwWindowShouldClose(window))
        render();
    destroyWindow();
}

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

1 ответ

Решение

Вы используете профиль ядра OpenGL 3.3. В таком контексте использование объектов Vertex Array (VAO) является обязательным. То же самое верно для программных объектов. Вы должны указать свои собственные шейдеры и не можете использовать фиксированную функцию pipleline. glLoadIdentity Вызов относится к устаревшей функциональности стека матриц, которая также удалена из профилей ядра.

Ваш glDrawArrays вызов должен генерировать GL_INVALID_OPERATION потому что у вас нет программного объекта и нет привязки VAO во время вызова отрисовки. Я обычно рекомендую добавлять проверки ошибок GL хотя бы для отладочных сборок. Если версия GL, на которую вы ориентируетесь, поддерживает ее, я рекомендую вместо этого использовать контекст отладки. Это значительно облегчит обнаружение ошибок во время разработки.

Также обратите внимание, что ни одна из этих проблем не связана с переходом с Java с LWJGL на C++. Если бы вы использовали ранее унаследованный контекстный / основной профиль с java, вы могли бы сделать это и в C++ (хотя я настоятельно советую вам изучать современный GL), и вы бы столкнулись с такими же проблемами, если бы использовали современный базовый контекстный профиль с LWJGL.

Другие вопросы по тегам