2014-11-14 11 views
0

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

Здесь это код инициализации для фреймбуфера ничтожной 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 мультисэмплах

#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. В моей функции инициализации для фреймбуфера, когда я передаю GL_DEPTH_COMPONENT в glTexStorage2DMultisample, тогда я получаю ошибку. Я решил передать GL_DEPTH_COMPONENT16, и он работает. Почему это?
  3. Должен ли я лучше использовать RENDERBUFFER для некоторых вариантов, и если да, то как я могу прочитать его текстуре?

ответ

1

текстура с идентификатором 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, первая автоматически становится несвязанной.

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

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

Спасибо большое. Я бы никогда не нашел эту опечатку самостоятельно. – Antiusninja