我正在研究一些Android代码,用于在EGL上下文丢失和重新创建之间缓存和重绘framebuffer对象的颜色缓冲区。开发主要在运行Honeycomb的Xoom平板电脑上进行。无论如何,我想做的是将在FBO上调用glReadPixels()的结果存储在直接的ByteBuffer中,然后将该缓冲区与glTexImage2D()一起使用,并将其重新绘制到(现已清除)帧缓冲区中。所有这些似乎都可以正常工作-ByteBuffer包含正确的值([1,0,0,-1]等,根据Java无法理解无符号字节的像素),似乎没有抛出GlErrors,并且四边形绘制在屏幕的右侧(当前用于测试目的的帧缓冲区的左上四分之一)。
但是,无论我如何尝试,glTexImage2D()始终输出纯黑色纹理。之前,我遇到了一些问题-在显示位图时,我最终放弃了尝试将基本的GLES20.glTexImage2D()与缓冲区一起使用,而转而使用了为您处理位图的GLUtils.glTexImage2D()。不幸的是,这里的选择较少(我确实尝试将ByteBuffer转换为Bitmap,以便我可以使用GLUtils,但收效不大),所以我的想法真的用完了。
谁能想到会导致glTexImage2D()无法正确处理完美的ByteBuffer的任何东西?任何和所有建议都将受到欢迎。
ByteBuffer pixelBuffer;
void storePixels() {
try {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbuf);
pixelBuffer = ByteBuffer.allocateDirect(width * height * 4).order(ByteOrder.nativeOrder());
GLES20.glReadPixels(0, 0, width, height, GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, pixelBuffer);
GLES20.glBindFrameBuffer(GLES20.GL_FRAMEBUFFER, 0);
gfx.checkGlError("store Pixels");
}catch (OutOfMemoryError e) {
pixelBuffer = null;
}
}
void redrawPixels() {
GLES20.glBindFramebuffer(GL20.GL_FRAMEBUFFER, fbuf);
int[] texId = new int[1];
GLES20.glGenTextures(1, texId, 0);
int bufferTex = texId[0];
GLES20.glBindTexture(GL20.GL_TEXTURE_2D, bufferTex);
GLES20.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_LINEAR);
GLES20.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_LINEAR);
GLES20.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S, repeatX ? GL20.GL_REPEAT
: GL20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T, repeatY ? GL20.GL_REPEAT
: GL20.GL_CLAMP_TO_EDGE);
GLES20.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_RGBA, width, height, 0, GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, pixelBuffer);
gfx.drawTexture(bufferTex, width, height, Transform.IDENTITY, width/2, height/2, false, false, 1);
GLES20.glDeleteTextures(1, IntBuffer.wrap(new int[] {bufferTex}));
pixelBuffer = null;
GLES20.glBindFrameBuffer(GLES20.GL_FRAMEBUFFER, 0);
}
gfx.drawTexture()会生成一个四边形并将其绘制到当前绑定的帧缓冲区。该代码已经在我的项目的其他部分进行了很好的测试-在这里不应该成为问题。
最佳答案
对于在家中玩耍的人来说,此代码实际上是完全有效的。还记得当我发誓盲目地说gfx.drawTexture()
已经过充分测试并且不应该成为这里的问题时吗?”是的,那完全是问题所在。我在缓冲要绘制的顶点时并没有通过glDrawElements()
调用实际冲洗它们。哎呀