Шейдер OpenGL ничего не рисует - плохой спрайт - PullRequest
1 голос
/ 03 февраля 2020

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

Я почти уверен, что мой класс окна работает нормально (я проверил на ошибки), но я думаю, что ошибка в моем классе спрайта но я понятия не имею, что это такое.

Это мой класс спрайтов:

sprite_renderer.hpp

#ifndef SPRITE_RENDERER_H
#define SPRITE_RENDERER_H

#include <GL/glew.h>
#include "shader.hpp"


class SpriteRenderer
{
public:
    SpriteRenderer(Shader &shader);
    ~SpriteRenderer();
    void DrawSprite();
private:
    Shader shader; 
    GLuint quadVAO;
    void initRenderData();
};

#endif

sprite_renderer. cpp

#include "sprite_renderer.hpp"

SpriteRenderer::SpriteRenderer(Shader &shader)
{
    this->shader = shader;
    this->initRenderData();
}

SpriteRenderer::~SpriteRenderer()
{
    glDeleteVertexArrays(1, &this->quadVAO);
}

void SpriteRenderer::DrawSprite()
{
    this->shader.Use();

    glBindVertexArray(this->quadVAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);
}

void SpriteRenderer::initRenderData()
{
    GLuint VBO;
    GLfloat vertices[] = { 
        // Pos      
        0.0f, 1.0f, 
        1.0f, 0.0f,
        0.0f, 0.0f, 

        0.0f, 1.0f,
        1.0f, 1.0f, 
        1.0f, 0.0f, 
    };

    glGenVertexArrays(1, &this->quadVAO);
    glGenBuffers(1, &VBO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindVertexArray(this->quadVAO);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

Я использую это в своем основном как это. cpp:

int main()
{
    Window window = Window();
    Shader shader = ResourceManager::LoadShader("./assets/shaders/sprite.vert", "./assets/shaders/sprite.frag", "sprite");
    SpriteRenderer* renderer = new SpriteRenderer(shader);

    while (window.IsOpen())
    {
        window.BeginDraw();
        renderer->DrawSprite();
        window.EndDraw();
    }

    glfwTerminate();
    return 0;
}

Где window.BeginDraw() и window.EndDraw() просто:

void Window::BeginDraw()
{
  glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT);
}

void Window::EndDraw()
{
  glfwSwapBuffers(window);
  glfwPollEvents();
}

1 Ответ

1 голос
/ 04 февраля 2020

Просто чтобы исключить очевидное, попробуйте вставить оператор print в деструктор вашего класса Shader. Судя по дизайну вашего класса Shader, вы должны найти, что в конечном итоге вызвать glDeleteProgram до фактического использования шейдера.

В общем, если у вас есть оболочка вокруг шейдера или программы GLSL, вы, вероятно, захотите удалить конструктор копирования и оператор присваивания (или внедрить систему подсчета ссылок).

\ edit для удаления копии ctor и оператора присваивания ....

Shader(const Shader&) = delete;
Shader& operator = (const Shader&) = delete;

Возможно, вы хотите где-то управлять этими шейдерами (возможно, ref ref count) , и хранить только указатели на них в вашем SpriteRenderer. Я не вижу никакой другой проблемы с кодом, который вы опубликовали выше, поэтому проблема может быть в вашем шейдере или в том, как вы передаете любые унифицированные переменные, которые вы используете.

...