diff --git a/gfx_es2/fbo.cpp b/gfx_es2/fbo.cpp index bd60a14d0..232ed8577 100644 --- a/gfx_es2/fbo.cpp +++ b/gfx_es2/fbo.cpp @@ -43,6 +43,9 @@ struct FBO { static FBO *g_overriddenBackbuffer; +static GLuint currentDrawHandle_ = 0; +static GLuint currentReadHandle_ = 0; + // On PC, we always use GL_DEPTH24_STENCIL8. // On Android, we try to use what's available. @@ -118,6 +121,9 @@ FBO *fbo_ext_create(int width, int height, int num_color_textures, bool z_stenci // Unbind state we don't need glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glBindTexture(GL_TEXTURE_2D, 0); + + currentDrawHandle_ = fbo->handle; + currentReadHandle_ = fbo->handle; return fbo; } #endif @@ -237,6 +243,9 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F // Unbind state we don't need glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); + + currentDrawHandle_ = fbo->handle; + currentReadHandle_ = fbo->handle; return fbo; } @@ -258,6 +267,37 @@ FBO *fbo_create_from_native_fbo(GLuint native_fbo, FBO *fbo) return fbo; } +static GLenum fbo_get_fb_target(bool read, GLuint **cached) { + bool supportsBlit = gl_extensions.FBO_ARB; +#ifdef USING_GLES2 + supportsBlit = supportsBlit && (gl_extensions.GLES3 || gl_extensions.NV_framebuffer_blit); +#endif + + // Note: GL_FRAMEBUFFER_EXT and GL_FRAMEBUFFER have the same value, same with _NV. + if (supportsBlit) { + if (read) { + *cached = ¤tReadHandle_; + return GL_READ_FRAMEBUFFER; + } else { + *cached = ¤tDrawHandle_; + return GL_DRAW_FRAMEBUFFER; + } + } else { + *cached = ¤tDrawHandle_; + return GL_FRAMEBUFFER; + } +} + +static void fbo_bind_fb_target(bool read, GLuint name) { + GLuint *cached; + GLenum target = fbo_get_fb_target(read, &cached); + + if (*cached != name) { + glBindFramebuffer(target, name); + *cached = name; + } +} + void fbo_unbind() { if (g_overriddenBackbuffer) { fbo_bind_as_render_target(g_overriddenBackbuffer); @@ -275,6 +315,9 @@ void fbo_unbind() { #ifdef IOS bindDefaultFBO(); #endif + + currentDrawHandle_ = 0; + currentReadHandle_ = 0; } void fbo_override_backbuffer(FBO *fbo) { @@ -282,48 +325,24 @@ void fbo_override_backbuffer(FBO *fbo) { } void fbo_bind_as_render_target(FBO *fbo) { - if (gl_extensions.FBO_ARB) { -#ifndef USING_GLES2 - if (true) { -#else - if (gl_extensions.GLES3) { -#endif - // GL_DRAW_FRAMEBUFFER is actually the same value as GL_FRAMEBUFFER so this is a bit redundant. - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo->handle); - } else { - // This will collide with bind_for_read - but there's nothing in ES 2.0 - // that actually separate them anyway of course, so doesn't matter. - glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); - } - }else{ -#ifndef USING_GLES2 - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->handle); -#endif - } + // Without FBO_ARB / GLES3, this will collide with bind_for_read, but there's nothing + // in ES 2.0 that actually separate them anyway of course, so doesn't matter. + fbo_bind_fb_target(false, fbo->handle); // Always restore viewport after render target binding glstate.viewport.restore(); } +void fbo_unbind_render_target() { + fbo_unbind(); +} + // For GL_EXT_FRAMEBUFFER_BLIT and similar. void fbo_bind_for_read(FBO *fbo) { - if (gl_extensions.FBO_ARB) { -#ifndef USING_GLES2 - if (true) { -#else - if (gl_extensions.GLES3 || gl_extensions.NV_framebuffer_blit) { -#endif - // GL_READ_FRAMEBUFFER is defined to the same value as GL_READ_FRAMEBUFFER_NV. - glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle); - } else { - // This will collide with bind_as_render_target - but there's nothing in ES 2.0 - // that actually separate them anyway of course, so doesn't matter. - glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); - } - } else { -#ifndef USING_GLES2 - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->handle); -#endif - } + fbo_bind_fb_target(true, fbo->handle); +} + +void fbo_unbind_read() { + fbo_bind_fb_target(true, 0); } void fbo_bind_color_as_texture(FBO *fbo, int color) { @@ -358,6 +377,9 @@ void fbo_destroy(FBO *fbo) { #endif } + currentDrawHandle_ = 0; + currentReadHandle_ = 0; + glDeleteTextures(1, &fbo->color_texture); delete fbo; } diff --git a/gfx_es2/fbo.h b/gfx_es2/fbo.h index 70e4e9279..9fd942617 100644 --- a/gfx_es2/fbo.h +++ b/gfx_es2/fbo.h @@ -36,6 +36,8 @@ void fbo_bind_as_render_target(FBO *fbo); void fbo_bind_color_as_texture(FBO *fbo, int color); void fbo_bind_for_read(FBO *fbo); void fbo_unbind(); +void fbo_unbind_render_target(); +void fbo_unbind_read(); void fbo_destroy(FBO *fbo); void fbo_get_dimensions(FBO *fbo, int *w, int *h);