Beispiel #1
0
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));
   }
}
Beispiel #2
0
static void ogl_unlock_region_nonbb_fbo_writeonly(ALLEGRO_BITMAP *bitmap,
   ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format)
{
   const int lock_format = bitmap->locked_region.format;
   const int orig_pixel_size = al_get_pixel_size(orig_format);
   const int dst_pitch = bitmap->lock_w * orig_pixel_size;
   unsigned char * const tmpbuf = al_malloc(dst_pitch * bitmap->lock_h);
   GLenum e;

   _al_convert_bitmap_data(
      ogl_bitmap->lock_buffer,
      bitmap->locked_region.format,
      -bitmap->locked_region.pitch,
      tmpbuf,
      orig_format,
      dst_pitch,
      0, 0, 0, 0,
      bitmap->lock_w, bitmap->lock_h);

   glTexSubImage2D(GL_TEXTURE_2D, 0,
      bitmap->lock_x, gl_y,
      bitmap->lock_w, bitmap->lock_h,
      get_glformat(orig_format, 2),
      get_glformat(orig_format, 1),
      tmpbuf);
   e = glGetError();
   if (e) {
      ALLEGRO_ERROR("glTexSubImage2D for format %d failed (%s).\n",
         lock_format, _al_gl_error_string(e));
   }

   al_free(tmpbuf);
}
Beispiel #3
0
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;
}
Beispiel #4
0
static void 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;
   (void) w;

   ogl_bitmap->lock_buffer = al_malloc(pitch * ogl_bitmap->true_h);

   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_format_name(format), _al_gl_error_string(e));
   }

   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;
}
Beispiel #5
0
static void 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;

   glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &old_fbo);

   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ogl_bitmap->fbo_info->fbo);

   ogl_bitmap->lock_buffer = al_malloc(pitch * h);

   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_format_name(format), _al_gl_error_string(e));
   }

   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fbo);

   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;
}
Beispiel #6
0
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);
   }
}
Beispiel #7
0
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;

   /* 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_format_name(lock_format), _al_gl_error_string(e));
   }

   if (popmatrix) {
      glPopMatrix();
   }
}
Beispiel #8
0
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);
   }
}