Есть ли способ обмениваться данными между шейдерами? Могу ли я просто создать 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);