Opengl es 如何在Android上的OpenGL ES中渲染到深度纹理

Opengl es 如何在Android上的OpenGL ES中渲染到深度纹理,opengl-es,opengl-es-2.0,opengl-3,Opengl Es,Opengl Es 2.0,Opengl 3,我需要在Android中渲染到深度纹理,但我很难理解它。我在网上搜索了几天,拼凑了以下代码: public void loadFrameBuffer(Context context, int resourceId) { final Bitmap bitmap = createBitmap(context, resourceId); // generate the framebuffer and texture object names glGenFramebuffe

我需要在Android中渲染到深度纹理,但我很难理解它。我在网上搜索了几天,拼凑了以下代码:

  public void loadFrameBuffer(Context context, int resourceId) {
    final Bitmap bitmap = createBitmap(context, resourceId);

    // generate the framebuffer and texture object names
    glGenFramebuffers(1, frameBuffers, 0);
    glGenTextures(2, textures, 0);

    // bind color texture and load the texture mip level 0 texels are RGB565
    // no texels need to specified as we are going to draw into the texture
    glBindTexture(GL_TEXTURE_2D, textures[COLOR_TEXTURE]);
    texImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmap, 0);
    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_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    // bind depth texture and load the texture mip level 0
    // no texels need to specified as we are going to draw into
    // the texture
    glBindTexture(GL_TEXTURE_2D, textures[DEPTH_TEXTURE]);
    texImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, bitmap, 0);
    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);

    // bind the framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffers[0]);

    // specify texture as color attachment
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
      GL_TEXTURE_2D, textures[COLOR_TEXTURE],
      0);

    checkStatus();

    // specify texture as depth attachment
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
      GL_TEXTURE_2D, textures[DEPTH_TEXTURE],
      0);

    checkStatus();
  }
颜色附件的checkStatus()成功:GL\u FRAMEBUFFER\u COMPLETE 但是,深度附件的checkStatus()为:GL\u FRAMEBUFFER\u complete\u attachment

错误的文档说明:

并非所有帧缓冲区连接点都是帧缓冲区连接点 完成这意味着至少有一个附着点具有 “渲染缓冲区”或“附加纹理”的附加对象不再位于 存在或具有宽度或高度为零的附加图像,或 颜色附着点附着了非颜色可渲染图像, 或者深度附着点具有不可深度渲染的图像 附着,或模具附着点具有不可渲染的模具 附上图片

颜色可渲染格式包括GL_RGBA4、GL_RGB5_A1和GL_RGB565。 GL_DEPTH_COMPONENT16是唯一的深度渲染格式。 GL_STENCIL_INDEX8是唯一可渲染的模具格式

即使有这样的描述,我也不知所措。颜色附件工作得很好

编辑: 我在前面提到的状态错误之前的日志中看到:

:GL\u无效\u操作

这似乎是因为这一行代码:

texImage2D(GL_纹理2D,0,GL_深度分量,位图,0)

编辑: 我克服了错误。我从通话切换到:

texImage2D(GL_纹理2D,0,GL_深度分量,位图,0)

这实际上是错误的,现在我打电话:

glTexImage2D(GL_纹理_2D,0,GL_深度_分量,texWidth,texHeight,0,
GL_深度分量,GLES30.GL_浮点,空)

这很有效。我看不到更多的错误。然而,我仍然有一个问题

以下是直接渲染到默认缓冲区(直接渲染到窗口)的模型:

但是,当我尝试渲染附加到帧缓冲区的纹理时,贴图如下:

// x, y, z, S, T
      new float[]{
        // left triangle
        -1f, -1f, 0f, 0f, 0f, //
        1f, 1f, 0f, 1f, 1f, //
        -1f, 1f, 0f, 0f, 1f, //

        // right triangle
        -1f, -1f, 0f, 0f, 0f, //
        1f, -1f, 0f, 1f, 0f, //
        1f, 1f, 0f, 1f, 1f //
      }
    );
它会拉伸纹理:

如果移除左三角形并渲染,则得到以下结果:

最后,渲染“深度”纹理会使我全身呈红色:

一切正常,无需修复 你的深度纹理是正确的。没有什么可修的了

问题似乎是你期望的东西更具对比度。我下载了您的图片,并在图像编辑器中增强了对比度:

你可以看到里面有很多细节!然而,这里丢失了大量数据。你的屏幕可能最多有一个8位帧缓冲区,然后我下载一个JPEG格式的结果,它会进一步量化,但是。。。原始深度纹理本身可能是16位。因此,我可以猜测,在我制作上述图像时,我们可能已经丢失了约10位

换句话说,深度缓冲区有16位精度,但屏幕只有8位精度。所以,你当然看不到细节。数据很好

为什么是红色的?
当然是红色的。这是一个只有一个频道的图像。如果要对其进行不同的着色,请使用纹理旋转,或在片段着色器中应用颜色。

GL\u FRAMEBUFFER\u complete\u ATTACHMENT
表示其中一个附加图像不完整。您的设备是否可能不支持
OES\u depth\u纹理
扩展?请注意,深度纹理不是OpenGL ES 2.0规范的一部分,它们是一个扩展,并且已知某些设备不支持深度纹理。此外,如果您的设备支持
KHR_debug
,我强烈建议您使用深度纹理。使用
glDebugMessageCallbackKHR()
注册日志回调。如何检查设备是否支持
OES\u depth\u纹理
?另外,我正在运行安卓5.0.1的股票Nexus5上测试这一点。此外,我正在使用安卓SDK附带的Java版OpenGL ES。我没有看到
glDebugMessageCallbackKHR()
method.Hm,看起来Nexus5应该支持深度纹理,不支持调试输出。