LINUX.ORG.RU

Сообщения teddiet

 

Рендер нескольких текстур в FBO

Форум — Development

Доброго времени суток,

Прошу помочь в следующей задаче:

Цель: Применить алгоритм сглаживания на отображаемую сцену. Исходные данные: AR проект, в котором при наведении на картинку начинает проигрываться анимация на экране. У каждого объекта анимации соответственно своя текстура и шейдер.

Пробовал реализовать двумя способами:

  1. Добавил реализацию алгоритма FXAA (http://www.geeks3d.com/20110405/fxaa...eon-geforce/3/) в шейдер каждой из текстур, однако сглаживание не применялось. Проверял следующим образом: делал скрин экрана и увеличивал, сглаживание не было. Поправьте, пожалуйста, если я не прав, но как я понял, такой подход не будет работать потому как в нем алгоритм применялся на каждую текстуру отдельно.

  2. Решил попробовать следующий вариант: сделать рендер всех объектов в одну текстуру, и потом применить алгоритм сглаживания к этой текстуре. Поэтому создал 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

Подскажите, что я делаю не так?)

 ,

teddiet
()

RSS подписка на новые темы