ПрограммированиеФорумГрафика

OpenGL: проблемы с рендером в текстуру и depth-тестом

Страницы: 1 2 3 4 Следующая »
#0
2:20, 12 апр 2011

Всем привет.

Есть такая проблема.  С одним знакомым сидим курим баг - рендерим не очень сложную модельку напрямую в 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);

вот, получили гору "мусора" на экране : (

#1
3:14, 12 апр 2011

.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);
}

Если у тебя всё примерно так же, значит ошибки где-то ещё.

#2
3:20, 12 апр 2011

Вобщем то сейчас такая картина

создаем 
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, чтобы убедится - работает все правильно !!

где ошибаемся мы ?

#3
3:28, 12 апр 2011

I
> где ошибаемся мы ?
Ну для начала исправь формат текстуры, потом, если что-то всё равно неправильно, внимательно посмотри на мой код несколько раз.

I
> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> glBindFramebuffer(GL_DRAW_FRAMEBUFFER, bufferID);
Уверен в правильности порядка этих операций? И ещё раз внимательно посмотри как правильно его биндить.

#4
3:35, 12 апр 2011

Можешь попробовать рисовать в окно без очистки глубины, тоже ничего красивого не выйдет.

#5
4:02, 12 апр 2011

SNVampyre
> Ну для начала исправь формат текстуры, потом, если что-то всё равно неправильно, внимательно посмотри на мой код несколько раз.
не могли бы пояснить ? формат текстуры мне нужен для хранения в ней не только глубины, или вы о другом ?

> Уверен в правильности порядка этих операций? И ещё раз внимательно посмотри как правильно его биндить.
не особо уверен, но разницы не какой не увидел

вобщем сделал bind/unbind, как у вас
проверил еще создание, переписал под ваш пример

по сути не чего так и не изменилось ( больше не чего не заметили ?

#6
4:57, 12 апр 2011

I
> не особо уверен, но разницы не какой не увидел
Ну просто в твоём коде не было очистки глубины в fbo :)
Ну а формат текстуры просто такой, который никто не использует. Используй GL_RGBA16F без извращений для больных.

#7
6:14, 12 апр 2011

SNVampyre
>
> Ну просто в твоём коде не было очистки глубины в fbo :)
> Ну а формат текстуры просто такой, который никто не использует. Используют
> GL_RGBA8, GL_R11F_G11F_B10F, GL_RGBA16F и варианты с 8 или 16F RED/RG. Всё
> остальное на свой страх и риск.
> Больше никаких проблем не должно быть.
Хм... А ведь в RG16F можно запихать depth32?

#8
6:36, 12 апр 2011

-Eugene-
> Хм... А ведь в RG16F можно запихать depth32?
Зачем? Для этого есть GL_R32F.

#9
6:38, 12 апр 2011

SNVampyre
> Всё остальное на свой страх и риск.

#10
6:51, 12 апр 2011

-Eugene-
Детский сад.

#11
8:38, 12 апр 2011

SNVampyre
> Вообще не понятно как в таком примитивном расширении можно не разобраться.

вначале его спек нужно весь прочитать :)

#12
9:37, 12 апр 2011

.L
I
С форматом вершин всё нормально. Никаких проблем тут не будет.
Ну а по обрывкам кода мало что сказать можно. На лицо явное не понимание как всё работает, иначе бы не тусовали местами ГЛ функции на угад, авось заработает.
Очень смущают шейдеры, написаны в стиле OpenGL версии 2.7533333. :D
Какую версию ГЛя юзаете? Третью или вторую?

#13
9:40, 12 апр 2011

Ну судя по рендербуферам юзают не 3ю, по крайне мере не хотят.

#14
9:55, 12 апр 2011

KpeHDeJIb
А что с рендербуферами не так?

Страницы: 1 2 3 4 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.