OpenGL C ++ абстракция и проблема с рисованием вершин - PullRequest
0 голосов
/ 10 апреля 2020

Я изучаю OpenGL из https://learnopengl.com/Getting-started/OpenGL, и я следую первым урокам и пытаюсь абстрагировать материал OpenGL в классы. Я выложу код того, что я сделал.

Создание окна работает нормально, но рисование меня sh ничего не показывает. Кроме того, код для класса Shader находится здесь: https://learnopengl.com/code_viewer_gh.php?code=includes / learnopengl / shader_s.h

(Обратите внимание: я не получаю никакой ошибки в классе шейдеров)

Теперь для моего кода:

Дисплей. cpp:

    Display::Display(int width, int height, const std::string &title) {

    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    m_window = glfwCreateWindow(width, height, "LearnOpenGL", nullptr, nullptr);

    if (m_window == NULL) {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        exit(-1);
    }

    glfwMakeContextCurrent(m_window);
    glewInit();


    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glCullFace(GL_BACK);
}

Display::~Display() {
    glfwDestroyWindow(m_window);
    glfwTerminate();
}

void Display::Clear(float r, float g, float b, float a) {
    glClearColor(r, g, b, a);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void Display::SwapBuffers() {
    glfwSwapBuffers(m_window);
}

bool Display::ShouldClose() {
    return glfwWindowShouldClose(m_window);
}

void Display::SetClose() {
    glfwSetWindowShouldClose(m_window, GL_TRUE);
}

void Display::ProcessInput() {
    if (glfwGetKey(m_window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
        SetClose();
    }
}

Класс вершины:

class Vertex {
    glm::vec3 pos;
public:
    Vertex(const glm::vec3 &pos) {
        this->pos = pos;
    }

};

Me sh. cpp:

Mesh::Mesh(Vertex *vertices, unsigned int numVertices, unsigned int *indices, unsigned int numIndices) {
    // m_numIndices, VAO, VBO, VEO are members
    m_numIndices = numIndices;

    //VAO
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    //VBO
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Vertex), vertices, GL_STATIC_DRAW);


    //EBO
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(unsigned int), indices, GL_STATIC_DRAW);

    //VBO Attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr);
    glEnableVertexAttribArray(0);

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

}

Mesh::~Mesh() {
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
}

void Mesh::draw() {

    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, m_numIndices, GL_UNSIGNED_INT, nullptr);
}

main. cpp:

#define DISPLAY_WIDTH 840
#define DISPLAY_HEIGHT 640

int main() {
    Display display(DISPLAY_WIDTH, DISPLAY_HEIGHT, "Test");
    Vertex vertex[] = {Vertex(glm::vec3(0.5f, 0.5f, 0.0f)),  // top right
                       Vertex(glm::vec3(0.5f, -0.5f, 0.0f)),  // bottom right
                       Vertex(glm::vec3(-0.5f, -0.5f, 0.0f)),  // bottom left
                       Vertex(glm::vec3(-0.5f, 0.5f, 0.0f))   // top left
    };
    unsigned int indices[] = {
            0, 1, 2,
            2, 3, 0
    };
    Mesh mesh(vertex, 4, indices, 6);
    Shader shader("./res/shaders/basicVs.shader", "./res/shaders/basicFs.shader");

    while (!display.ShouldClose()) {

        display.ProcessInput();
        display.Clear(0.2f, 0.3f, 0.3f, 1.0f);
        shader.use();
        mesh.draw();

        display.SwapBuffers();
        glfwPollEvents();
    }

    return 0;
}

Запуск кода приведет только к рабочему окну. Нет рисунка или что-то. Извините за длинный пост, спасибо за помощь!

Ответы [ 2 ]

2 голосов
/ 10 апреля 2020

Я следую первым урокам и пытаюсь абстрагировать материал OpenGL в классы.

Я знаю, что вы не хотите этого слышать, но:

Не надо!

Не пытайтесь обернуть OpenGL в каркас класса. На этом пути вас ждут только страдания, отчаяние и guish.

Способ, которым OpenGL работает, как он организует свое внутреннее состояние и отражает свой внутренний объект, не очень хорошо отображается в классы , На первый взгляд это может выглядеть не так. Вы можете подумать: «Текстуры, да, я собираюсь обернуть их в класс!»

Но это не так просто! Чтобы остаться в этом примере:

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

Это лишь небольшая часть того, что предлагает OpenGL, и уже это открыло ОГРОМНО банка червей, чтобы правильно отобразить и отследить это в OOP дизайне, основанном на классах.

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

Если вы абсолютно уверены, что вам нужно что-то надеть, то оберните Vulkan. Эти API предназначены для использования таким образом.

1 голос
/ 10 апреля 2020

Проблема вызвана Отбор лица . Ваша установка отбирает лица.

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

Если грань является лицевой или обратной, определяется порядком намотки примитива треугольника.

Ваши лица повернуты по часовой стрелке (0-1-2, 2-3-0):

3        0
 +-----+ +
 |   / / |
 | / /   |
 + +-----+
2         1

По умолчанию фронтальные многоугольники расположены против часовой стрелки GL_CCW. См. glFrontFace.

Измените фронтальный режим (glFrontFace(GL_CW);) или отключите выборку лица для решения проблемы.

В качестве альтернативы вы можете изменить порядок наматывания граней (например, 2-1-0, 2-0-3).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...