Android OpenGL ES 2.0 - glReadPixels () и glTexImage2D () рисуют черную текстуру? - PullRequest
2 голосов
/ 26 августа 2011

Я работаю над кодом Android для кеширования и перерисовки цветового буфера объекта кадрового буфера между потерей и воссозданием контекстов EGL.Разработка в основном происходит на планшете Xoom под управлением Honeycomb.В любом случае, я пытаюсь сохранить результат вызова glReadPixels () для FBO в прямом 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 () создает четырехугольник и, кстати, выводит его в текущий связанный кадровый буфер.Этот код был хорошо протестирован в других частях моего проекта - здесь не должно быть проблем.

1 Ответ

2 голосов
/ 30 августа 2011

Для тех из вас, кто играет дома, этот код на самом деле полностью действителен. Помните, когда я поклялся слепо, что gfx.drawTexture() был хорошо протестирован и не должен быть проблемой здесь? »Да, это была полная проблема. Я буферизовал вершины для рисования, фактически не сбрасывая их через вызов glDrawElements(). Упс.

...