Example #1
0
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;
}
Example #2
0
static void use_fbo_for_bitmap(ALLEGRO_DISPLAY *display,
   ALLEGRO_BITMAP *bitmap, ALLEGRO_FBO_INFO *info)
{
   ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra;
   GLint e;

   if (info->fbo_state == FBO_INFO_UNUSED)
      info->fbo_state = FBO_INFO_TRANSIENT;
   info->owner = bitmap;
   info->last_use_time = al_get_time();
   ogl_bitmap->fbo_info = info;

   /* Bind to the FBO. */
   _al_ogl_bind_framebuffer(info->fbo);

   /* Attach the texture. */
   if (ANDROID_PROGRAMMABLE_PIPELINE(al_get_current_display())) {
      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
         GL_TEXTURE_2D, ogl_bitmap->texture, 0);
   }
   else {
      glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
         GL_TEXTURE_2D, ogl_bitmap->texture, 0);
   }
   e = glGetError();
   if (e) {
      ALLEGRO_DEBUG("glFrameBufferTexture2DEXT failed! fbo=%d texture=%d (%s)",
         info->fbo, ogl_bitmap->texture, _al_gl_error_string(e));
   }

   /* See comment about unimplemented functions on Android above */
   if (UNLESS_ANDROID_OR_RPI(
         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(al_get_bitmap_format(bitmap)));
      ALLEGRO_ERROR("*** SWITCHING TO SOFTWARE MODE ***\n");
      _al_ogl_bind_framebuffer(0);
      glDeleteFramebuffersEXT(1, &info->fbo);
      _al_ogl_reset_fbo_info(info);
      ogl_bitmap->fbo_info = NULL;
   }
   else {
      display->ogl_extras->opengl_target = bitmap;
   }
}
Example #3
0
ALLEGRO_FBO_INFO *_al_ogl_persist_fbo(ALLEGRO_DISPLAY *display,
   ALLEGRO_FBO_INFO *transient_fbo_info)
{
   ALLEGRO_OGL_EXTRAS *extras = display->ogl_extras;
   int i;
   ASSERT(transient_fbo_info->fbo_state == FBO_INFO_TRANSIENT);

   for (i = 0; i < ALLEGRO_MAX_OPENGL_FBOS; i++) {
      if (transient_fbo_info == &extras->fbos[i]) {
         ALLEGRO_FBO_INFO *new_info = al_malloc(sizeof(ALLEGRO_FBO_INFO));
         *new_info = *transient_fbo_info;
         new_info->fbo_state = FBO_INFO_PERSISTENT;
         _al_ogl_reset_fbo_info(transient_fbo_info);
         ALLEGRO_DEBUG("Persistent FBO: %u\n", new_info->fbo);
         return new_info;
      }
   }

   ALLEGRO_ERROR("Could not find FBO %u in pool\n", transient_fbo_info->fbo);
   return transient_fbo_info;
}
Example #4
0
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
}