예제 #1
0
void
_cogl_texture_driver_upload_to_gl (GLenum       gl_target,
                                   GLuint       gl_handle,
                                   CoglBitmap  *source_bmp,
                                   GLint        internal_gl_format,
                                   GLuint       source_gl_format,
                                   GLuint       source_gl_type)
{
  int bpp = _cogl_get_format_bpp (source_bmp->format);
  CoglBitmap bmp = *source_bmp;
  gboolean bmp_owner = FALSE;

  /* If the rowstride can't be specified with just GL_ALIGNMENT alone
     then we need to copy the bitmap because there is no GL_ROW_LENGTH */
  if (source_bmp->rowstride / bpp != source_bmp->width)
    {
      bmp.rowstride = bpp * bmp.width;
      bmp.data = g_malloc (bmp.rowstride * bmp.height);
      bmp_owner = TRUE;

      _cogl_bitmap_copy_subregion (source_bmp,
                                   &bmp,
                                   0, 0, 0, 0,
                                   bmp.width,
                                   bmp.height);
    }

  /* Setup gl alignment to match rowstride and top-left corner */
  _cogl_texture_driver_prep_gl_for_pixels_upload (bmp.rowstride,
                                                  bpp);

  GE( glBindTexture (gl_target, gl_handle) );

  GE( glTexImage2D (gl_target, 0,
                    internal_gl_format,
                    bmp.width, bmp.height,
                    0,
                    source_gl_format,
                    source_gl_type,
                    bmp.data) );

  if (bmp_owner)
    g_free (bmp.data);
}
예제 #2
0
void
_cogl_texture_driver_upload_to_gl (GLenum       gl_target,
                                   GLuint       gl_handle,
                                   gboolean     is_foreign,
                                   CoglBitmap  *source_bmp,
                                   GLint        internal_gl_format,
                                   GLuint       source_gl_format,
                                   GLuint       source_gl_type)
{
    int bpp = _cogl_get_format_bpp (_cogl_bitmap_get_format (source_bmp));
    int rowstride;
    int bmp_width = _cogl_bitmap_get_width (source_bmp);
    int bmp_height = _cogl_bitmap_get_height (source_bmp);
    CoglBitmap *bmp;
    guint8 *data;

    bmp = prepare_bitmap_alignment_for_upload (source_bmp);
    rowstride = _cogl_bitmap_get_rowstride (bmp);

    /* Setup gl alignment to match rowstride and top-left corner */
    _cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp);

    _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);

    data = _cogl_bitmap_bind (bmp, COGL_BUFFER_ACCESS_READ, 0);

    GE( glTexImage2D (gl_target, 0,
                      internal_gl_format,
                      bmp_width, bmp_height,
                      0,
                      source_gl_format,
                      source_gl_type,
                      data) );

    _cogl_bitmap_unbind (bmp);

    cogl_object_unref (bmp);
}
static CoglBool
_cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx,
                                      GLenum gl_target,
                                      GLuint gl_handle,
                                      CoglBool is_foreign,
                                      GLint height,
                                      GLint depth,
                                      CoglBitmap *source_bmp,
                                      GLint internal_gl_format,
                                      GLuint source_gl_format,
                                      GLuint source_gl_type,
                                      CoglError **error)
{
  CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp);
  int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format);
  int rowstride = cogl_bitmap_get_rowstride (source_bmp);
  int bmp_width = cogl_bitmap_get_width (source_bmp);
  int bmp_height = cogl_bitmap_get_height (source_bmp);
  uint8_t *data;
  GLenum gl_error;

  _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);

  /* If the rowstride or image height can't be specified with just
     GL_ALIGNMENT alone then we need to copy the bitmap because there
     is no GL_ROW_LENGTH */
  if (rowstride / bpp != bmp_width ||
      height != bmp_height / depth)
    {
      CoglBitmap *bmp;
      int image_height = bmp_height / depth;
      CoglPixelFormat source_bmp_format = cogl_bitmap_get_format (source_bmp);
      int i;

      _cogl_texture_driver_prep_gl_for_pixels_upload (ctx, bmp_width * bpp, bpp);

      /* Initialize the texture with empty data and then upload each
         image with a sub-region update */

      /* Clear any GL errors */
      while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
        ;

      ctx->glTexImage3D (gl_target,
                         0, /* level */
                         internal_gl_format,
                         bmp_width,
                         height,
                         depth,
                         0,
                         source_gl_format,
                         source_gl_type,
                         NULL);

      if (_cogl_gl_util_catch_out_of_memory (ctx, error))
        return FALSE;

      bmp = _cogl_bitmap_new_with_malloc_buffer (ctx,
                                                 bmp_width,
                                                 height,
                                                 source_bmp_format,
                                                 error);
      if (!bmp)
        return FALSE;

      for (i = 0; i < depth; i++)
        {
          if (!_cogl_bitmap_copy_subregion (source_bmp,
                                            bmp,
                                            0, image_height * i,
                                            0, 0,
                                            bmp_width,
                                            height,
                                            error))
            {
              cogl_object_unref (bmp);
              return FALSE;
            }

          data = _cogl_bitmap_gl_bind (bmp,
                                       COGL_BUFFER_ACCESS_READ, 0, error);
          if (!data)
            {
              cogl_object_unref (bmp);
              return FALSE;
            }

          /* Clear any GL errors */
          while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
            ;

          ctx->glTexSubImage3D (gl_target,
                                0, /* level */
                                0, /* xoffset */
                                0, /* yoffset */
                                i, /* zoffset */
                                bmp_width, /* width */
                                height, /* height */
                                1, /* depth */
                                source_gl_format,
                                source_gl_type,
                                data);

          if (_cogl_gl_util_catch_out_of_memory (ctx, error))
            {
              cogl_object_unref (bmp);
              _cogl_bitmap_gl_unbind (bmp);
              return FALSE;
            }

          _cogl_bitmap_gl_unbind (bmp);
        }

      cogl_object_unref (bmp);
    }
  else
    {
      data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error);
      if (!data)
        return FALSE;

      _cogl_texture_driver_prep_gl_for_pixels_upload (ctx, rowstride, bpp);

      /* Clear any GL errors */
      while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
        ;

      ctx->glTexImage3D (gl_target,
                         0, /* level */
                         internal_gl_format,
                         bmp_width,
                         height,
                         depth,
                         0,
                         source_gl_format,
                         source_gl_type,
                         data);

      if (_cogl_gl_util_catch_out_of_memory (ctx, error))
        {
          _cogl_bitmap_gl_unbind (source_bmp);
          return FALSE;
        }

      _cogl_bitmap_gl_unbind (source_bmp);
    }

  return TRUE;
}
static CoglBool
_cogl_texture_driver_upload_to_gl (CoglContext *ctx,
                                   GLenum gl_target,
                                   GLuint gl_handle,
                                   CoglBool is_foreign,
                                   CoglBitmap *source_bmp,
                                   GLint internal_gl_format,
                                   GLuint source_gl_format,
                                   GLuint source_gl_type,
                                   CoglError **error)
{
  CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp);
  int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format);
  int rowstride;
  int bmp_width = cogl_bitmap_get_width (source_bmp);
  int bmp_height = cogl_bitmap_get_height (source_bmp);
  CoglBitmap *bmp;
  uint8_t *data;
  GLenum gl_error;
  CoglError *internal_error = NULL;
  CoglBool status = TRUE;

  bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp, error);
  if (!bmp)
    return FALSE;

  rowstride = cogl_bitmap_get_rowstride (bmp);

  /* Setup gl alignment to match rowstride and top-left corner */
  _cogl_texture_driver_prep_gl_for_pixels_upload (ctx, rowstride, bpp);

  _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);

  data = _cogl_bitmap_gl_bind (bmp,
                               COGL_BUFFER_ACCESS_READ,
                               0, /* hints */
                               &internal_error);

  /* NB: _cogl_bitmap_gl_bind() may return NULL when successful so we
   * have to explicitly check the cogl error pointer to catch
   * problems... */
  if (internal_error)
    {
      cogl_object_unref (bmp);
      _cogl_propagate_error (error, internal_error);
      return FALSE;
    }

  /* Clear any GL errors */
  while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
    ;

  ctx->glTexImage2D (gl_target, 0,
                     internal_gl_format,
                     bmp_width, bmp_height,
                     0,
                     source_gl_format,
                     source_gl_type,
                     data);

  if (_cogl_gl_util_catch_out_of_memory (ctx, error))
    status = FALSE;

  _cogl_bitmap_gl_unbind (bmp);

  cogl_object_unref (bmp);

  return status;
}
예제 #5
0
void
_cogl_texture_driver_upload_to_gl_3d (GLenum       gl_target,
                                      GLuint       gl_handle,
                                      gboolean     is_foreign,
                                      GLint        height,
                                      GLint        depth,
                                      CoglBitmap  *source_bmp,
                                      GLint        internal_gl_format,
                                      GLuint       source_gl_format,
                                      GLuint       source_gl_type)
{
    int bpp = _cogl_get_format_bpp (_cogl_bitmap_get_format (source_bmp));
    int rowstride = _cogl_bitmap_get_rowstride (source_bmp);
    int bmp_width = _cogl_bitmap_get_width (source_bmp);
    int bmp_height = _cogl_bitmap_get_height (source_bmp);
    guint8 *data;

    _COGL_GET_CONTEXT (ctx, NO_RETVAL);

    _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);

    /* If the rowstride or image height can't be specified with just
       GL_ALIGNMENT alone then we need to copy the bitmap because there
       is no GL_ROW_LENGTH */
    if (rowstride / bpp != bmp_width ||
            height != bmp_height / depth)
    {
        CoglBitmap *bmp;
        int image_height = bmp_height / depth;
        int i;

        _cogl_texture_driver_prep_gl_for_pixels_upload (bmp_width * bpp, bpp);

        /* Initialize the texture with empty data and then upload each
           image with a sub-region update */

        GE( glTexImage3D (gl_target,
                          0, /* level */
                          internal_gl_format,
                          bmp_width,
                          height,
                          depth,
                          0,
                          source_gl_format,
                          source_gl_type,
                          NULL) );

        bmp = _cogl_bitmap_new_from_data (g_malloc (bpp * bmp_width * height),
                                          _cogl_bitmap_get_format (source_bmp),
                                          bmp_width,
                                          height,
                                          bpp * bmp_width,
                                          (CoglBitmapDestroyNotify) g_free,
                                          NULL);

        for (i = 0; i < depth; i++)
        {
            _cogl_bitmap_copy_subregion (source_bmp,
                                         bmp,
                                         0, image_height * i,
                                         0, 0,
                                         bmp_width,
                                         height);

            data = _cogl_bitmap_bind (bmp,
                                      COGL_BUFFER_ACCESS_READ, 0);

            GE( glTexSubImage3D (gl_target,
                                 0, /* level */
                                 0, /* xoffset */
                                 0, /* yoffset */
                                 i, /* zoffset */
                                 bmp_width, /* width */
                                 height, /* height */
                                 1, /* depth */
                                 source_gl_format,
                                 source_gl_type,
                                 data) );

            _cogl_bitmap_unbind (bmp);
        }

        cogl_object_unref (bmp);
    }
    else
    {
        data = _cogl_bitmap_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0);

        _cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp);

        GE( glTexImage3D (gl_target,
                          0, /* level */
                          internal_gl_format,
                          bmp_width,
                          height,
                          depth,
                          0,
                          source_gl_format,
                          source_gl_type,
                          data) );

        _cogl_bitmap_unbind (source_bmp);
    }
}
예제 #6
0
void
_cogl_texture_driver_upload_subregion_to_gl (GLenum       gl_target,
        GLuint       gl_handle,
        gboolean     is_foreign,
        int          src_x,
        int          src_y,
        int          dst_x,
        int          dst_y,
        int          width,
        int          height,
        CoglBitmap  *source_bmp,
        GLuint       source_gl_format,
        GLuint       source_gl_type)
{
    guint8 *data;
    CoglPixelFormat source_format = _cogl_bitmap_get_format (source_bmp);
    int bpp = _cogl_get_format_bpp (source_format);
    CoglBitmap *slice_bmp;
    int rowstride;

    /* If we are copying a sub region of the source bitmap then we need
       to copy it because GLES does not support GL_UNPACK_ROW_LENGTH */
    if (src_x != 0 || src_y != 0 ||
            width != _cogl_bitmap_get_width (source_bmp) ||
            height != _cogl_bitmap_get_height (source_bmp))
    {
        rowstride = bpp * width;
        rowstride = (rowstride + 3) & ~3;
        slice_bmp =
            _cogl_bitmap_new_from_data (g_malloc (height * rowstride),
                                        source_format,
                                        width, height,
                                        rowstride,
                                        (CoglBitmapDestroyNotify) g_free,
                                        NULL);
        _cogl_bitmap_copy_subregion (source_bmp,
                                     slice_bmp,
                                     src_x, src_y,
                                     0, 0, /* dst_x/y */
                                     width, height);
    }
    else
    {
        slice_bmp = prepare_bitmap_alignment_for_upload (source_bmp);
        rowstride = _cogl_bitmap_get_rowstride (slice_bmp);
    }

    /* Setup gl alignment to match rowstride and top-left corner */
    _cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp);

    data = _cogl_bitmap_bind (slice_bmp, COGL_BUFFER_ACCESS_READ, 0);

    _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);

    GE( glTexSubImage2D (gl_target, 0,
                         dst_x, dst_y,
                         width, height,
                         source_gl_format,
                         source_gl_type,
                         data) );

    _cogl_bitmap_unbind (slice_bmp);

    cogl_object_unref (slice_bmp);
}