コード例 #1
0
ファイル: ogl_display.c プロジェクト: SaiSrini/Shooter
ALLEGRO_BITMAP_OGL* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp)
{
   ALLEGRO_BITMAP_OGL *ogl_backbuffer;
   ALLEGRO_BITMAP *backbuffer;
   ALLEGRO_STATE backup;
   int format;

   ALLEGRO_DEBUG("Creating backbuffer\n");

   al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS);

   // FIXME: _al_deduce_color_format would work fine if the display paramerers
   // are filled in, for WIZ and IPOD
#ifdef ALLEGRO_GP2XWIZ
   format = ALLEGRO_PIXEL_FORMAT_RGB_565; /* Only support display format */
#elif defined ALLEGRO_IPHONE
   format = ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE;
   // TODO: This one is also supported
   //format = ALLEGRO_PIXEL_FORMAT_RGB_565;
#else
   format = _al_deduce_color_format(&disp->extra_settings);
   /* Eww. No OpenGL hardware in the world does that - let's just
    * switch to some default.
    */
   if (al_get_pixel_size(format) == 3) {
      /* Or should we use RGBA? Maybe only if not Nvidia cards? */
      format = ALLEGRO_PIXEL_FORMAT_ABGR_8888;
   }
#endif
   ALLEGRO_TRACE_CHANNEL_LEVEL("display", 1)("Deduced format %s for backbuffer.\n",
      _al_pixel_format_name(format));

   /* Now that the display backbuffer has a format, update extra_settings so
    * the user can query it back.
    */
   _al_set_color_components(format, &disp->extra_settings, ALLEGRO_REQUIRE);
   disp->backbuffer_format = format;

   ALLEGRO_DEBUG("Creating backbuffer bitmap\n");
   al_set_new_bitmap_format(format);
   /* Using ALLEGRO_NO_PRESERVE_TEXTURE prevents extra memory being allocated */
   al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP | ALLEGRO_NO_PRESERVE_TEXTURE);
   backbuffer = _al_ogl_create_bitmap(disp, disp->w, disp->h);
   al_restore_state(&backup);

   if (!backbuffer) {
      ALLEGRO_DEBUG("Backbuffer bitmap creation failed.\n");
      return NULL;
   }
   
   ALLEGRO_TRACE_CHANNEL_LEVEL("display", 1)(
      "Created backbuffer bitmap (actual format: %s)\n",
      _al_pixel_format_name(backbuffer->format));

   ogl_backbuffer = (ALLEGRO_BITMAP_OGL*)backbuffer;
   ogl_backbuffer->is_backbuffer = 1;
   backbuffer->display = disp;

   return ogl_backbuffer;
}
コード例 #2
0
ファイル: ogl_lock.c プロジェクト: liballeg/allegro5
static void ogl_unlock_region_nonbb_nonfbo(ALLEGRO_BITMAP *bitmap,
   ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y)
{
   const int lock_format = bitmap->locked_region.format;
   unsigned char *start_ptr;
   GLenum e;

   if (bitmap->lock_flags & ALLEGRO_LOCK_WRITEONLY) {
      ALLEGRO_DEBUG("Unlocking non-backbuffer non-FBO WRITEONLY\n");
      start_ptr = ogl_bitmap->lock_buffer;
   }
   else {
      ALLEGRO_DEBUG("Unlocking non-backbuffer non-FBO READWRITE\n");
      glPixelStorei(GL_UNPACK_ROW_LENGTH, ogl_bitmap->true_w);
      start_ptr = (unsigned char *)bitmap->lock_data
            + (bitmap->lock_h - 1) * bitmap->locked_region.pitch;
   }

   glTexSubImage2D(GL_TEXTURE_2D, 0,
      bitmap->lock_x, gl_y,
      bitmap->lock_w, bitmap->lock_h,
      get_glformat(lock_format, 2),
      get_glformat(lock_format, 1),
      start_ptr);

   e = glGetError();
   if (e) {
      ALLEGRO_ERROR("glTexSubImage2D for format %s failed (%s).\n",
         _al_pixel_format_name(lock_format), _al_gl_error_string(e));
   }
}
コード例 #3
0
ファイル: ogl_lock.c プロジェクト: liballeg/allegro5
static bool ogl_lock_region_backbuffer(
   ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap,
   int x, int gl_y, int w, int h, int format, int flags)
{
   const int pixel_size = al_get_pixel_size(format);
   const int pitch = ogl_pitch(w, pixel_size);
   GLenum e;

   ogl_bitmap->lock_buffer = al_malloc(pitch * h);
   if (ogl_bitmap->lock_buffer == NULL) {
      return false;
   }

   if (!(flags & ALLEGRO_LOCK_WRITEONLY)) {
      glReadPixels(x, gl_y, w, h,
         get_glformat(format, 2),
         get_glformat(format, 1),
         ogl_bitmap->lock_buffer);
      e = glGetError();
      if (e) {
         ALLEGRO_ERROR("glReadPixels for format %s failed (%s).\n",
            _al_pixel_format_name(format), _al_gl_error_string(e));
         al_free(ogl_bitmap->lock_buffer);
         ogl_bitmap->lock_buffer = NULL;
         return false;
      }
   }

   bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (h - 1);
   bitmap->locked_region.format = format;
   bitmap->locked_region.pitch = -pitch;
   bitmap->locked_region.pixel_size = pixel_size;
   return true;
}
コード例 #4
0
ファイル: ogl_lock.c プロジェクト: liballeg/allegro5
static void ogl_unlock_region_backbuffer(ALLEGRO_BITMAP *bitmap,
      ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y)
{
   const int lock_format = bitmap->locked_region.format;
   bool popmatrix = false;
   GLenum e;
   GLint program = 0;
   ALLEGRO_DISPLAY *display = al_get_current_display();

   if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
      // FIXME: This is a hack where we temporarily disable the active shader.
      // It will only work on Desktop OpenGL in non-strict mode where we even
      // can switch back to the fixed pipeline. The correct way would be to not
      // use any OpenGL 2 functions (like glDrawPixels). Probably we will want
      // separate OpenGL <= 2 (including OpenGL ES 1) and OpenGL >= 3 (including
      // OpenGL ES >= 2) drivers at some point.
      glGetIntegerv(GL_CURRENT_PROGRAM, &program);
      glUseProgram(0);
   }

   /* glWindowPos2i may not be available. */
   if (al_get_opengl_version() >= _ALLEGRO_OPENGL_VERSION_1_4) {
      glWindowPos2i(bitmap->lock_x, gl_y);
   }
   else {
      /* glRasterPos is affected by the current modelview and projection
       * matrices (so maybe we actually need to reset both of them?).
       * The coordinate is also clipped; the small offset was required to
       * prevent it being culled on one of my machines. --pw
       *
       * Consider using glWindowPos2fMESAemulate from:
       * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/
       */
      glPushMatrix();
      glLoadIdentity();
      glRasterPos2f(bitmap->lock_x, bitmap->lock_y + bitmap->lock_h - 1e-4f);
      popmatrix = true;
   }

   glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);
   glDrawPixels(bitmap->lock_w, bitmap->lock_h,
      get_glformat(lock_format, 2),
      get_glformat(lock_format, 1),
      ogl_bitmap->lock_buffer);
   e = glGetError();
   if (e) {
      ALLEGRO_ERROR("glDrawPixels for format %s failed (%s).\n",
         _al_pixel_format_name(lock_format), _al_gl_error_string(e));
   }

   if (popmatrix) {
      glPopMatrix();
   }

   if (program != 0) {
      glUseProgram(program);
   }
}
コード例 #5
0
ファイル: ogl_fbo.c プロジェクト: tsteinholz/SR-Gaming
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;
   }
}
コード例 #6
0
ファイル: ogl_lock.c プロジェクト: liballeg/allegro5
static bool ogl_lock_region_nonbb_readwrite_nonfbo(
   ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap,
   int x, int gl_y, int w, int h, int format)
{
   /* No FBO - fallback to reading the entire texture */
   const int pixel_size = al_get_pixel_size(format);
   const int pitch = ogl_pitch(ogl_bitmap->true_w, pixel_size);
   GLenum e;
   bool ok;
   (void) w;

   ogl_bitmap->lock_buffer = al_malloc(pitch * ogl_bitmap->true_h);
   if (ogl_bitmap->lock_buffer == NULL) {
      return false;
   }

   ok = true;

   glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture);
   glGetTexImage(GL_TEXTURE_2D, 0,
      get_glformat(format, 2),
      get_glformat(format, 1),
      ogl_bitmap->lock_buffer);

   e = glGetError();
   if (e) {
      ALLEGRO_ERROR("glGetTexImage for format %s failed (%s).\n",
         _al_pixel_format_name(format), _al_gl_error_string(e));
      al_free(ogl_bitmap->lock_buffer);
      ogl_bitmap->lock_buffer = NULL;
      ok = false;
   }

   if (ok) {
      bitmap->locked_region.data = ogl_bitmap->lock_buffer +
         pitch * (gl_y + h - 1) + pixel_size * x;
      bitmap->locked_region.format = format;
      bitmap->locked_region.pitch = -pitch;
      bitmap->locked_region.pixel_size = pixel_size;
   }

   return ok;
}
コード例 #7
0
ファイル: ogl_lock.c プロジェクト: liballeg/allegro5
static void ogl_unlock_region_nonbb_fbo_readwrite(ALLEGRO_BITMAP *bitmap,
   ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y)
{
   const int lock_format = bitmap->locked_region.format;
   GLenum e;
   GLint tex_internalformat;

   glTexSubImage2D(GL_TEXTURE_2D, 0, bitmap->lock_x, gl_y,
      bitmap->lock_w, bitmap->lock_h,
      get_glformat(lock_format, 2),
      get_glformat(lock_format, 1),
      ogl_bitmap->lock_buffer);

   e = glGetError();
   if (e) {
      ALLEGRO_ERROR("glTexSubImage2D for format %s failed (%s).\n",
         _al_pixel_format_name(lock_format), _al_gl_error_string(e));
      glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
         GL_TEXTURE_INTERNAL_FORMAT, &tex_internalformat);
      ALLEGRO_DEBUG("x/y/w/h: %d/%d/%d/%d, internal format: %d\n",
         bitmap->lock_x, gl_y, bitmap->lock_w, bitmap->lock_h,
         tex_internalformat);
   }
}
コード例 #8
0
ファイル: ogl_lock.c プロジェクト: liballeg/allegro5
static bool ogl_lock_region_nonbb_readwrite_fbo(
   ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap,
   int x, int gl_y, int w, int h, int format)
{
   const int pixel_size = al_get_pixel_size(format);
   const int pitch = ogl_pitch(w, pixel_size);
   GLint old_fbo;
   GLenum e;
   bool ok;

   glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &old_fbo);
   e = glGetError();
   if (e) {
      ALLEGRO_ERROR("glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT) failed (%s).\n",
         _al_gl_error_string(e));
      return false;
   }

   ok = true;

   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ogl_bitmap->fbo_info->fbo);
   e = glGetError();
   if (e) {
      ALLEGRO_ERROR("glBindFramebufferEXT failed (%s).\n",
         _al_gl_error_string(e));
      ok = false;
   }

   if (ok) {
      ogl_bitmap->lock_buffer = al_malloc(pitch * h);
      if (ogl_bitmap->lock_buffer == NULL) {
         ok = false;
      }
   }

   if (ok) {
      glReadPixels(x, gl_y, w, h,
         get_glformat(format, 2),
         get_glformat(format, 1),
         ogl_bitmap->lock_buffer);
      e = glGetError();
      if (e) {
         ALLEGRO_ERROR("glReadPixels for format %s failed (%s).\n",
            _al_pixel_format_name(format), _al_gl_error_string(e));
      }
   }

   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fbo);

   if (ok) {
      bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (h - 1);
      bitmap->locked_region.format = format;
      bitmap->locked_region.pitch = -pitch;
      bitmap->locked_region.pixel_size = pixel_size;
      return true;
   }

   al_free(ogl_bitmap->lock_buffer);
   ogl_bitmap->lock_buffer = NULL;
   return ok;
}
コード例 #9
0
ファイル: ogl_display.c プロジェクト: SaiSrini/Shooter
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
}