mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 19:40:43 -05:00
[cogl-texture] Split CoglTexture into an abstract class + CoglTexture2dSliced
cogl-texture-2d-sliced provides an implementation of CoglTexture and this seperation lays the foundation for potentially supporting atlas textures, pixmap textures (as in GLX_EXT_texture_from_pixmap) and fast-path GL_TEXTURE_{1D,2D,3D,RECTANGLE} textures in a maintainable fashion.
This commit is contained in:
parent
9da26fc1ca
commit
568d684187
@ -114,8 +114,10 @@ libclutter_cogl_la_SOURCES = \
|
|||||||
cogl-blend-string.h \
|
cogl-blend-string.h \
|
||||||
cogl-debug.c \
|
cogl-debug.c \
|
||||||
cogl-texture-private.h \
|
cogl-texture-private.h \
|
||||||
|
cogl-texture-2d-sliced-private.h \
|
||||||
cogl-texture-driver.h \
|
cogl-texture-driver.h \
|
||||||
cogl-texture.c \
|
cogl-texture.c \
|
||||||
|
cogl-texture-2d-sliced.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
EXTRA_DIST += stb_image.c cogl-enum-types.h.in cogl-enum-types.c.in
|
EXTRA_DIST += stb_image.c cogl-enum-types.h.in cogl-enum-types.c.in
|
||||||
|
@ -100,6 +100,8 @@ cogl_create_context (void)
|
|||||||
_context->quad_indices_short = COGL_INVALID_HANDLE;
|
_context->quad_indices_short = COGL_INVALID_HANDLE;
|
||||||
_context->quad_indices_short_len = 0;
|
_context->quad_indices_short_len = 0;
|
||||||
|
|
||||||
|
_context->texture_download_material = COGL_INVALID_HANDLE;
|
||||||
|
|
||||||
/* Initialise the clip stack */
|
/* Initialise the clip stack */
|
||||||
_cogl_clip_stack_state_init ();
|
_cogl_clip_stack_state_init ();
|
||||||
|
|
||||||
|
@ -115,6 +115,8 @@ typedef struct
|
|||||||
guint viewport_width;
|
guint viewport_width;
|
||||||
guint viewport_height;
|
guint viewport_height;
|
||||||
|
|
||||||
|
CoglHandle texture_download_material;
|
||||||
|
|
||||||
CoglContextDriver drv;
|
CoglContextDriver drv;
|
||||||
} CoglContext;
|
} CoglContext;
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ typedef struct _CoglHandleObject
|
|||||||
\
|
\
|
||||||
static CoglHandleClass _cogl_##type_name##_class; \
|
static CoglHandleClass _cogl_##type_name##_class; \
|
||||||
\
|
\
|
||||||
static GQuark \
|
GQuark \
|
||||||
_cogl_handle_##type_name##_get_type (void) \
|
_cogl_handle_##type_name##_get_type (void) \
|
||||||
{ \
|
{ \
|
||||||
static GQuark type = 0; \
|
static GQuark type = 0; \
|
||||||
@ -93,7 +93,7 @@ _cogl_handle_##type_name##_get_type (void) \
|
|||||||
static CoglHandle \
|
static CoglHandle \
|
||||||
_cogl_##type_name##_handle_new (Cogl##TypeName *new_obj) \
|
_cogl_##type_name##_handle_new (Cogl##TypeName *new_obj) \
|
||||||
{ \
|
{ \
|
||||||
CoglHandleObject *obj = &new_obj->_parent; \
|
CoglHandleObject *obj = (CoglHandleObject *)&new_obj->_parent;\
|
||||||
obj->ref_count = 1; \
|
obj->ref_count = 1; \
|
||||||
\
|
\
|
||||||
obj->klass = &_cogl_##type_name##_class; \
|
obj->klass = &_cogl_##type_name##_class; \
|
||||||
|
191
clutter/cogl/cogl/cogl-texture-2d-sliced-private.h
Normal file
191
clutter/cogl/cogl/cogl-texture-2d-sliced-private.h
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007,2008,2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __COGL_TEXTURE_2D_SLICED_H
|
||||||
|
#define __COGL_TEXTURE_2D_SLICED_H
|
||||||
|
|
||||||
|
#include "cogl-bitmap-private.h"
|
||||||
|
#include "cogl-handle.h"
|
||||||
|
#include "cogl-material-private.h"
|
||||||
|
#include "cogl-texture-private.h"
|
||||||
|
|
||||||
|
#define COGL_TEXTURE_2D_SLICED(tex) ((CoglTexture2DSliced *)tex)
|
||||||
|
|
||||||
|
typedef struct _CoglTexture2DSliced CoglTexture2DSliced;
|
||||||
|
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
||||||
|
typedef struct _CoglSpanIter CoglSpanIter;
|
||||||
|
typedef struct _CoglTexturePixel CoglTexturePixel;
|
||||||
|
|
||||||
|
struct _CoglTexSliceSpan
|
||||||
|
{
|
||||||
|
int start;
|
||||||
|
int size;
|
||||||
|
int waste;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _CoglSpanIter
|
||||||
|
{
|
||||||
|
gint index;
|
||||||
|
GArray *array;
|
||||||
|
CoglTexSliceSpan *span;
|
||||||
|
float pos;
|
||||||
|
float next_pos;
|
||||||
|
float origin;
|
||||||
|
float cover_start;
|
||||||
|
float cover_end;
|
||||||
|
float intersect_start;
|
||||||
|
float intersect_end;
|
||||||
|
float intersect_start_local;
|
||||||
|
float intersect_end_local;
|
||||||
|
gboolean intersects;
|
||||||
|
gboolean flipped;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is used to store the first pixel of each slice. This is only
|
||||||
|
used when glGenerateMipmap is not available */
|
||||||
|
struct _CoglTexturePixel
|
||||||
|
{
|
||||||
|
/* We need to store the format of the pixel because we store the
|
||||||
|
data in the source format which might end up being different for
|
||||||
|
each slice if a subregion is updated with a different format */
|
||||||
|
GLenum gl_format;
|
||||||
|
GLenum gl_type;
|
||||||
|
guint8 data[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _CoglTexture2DSliced
|
||||||
|
{
|
||||||
|
CoglTexture _parent;
|
||||||
|
GArray *slice_x_spans;
|
||||||
|
GArray *slice_y_spans;
|
||||||
|
GArray *slice_gl_handles;
|
||||||
|
gint max_waste;
|
||||||
|
|
||||||
|
/* This holds a copy of the first pixel in each slice. It is only
|
||||||
|
used to force an automatic update of the mipmaps when
|
||||||
|
glGenerateMipmap is not available. */
|
||||||
|
CoglTexturePixel *first_pixels;
|
||||||
|
};
|
||||||
|
|
||||||
|
GQuark
|
||||||
|
_cogl_handle_texture_2d_sliced_get_type (void);
|
||||||
|
|
||||||
|
CoglHandle
|
||||||
|
_cogl_texture_2d_sliced_new_with_size (unsigned int width,
|
||||||
|
unsigned int height,
|
||||||
|
CoglTextureFlags flags,
|
||||||
|
CoglPixelFormat internal_format);
|
||||||
|
|
||||||
|
CoglHandle
|
||||||
|
_cogl_texture_2d_sliced_new_from_file (const gchar *filename,
|
||||||
|
CoglTextureFlags flags,
|
||||||
|
CoglPixelFormat internal_format,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
CoglHandle
|
||||||
|
_cogl_texture_2d_sliced_new_from_foreign (GLuint gl_handle,
|
||||||
|
GLenum gl_target,
|
||||||
|
GLuint width,
|
||||||
|
GLuint height,
|
||||||
|
GLuint x_pot_waste,
|
||||||
|
GLuint y_pot_waste,
|
||||||
|
CoglPixelFormat format);
|
||||||
|
|
||||||
|
CoglHandle
|
||||||
|
_cogl_texture_2d_sliced_new_from_data (unsigned int width,
|
||||||
|
unsigned int height,
|
||||||
|
CoglTextureFlags flags,
|
||||||
|
CoglPixelFormat format,
|
||||||
|
CoglPixelFormat internal_format,
|
||||||
|
unsigned int rowstride,
|
||||||
|
const guint8 *data);
|
||||||
|
|
||||||
|
|
||||||
|
CoglHandle
|
||||||
|
_cogl_texture_2d_sliced_new_from_bitmap (CoglHandle bmp_handle,
|
||||||
|
CoglTextureFlags flags,
|
||||||
|
CoglPixelFormat internal_format);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_2d_sliced_set_region (CoglHandle handle,
|
||||||
|
int src_x,
|
||||||
|
int src_y,
|
||||||
|
int dst_x,
|
||||||
|
int dst_y,
|
||||||
|
unsigned int dst_width,
|
||||||
|
unsigned int dst_height,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
CoglPixelFormat format,
|
||||||
|
unsigned int rowstride,
|
||||||
|
const guint8 *data);
|
||||||
|
|
||||||
|
int
|
||||||
|
_cogl_texture_2d_sliced_get_data (CoglHandle handle,
|
||||||
|
CoglPixelFormat format,
|
||||||
|
unsigned int rowstride,
|
||||||
|
guint8 *data);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_2d_sliced_foreach_sub_texture_in_region (
|
||||||
|
CoglTexture2DSliced *tex_2ds,
|
||||||
|
float virtual_tx_1,
|
||||||
|
float virtual_ty_1,
|
||||||
|
float virtual_tx_2,
|
||||||
|
float virtual_ty_2,
|
||||||
|
CoglTextureSliceCallback callback,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
gint
|
||||||
|
_cogl_texture_2d_sliced_get_max_waste (CoglHandle handle);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_2d_sliced_is_sliced (CoglHandle handle);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_2d_sliced_can_hardware_repeat (CoglHandle handle);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_2d_sliced_transform_coords_to_gl (CoglTexture2DSliced *tex_2ds,
|
||||||
|
float *s,
|
||||||
|
float *t);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_2d_sliced_get_gl_texture (CoglHandle handle,
|
||||||
|
GLuint *out_gl_handle,
|
||||||
|
GLenum *out_gl_target);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_2d_sliced_set_filters (CoglHandle handle,
|
||||||
|
GLenum min_filter,
|
||||||
|
GLenum mag_filter);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_2d_sliced_ensure_mipmaps (CoglHandle handle);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_2d_sliced_set_wrap_mode_parameter (CoglTexture2DSliced *tex_2ds,
|
||||||
|
GLenum wrap_mode);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __COGL_TEXTURE_2D_SLICED_H */
|
1871
clutter/cogl/cogl/cogl-texture-2d-sliced.c
Normal file
1871
clutter/cogl/cogl/cogl-texture-2d-sliced.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -91,6 +91,18 @@ _cogl_texture_driver_download_from_gl (CoglTexture *tex,
|
|||||||
GLuint target_gl_format,
|
GLuint target_gl_format,
|
||||||
GLuint target_gl_type);
|
GLuint target_gl_type);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This driver abstraction is needed because GLES doesn't support glGetTexImage
|
||||||
|
* (). On GLES this currently just returns FALSE which will lead to a generic
|
||||||
|
* fallback path being used that simply renders the texture and reads it back
|
||||||
|
* from the framebuffer. (See _cogl_texture_draw_and_read () )
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_driver_gl_get_tex_image (GLenum gl_target,
|
||||||
|
GLenum dest_gl_format,
|
||||||
|
GLenum dest_gl_type,
|
||||||
|
guint8 *dest);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It may depend on the driver as to what texture sizes are supported...
|
* It may depend on the driver as to what texture sizes are supported...
|
||||||
*/
|
*/
|
||||||
|
@ -28,72 +28,31 @@
|
|||||||
#include "cogl-handle.h"
|
#include "cogl-handle.h"
|
||||||
#include "cogl-material-private.h"
|
#include "cogl-material-private.h"
|
||||||
|
|
||||||
|
#define COGL_TEXTURE(tex) ((CoglTexture *)(tex))
|
||||||
|
|
||||||
typedef struct _CoglTexture CoglTexture;
|
typedef struct _CoglTexture CoglTexture;
|
||||||
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
|
||||||
typedef struct _CoglSpanIter CoglSpanIter;
|
|
||||||
typedef struct _CoglTexturePixel CoglTexturePixel;
|
|
||||||
|
|
||||||
struct _CoglTexSliceSpan
|
typedef enum _CoglTextureType
|
||||||
{
|
{
|
||||||
gint start;
|
COGL_TEXTURE_TYPE_2D_SLICED
|
||||||
gint size;
|
} CoglTextureType;
|
||||||
gint waste;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _CoglSpanIter
|
|
||||||
{
|
|
||||||
gint index;
|
|
||||||
GArray *array;
|
|
||||||
CoglTexSliceSpan *span;
|
|
||||||
float pos;
|
|
||||||
float next_pos;
|
|
||||||
float origin;
|
|
||||||
float cover_start;
|
|
||||||
float cover_end;
|
|
||||||
float intersect_start;
|
|
||||||
float intersect_end;
|
|
||||||
float intersect_start_local;
|
|
||||||
float intersect_end_local;
|
|
||||||
gboolean intersects;
|
|
||||||
gboolean flipped;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This is used to store the first pixel of each slice. This is only
|
|
||||||
used when glGenerateMipmap is not available */
|
|
||||||
struct _CoglTexturePixel
|
|
||||||
{
|
|
||||||
/* We need to store the format of the pixel because we store the
|
|
||||||
data in the source format which might end up being different for
|
|
||||||
each slice if a subregion is updated with a different format */
|
|
||||||
GLenum gl_format;
|
|
||||||
GLenum gl_type;
|
|
||||||
guint8 data[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _CoglTexture
|
struct _CoglTexture
|
||||||
{
|
{
|
||||||
CoglHandleObject _parent;
|
CoglHandleObject _parent;
|
||||||
|
CoglTextureType type;
|
||||||
CoglBitmap bitmap;
|
CoglBitmap bitmap;
|
||||||
gboolean bitmap_owner;
|
gboolean bitmap_owner;
|
||||||
GLenum gl_target;
|
GLenum gl_target;
|
||||||
GLenum gl_intformat;
|
GLenum gl_intformat;
|
||||||
GLenum gl_format;
|
GLenum gl_format;
|
||||||
GLenum gl_type;
|
GLenum gl_type;
|
||||||
GArray *slice_x_spans;
|
|
||||||
GArray *slice_y_spans;
|
|
||||||
GArray *slice_gl_handles;
|
|
||||||
gint max_waste;
|
|
||||||
GLenum min_filter;
|
GLenum min_filter;
|
||||||
GLenum mag_filter;
|
GLenum mag_filter;
|
||||||
gboolean is_foreign;
|
gboolean is_foreign;
|
||||||
GLint wrap_mode;
|
GLint wrap_mode;
|
||||||
gboolean auto_mipmap;
|
gboolean auto_mipmap;
|
||||||
gboolean mipmaps_dirty;
|
gboolean mipmaps_dirty;
|
||||||
|
|
||||||
/* This holds a copy of the first pixel in each slice. It is only
|
|
||||||
used to force an automatic update of the mipmaps when
|
|
||||||
glGenerateMipmap is not available. */
|
|
||||||
CoglTexturePixel *first_pixels;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* To improve batching of geometry when submitting vertices to OpenGL we
|
/* To improve batching of geometry when submitting vertices to OpenGL we
|
||||||
@ -117,9 +76,6 @@ typedef void (*CoglTextureSliceCallback) (CoglHandle handle,
|
|||||||
float *virtual_coords,
|
float *virtual_coords,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
CoglTexture*
|
|
||||||
_cogl_texture_pointer_from_handle (CoglHandle handle);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_texture_foreach_sub_texture_in_region (CoglHandle handle,
|
_cogl_texture_foreach_sub_texture_in_region (CoglHandle handle,
|
||||||
float virtual_tx_1,
|
float virtual_tx_1,
|
||||||
@ -151,10 +107,34 @@ _cogl_texture_set_filters (CoglHandle handle,
|
|||||||
void
|
void
|
||||||
_cogl_texture_ensure_mipmaps (CoglHandle handle);
|
_cogl_texture_ensure_mipmaps (CoglHandle handle);
|
||||||
|
|
||||||
|
|
||||||
|
/* Functions currently only used by CoglTexture implementations or
|
||||||
|
* drivers... */
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_free (CoglTexture *tex);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_bitmap_free (CoglTexture *tex);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_bitmap_swap (CoglTexture *tex,
|
||||||
|
CoglBitmap *new_bitmap);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_bitmap_prepare (CoglTexture *tex,
|
||||||
|
CoglPixelFormat internal_format);
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_texture_prep_gl_alignment_for_pixels_upload (int pixels_rowstride);
|
_cogl_texture_prep_gl_alignment_for_pixels_upload (int pixels_rowstride);
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_texture_prep_gl_alignment_for_pixels_download (int pixels_rowstride);
|
_cogl_texture_prep_gl_alignment_for_pixels_download (int pixels_rowstride);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_draw_and_read (CoglTexture *tex,
|
||||||
|
CoglBitmap *target_bmp,
|
||||||
|
GLuint target_gl_format,
|
||||||
|
GLuint target_gl_type);
|
||||||
|
|
||||||
#endif /* __COGL_TEXTURE_PRIVATE_H */
|
#endif /* __COGL_TEXTURE_PRIVATE_H */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -135,95 +135,16 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_texture_driver_download_from_gl (CoglTexture *tex,
|
_cogl_texture_driver_gl_get_tex_image (GLenum gl_target,
|
||||||
CoglBitmap *target_bmp,
|
GLenum dest_gl_format,
|
||||||
GLuint target_gl_format,
|
GLenum dest_gl_type,
|
||||||
GLuint target_gl_type)
|
guint8 *dest)
|
||||||
{
|
{
|
||||||
CoglTexSliceSpan *x_span;
|
GE (glGetTexImage (gl_target,
|
||||||
CoglTexSliceSpan *y_span;
|
|
||||||
GLuint gl_handle;
|
|
||||||
gint bpp;
|
|
||||||
gint x,y;
|
|
||||||
CoglBitmap slice_bmp;
|
|
||||||
|
|
||||||
bpp = _cogl_get_format_bpp (target_bmp->format);
|
|
||||||
|
|
||||||
/* Iterate vertical slices */
|
|
||||||
for (y = 0; y < tex->slice_y_spans->len; ++y)
|
|
||||||
{
|
|
||||||
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, y);
|
|
||||||
|
|
||||||
/* Iterate horizontal slices */
|
|
||||||
for (x = 0; x < tex->slice_x_spans->len; ++x)
|
|
||||||
{
|
|
||||||
/*if (x != 0 || y != 1) continue;*/
|
|
||||||
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, x);
|
|
||||||
|
|
||||||
/* Pick the gl texture object handle */
|
|
||||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
|
|
||||||
y * tex->slice_x_spans->len + x);
|
|
||||||
|
|
||||||
/* If there's any waste we need to copy manually
|
|
||||||
(no glGetTexSubImage) */
|
|
||||||
|
|
||||||
if (y_span->waste != 0 || x_span->waste != 0)
|
|
||||||
{
|
|
||||||
/* Setup temp bitmap for slice subregion */
|
|
||||||
slice_bmp.format = target_bmp->format;
|
|
||||||
slice_bmp.width = x_span->size;
|
|
||||||
slice_bmp.height = y_span->size;
|
|
||||||
slice_bmp.rowstride = bpp * slice_bmp.width;
|
|
||||||
slice_bmp.data = (guchar*) g_malloc (slice_bmp.rowstride *
|
|
||||||
slice_bmp.height);
|
|
||||||
|
|
||||||
/* Setup gl alignment to 0,0 top-left corner */
|
|
||||||
_cogl_texture_driver_prep_gl_for_pixels_download (
|
|
||||||
slice_bmp.rowstride,
|
|
||||||
bpp);
|
|
||||||
|
|
||||||
/* Download slice image data into temp bmp */
|
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
|
||||||
|
|
||||||
GE (glGetTexImage (tex->gl_target,
|
|
||||||
0, /* level */
|
0, /* level */
|
||||||
target_gl_format,
|
dest_gl_format,
|
||||||
target_gl_type,
|
dest_gl_type,
|
||||||
slice_bmp.data) );
|
(GLvoid *)dest));
|
||||||
|
|
||||||
/* Copy portion of slice from temp to target bmp */
|
|
||||||
_cogl_bitmap_copy_subregion (&slice_bmp,
|
|
||||||
target_bmp,
|
|
||||||
0, 0,
|
|
||||||
x_span->start,
|
|
||||||
y_span->start,
|
|
||||||
x_span->size - x_span->waste,
|
|
||||||
y_span->size - y_span->waste);
|
|
||||||
/* Free temp bitmap */
|
|
||||||
g_free (slice_bmp.data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GLvoid *dst = target_bmp->data
|
|
||||||
+ x_span->start * bpp
|
|
||||||
+ y_span->start * target_bmp->rowstride;
|
|
||||||
|
|
||||||
_cogl_texture_driver_prep_gl_for_pixels_download (
|
|
||||||
target_bmp->rowstride,
|
|
||||||
bpp);
|
|
||||||
|
|
||||||
/* Download slice image data */
|
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
|
||||||
|
|
||||||
GE( glGetTexImage (tex->gl_target,
|
|
||||||
0, /* level */
|
|
||||||
target_gl_format,
|
|
||||||
target_gl_type,
|
|
||||||
dst) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,6 @@
|
|||||||
void
|
void
|
||||||
_cogl_create_context_driver (CoglContext *context)
|
_cogl_create_context_driver (CoglContext *context)
|
||||||
{
|
{
|
||||||
context->drv.texture_download_material = COGL_INVALID_HANDLE;
|
|
||||||
|
|
||||||
/* Init the GLES2 wrapper */
|
/* Init the GLES2 wrapper */
|
||||||
#ifdef HAVE_COGL_GLES2
|
#ifdef HAVE_COGL_GLES2
|
||||||
cogl_gles2_wrapper_init (&context->drv.gles2);
|
cogl_gles2_wrapper_init (&context->drv.gles2);
|
||||||
|
@ -29,8 +29,6 @@
|
|||||||
typedef struct _CoglContextDriver
|
typedef struct _CoglContextDriver
|
||||||
|
|
||||||
{
|
{
|
||||||
CoglHandle texture_download_material;
|
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GLES2
|
#ifdef HAVE_COGL_GLES2
|
||||||
CoglGles2Wrapper gles2;
|
CoglGles2Wrapper gles2;
|
||||||
|
|
||||||
|
@ -128,217 +128,16 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
g_free (slice_bmp.data);
|
g_free (slice_bmp.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* NB: GLES doesn't support glGetTexImage2D, so cogl-texture will instead
|
||||||
_cogl_texture_draw_and_read (CoglTexture *tex,
|
* fallback to a generic render + readpixels approach to downloading
|
||||||
CoglBitmap *target_bmp,
|
* texture data. (See _cogl_texture_draw_and_read() ) */
|
||||||
GLint *viewport)
|
|
||||||
{
|
|
||||||
gint bpp;
|
|
||||||
float rx1, ry1;
|
|
||||||
float rx2, ry2;
|
|
||||||
float tx1, ty1;
|
|
||||||
float tx2, ty2;
|
|
||||||
int bw, bh;
|
|
||||||
CoglBitmap rect_bmp;
|
|
||||||
CoglHandle handle;
|
|
||||||
|
|
||||||
handle = (CoglHandle) tex;
|
|
||||||
bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888);
|
|
||||||
|
|
||||||
ry1 = 0; ry2 = 0;
|
|
||||||
ty1 = 0; ty2 = 0;
|
|
||||||
|
|
||||||
/* Walk Y axis until whole bitmap height consumed */
|
|
||||||
for (bh = tex->bitmap.height; bh > 0; bh -= viewport[3])
|
|
||||||
{
|
|
||||||
/* Rectangle Y coords */
|
|
||||||
ry1 = ry2;
|
|
||||||
ry2 += (bh < viewport[3]) ? bh : viewport[3];
|
|
||||||
|
|
||||||
/* Normalized texture Y coords */
|
|
||||||
ty1 = ty2;
|
|
||||||
ty2 = (ry2 / (float)tex->bitmap.height);
|
|
||||||
|
|
||||||
rx1 = 0; rx2 = 0;
|
|
||||||
tx1 = 0; tx2 = 0;
|
|
||||||
|
|
||||||
/* Walk X axis until whole bitmap width consumed */
|
|
||||||
for (bw = tex->bitmap.width; bw > 0; bw-=viewport[2])
|
|
||||||
{
|
|
||||||
/* Rectangle X coords */
|
|
||||||
rx1 = rx2;
|
|
||||||
rx2 += (bw < viewport[2]) ? bw : viewport[2];
|
|
||||||
|
|
||||||
/* Normalized texture X coords */
|
|
||||||
tx1 = tx2;
|
|
||||||
tx2 = (rx2 / (float)tex->bitmap.width);
|
|
||||||
|
|
||||||
/* Draw a portion of texture */
|
|
||||||
cogl_rectangle_with_texture_coords (0, 0,
|
|
||||||
rx2 - rx1,
|
|
||||||
ry2 - ry1,
|
|
||||||
tx1, ty1,
|
|
||||||
tx2, ty2);
|
|
||||||
|
|
||||||
/* Read into a temporary bitmap */
|
|
||||||
rect_bmp.format = COGL_PIXEL_FORMAT_RGBA_8888;
|
|
||||||
rect_bmp.width = rx2 - rx1;
|
|
||||||
rect_bmp.height = ry2 - ry1;
|
|
||||||
rect_bmp.rowstride = bpp * rect_bmp.width;
|
|
||||||
rect_bmp.data = (guchar*) g_malloc (rect_bmp.rowstride *
|
|
||||||
rect_bmp.height);
|
|
||||||
|
|
||||||
_cogl_texture_driver_prep_gl_for_pixels_download (rect_bmp.rowstride,
|
|
||||||
bpp);
|
|
||||||
GE( glReadPixels (viewport[0], viewport[1],
|
|
||||||
rect_bmp.width,
|
|
||||||
rect_bmp.height,
|
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
|
||||||
rect_bmp.data) );
|
|
||||||
|
|
||||||
/* Copy to target bitmap */
|
|
||||||
_cogl_bitmap_copy_subregion (&rect_bmp,
|
|
||||||
target_bmp,
|
|
||||||
0,0,
|
|
||||||
rx1,ry1,
|
|
||||||
rect_bmp.width,
|
|
||||||
rect_bmp.height);
|
|
||||||
|
|
||||||
/* Free temp bitmap */
|
|
||||||
g_free (rect_bmp.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_texture_driver_download_from_gl (CoglTexture *tex,
|
_cogl_texture_driver_gl_get_tex_image (GLenum gl_target,
|
||||||
CoglBitmap *target_bmp,
|
GLenum dest_gl_format,
|
||||||
GLuint target_gl_format,
|
GLenum dest_gl_type,
|
||||||
GLuint target_gl_type)
|
guint8 *dest)
|
||||||
{
|
{
|
||||||
gint bpp;
|
|
||||||
GLint viewport[4];
|
|
||||||
CoglBitmap alpha_bmp;
|
|
||||||
CoglHandle prev_source;
|
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, FALSE);
|
|
||||||
|
|
||||||
|
|
||||||
bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888);
|
|
||||||
|
|
||||||
/* Viewport needs to have some size and be inside the window for this */
|
|
||||||
GE( glGetIntegerv (GL_VIEWPORT, viewport) );
|
|
||||||
|
|
||||||
if (viewport[0] < 0 || viewport[1] < 0 ||
|
|
||||||
viewport[2] <= 0 || viewport[3] <= 0)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Setup orthographic projection into current viewport
|
|
||||||
(0,0 in bottom-left corner to draw the texture
|
|
||||||
upside-down so we match the way glReadPixels works) */
|
|
||||||
|
|
||||||
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
|
|
||||||
_cogl_current_matrix_push ();
|
|
||||||
_cogl_current_matrix_identity ();
|
|
||||||
|
|
||||||
_cogl_current_matrix_ortho (0, (float)(viewport[2]),
|
|
||||||
0, (float)(viewport[3]),
|
|
||||||
(float)(0),
|
|
||||||
(float)(100));
|
|
||||||
|
|
||||||
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
|
|
||||||
_cogl_current_matrix_push ();
|
|
||||||
_cogl_current_matrix_identity ();
|
|
||||||
|
|
||||||
/* Direct copy operation */
|
|
||||||
|
|
||||||
if (ctx->drv.texture_download_material == COGL_INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
ctx->drv.texture_download_material = cogl_material_new ();
|
|
||||||
cogl_material_set_blend (ctx->drv.texture_download_material,
|
|
||||||
"RGBA = ADD (SRC_COLOR, 0)",
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_source = cogl_handle_ref (ctx->source_material);
|
|
||||||
cogl_set_source (ctx->drv.texture_download_material);
|
|
||||||
|
|
||||||
cogl_material_set_layer (ctx->drv.texture_download_material, 0, tex);
|
|
||||||
|
|
||||||
cogl_material_set_layer_combine (ctx->drv.texture_download_material,
|
|
||||||
0, /* layer */
|
|
||||||
"RGBA = REPLACE (TEXTURE)",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
_cogl_texture_draw_and_read (tex, target_bmp, viewport);
|
|
||||||
|
|
||||||
/* Check whether texture has alpha and framebuffer not */
|
|
||||||
/* FIXME: For some reason even if ALPHA_BITS is 8, the framebuffer
|
|
||||||
still doesn't seem to have an alpha buffer. This might be just
|
|
||||||
a PowerVR issue.
|
|
||||||
GLint r_bits, g_bits, b_bits, a_bits;
|
|
||||||
GE( glGetIntegerv (GL_ALPHA_BITS, &a_bits) );
|
|
||||||
GE( glGetIntegerv (GL_RED_BITS, &r_bits) );
|
|
||||||
GE( glGetIntegerv (GL_GREEN_BITS, &g_bits) );
|
|
||||||
GE( glGetIntegerv (GL_BLUE_BITS, &b_bits) );
|
|
||||||
printf ("R bits: %d\n", r_bits);
|
|
||||||
printf ("G bits: %d\n", g_bits);
|
|
||||||
printf ("B bits: %d\n", b_bits);
|
|
||||||
printf ("A bits: %d\n", a_bits); */
|
|
||||||
if ((tex->bitmap.format & COGL_A_BIT)/* && a_bits == 0*/)
|
|
||||||
{
|
|
||||||
guchar *srcdata;
|
|
||||||
guchar *dstdata;
|
|
||||||
guchar *srcpixel;
|
|
||||||
guchar *dstpixel;
|
|
||||||
gint x,y;
|
|
||||||
|
|
||||||
/* Create temp bitmap for alpha values */
|
|
||||||
alpha_bmp.format = COGL_PIXEL_FORMAT_RGBA_8888;
|
|
||||||
alpha_bmp.width = target_bmp->width;
|
|
||||||
alpha_bmp.height = target_bmp->height;
|
|
||||||
alpha_bmp.rowstride = bpp * alpha_bmp.width;
|
|
||||||
alpha_bmp.data = (guchar*) g_malloc (alpha_bmp.rowstride *
|
|
||||||
alpha_bmp.height);
|
|
||||||
|
|
||||||
/* Draw alpha values into RGB channels */
|
|
||||||
cogl_material_set_layer_combine (ctx->drv.texture_download_material,
|
|
||||||
0, /* layer */
|
|
||||||
"RGBA = REPLACE (TEXTURE[A])",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
_cogl_texture_draw_and_read (tex, &alpha_bmp, viewport);
|
|
||||||
|
|
||||||
/* Copy temp R to target A */
|
|
||||||
srcdata = alpha_bmp.data;
|
|
||||||
dstdata = target_bmp->data;
|
|
||||||
|
|
||||||
for (y=0; y<target_bmp->height; ++y)
|
|
||||||
{
|
|
||||||
for (x=0; x<target_bmp->width; ++x)
|
|
||||||
{
|
|
||||||
srcpixel = srcdata + x*bpp;
|
|
||||||
dstpixel = dstdata + x*bpp;
|
|
||||||
dstpixel[3] = srcpixel[0];
|
|
||||||
}
|
|
||||||
srcdata += alpha_bmp.rowstride;
|
|
||||||
dstdata += target_bmp->rowstride;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (alpha_bmp.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore old state */
|
|
||||||
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
|
|
||||||
_cogl_current_matrix_pop ();
|
|
||||||
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
|
|
||||||
_cogl_current_matrix_pop ();
|
|
||||||
|
|
||||||
/* restore the original material */
|
|
||||||
cogl_set_source (prev_source);
|
|
||||||
cogl_handle_unref (prev_source);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
Loading…
Reference in New Issue
Block a user