I am writing an android app that does some image editing in a compute shader. The compute shader writes to a texture using imageStore
and I need to get the data back from that texture into a bitmap for the rest of my application to work with.
I am using OpenGL ES 3.1. glGetTexImage
does not exist in ES, so I have to bind the texture to a framebuffer and read pixels from that, as described here: https://stackoverflow.com/a/53993894/5899608
I am running into an issue with glReadPixels
on a framebuffer object which is bound to the texture. Here are the relevant parts of my code.
Texture is created:
int[] textures = new int[1];
GLES31.glGenTextures(1, textures, 0);
mainImageID = textures[0];
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mainImageID);
GLES31.glTexParameterf(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MIN_FILTER, GLES31.GL_NEAREST); // Nearest neighbor scaling
GLES31.glTexParameterf(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MAG_FILTER, GLES31.GL_NEAREST);
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_S, GLES31.GL_CLAMP_TO_EDGE);
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_T, GLES31.GL_CLAMP_TO_EDGE);
GLES31.glTexStorage2D(GLES31.GL_TEXTURE_2D, 1, GLES31.GL_RGBA32F, mWidth, mHeight);
checkGlError("glTexStorage2D mainImageHandle");
Framebuffer is created:
int[] fbos = new int[1];
GLES31.glGenFramebuffers(1, fbos, 0);
mainFBO = fbos[0];
Texture is bound to the compute shader:
GLES31.glActiveTexture(GLES31.GL_TEXTURE2);
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mainImageID);
GLES31.glBindImageTexture(2, mainImageID, 0, false, 0, GLES31.GL_READ_WRITE, GLES31.GL_RGBA32F);
checkGlError("glBindImageTexture mainImageHandle");
Compute shader runs:
GLES31.glDispatchCompute(WORK_GROUPS_X, WORK_GROUPS_Y, WORK_GROUPS_Z);
checkGlError("glDispatchCompute");
GLES31.glFinish();
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0); // release textures
Pixels are read from texture: (ERROR HERE)
GLES31.glBindFramebuffer(GLES31.GL_READ_FRAMEBUFFER, mainFBO);
GLES31.glFramebufferTexture2D(GLES31.GL_READ_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mainImageID, 0);
//checkFramebufferStatus(GLES31.GL_READ_FRAMEBUFFER); // framebuffer is ok: complete, 0 sample buffers
GLES31.glReadBuffer(GLES31.GL_COLOR_ATTACHMENT0);
mTextureRender.checkGlError("glReadBuffer");
GLES31.glBindBuffer(GLES31.GL_PIXEL_PACK_BUFFER, 0);
mTextureRender.checkGlError("glBindBuffer");
mainPixelBuf = ByteBuffer.allocateDirect(mWidth * mHeight * 4);
mainPixelBuf.order(ByteOrder.LITTLE_ENDIAN);
mainPixelBuf.rewind();
GLES31.glReadPixels(0, 0, mWidth, mHeight, GLES31.GL_RGBA, GLES31.GL_UNSIGNED_BYTE, mainPixelBuf); // !!!! ERROR 1282 INVALID_OPERATION !!!!
mTextureRender.checkGlError("glReadPixels mainPixelBuf");
bmp.copyPixelsFromBuffer(mainPixelBuf);
GLES31.glBindFramebuffer(GLES31.GL_READ_FRAMEBUFFER, 0); // unbind fbo
Could someone help me fix this issue?