【发布时间】:2015-01-15 17:00:43
【问题描述】:
我需要在 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_FRAMEBUFFER_COMPLETE 但是深度附件的 checkStatus() 是:GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
错误状态的文档:
并非所有的帧缓冲连接点都是帧缓冲连接 完全的。这意味着至少有一个连接点具有 附加的渲染缓冲区或纹理的附加对象不再位于 存在或具有宽度或高度为零的附加图像,或 颜色附加点附加了一个不可颜色渲染的图像, 或者深度附着点具有不可深度渲染的图像 附加,或模板连接点具有不可模板渲染 附上图片。
可呈现颜色的格式包括 GL_RGBA4、GL_RGB5_A1 和 GL_RGB565。 GL_DEPTH_COMPONENT16 是唯一可深度渲染的格式。 GL_STENCIL_INDEX8 是唯一可模板渲染的格式。
即使有这样的描述,我也很茫然。颜色附件效果很好。
编辑:
我在前面提到的状态错误之前的日志中看到了这个:
<core_glTexImage2D:501>: GL_INVALID_OPERATION
似乎是因为这行代码:
texImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, bitmap, 0);
编辑:
我克服了错误。我从通话切换到:
texImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, bitmap, 0);
这实际上是错误的,现在我正在打电话:
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, texWidth, texHeight, 0,
GL_DEPTH_COMPONENT, GLES30.GL_FLOAT, null);
有效。我没有看到更多错误。但是,我仍然遇到问题。
这是直接渲染到默认缓冲区(直接到窗口)的模型:
但是当我尝试渲染附加到我的 FrameBuffer 的纹理时,映射到以下内容:
// 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 //
}
);
它拉伸纹理:
如果我删除左三角形并进行渲染,我会得到:
最后,渲染深度纹理让我全是红色:
【问题讨论】:
-
GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT表示其中一张图片不完整。您的设备是否可能不支持OES_depth_texture扩展?请注意,深度纹理不是 OpenGL ES 2.0 规范的一部分,它们是一种扩展,并且已知某些设备不支持它。 -
另外,如果你的设备支持
KHR_debug,我强烈推荐使用它。使用glDebugMessageCallbackKHR()注册一个日志回调。 -
如何查看设备是否支持
OES_depth_texture?另外,我正在运行 Android 5.0.1 的 Nexus 5 上进行测试 -
另外,我使用的是 Android SDK 附带的 Java 版本的 OpenGL ES。我没有看到
glDebugMessageCallbackKHR()方法。 -
嗯,Nexus 5 应该支持深度纹理,不支持调试输出。
标签: opengl-es opengl-es-2.0 opengl-3