Доброго времени суток,
Прошу помочь в следующей задаче:
Цель: Применить алгоритм сглаживания на отображаемую сцену. Исходные данные: AR проект, в котором при наведении на картинку начинает проигрываться анимация на экране. У каждого объекта анимации соответственно своя текстура и шейдер.
Пробовал реализовать двумя способами:
-
Добавил реализацию алгоритма FXAA (http://www.geeks3d.com/20110405/fxaa...eon-geforce/3/) в шейдер каждой из текстур, однако сглаживание не применялось. Проверял следующим образом: делал скрин экрана и увеличивал, сглаживание не было. Поправьте, пожалуйста, если я не прав, но как я понял, такой подход не будет работать потому как в нем алгоритм применялся на каждую текстуру отдельно.
-
Решил попробовать следующий вариант: сделать рендер всех объектов в одну текстуру, и потом применить алгоритм сглаживания к этой текстуре. Поэтому создал FBO, перед функцией рендеринга устанавливаю framebuffer в созданный, а после функции рендеринга сбрасываю framebuffer. Потом отображаю текстуру на экран. В результате я вижу только черный экран.
Используемый код:
1. Создаю FBO следующим образом:
void Initialize()
{
glGenFramebuffers(1, &object);
glGenTextures(1, &texture_map);
//glGenRenderbuffers(1, &renderBufferId);
glBindFramebuffer(GL_FRAMEBUFFER, object);
glActiveTexture (GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_map);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1080, 1920, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId);
//glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_map, 0);
//glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBufferId);
glBindTexture(GL_TEXTURE_2D, 0);
//glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
assert (glGetError () == GL_NO_ERROR);
}
2. Потом загружаю модель которая должна отобразиться на экране. Она использует свой шейдер и свою текстуру:
{
glGenTextures (1, &texture);
glBindTexture (GL_TEXTURE_2D, texture);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (_current_data)
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, _current_data);
glBindTexture (GL_TEXTURE_2D, 0);
assert (glGetError () == GL_NO_ERROR);
}
3. Затем в функцию рендеринга:
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo.object);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport (0, 0, 1080, 1920);
model->render(fbo, camera);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, 1080, 1920);
glUseProgram(shaderProgram);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices);
glEnableVertexAttribArray(vertexLocation);
glVertexAttribPointer(textureCordLocation, 2, GL_FLOAT, GL_FALSE, 0, quadTextureCords);
glEnableVertexAttribArray(textureCordLocation);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbo.texture_map);
glUniform1i(textureLocation, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}
4. Функция render у созданной model:
{
glUseProgram (shader->program);
// bind texture
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, texture->texture);
glUniform1i (shader->Uniform ("texture"), 0);
// set uniforms
glUniformMatrix4fv (shader->Uniform ("camera_projection"), 1, false, &camera.projection[0][0]);
glUniformMatrix4fv (shader->Uniform ("camera_transformation"), 1, false, &camera.transformation[0][0]);
glBindBuffer (GL_ARRAY_BUFFER, vertices);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indices);
// set attributes
GLint position = shader->Location ("position");
assert (position >= 0);
glVertexAttribPointer (position, 4, GL_FLOAT, GL_FALSE, sizeof (Mesh::Vertex), 0);
glEnableVertexAttribArray (position);
GLint uv = shader->Location ("uv");
if (node.uvs != 0 && uv >= 0) {
glVertexAttribPointer (uv, 2, GL_FLOAT, GL_FALSE, sizeof (Mesh::Vertex), (GLvoid*) (sizeof (GLfloat) * 4));
glEnableVertexAttribArray (uv);
}
GLint normal = shader->Location ("normal");
if (node.normals != 0 && normal >= 0) {
glVertexAttribPointer (normal, 4, GL_FLOAT, GL_FALSE, sizeof (Mesh::Vertex), (GLvoid*) (sizeof (GLfloat) * 4 + sizeof (GLfloat) * 2));
glEnableVertexAttribArray (normal);
}
GLint color = shader->Uniform ("color");
if (color >= 0) {
glUniform4f (color, this->color[0], this->color[1], this->color[2], this->color[3]);
}
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// render to framebuffer
glDrawElements (GL_TRIANGLES, node.faces * 3, GL_UNSIGNED_INT, 0);
glDisable (GL_BLEND);
// reset state
if (normal >= 0) {
glDisableVertexAttribArray (normal);
}
if (uv >= 0) {
glDisableVertexAttribArray (uv);
}
glDisableVertexAttribArray (position);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer (GL_ARRAY_BUFFER, 0);
// checks errors
assert (glGetError ()== GL_NO_ERROR);
// reset state
glBindTexture (texture->target, 0);
glUseProgram (0);
}
В итоге получаю только черный экран.
Суть в том, что таких model несколько, и у меня идея (возможно неверная, поправьте если так) срендерить все эти модели в FBO, и потом поместить FXAA фильтр в fragment.glsl, который выведет на экран текстуру, привязанную к FBO
Подскажите, что я делаю не так?)