如何在渲染器中使用多个着色器?

时间:2018-07-09 22:14:13

标签: c++ opengl shader renderer

我正在尝试使渲染器能够使用默认或自定义着色器。

class Renderer
{
public:
    void Create()
    {
        //Setup vao, vbo, ebo, quad indices, add data to ebo, 
        //create default Shader
        //set camera projection
    }

    void Map()
    {
        vertexData = (VertexData*)glMapBufferRange(...);
    }

    void Draw(Rectangle destRect, Rectangle texCoordRect, Texture* texture)
    {
        //4 times for 4 different corners
        float textureSlot = FindTexture(texture);
        AddDataToMappedBuffer(position, texCoords, textureSlot, color);

        indexCount += 6;
    }

    void Unmap()
    {
        glUnmapBuffer(...);
    }

    void Render()
    {
        Unmap();

        shader.UniformMatrix4fv("projection", camera.getProjection());

        for(uint i = 0; i < texture.size(); ++i)
        {
            texture[i]->Bind(i);
        }

        BindVAO();
        DrawElements(TRIANGELS, indexCount, UNSIGNED_INT, nullptr);
        UnbindVAO();

        For(uint i = 0; i < texture.size(); ++i)
        {
            texture[i]->Unbind(i);
        }

        indexCount = 0;
        texture.clear();
    }

    float Renderer2D::FindTexture(Texture* t)
    {
        float result = 0.0f;
        bool found = false;
        for (uint i = 0; i < texture.size(); ++i) {
            if (texture[i] == t) {
                result = static_cast<float>(i + 1);
                found = true;
                break;
            }
        }

        if (!found) {
            if (texture.size() >= MAX_TEXTURES) {
                Render();
                Map();
            }
            texture.push_back(t);
            result = static_cast<float>(texture.size());
        }

        return result;
    }
private:
    std::vector<Texture*> texture;
    uint vao, vbo, ebo;
    VertexData* vertexData;
    float FindTexture(Texture*);
    Shader shader;
    Camera2D camera;
};


int main()
{
    Renderer renderer;
    renderer.Create();

    while(!quit)
    {
        //Clear color etc.

        renderer.Map();
        renderer.Draw(Rectangle(0.0f, 0.0f, 500.0f, 500.0f), Rectangle(0.0f, 0.0f, 1.0f, 1.0f), texture("sometexture.png"));
        renderer.Render();
    }
}

这就是现在的工作方式。

我希望我的渲染器是这样的:

  • Draw方法集着色器中
  • 检查此着色器是否在数组中
  • 如果是,请不要再进行其他绘制调用-使用已经在数组中的着色器
  • 如果不是,请将此着色器添加到数组,使用它并执行另一个绘制调用

我试图做一个找到着色器的方法-与纹理类似-遍历所有着色器并使用它们。它不能完全满足我的要求。

std::vector<Shader*> shader;

void Renderer2D::FindShader(Shader* sh)
{
    bool found = false;
    for (uint i = 0; i < shader.size(); ++i) {
        if (shader[i] == sh) {
            found = true;
            return;
        }
    }

    if (!found) {
        shader.push_back(sh);
        Render();
        Map();
    }
}

void Render()
{
    Unmap();

    for(const auto& shader : shader) 
    {
        shader->UseProgram();
        shader.UniformMatrix4fv("projection", camera.getProjection());   
    }

    for(uint i = 0; i < texture.size(); ++i)
    {
        texture[i]->Bind(i);
    }

    BindVAO();
    DrawElements(TRIANGELS, indexCount, UNSIGNED_INT, nullptr);
    UnbindVAO();

    For(uint i = 0; i < texture.size(); ++i)
    {
        texture[i]->Unbind(i);
    }

    indexCount = 0;
    texture.clear();
}

void Draw(Rectangle destRect, Rectangle texCoordRect, Texture* texture, Shader* shader)
{
    FindShader(shader);
    float textureSlot = FindTexture(texture);
    AddDataToMappedBuffer(position, texCoords, textureSlot, color);

    indexCount += 6;
}

我也尝试过在未找到着色器时不进行着色调用的情况下找到着色器-仅将其添加到数组中-并且在render方法中遍历所有着色器并进行绘制调用。它也不能很好地工作。

我应该怎么做?

0 个答案:

没有答案