static ALLEGRO_FBO_INFO *ogl_new_fbo(ALLEGRO_DISPLAY *display) { ALLEGRO_FBO_INFO *info; GLint e; info = ogl_find_unused_fbo(display); ASSERT(info->fbo_state != FBO_INFO_PERSISTENT); if (info->fbo_state == FBO_INFO_TRANSIENT) { ALLEGRO_BITMAP_EXTRA_OPENGL *extra = info->owner->extra; extra->fbo_info = NULL; ALLEGRO_DEBUG("Deleting FBO: %u\n", info->fbo); if (ANDROID_PROGRAMMABLE_PIPELINE(al_get_current_display())) { glDeleteFramebuffers(1, &info->fbo); } else { glDeleteFramebuffersEXT(1, &info->fbo); } _al_ogl_reset_fbo_info(info); } else { /* FBO_INFO_UNUSED */ } if (ANDROID_PROGRAMMABLE_PIPELINE(al_get_current_display())) { glGenFramebuffers(1, &info->fbo); } else { glGenFramebuffersEXT(1, &info->fbo); } e = glGetError(); if (e) { ALLEGRO_ERROR("glGenFramebuffersEXT failed\n"); _al_ogl_reset_fbo_info(info); return NULL; } ALLEGRO_DEBUG("Created FBO: %u\n", info->fbo); return info; }
static void setup_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_OGL *ogl_bitmap; if (bitmap->parent) bitmap = bitmap->parent; ogl_bitmap = (void *)bitmap; /* We can't return here. Target's FBO can be taken away by locking * a lot of bitmaps consecutively. * Also affects ex_multiwin; resizing one window affects the other. */ if (false && display->ogl_extras->opengl_target == ogl_bitmap) return; #if !defined ALLEGRO_GP2XWIZ if (!ogl_bitmap->is_backbuffer) { ALLEGRO_FBO_INFO *info = NULL; /* When a bitmap is set as target bitmap, we try to create an FBO for it. */ if (ogl_bitmap->fbo_info == NULL && !(bitmap->flags & ALLEGRO_FORCE_LOCKING)) { #ifdef ALLEGRO_IPHONE /* FIXME This is quite a hack but I don't know how the Allegro extension * manager works to fix this properly (getting extensions properly reported * on iphone. */ if (true) #else if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object || al_get_opengl_extension_list()->ALLEGRO_GL_OES_framebuffer_object) #endif { info = ogl_find_unused_fbo(display); ASSERT(info->fbo_state != FBO_INFO_PERSISTENT); if (info->fbo_state == FBO_INFO_TRANSIENT) { info->owner->fbo_info = NULL; ALLEGRO_DEBUG("Deleting FBO: %u\n", info->fbo); glDeleteFramebuffersEXT(1, &info->fbo); _al_ogl_reset_fbo_info(info); } glGenFramebuffersEXT(1, &info->fbo); ALLEGRO_DEBUG("Created FBO: %u\n", info->fbo); } } else { info = ogl_bitmap->fbo_info; } if (info && info->fbo) { /* Bind to the FBO. */ #ifndef ALLEGRO_IPHONE ASSERT(display->ogl_extras->extension_list->ALLEGRO_GL_EXT_framebuffer_object || display->ogl_extras->extension_list->ALLEGRO_GL_OES_framebuffer_object); #endif if (info->fbo_state == FBO_INFO_UNUSED) info->fbo_state = FBO_INFO_TRANSIENT; info->owner = ogl_bitmap; info->last_use_time = al_get_time(); ogl_bitmap->fbo_info = info; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, info->fbo); /* Attach the texture. */ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ogl_bitmap->texture, 0); if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { /* For some reason, we cannot use the FBO with this * texture. So no reason to keep re-trying, output a log * message and switch to (extremely slow) software mode. */ ALLEGRO_ERROR("Could not use FBO for bitmap with format %s.\n", _al_pixel_format_name(bitmap->format)); ALLEGRO_ERROR("*** SWITCHING TO SOFTWARE MODE ***\n"); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glDeleteFramebuffersEXT(1, &info->fbo); _al_ogl_reset_fbo_info(info); ogl_bitmap->fbo_info = NULL; } else { display->ogl_extras->opengl_target = ogl_bitmap; glViewport(0, 0, bitmap->w, bitmap->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, bitmap->w, bitmap->h, 0, -1, 1); } } } else { display->ogl_extras->opengl_target = ogl_bitmap; // TODO: Might as well have a vtable entry here #ifdef ALLEGRO_IPHONE _al_iphone_setup_opengl_view(display); #else if (display->ogl_extras->extension_list->ALLEGRO_GL_EXT_framebuffer_object || display->ogl_extras->extension_list->ALLEGRO_GL_OES_framebuffer_object) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } glViewport(0, 0, display->w, display->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* We use upside down coordinates compared to OpenGL, so the bottommost * coordinate is display->h not 0. */ glOrtho(0, display->w, display->h, 0, -1, 1); #endif } #else ALLEGRO_DISPLAY_GP2XWIZ_OGL *wiz_disp = (ALLEGRO_DISPLAY_GP2XWIZ_OGL *)display; display->ogl_extras->opengl_target = ogl_bitmap; if (!ogl_bitmap->is_backbuffer) { /* FIXME: implement */ } else { eglMakeCurrent(wiz_disp->egl_display, wiz_disp->egl_surface, wiz_disp->egl_surface, wiz_disp->egl_context); glViewport(0, 0, display->w, display->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* We use upside down coordinates compared to OpenGL, so the bottommost * coordinate is display->h not 0. */ glOrtho(0, display->w, display->h, 0, -1, 1); } #endif }