We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi!I'm trying to get working multisampled FBO on Samsung Galaxy S10+ with Mali-G76 (Android 10).Minimal example from spec fails with GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT (8D56) for me.Tried it with 256x256, 1024x768, 4 samples, GL_MAX_SAMPLES_EXT is 4.I'm building app with gl2.h and gl2ext.h and ndk-r19c.
OpenGL version: OpenGL ES 3.2 v1.r19p0-01rel0.###other-sha0123456789ABCDEF0### Compatibility profileMy desired setup is:- bind texture to COLOR_ATTACHMENT_0 (with glFramebufferTexture2DMultisampleEXT)
- bind d24s8 multisampled renderbuffer to both DEPTH_ATTACHMENT and STENCIL_ATTACHMENT (create with glRenderBufferStorageMultisample, bind with glFramebufferRenderBuffer)
Is there any detail I missed about using this extension?
Just for reference, here's a patch on top of the gles3jni example from https://github.com/android/ndk-samples (the same type of code works for the hello-gl2 sample as well) demonstrating how to load the right function pointers, plus how using the non-EXT glRenderbufferStorageMultisample can result in this error (see the #if for good vs non-working code):
diff --git a/gles3jni/app/src/main/cpp/RendererES3.cpp b/gles3jni/app/src/main/cpp/RendererES3.cpp index df71a85..c7366a5 100644 --- a/gles3jni/app/src/main/cpp/RendererES3.cpp +++ b/gles3jni/app/src/main/cpp/RendererES3.cpp @@ -15,6 +15,8 @@ */ #include "gles3jni.h" +#include <GLES2/gl2ext.h> #include <EGL/egl.h> #define STR(s) #s @@ -117,6 +119,55 @@ bool RendererES3::init() { glVertexAttribPointer(OFFSET_ATTRIB, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0); glEnableVertexAttribArray(OFFSET_ATTRIB); glVertexAttribDivisor(OFFSET_ATTRIB, 1); +#if 1 + GLsizei width = 256; + GLsizei height = 256; + GLint samples; + glGetIntegerv(GL_MAX_SAMPLES_EXT, &samples); + + PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)eglGetProcAddress("glRenderbufferStorageMultisampleEXT"); + PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT =(PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)eglGetProcAddress("glFramebufferTexture2DMultisampleEXT"); + + /* Create multisampled depth renderbuffer */ + GLuint depthbuffer; + glGenRenderbuffers(1, &depthbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer); +#if 0 // OK + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, + GL_DEPTH_COMPONENT16, width, height); +#else // Fails + glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, + GL_DEPTH_COMPONENT16, width, height); +#endif + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + /* Create RGBA texture with single mipmap level */ + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_SHORT_4_4_4_4, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); + + /* Create framebuffer object, attach texture and depth renderbuffer */ + GLuint framebuffer; + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, depthbuffer); + glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0, samples); + + /* handle unsupported cases */ + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != + GL_FRAMEBUFFER_COMPLETE) + { + ALOGE("FBO incomplete: %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + } else ALOGE("FBO OK"); + + checkGlError("FBO"); +#endif ALOGV("Using OpenGL ES 3.0 renderer"); return true;
It might be good to double-check any function pointer loader you might be using isn't grabbing the wrong function.
I'll check it and answer tomorrow.Thank you a lot!
Hello.I copy-pasted retrieving glRenderbufferStorageMultisampleEXT pointer as PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC into example and it fixes my issue.The problem was in our engine macro GET_GL_FUNC(func_name, extSuffix) which first looks up function without suffix and only when it is not found looks up EXT version.Thank you for help!
Super, thanks for confirming this was the issue! :)