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

FBO OpenGL 2.0.

#0
19:33, 15 янв 2012

Создаю (как во всех примерах) буфер и текстуру:

  glGenTextures(1, &m_depthTexture);

  // сделаем текстуру активной
  glActiveTexture(GL_TEXTURE7);
  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, m_depthTexture);

  // установим параметры фильтрации текстуры - линейная фильтрация
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  // установим параметры "оборачиваниея" текстуры - отсутствие оборачивания
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  // соаздем "пустую" текстуру под depth-данные
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_SIZE, SHADOW_SIZE, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
  
  // создаем FBO для рендера глубины в текстуру
  glGenFramebuffers(1, &m_fbo);
  // делаем созданный FBO текущим
  glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);

  // отключаем вывод цвета в текущий FBO
  glDrawBuffer(GL_NONE);
  glReadBuffer(GL_NONE);

  // указываем для текущего FBO текстуру, куда следует производить рендер глубины
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);

Затем есть две функции:

void Render::beginFrameBuffer()
{
  glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
  glViewport(0, 0, SHADOW_SIZE, SHADOW_SIZE);
  setShader(SHADER_FLAT);
  m_isDepthRender = true;
}

void Render::endFrameBuffer()
{
  glBindFramebuffer(GL_FRAMEBUFFER,0);
  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
  glViewport(0, 0, m_width, m_height);
  m_isDepthRender = false;
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

Затем просто рисую все объекты один раз с применением beginFrameBuffer вначале, затем второй раз после endFrameBuffer. При этом в шейдере пытаюсь обратиться к текстуре. Если сделать бинд какой-то другой текстуры, то все норм. А тут чисто белая текстура. Может что-то надо разрешить, или я чего-то не понимаю...

#1
19:39, 15 янв 2012

AntonV
> glActiveTexture(GL_TEXTURE7);
> glEnable(GL_TEXTURE_2D);

Это зачем?

#2
19:42, 15 янв 2012

AntonV
ты пытаешься при рендере в текстуру применить шейдер, который обращается к этой самой текстуре? так нельзя.

#3
22:39, 15 янв 2012

Когда я рендерю в первый проход, я использую обычный шейдер без теней, а во втором проходе использую специальный, где текстура 7 и должна иметь значения глубины. Если я неправ, то в чем, и как это исправить?

#4
23:21, 15 янв 2012

AntonV
В ручную глубину хочешь получить? Как то странно, по-моему этим FBO сам занимается.

#5
23:23, 15 янв 2012

Для создания теней разве есть более простой подход?

#6
23:54, 15 янв 2012

AntonV
> А тут чисто белая текстура.
Возможно выключена запись в буфер глубины вообще? Либо на самом деле текстура не белая, но глазом не видно различия из-за разницы между ближней и дальней плоскостями отсечения? Возьми gDEBugger и погляди что лежит в этой текстуре после рендера по факту.

#7
1:15, 16 янв 2012

KpeHDeJIb
> Возможно выключена запись в буфер глубины вообще
glEnable(GL_DEPTH_TEST); - такая строчка есть. На всякий случай добавил glDepthMask(GL_TRUE);

Может надо как-то настроить дополнительно этот буффер, или еще что? Не влияет ли то, что я в процессе рендера меняю активную текстуру?

#8
1:37, 16 янв 2012

Все, вопрос решен. Помог дебагер.

#9
9:25, 16 янв 2012

AntonV
> Когда я рендерю в первый проход, я использую обычный шейдер без теней, а во
> втором проходе использую специальный, где текстура 7 и должна иметь значения
> глубины. Если я неправ, то в чем, и как это исправить?

Ну у тебя текстура делается активной один раз, а надо каждый кадр.
glEnable(GL_TEXTURE_2D); вообще не нужно.

#10
11:02, 16 янв 2012

Кстати, depth-рендербуфер надо очистить (glClear). Иначе там будет мусор (или, например, вообще белый экран) и glDepthFunc(GL_LEQUAL) всегда будет проигрывать.

#11
12:35, 16 янв 2012

ALPINE
У него нет рендербуфера.

#12
13:31, 16 янв 2012

Executor
а, ну я имел в виду текстуру. текстура по умолчанию разве пустая? операцию по очистке никто же не проводил

#13
15:57, 16 янв 2012

ALPINE
Ну у него же чистится:

  glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Правда у него тут и цвет, а это уже лишнее, так как у него только глубина есть.

#14
16:56, 16 янв 2012

Ой, точно. Проглядел.

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

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