OpenGL делится данными модели между шейдерами - PullRequest
0 голосов
/ 18 июня 2020

Есть ли способ обмениваться данными между шейдерами? Могу ли я просто создать VAO, а затем переключать шейдерные программы по мере необходимости? Полагаю, шейдеры, вероятно, должны иметь такую ​​же раскладку.

Или я могу создать VBO и для каждой пары объект-шейдер я создать VAO, который привязывает данные к переменным шейдера? Это должно загружать большинство данных только один раз в OpenGl + я мог бы многократно использовать повторно.

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

Или есть какой-то другой, даже лучший способ?

Идея состоит в том, чтобы уменьшить использование памяти и общее ускорение процесса.

void Mesh::bind()
{
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, verticesCount * sizeof(GLfloat), vertices, GL_STATIC_DRAW);


    glBindBuffer(GL_ARRAY_BUFFER, nbo);
    glBufferData(GL_ARRAY_BUFFER, normalCount * sizeof(GLfloat), normals, GL_STATIC_DRAW);


    glBindBuffer(GL_ARRAY_BUFFER, uvbo);
    glBufferData(GL_ARRAY_BUFFER, uvCount * sizeof(GLfloat), UVs, GL_STATIC_DRAW);


    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesCount * sizeof(GLuint), indices, GL_STATIC_DRAW);
}



void MeshRenderer::init()
{
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glBindBuffer(GL_ARRAY_BUFFER, mesh->getVertexBufferId());
    GLuint posId = shaderProgram->getAttribute("LVertexPos2D");
    glVertexAttribPointer(posId, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
    glEnableVertexAttribArray(posId);

    glBindBuffer(GL_ARRAY_BUFFER, mesh->getNormalBufferId());
    GLuint normId = shaderProgram->getAttribute("LVertexNorm");
    glVertexAttribPointer(normId, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
    glEnableVertexAttribArray(normId);

    glBindBuffer(GL_ARRAY_BUFFER, mesh->getUVBufferId());
    GLuint uvId = shaderProgram->getAttribute("uv");
    glVertexAttribPointer(uvId, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), NULL);
    glEnableVertexAttribArray(uvId);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->getIndexBufferId());

    glBindVertexArray(0);
}

GameObject* GameObject::createCustom(Mesh* mesh)
{
    Texture* texture = new Texture();
    texture->loadFromFile("UV.png", NULL);
    GenericShaderProgram* shader = new GenericShaderProgram("basic.vs", "basic.fs");
    shader->loadProgram();
    return new GameObject(texture, shader, mesh);
}

GameObject::GameObject(Texture* texture, ShaderProgram* program, Mesh* mesh)
{
    this->texture = texture;
    dir = new Vector3(1, 0, 0);
    meshRenderer = new MeshRenderer(mesh, program);
    transform.setRotation(1.57, 1, 0, 0);
    transform.translate(Vector3(0, -2, 0));
    transform.setScale(Vector3(1, 1, 1));
}

//In main.cpp
Mesh* mesh = new Mesh();
    mesh->cubePrimitive();
    mesh->init();

    object = GameObject::createCustom(mesh);
    object2 = GameObject::createCustom(mesh);
    object3 = GameObject::createCustom(mesh);
...