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

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

Вот код инициализации для кадрового буфера
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;
}

фрагментный шейдер написан с целью интерпретации мультисэмплов

#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 на что-то вшей out_color = vec4 (1.0,0.0,0.0,1.0), я получаю красный экран.

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

0

Решение

Текстура с идентификатором 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);
1

Другие решения


По вопросам рекламы [email protected]