openframeworks / openFrameworks

openFrameworks is a community-developed cross platform toolkit for creative coding in C++.
http://openframeworks.cc
Other
9.96k stars 2.55k forks source link

ofFbo: broken on Android #5183

Open glungtung opened 8 years ago

glungtung commented 8 years ago

Following code shouldn't draw anything because I don't call fbo.draw() But I get a red screen with a green square at the bottom (y coord is inverted)

ofFbo fbo;

//--------------------------------------------------------------
void ofApp::setup(){
    fbo.allocate(600, 400);
}

//--------------------------------------------------------------
void ofApp::draw(){
    fbo.begin();
    ofClear(125,0,0);
    ofSetColor(0,255,0);
    ofFill();
    ofDrawRectangle(10, 10, 100, 100);
    fbo.end();
}

597ddfc1367a9ba05093f3afa648306f22fd5eba_1_281x500

glungtung commented 8 years ago

Forum discussion here : https://forum.openframeworks.cc/t/opengl-error-with-fbo/24061/8

Ant1r commented 6 years ago

that bug appeared with commit 4c2d00c8ccf2b866345bd2ceb5798087236fae18 (on 20 july 2015, "refactor fbo").

I finally discovered something I can't explain: glBindFramebuffer() seems working only when called from ofFbo class.

If you create a new ofFbo bind function:

void ofFbo::bindme() const{
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
}

which is called by ofGLRenderer::bind() instead of glBindFramebuffer():

void ofGLRenderer::bind(const ofFbo & fbo){
        (...)
    currentFramebufferId = fbo.getId(); // get fbo.fbo
    //glBindFramebuffer(GL_FRAMEBUFFER, currentFramebufferId);
    fbo.bindme();
}

then the bug vanishes. How can that be?

Ant1r commented 6 years ago

note: it is also necessary to change unbinding function:

void ofFbo::unbindme(const GLuint& previousFramebufferID) const{
    glBindFramebuffer(GL_FRAMEBUFFER, previousFramebufferID);
}
void ofGLRenderer::unbind(const ofFbo & fbo){
(...)
    //glBindFramebuffer(GL_FRAMEBUFFER, currentFramebufferId);
    fbo.unbindme(currentFramebufferId);
    fbo.flagDirty();
}

That's really weird...

gsautr commented 6 years ago

Thank you for your solution @Ant1r

alvaroga91 commented 5 years ago

Thank you so much @Ant1r, this solved an issue of being unable to use fbo in a ARMv7 Apalis iMX6! After this, I could perfectly run fboTrailsExample, which I couldn't before.

Ant1r commented 5 years ago

@alvaroga91: My pleasure! Could you just specify which version of openFrameworks you're using, and on which Android version? Thanks!

alvaroga91 commented 5 years ago

@Ant1r, sure! but the truth is I'm not using Android at all, but an embedded Linux built with Yocto (kernel 4.9.87). This board does uses OpenGL, OpenGL ES and EGL (GLX is not supported) for the iMX6 GPU unit (Vivante).


root@apalis-imx6:~# uname -r
4.9.87-2.8.4+g3bb6e3284a1b

root@apalis-imx6:~# ./fboTrailsExample 
[notice ] ofAppEGLWindow: createSurface(): setting up EGL Display
[notice ] ofAppEGLWindow: createSurface(): EGL Display correctly set 0x17404c0
[notice ] ofAppEGLWindow: createSurface(): no current renderer selected
[notice ] ofAppEGLWindow: createSurface(): default renderer detected
[notice ] ofAppEGLWindow: createSurface(): surface created correctly
[notice ] ofAppEGLWindow: createSurface(): API bound correctly
[notice ] ofAppEGLWindow: createSurface(): -----EGL-----
[notice ] ofAppEGLWindow: createSurface(): EGL_VERSION_MAJOR = 1
[notice ] ofAppEGLWindow: createSurface(): EGL_VERSION_MINOR = 5
[notice ] ofAppEGLWindow: createSurface(): EGL_CLIENT_APIS = OpenGL_ES OpenVG
[notice ] ofAppEGLWindow: createSurface(): EGL_VENDOR = Vivante Corporation
[notice ] ofAppEGLWindow: createSurface(): EGL_VERSION = 1.5
[notice ] ofAppEGLWindow: createSurface(): EGL_EXTENSIONS = EGL_KHR_fence_sync EGL_KHR_reusable_sync EGL_KHR_wait_sync EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_gl_renderbuffer_image EGL_EXT_image_dma_buf_import EGL_EXT_client_extensions EGL_KHR_lock_surface EGL_KHR_create_context EGL_KHR_surfaceless_context EGL_EXT_create_context_robustness
[notice ] ofAppEGLWindow: createSurface(): GL_RENDERER = Vivante GC2000
[notice ] ofAppEGLWindow: createSurface(): GL_VERSION  = OpenGL ES-CM 1.1
[notice ] ofAppEGLWindow: createSurface(): GL_VENDOR   = Vivante Corporation

The version of OpenFramework I'm using is of_v0.10.0_linuxarmv7l_release. IMHO, ofFbo might be buggy in ARMv7, because of OpenGL, but I believe this did not happen with a RaspPi 2 that used of_v0.10.0_linuxarmv6l_release (I don't know how RaspPi uses OpenGL tho).

Additionally, I had this issue with this board because of GLX being setted as default even though is not available: https://forum.openframeworks.cc/t/use-only-egl-disabling-glx-calls/31095/2 The solution was to to change the main files to use ofAppEGLWindow and pass that to ofSetupOpenGL.

zkg commented 4 years ago

I just wanted to note that as of 2020 this bug is still present. Thankfully also the hack-workaround still works.

gwitt commented 3 years ago

This workaround fixed crashing when calling fbo.begin() on a Samsung Tab A7. Thanks!