Отображение теней Android NDK SDL2 OpenGL ES 2 (направленное) — возможно ли это?

Попытка использовать направленное отображение теней в OpenGL. Необходимо сгенерировать текстуру глубины, которая не является буфером рендеринга (должна быть возможность считывания из него), чтобы она прошла в будущем. Продолжайте получать GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT (как результат glCheckFramebufferStatus) при работе на Android (не получайте ошибку при работе на OSX).

Вот мой код:

 //Shadow
  //gen tex
  gl_shadow_bogus_texture_active_n = 7;
  glActiveTexture(GL_TEXTURE0+gl_shadow_bogus_texture_active_n);
  glGenTextures(1, &gl_shadow_bogus_texture_buff_id);
  glBindTexture(GL_TEXTURE_2D, gl_shadow_bogus_texture_buff_id);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,tex_dim.x,tex_dim.y,0,GL_RGB,GL_UNSIGNED_BYTE,0);

  //gen depth
  gl_shadow_texture_active_n = 4;
  glActiveTexture(GL_TEXTURE0+gl_shadow_texture_active_n);
  glGenTextures(1, &gl_shadow_texture_buff_id);
  glBindTexture(GL_TEXTURE_2D, gl_shadow_texture_buff_id);
  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_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT16,1024,1024,0,GL_DEPTH_COMPONENT,GL_FLOAT,0);

  glGenFramebuffers(1, &gl_shadow_framebuffer_id); //gen fb
  glBindFramebuffer(GL_FRAMEBUFFER, gl_shadow_framebuffer_id); //bind fb
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl_shadow_bogus_texture_buff_id, 0); //attach tex
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gl_shadow_texture_buff_id, 0); //attach depth

обратите внимание, что вся штука gl_shadow_bogus_texture_buff_id (генерация и привязка цветовой текстуры) — это всего лишь попытка заполнить фреймбуфер, таким образом избавившись от ошибки. На самом деле меня не волнуют данные о цвете.

еще одно замечание: «color tex gen/bind» не требуется на Mac и может быть заменен на glDrawBuffer(GL_NONE) и glReadBuffer(GL_NONE). Но я не могу скомпилировать с теми, что для Android...


person Phildo    schedule 31.01.2016    source источник
comment
Для чего gl_shadow_texture_active_n? Кроме того, вы проверяете наличие других ошибок OpenGL?   -  person Nicol Bolas    schedule 01.02.2016
comment
@NicolBolas - gl_blah_texture_active_n - это средство, с помощью которого я могу отслеживать, к какой glActiveTexture привязана эта текстура. У меня достаточно текстур, и в настоящее время я использую архитектуру типа texture_id-to-active_texture_n один к одному. Значительно упрощает вещи (хотя и делает слой ActiveTexture косвенного обращения излишним...). И да, я проверяю другие ошибки OpenGL. Все они проходят, поэтому я исключил их из примера кода для удобочитаемости.   -  person Phildo    schedule 01.02.2016
comment
У меня достаточно текстур, и в настоящее время я использую архитектуру вида texture_id-to-active_texture_n один к одному. В этом нет никакого смысла. Если вы создаете текстуру, она должна быть привязана только для этой цели; после создания вы отвязываете его.   -  person Nicol Bolas    schedule 01.02.2016
comment
Возможно, я использую неправильную терминологию в отношении привязки. В конце концов, мне нужно передать uniform sampler2D blah_tex; моему шейдеру. Я делаю это, передавая ActiveTexture (GLuint) в glUniform1i. Поэтому любая текстура, которую я использую, должна быть связана с ActiveTexture. Там, где в некоторых случаях можно установить активные текстуры непосредственно перед вызовом отрисовки, который их использует, а затем переключить их для следующего вызова отрисовки, для которого нужны diff текстуры, я просто устанавливаю каждую текстуру в активную текстуру один раз и никогда не перемешиваю их. Что-то не так с этим ходом мыслей?   -  person Phildo    schedule 01.02.2016
comment
Где в некоторых случаях можно установить активные текстуры непосредственно перед вызовом отрисовки, который их использует Нет, это не в некоторых случаях; это стандартное поведение для большинства приложений OpenGL. Причина в том, что ваш способ, который сохраняет границы всех текстур и заставляет вас менять униформу, ограничивает количество текстур, которые вы можете иметь вокруг, до количества доступных блоков изображения текстуры. Точки привязки текстур должны быть эфемерными; вы устанавливаете их по мере необходимости и отключаете их, когда они больше не нужны. Может быть, это работает для небольших примеров, но не для каких-либо важных программ.   -  person Nicol Bolas    schedule 01.02.2016
comment
что точно оправдало мое утверждение «У меня мало текстур…» и подкрепило мою выраженную модель, описывающую этот слой косвенности… Ваш комментарий «Это вообще не имеет смысла, а общий агрессивный тон бесполезен и, ну, в общем, странен. Чего ты хочешь от меня?   -  person Phildo    schedule 02.02.2016
comment
От тебя? Я ничего не жду. Я бы хотел, чтобы все, кто читает ваш код, знали, что это не пример хорошей практики программирования для OpenGL. Вы можете соглашаться или не соглашаться с этой оценкой, но я не хочу, чтобы кто-нибудь понял, что использование текстурных блоков в качестве хранилища для текстурных объектов широко используется или является хорошей идеей.   -  person Nicol Bolas    schedule 02.02.2016


Ответы (1)


У вас нет прикрепленного шаблона, поэтому, вероятно, вы получаете ошибку GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT. Хотя это прямо не указано в спецификации, большинству драйверов требуется крепление трафарета, когда также присутствует крепление глубины. Однако, в зависимости от реализации, вы можете столкнуться с проблемами, потому что использование GL_DEPTH_COMPONENT16 с прикрепленным шаблоном может не поддерживаться комбинацией (фактически, по моему опыту, обычно это не так). Каждый драйвер должен поддерживать хотя бы одну комбинацию — к сожалению, нет возможности узнать, какой именно может быть комбинация. Вы в основном просто должны угадать и надеяться, что это удастся.

Большинство реализаций Android поддерживают упакованный формат шаблона глубины DEPTH24_STENCIL8_OES, и расширение неявно поддерживает глубину, являющуюся текстурой, которую можно сэмплировать. Скорее всего, вы добьетесь значительно большего успеха, используя его (но успех не гарантирован!).

person MuertoExcobito    schedule 01.02.2016
comment
Ах. Право на. Решением для меня было просто использовать GL_DEPTH_COMPONENT, а не GL_DEPTH_COMPONENT16, чтобы позволить ему выбирать все, что доступно. Мне не нужно было создавать/прикреплять трафаретный буфер. Вы бы порекомендовали мне сделать это в любом случае в целях совместимости? Или просто глубинная привязанность, функционирующая здесь, подразумевает, что она, вероятно, будет работать где-то еще? - person Phildo; 01.02.2016