внеэкранный рендеринг opengl 4.5 мультисэмпл FBO

0

Я ссылаюсь на OpenGL Superbible 6 в своем коде. Сначала я просто хотел реализовать сбор объектов в своей 3D-сцене. В конце концов я решил использовать объекты framebuffer, и я преуспел, а затем я понял проблему с необходимостью решить проблему полигонального сглаживания края, поэтому я снова переписал свой код, чтобы использовать GL_TEXTURE_2D_MULTISAMPLE

Вот код инициализации для framebuffer void window_glview :: init_framebuffer()

{
    //CREATE FRAMEBUFFER OBJECT
    GLenum gl_error=glGetError();

    glGenTextures(1,&texture_id_framebuffer_color);
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,texture_id_framebuffer_color);
    glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,ANTIALIASING_SAMPLES,GL_RGBA8,client_area.right,client_area.bottom,GL_TRUE);

    glGenTextures(1,&texture_id_framebuffer_objectid);
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,texture_id_framebuffer_objectid);
    glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,ANTIALIASING_SAMPLES,GL_RGBA8,client_area.right,client_area.bottom,GL_TRUE);

    glGenTextures(1,&texture_id_framebuffer_depth);
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,texture_id_framebuffer_depth);
    glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,ANTIALIASING_SAMPLES,GL_DEPTH_COMPONENT32,client_area.right,client_area.bottom,GL_TRUE);
    gl_error=glGetError();

    glGenFramebuffers(1,&buffer_id_framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER,buffer_id_framebuffer);
    gl_error=glGetError();
    glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,texture_id_framebuffer_color,0);
    glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,texture_id_framebuffer_objectid,0);
    glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,texture_id_framebuffer_depth,0);

    GLenum draw_buffers[] =
    {
        GL_COLOR_ATTACHMENT0,
        GL_COLOR_ATTACHMENT1
    };
    glDrawBuffers(2,draw_buffers);
    GLenum status=glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if(status!=GL_FRAMEBUFFER_COMPLETE)
        MessageBox(0,L"Failed to create framebuffer object",0,0);
    glBindFramebuffer(GL_FRAMEBUFFER,0);
}

Это довольно распространено для большинства интернет-списков по той же теме. Теперь вот мой код чертежа

void window_glview::paint()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


        //DRAW TO CUSTOM FRAMEBUFFER
        glBindFramebuffer(GL_FRAMEBUFFER,buffer_id_framebuffer);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

        glLineWidth(1.0);
        draw_viewport();
        viewport_object_count=0;

        draw_lights();
        glLineWidth(1.5);
        for (unsigned short i=0;i<mesh_count;i++)
        {
            draw_mesh(mesh_table[i],GL_TRIANGLES,false);
        }

    //DRAW TO DEFAULT
    glBindFramebuffer(GL_FRAMEBUFFER,0);

    //USE TEXTURE FROM FRAMEBUFFER COLOR_ATTACHMENT0
    glUseProgram(program_id_screen_render);
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,texture_id_framebuffer_color);

    //HERE IS A QUAD DRAWING PROCESS
    glBindBuffer(GL_ARRAY_BUFFER,buffer_id_screen_quad);
    glVertexAttribPointer(0,4,GL_FLOAT,GL_FALSE,24,0);
    glEnableVertexAttribArray(0);

    glDrawArrays(GL_QUADS,0,4);
    SwapBuffers(hDC);
}

вершинный шейдер прост

#version 450

layout(location=0) in vec4 _pos;
void main(void)
{
    gl_Position=_pos;
}

фрагментарный шейдер написан с целью iterpreting multisamples

#version 450
uniform sampler2DMS screen_texture;
layout(location=0) out vec4 out_color;

void main(void) 
{
    ivec2 coord=ivec2(gl_FragCoord.xy);
    vec4 result=vec4(0.0);
    int i;
    for (i=0;i<4;i++)
    {
        result=max(result,texelFetch(screen_texture,coord,i));
    }
    out_color=result;
}

Я получаю черный экран. Если я изменяю out_color на что-то lice out_color = vec4 (1.0,0.0,0.0,1.0), я получаю красный экран.

  1. Что может пойти не так?
  2. В моей функции инициализации для framebuffer, когда я передаю GL_DEPTH_COMPONENT в glTexStorage2DMultisample, тогда я получаю ошибку. Я решил передать GL_DEPTH_COMPONENT16, и он работает. Почему это?
  3. Должен ли я лучше использовать RENDERBUFFER для некоторых целей, и если да, то как я могу прочитать его текстуру?
Теги:
opengl-4
antialiasing
framebuffer
fbo

1 ответ

1

Текстура с id texture_id_framebuffer_color, которая является текстурой, которую вы используете для окончательного рендеринга, не привязана к FBO, пока вы оказываете FBO:

glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,texture_id_framebuffer_color,0);
glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,texture_id_framebuffer_objectid,0);

Только одна текстура может быть привязана к данной точке привязки за раз. Поэтому, когда вы указываете вторую текстуру, которая должна быть привязана к COLOR_ATTACHMENT0, первая автоматически становится COLOR_ATTACHMENT0.

Если вы хотите иметь два вложения, им нужно будет использовать разные точки привязки:

glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,texture_id_framebuffer_color,0);
glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT1,texture_id_framebuffer_objectid,0);
  • 0
    Большое спасибо. Я бы никогда не нашел эту опечатку сам.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню