【问题标题】:Android OpenGL ES 2.0 -- glReadPixels() and glTexImage2D() drawing a black texture?Android OpenGL ES 2.0 -- glReadPixels() 和 glTexImage2D() 绘制黑色纹理?
【发布时间】:2012-04-05 21:54:09
【问题描述】:

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

但是,无论我尝试什么,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() 构建一个四边形并将其绘制到当前绑定的帧缓冲区。该代码已经在我项目的其他部分经过了很好的测试——这不应该是这里的问题。

【问题讨论】:

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


    【解决方案1】:

    对于那些在家玩的人来说,这个代码实际上是完全有效的。还记得当我发誓gfx.drawTexture() 已经过良好测试并且不应该成为这里的问题时“吗?是的,这完全是那里的问题。我正在缓冲顶点以进行绘制,而没有通过glDrawElements() 调用实际刷新它们。哎呀。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-14
      • 1970-01-01
      相关资源
      最近更新 更多