Всем привет.
Есть такая проблема. С одним знакомым сидим курим баг - рендерим не очень сложную модельку напрямую в BackBuffer - всё рендерится правильно!
Создаём RenderTarget (в OpenGL вроде называется FrameBuffer), не меняя код просто биндим его и рисуем в этот фреймбуфер. Получаем текстуру, накладываем на полноэкранный квад и рендерим уже в основной фейм буфер.
Тоесть самый самый обычный рендер в текстуру! Вот только проблема в том, что если рендерить в текстуру, то depth test не работает! : \
гуглил, читал по форуму и понял ошибку - не создали RenderBuffer ! И даже не прибиндили к дефолтному рендер-буферу.
Слепили такой код:
glGenTextures (1, &bufferData ); glBindTexture ( GL_TEXTURE_2D, bufferData ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA16, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 ); glGenFramebuffers ( 1, &bufferID ); glBindFramebuffer( GL_DRAW_FRAMEBUFFER, bufferID); glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bufferData, 0); glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0); glGenRenderbuffers( 1, &depth_rb); glBindRenderbuffer( GL_RENDERBUFFER, depth_rb); glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); glBindRenderbuffer( GL_RENDERBUFFER, 0); glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, depth_rb);
Но не помогло (делали по примеру). OpenGL мягко говоря вообще не знаю (методы эти увидел сегодня) но рабочий код очень скоро будет нужен. Надеюсь на Вашу помощь, мои невероятные друзья!(с)
upd:
немного покурили и "додумались" что аттачить данные надо не к дефолтным буферам а друг к другу и сделали так:
glGenTextures (1, &bufferData ); glBindTexture ( GL_TEXTURE_2D, bufferData ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA16, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 ); glGenFramebuffers ( 1, &bufferID ); glBindFramebuffer( GL_DRAW_FRAMEBUFFER, bufferID); glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bufferData, 0); glGenRenderbuffers( 1, &depth_rb); glBindRenderbuffer( GL_RENDERBUFFER, depth_rb); glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, depth_rb);
вот, получили гору "мусора" на экране : (
.L
> GL_RGBA16
> GL_UNSIGNED_BYTE
Пока увидел только это.
Вообще не понятно как в таком примитивном расширении можно не разобраться.
Покажи весь код по работе с FBO.
На всякий случай, код, как у меня сделано, и это всегда и везде работало, причём сразу:
fbo::bind () { glBindFramebuffer ( GL_FRAMEBUFFER, ID), glViewport ( 0, 0, width, height), glDrawBuffer ( GL_COLOR_ATTACHMENT0), glReadBuffer ( GL_COLOR_ATTACHMENT0); } fbo::unbind ( ) { glBindFramebuffer ( GL_FRAMEBUFFER, 0), glDrawBuffer ( GL_BACK), glReadBuffer ( GL_BACK), screenViewPort ( ); }
у тебя так сделано?
fbo::create (int width, int height, int renderBufferFormat) { glGenFramebuffers ( 1, &ID), glBindFramebuffer ( GL_FRAMEBUFFER, ID); if( renderBufferFormat) { glGenRenderbuffers ( 1, &renderID), glBindRenderbuffer ( GL_RENDERBUFFER, renderID), glRenderbufferStorage ( GL_RENDERBUFFER, renderBufferFormat, width, height), glFramebufferRenderbuffer ( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderID); if( renderBufferFormat == GL_DEPTH24_STENCIL8) glFramebufferRenderbuffer ( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderID); } } fbo::attachTexture ( int id, int attachment) { glFramebufferTexture2D ( GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, id, 0); }
Если у тебя всё примерно так же, значит ошибки где-то ещё.
Вобщем то сейчас такая картина
создаем glGenTextures(1, &bufferData); glBindTexture(GL_TEXTURE_2D, bufferData); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT, 0); glBindTexture(GL_TEXTURE_2D, 0); glGenRenderbuffers(1, &depth_rb); glBindRenderbuffer(GL_RENDERBUFFER, depth_rb); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); glBindRenderbuffer(GL_RENDERBUFFER, 0); glGenFramebuffers(1, &bufferID); glBindFramebuffer(GL_FRAMEBUFFER, bufferID); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bufferData, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rb); glBindFramebuffer(GL_FRAMEBUFFER, 0);
далее рендер
glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, bufferID); ставим шейдер и рисуем графику вот таким шейдером покажу, то в чем я не уверен #extension GL_EXT_gpu_shader4 : enable varying out vec4 gbuffer; gbuffer = vec4 ( normal, depth); <- что тут лежит особо не важно, можно позицию положить, можно нормали, сути вопроса и проблемы не решает отрисовали ? закрываем шейдеры и т/д/ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); следующий пасс ( хочу получить то, что получилось в прошлом шаге отрисовав шейдером квад на весь экран ( просто чтобы посмотреть как работает и что у нас в текстуре получилось ) glDisable(GL_DEPTH_TEST); glActiveTexture ( GL_TEXTURE0 ); glBindTexture ( GL_TEXTURE_2D, bufferData); ставим травиальный шейдер и по текстурным координатам вынимаем данные uniform sampler2D dataMap; vec4 nz = texture2D ( dataMap, texCoord.xy ); gl_FragColor = vec4 ( nz.xyz, 1.0 );
так, ну, а теперь суть
итак, если убрать - glEnable(GL_DEPTH_TEST);
рисуется объект, но с багами ( не работает DEPTH_TEST )
если оставляем все как показано, на экране мусор
далее если пишем такой код
glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->getBuffer()); все, как в прошлом шаге за исключением шейдера //#extension GL_EXT_gpu_shader4 : enable //varying out vec4 gbuffer; gl_FragColor = vec4 ( normal, depth); //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
то есть, только рисуем модель с DEPTH_TEST, чтобы убедится - работает все правильно !!
где ошибаемся мы ?
I
> где ошибаемся мы ?
Ну для начала исправь формат текстуры, потом, если что-то всё равно неправильно, внимательно посмотри на мой код несколько раз.
I
> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> glBindFramebuffer(GL_DRAW_FRAMEBUFFER, bufferID);
Уверен в правильности порядка этих операций? И ещё раз внимательно посмотри как правильно его биндить.
Можешь попробовать рисовать в окно без очистки глубины, тоже ничего красивого не выйдет.
SNVampyre
> Ну для начала исправь формат текстуры, потом, если что-то всё равно неправильно, внимательно посмотри на мой код несколько раз.
не могли бы пояснить ? формат текстуры мне нужен для хранения в ней не только глубины, или вы о другом ?
> Уверен в правильности порядка этих операций? И ещё раз внимательно посмотри как правильно его биндить.
не особо уверен, но разницы не какой не увидел
вобщем сделал bind/unbind, как у вас
проверил еще создание, переписал под ваш пример
по сути не чего так и не изменилось ( больше не чего не заметили ?
I
> не особо уверен, но разницы не какой не увидел
Ну просто в твоём коде не было очистки глубины в fbo :)
Ну а формат текстуры просто такой, который никто не использует. Используй GL_RGBA16F без извращений для больных.
SNVampyre
>
> Ну просто в твоём коде не было очистки глубины в fbo :)
> Ну а формат текстуры просто такой, который никто не использует. Используют
> GL_RGBA8, GL_R11F_G11F_B10F, GL_RGBA16F и варианты с 8 или 16F RED/RG. Всё
> остальное на свой страх и риск.
> Больше никаких проблем не должно быть.
Хм... А ведь в RG16F можно запихать depth32?
-Eugene-
> Хм... А ведь в RG16F можно запихать depth32?
Зачем? Для этого есть GL_R32F.
SNVampyre
> Всё остальное на свой страх и риск.
-Eugene-
Детский сад.
SNVampyre
> Вообще не понятно как в таком примитивном расширении можно не разобраться.
вначале его спек нужно весь прочитать :)
.L
I
С форматом вершин всё нормально. Никаких проблем тут не будет.
Ну а по обрывкам кода мало что сказать можно. На лицо явное не понимание как всё работает, иначе бы не тусовали местами ГЛ функции на угад, авось заработает.
Очень смущают шейдеры, написаны в стиле OpenGL версии 2.7533333. :D
Какую версию ГЛя юзаете? Третью или вторую?
Ну судя по рендербуферам юзают не 3ю, по крайне мере не хотят.
KpeHDeJIb
А что с рендербуферами не так?
Тема в архиве.