Android OpenGL ES 2.0 - glReadPixels()和glTexImage2D()绘制黑色纹理?

问题描述:

我正在研究一些Android代码,用于在丢失和重新创建EGL上下文之间缓存和重绘帧缓冲区对象的颜色缓冲区。开发主要发生在运行Honeycomb的Xoom平板电脑上。无论如何,我想要做的就是将调用glOadPixels()的结果存储在FBO的直接ByteBuffer中,然后将该缓冲区与glTexImage2D()一起使用,并将其拖回(现在已清除)framebuffer中。所有这些似乎工作正常 - 根据Java无法理解无符号字节,ByteBuffer包含正确的值(像素为[-1,0,0,-1]等),没有GlErrors似乎被抛出,并且四元组被绘制到屏幕的右侧(为了测试目的,当前是帧缓冲区的左上角)。Android OpenGL ES 2.0 - glReadPixels()和glTexImage2D()绘制黑色纹理?

但是,不管我尝试什么,glTexImage2D()总是输出一个普通的黑色纹理。我之前遇到过一些问题 - 显示位图时,我最终放弃尝试使用带缓冲区的基本GLES20.glTexImage2D(),并跳过使用GLUtils.glTexImage2D(),它会为您处理位图。不幸的是,这里没有什么选择(我实际上已经尝试将ByteBuffer转换为位图,所以我可以使用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()调用喔。