glDrawBuffers(...) causes OpenGL ES 3.0 code to crash on Android (Galaxy S5)

No matter what I do i am unable to get glDrawBuffers to be called without crashing my engine. After some attempts without and some online tutorials that don’t seem to agree on whether the instruction is necessary, I have found myself with a single texture being drawn to without it.

for each of my textures I run through and call the following:


                    glFramebufferTexture2D(GL_FRAMEBUFFER,
                                           GL_COLOR_ATTACHMENT0 + targetToBuild, //output target
                                           GL_TEXTURE_2D,
                                           mTargetIds[targetToBuild], 0);

After setting this up with the currently bound framebuffer I created I finish out my operations with the following place holder code:


GLenum targets[4] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
glDrawBuffers(4,targets);

My max color attachment request states I should be able to set 4.

I have no explanation for the crash on call, other than the usual suspicions that don’t make sense given this is an Android 5 device with an OpenGL ES 3.0 supported GPU. Google searches just bring up a vague response about calling Flip() and Rewind() for which I haven’t a clue about (also hardly seem related given the naming).

Thanks in advance.

Are you binding the FBO before calling glDrawBuffers()? If the default framebuffer is bound, tt’s an error to bind more than one draw buffer or to bind anything other than GL_BACK or GL_NONE.

The glDrawBuffers() call is required the first time you bind the FBO. The specification says

For both the default framebuffer and framebuffer objects, the initial state of draw buffers for fragment colors other than zero is NONE.

The glDrawBuffers() state is part of the framebuffer’s state (rather than global state), so you don’t need to call glDrawBuffers() after each glBindFramebuffer() call.

Aside:

The specification actually says

If the GL is bound to a framebuffer object, the ith buffer listed in bufs must be COLOR_ATTACHMENTi or NONE.

I’m fairly sure that’s not literally correct, but is conflating ordinal and cardinal numbering; It should probably say “bufs[i]” or “the buffer with index i” rather than “the ith buffer”. Taken literally, COLOR_ATTACHMENT0 couldn’t be used, as there’s no such thing as a “zeroth” element.

And the reference page is also incorrect (aside from making the same mistake with ordinal numbering). It says:

n may range from zero to the value of GL_MAX_COLOR_ATTACHMENTS.

while the specification says

i in COLOR_ATTACHMENTi may range from zero to the value of MAX_COLOR_ATTACHMENTS minus one.

Yes, I’m calling glBindFramebuffer(GL_FRAMEBUFFER, mFrameID) before calling either glFramebufferTexture2D and glDrawBuffers. mFrameID is the name that glGenFramebuffer returned to me earlier in this same bit of code. This is all on first run or initialization. So we haven’t even started iterating over draw calls or anything of that nature.

I have 4 textures that I have set to my FBO and now I’m calling glDrawBuffers.

So I think I may have made some progress. I managed to get my clear color on all of my textures (green at present):

for the sake of completeness I had to take this right on android:


                GLenum targets[4] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
                //glDrawBuffers(4,targets);
                void* func = eglGetProcAddress("glDrawBuffers");
                ((void(*)(GLsizei, GLenum*) )func)(4,targets);

Apparently glDrawBuffers doesn’t link properly on GLESv3 libraries on android or perhaps my device and these sorts of calls are not uncommon and should work on any device that is running the OS.

This has resulted in a new problem where I have the clear color, but none of my geometry appears to be rendering to those textures. I run tracer and I see my first textures information getting the geometry, unable to see the others for what ever reason. When assigning each texture to be drawn to the screen in my second phases shader program I just get a green screen for each texture (the aforementioned clear color).