Android NDK SDL2 OpenGL ES 2 阴影映射(定向)- 可能吗?

Posted

技术标签:

【中文标题】Android NDK SDL2 OpenGL ES 2 阴影映射(定向)- 可能吗?【英文标题】:Android NDK SDL2 OpenGL ES 2 shadow mapping (directional)- is it possible? 【发布时间】:2016-01-31 22:48:05 【问题描述】:

尝试在 OpenGL 上使用定向阴影映射。需要生成一个深度纹理,不是一个渲染缓冲区(需要能够从中读取)它未来通过。在 android 上运行时不断获取 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT(作为 glCheckFramebufferStatus 的结果)(在 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) 替换。但是我不能用那些在 for android 编译...

【问题讨论】:

gl_shadow_texture_active_n 是干什么用的?另外,您是否正在检查其他 OpenGL 错误? @NicolBolas - gl_blah_texture_active_n 是我跟踪纹理绑定到哪个 glActiveTexture 的一种方式。我的纹理很少,我目前正在使用一对一的 texture_id-to-active_texture_n 架构。大大简化了事情(尽管它使间接的“ActiveTexture”层变得多余......)。是的 - 我正在检查其他 OpenGL 错误。它们都通过了,所以为了便于阅读,我将它们排除在示例代码之外。 "在我目前使用一对一的 texture_id-to-active_texture_n 架构的情况下,我的纹理很少。" 这完全没有意义。如果您正在创建纹理,它应该只用于该目的;创建后,您取消绑定它。 也许我使用了关于“绑定”的错误术语。归根结底,我需要将uniform sampler2D blah_tex; 传递给我的着色器。我这样做的方法是将ActiveTextureGLuint)传递给glUniform1i。因此,我使用的任何纹理都必须与 ActiveTexture 相关联。在某些情况下,可能会在使用它们的绘制调用之前设置“活动纹理”,然后将它们切换到需要差异纹理的下一个绘制调用,我只是将每个纹理设置为一个 activeTexture 一次,并且从不打乱它们.这种思路有问题吗? "在某些情况下,可能会在使用它们的绘图调用之前设置“活动纹理”," 不,这不是“在某些情况下”;这是大多数 OpenGL 应用程序的标准行为。原因是您的方式(保持所有纹理边界并让您更改制服)将您可以拥有的纹理数量限制为可用纹理图像单元的数量。纹理绑定点应该是短暂的;您可以根据需要设置它们,并在不再需要它们时取消设置它们。也许这适用于小例子,但不适用于任何重要的程序。 【参考方案1】:

您没有模板附件,这可能是您收到GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 错误的原因。虽然规范中没有明确说明,但大多数驱动程序在深度附件也存在时需要模板附件。但是,根据实现的不同,您可能会遇到问题,因为使用带有模板附件的GL_DEPTH_COMPONENT16 可能不是受支持的组合(实际上,根据我的经验,通常不支持)。每个驱动程序只需要支持至少一个组合 - 不幸的是,没有办法准确查询组合可能是什么。你基本上只需要猜测并希望它成功。

大多数 Android 实现都支持packed depth stencil format DEPTH24_STENCIL8_OES,并且扩展隐式支持深度是可以采样的纹理。使用它您可能会获得更大的成功(但不能保证成功!)。

【讨论】:

啊。对了。我的解决方案只是使用GL_DEPTH_COMPONENT 而不是GL_DEPTH_COMPONENT16 让它选择任何可用的东西。我不需要创建/附加模板缓冲区。出于兼容性目的,您会建议我无论如何都这样做吗?或者这里的“深度依恋”是否暗示它可能会在其他地方发挥作用?

以上是关于Android NDK SDL2 OpenGL ES 2 阴影映射(定向)- 可能吗?的主要内容,如果未能解决你的问题,请参考以下文章

编译android版本sdl2

使用 NDK、OpenGL ES 和 FFmpeg 的 Android 视频播放器

SDL2 主滴答系统(openGL)

SDL2:如何同时拥有 SDL2 菜单和 OpenGL 上下文?

SDL2 OpenGL 抗锯齿没有效果

SDL2 / Opengl3 无法显示任何内容