This is just to share something that took me a long time to figure out. If you don't need your Depthbuffer or don't have a Depth Buffer Attachment Point setup in EGL this might help.
For some reason I couldn't get rendering to texture to work setting the render buffer object RBO to depth buffer: like so
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D,
juliaTex[0], 0);
rain.checkGlError("glFramebufferTexture2D");
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER,
GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER,
juliaRBO[0]);
rain.checkGlError("glFramebufferRenderbuffer");
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
Causes error status == GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
If I change render buffer storage to GLES20.GL_RGBA4
, as opposed to GLES20.DEPTH_COMPONENT16
and change GLES20.GL_DEPTH_ATTACHMENT
to GLES20.GL_COLOR_ATTACHMENT0
then the error goes away,
Change this
// create render buffer and bind 16-bit depth buffer
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, juliaRBO[0]);
rain.checkGlError("glBindRenderBuffer");
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.DEPTH_COMPONENT16,
rain.width, rain.height);
to this
// create render buffer and bind 16-bit depth buffer
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, juliaRBO[0]);
rain.checkGlError("glBindRenderBuffer");
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_RGBA4,
rain.width, rain.height);
And the original code to this:
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D,
juliaTex[0], 0);
rain.checkGlError("glFramebufferTexture2D");
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_RENDERBUFFER,
juliaRBO[0]);
rain.checkGlError("glFramebufferRenderbuffer");
then status == GLES20.GL_FRAMEBUFFER_COMPLETE
But the texture is empty.
here is the call to create storage texture
// bind texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, juliaTex[0]);
// clamp texture to edges
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_LINEAR);
rain.checkGlError("glTexParameter JuliaTex");
// create it
/*
int[] buf = new int[rain.width * rain.height];
juliaTexBuff = ByteBuffer.allocateDirect(buf.length
* rain.FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asIntBuffer();
*/
// generate the textures
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA,
rain.width, rain.height, 0, GLES20.GL_RGBA,
GLES20.GL_UNSIGNED_SHORT_4_4_4_4, null);
To get this to work in addition to attaching the render buffer to the color attachment point I swapped the order of the Framebuffer attachments:
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_RENDERBUFFER,
juliaRBO[0]);
rain.checkGlError("glFramebufferRenderbuffer");
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D,
juliaTex[0], 0);
rain.checkGlError("glFramebufferTexture2D");
So that Texture2D is attached to the Framebuffer color layer after Renderbuffer. I assume the last connection point is the point OpenGL ES uses.