【问题标题】:OpenGL shader not drawing anything - bad sprite classOpenGL着色器不绘制任何东西 - 坏精灵类
【发布时间】:2020-05-19 15:38:30
【问题描述】:

我正在尝试将 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);
}

我在 main.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();
}

【问题讨论】:

  • glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0) 必须是 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0)。属性元组的大小是 2,因为每个顶点坐标由 2 个分量 (x, y) 组成——即使顶点着色器中的类型是vec4。缺失的组件自动设置为 0(对于 y 和 z)和 1(对于 w)。
  • 啊,好吧,我简化了这个例子,去掉了我认为不相关的内容。我已经在我的代码中替换了该行,但我仍然没有得到任何渲染
  • 编辑帖子以反映您的评论

标签: c++ opengl glfw


【解决方案1】:

只是为了排除显而易见的问题,尝试在 Shader 类的析构函数中添加一个 print 语句。从 Shader 类的设计来看,您应该会发现在实际使用着色器之前调用 glDeleteProgram 非常容易。

一般来说,如果你有一个 GLSL 着色器或程序的包装器,你可能想要删除复制构造函数和赋值运算符(或实现一个引用计数系统)。

\edit 删除复制 ctor & 赋值运算符....

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

您可能希望在某处管理这些着色器(可能是引用计数),并且只将指向它们的指针存储在您的 SpriteRenderer 中。 我看不出您上面发布的代码有任何其他问题,因此问题可能出在您的着色器中,或者您如何传递正在使用的任何统一变量。

【讨论】:

  • 谢谢,这正是发生的事情:着色器析构函数在渲染之前被调用。我不清楚我应该如何“删除复制构造函数”,我只是让它们成为空函数吗?
  • 这实际上并没有帮助,但也许它指出了我做错的更多事情!
猜你喜欢
  • 1970-01-01
  • 2014-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
  • 2012-04-27
相关资源
最近更新 更多