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

时间:2011-08-26 17:13:10

标签: android opengl-es opengl-es-2.0 glreadpixels glteximage2d

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

然而,无论我尝试什么,glTexImage2D()总是输出纯黑色纹理。我之前遇到过一些问题 - 当显示Bitmaps时,我最终放弃了尝试使用Buffers的基本GLES20.glTexImage2D()并跳过使用GLUtils.glTexImage2D(),它为您处理Bitmap。不幸的是,这不是一个选项(我实际上尝试将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()构建一个四边形并顺便将其绘制到当前绑定的帧缓冲区。该代码在我的项目的其他部分已经过充分测试 - 这不应该是问题。

1 个答案:

答案 0 :(得分:2)

对于那些在家里玩的人来说,这段代码实际上是完全有效的。还记得,当我发誓失明gfx.drawTexture()已经过充分测试,不应该是这里的问题吗?是的,这完全是那里的问题。我正在缓冲顶点绘制而不实际冲洗它们{{1呐喊。哎呀。