2009-11-27 13:45:36 -05:00
|
|
|
/*
|
|
|
|
* Cogl
|
|
|
|
*
|
|
|
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
|
|
|
*
|
|
|
|
* Copyright (C) 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.
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Neil Roberts <neil@linux.intel.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "cogl.h"
|
|
|
|
#include "cogl-internal.h"
|
|
|
|
#include "cogl-util.h"
|
|
|
|
#include "cogl-texture-private.h"
|
|
|
|
#include "cogl-texture-2d-private.h"
|
|
|
|
#include "cogl-texture-driver.h"
|
|
|
|
#include "cogl-context.h"
|
|
|
|
#include "cogl-handle.h"
|
2010-02-10 13:18:30 -05:00
|
|
|
#include "cogl-journal-private.h"
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
static void _cogl_texture_2d_free (CoglTexture2D *tex_2d);
|
|
|
|
|
|
|
|
COGL_HANDLE_DEFINE (Texture2D, texture_2d);
|
|
|
|
|
|
|
|
static const CoglTextureVtable cogl_texture_2d_vtable;
|
|
|
|
|
|
|
|
typedef struct _CoglTexture2DManualRepeatData
|
|
|
|
{
|
|
|
|
CoglTexture2D *tex_2d;
|
|
|
|
CoglTextureSliceCallback callback;
|
|
|
|
void *user_data;
|
|
|
|
} CoglTexture2DManualRepeatData;
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_2d_wrap_coords (float t_1, float t_2,
|
|
|
|
float *out_t_1, float *out_t_2)
|
|
|
|
{
|
|
|
|
float int_part;
|
|
|
|
|
|
|
|
/* Wrap t_1 and t_2 to the range [0,1] */
|
|
|
|
|
|
|
|
modff (t_1 < t_2 ? t_1 : t_2, &int_part);
|
|
|
|
t_1 -= int_part;
|
|
|
|
t_2 -= int_part;
|
2010-02-11 09:20:48 -05:00
|
|
|
if (cogl_util_float_signbit (int_part))
|
2009-11-27 13:45:36 -05:00
|
|
|
{
|
2010-01-11 11:21:56 -05:00
|
|
|
*out_t_1 = 1.0f + t_1;
|
|
|
|
*out_t_2 = 1.0f + t_2;
|
2009-11-27 13:45:36 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*out_t_1 = t_1;
|
|
|
|
*out_t_2 = t_2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_2d_manual_repeat_cb (const float *coords,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
CoglTexture2DManualRepeatData *data = user_data;
|
|
|
|
float slice_coords[4];
|
|
|
|
|
|
|
|
_cogl_texture_2d_wrap_coords (coords[0], coords[2],
|
|
|
|
slice_coords + 0, slice_coords + 2);
|
|
|
|
_cogl_texture_2d_wrap_coords (coords[1], coords[3],
|
|
|
|
slice_coords + 1, slice_coords + 3);
|
|
|
|
|
|
|
|
data->callback (COGL_TEXTURE (data->tex_2d),
|
|
|
|
data->tex_2d->gl_texture,
|
|
|
|
GL_TEXTURE_2D,
|
|
|
|
slice_coords,
|
|
|
|
coords,
|
|
|
|
data->user_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_2d_foreach_sub_texture_in_region (
|
|
|
|
CoglTexture *tex,
|
|
|
|
float virtual_tx_1,
|
|
|
|
float virtual_ty_1,
|
|
|
|
float virtual_tx_2,
|
|
|
|
float virtual_ty_2,
|
|
|
|
CoglTextureSliceCallback callback,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
|
|
|
|
CoglTexture2DManualRepeatData data;
|
|
|
|
|
|
|
|
data.tex_2d = tex_2d;
|
|
|
|
data.callback = callback;
|
|
|
|
data.user_data = user_data;
|
|
|
|
|
|
|
|
/* We need to implement manual repeating because if Cogl is calling
|
|
|
|
this function then it will set the wrap mode to GL_CLAMP_TO_EDGE
|
|
|
|
and hardware repeating can't be done */
|
|
|
|
_cogl_texture_iterate_manual_repeats (_cogl_texture_2d_manual_repeat_cb,
|
|
|
|
virtual_tx_1, virtual_ty_1,
|
|
|
|
virtual_tx_2, virtual_ty_2,
|
|
|
|
&data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_2d_set_wrap_mode_parameter (CoglTexture *tex,
|
|
|
|
GLenum wrap_mode)
|
|
|
|
{
|
|
|
|
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
|
|
|
|
|
|
|
|
/* Only set the wrap mode if it's different from the current
|
|
|
|
value to avoid too many GL calls */
|
|
|
|
if (tex_2d->wrap_mode != wrap_mode)
|
|
|
|
{
|
|
|
|
/* Any queued texture rectangles may be depending on the
|
|
|
|
* previous wrap mode... */
|
|
|
|
_cogl_journal_flush ();
|
|
|
|
|
|
|
|
GE( glBindTexture (GL_TEXTURE_2D, tex_2d->gl_texture) );
|
|
|
|
GE( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode) );
|
|
|
|
GE( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode) );
|
|
|
|
|
|
|
|
tex_2d->wrap_mode = wrap_mode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_2d_free (CoglTexture2D *tex_2d)
|
|
|
|
{
|
|
|
|
GE( glDeleteTextures (1, &tex_2d->gl_texture) );
|
|
|
|
g_free (tex_2d);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
_cogl_texture_2d_is_pot (unsigned int num)
|
|
|
|
{
|
|
|
|
gboolean have_bit = FALSE;
|
|
|
|
|
|
|
|
/* Make sure there is only one bit set */
|
|
|
|
while (num)
|
|
|
|
{
|
|
|
|
if (num & 1)
|
|
|
|
{
|
|
|
|
if (have_bit)
|
|
|
|
return FALSE;
|
|
|
|
have_bit = TRUE;
|
|
|
|
}
|
|
|
|
num >>= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
_cogl_texture_2d_can_create (unsigned int width,
|
|
|
|
unsigned int height,
|
|
|
|
CoglPixelFormat internal_format)
|
|
|
|
{
|
|
|
|
GLenum gl_intformat;
|
|
|
|
GLenum gl_type;
|
|
|
|
|
|
|
|
/* If the driver doesn't support glGenerateMipmap then we need to
|
|
|
|
store a copy of the first pixels to cause an update. Instead of
|
|
|
|
duplicating the code here we'll just make it fallback to
|
|
|
|
CoglTexture2DSliced */
|
|
|
|
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* If NPOT textures aren't supported then the size must be a power
|
|
|
|
of two */
|
|
|
|
if (!cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) &&
|
|
|
|
(!_cogl_texture_2d_is_pot (width) ||
|
|
|
|
!_cogl_texture_2d_is_pot (height)))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
_cogl_pixel_format_to_gl (internal_format,
|
|
|
|
&gl_intformat,
|
|
|
|
NULL,
|
|
|
|
&gl_type);
|
|
|
|
|
|
|
|
/* Check that the driver can create a texture with that size */
|
|
|
|
if (!_cogl_texture_driver_size_supported (GL_TEXTURE_2D,
|
|
|
|
gl_intformat,
|
|
|
|
gl_type,
|
|
|
|
width,
|
|
|
|
height))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CoglTexture2D *
|
|
|
|
_cogl_texture_2d_create_base (unsigned int width,
|
|
|
|
unsigned int height,
|
|
|
|
CoglTextureFlags flags,
|
|
|
|
CoglPixelFormat internal_format)
|
|
|
|
{
|
|
|
|
CoglTexture2D *tex_2d = g_new (CoglTexture2D, 1);
|
|
|
|
CoglTexture *tex = COGL_TEXTURE (tex_2d);
|
|
|
|
|
|
|
|
tex->vtable = &cogl_texture_2d_vtable;
|
|
|
|
|
|
|
|
tex_2d->width = width;
|
|
|
|
tex_2d->height = height;
|
|
|
|
tex_2d->mipmaps_dirty = TRUE;
|
|
|
|
tex_2d->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
|
|
|
|
|
2010-01-25 06:21:05 -05:00
|
|
|
/* We default to GL_LINEAR for both filters */
|
|
|
|
tex_2d->min_filter = GL_LINEAR;
|
|
|
|
tex_2d->mag_filter = GL_LINEAR;
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
/* Wrap mode not yet set */
|
|
|
|
tex_2d->wrap_mode = GL_FALSE;
|
|
|
|
|
|
|
|
tex_2d->format = internal_format;
|
|
|
|
|
|
|
|
return tex_2d;
|
|
|
|
}
|
|
|
|
|
|
|
|
CoglHandle
|
|
|
|
_cogl_texture_2d_new_with_size (unsigned int width,
|
|
|
|
unsigned int height,
|
|
|
|
CoglTextureFlags flags,
|
|
|
|
CoglPixelFormat internal_format)
|
|
|
|
{
|
|
|
|
CoglTexture2D *tex_2d;
|
|
|
|
GLenum gl_intformat;
|
|
|
|
GLenum gl_format;
|
|
|
|
GLenum gl_type;
|
|
|
|
|
|
|
|
/* Since no data, we need some internal format */
|
|
|
|
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
|
|
|
internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
|
|
|
|
|
|
|
if (!_cogl_texture_2d_can_create (width, height, internal_format))
|
|
|
|
return COGL_INVALID_HANDLE;
|
|
|
|
|
|
|
|
internal_format = _cogl_pixel_format_to_gl (internal_format,
|
|
|
|
&gl_intformat,
|
|
|
|
&gl_format,
|
|
|
|
&gl_type);
|
|
|
|
|
|
|
|
tex_2d = _cogl_texture_2d_create_base (width, height, flags, internal_format);
|
|
|
|
|
2010-02-09 07:21:10 -05:00
|
|
|
_cogl_texture_driver_gen (GL_TEXTURE_2D, 1, &tex_2d->gl_texture);
|
2009-11-27 13:45:36 -05:00
|
|
|
GE( glBindTexture (GL_TEXTURE_2D, tex_2d->gl_texture) );
|
|
|
|
GE( glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat,
|
|
|
|
width, height, 0, gl_format, gl_type, NULL) );
|
|
|
|
|
|
|
|
return _cogl_texture_2d_handle_new (tex_2d);
|
|
|
|
}
|
|
|
|
|
|
|
|
CoglHandle
|
|
|
|
_cogl_texture_2d_new_from_bitmap (CoglHandle bmp_handle,
|
|
|
|
CoglTextureFlags flags,
|
|
|
|
CoglPixelFormat internal_format)
|
|
|
|
{
|
2010-02-01 07:11:58 -05:00
|
|
|
CoglTexture2D *tex_2d;
|
|
|
|
CoglBitmap *bmp = (CoglBitmap *)bmp_handle;
|
|
|
|
CoglBitmap dst_bmp;
|
|
|
|
gboolean dst_bmp_owner;
|
|
|
|
GLenum gl_intformat;
|
|
|
|
GLenum gl_format;
|
|
|
|
GLenum gl_type;
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
g_return_val_if_fail (bmp_handle != COGL_INVALID_HANDLE, COGL_INVALID_HANDLE);
|
|
|
|
|
2010-02-01 07:11:58 -05:00
|
|
|
if (!_cogl_texture_prepare_for_upload (bmp,
|
|
|
|
internal_format,
|
|
|
|
&internal_format,
|
|
|
|
&dst_bmp,
|
|
|
|
&dst_bmp_owner,
|
|
|
|
&gl_intformat,
|
|
|
|
&gl_format,
|
|
|
|
&gl_type))
|
|
|
|
return COGL_INVALID_HANDLE;
|
2009-11-27 13:45:36 -05:00
|
|
|
|
2010-02-01 07:11:58 -05:00
|
|
|
tex_2d = _cogl_texture_2d_create_base (bmp->width,
|
|
|
|
bmp->height,
|
2009-11-27 13:45:36 -05:00
|
|
|
flags,
|
2010-02-01 07:11:58 -05:00
|
|
|
internal_format);
|
2009-11-27 13:45:36 -05:00
|
|
|
|
2010-01-25 06:21:05 -05:00
|
|
|
_cogl_texture_driver_gen (GL_TEXTURE_2D, 1, &tex_2d->gl_texture);
|
2009-11-27 13:45:36 -05:00
|
|
|
_cogl_texture_driver_upload_to_gl (GL_TEXTURE_2D,
|
|
|
|
tex_2d->gl_texture,
|
2010-02-01 07:11:58 -05:00
|
|
|
&dst_bmp,
|
|
|
|
gl_intformat,
|
|
|
|
gl_format,
|
|
|
|
gl_type);
|
2009-11-27 13:45:36 -05:00
|
|
|
|
2010-02-01 07:11:58 -05:00
|
|
|
tex_2d->gl_format = gl_intformat;
|
2009-11-27 13:45:36 -05:00
|
|
|
|
2010-02-01 07:11:58 -05:00
|
|
|
if (dst_bmp_owner)
|
|
|
|
g_free (dst_bmp.data);
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
return _cogl_texture_2d_handle_new (tex_2d);
|
|
|
|
}
|
|
|
|
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
static int
|
2009-11-27 13:45:36 -05:00
|
|
|
_cogl_texture_2d_get_max_waste (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
_cogl_texture_2d_is_sliced (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
_cogl_texture_2d_can_hardware_repeat (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_2d_transform_coords_to_gl (CoglTexture *tex,
|
|
|
|
float *s,
|
|
|
|
float *t)
|
|
|
|
{
|
|
|
|
/* The texture coordinates map directly so we don't need to do
|
|
|
|
anything */
|
|
|
|
}
|
|
|
|
|
2010-01-18 04:22:04 -05:00
|
|
|
static gboolean
|
|
|
|
_cogl_texture_2d_transform_quad_coords_to_gl (CoglTexture *tex,
|
|
|
|
float *coords)
|
|
|
|
{
|
|
|
|
/* The texture coordinates map directly so we don't need to do
|
|
|
|
anything */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2009-11-27 13:45:36 -05:00
|
|
|
static gboolean
|
|
|
|
_cogl_texture_2d_get_gl_texture (CoglTexture *tex,
|
|
|
|
GLuint *out_gl_handle,
|
|
|
|
GLenum *out_gl_target)
|
|
|
|
{
|
|
|
|
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
|
|
|
|
|
|
|
|
if (out_gl_handle)
|
|
|
|
*out_gl_handle = tex_2d->gl_texture;
|
|
|
|
|
|
|
|
if (out_gl_target)
|
|
|
|
*out_gl_target = GL_TEXTURE_2D;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_2d_set_filters (CoglTexture *tex,
|
|
|
|
GLenum min_filter,
|
|
|
|
GLenum mag_filter)
|
|
|
|
{
|
|
|
|
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
|
|
|
|
|
|
|
|
if (min_filter == tex_2d->min_filter
|
|
|
|
&& mag_filter == tex_2d->mag_filter)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Store new values */
|
|
|
|
tex_2d->min_filter = min_filter;
|
|
|
|
tex_2d->mag_filter = mag_filter;
|
|
|
|
|
|
|
|
/* Apply new filters to the texture */
|
|
|
|
GE( glBindTexture (GL_TEXTURE_2D, tex_2d->gl_texture) );
|
|
|
|
GE( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter) );
|
|
|
|
GE( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter) );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_2d_ensure_mipmaps (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
|
|
|
|
|
|
|
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
|
|
|
|
|
|
/* Only update if the mipmaps are dirty */
|
|
|
|
if (!tex_2d->auto_mipmap || !tex_2d->mipmaps_dirty)
|
|
|
|
return;
|
|
|
|
|
|
|
|
GE( glBindTexture (GL_TEXTURE_2D, tex_2d->gl_texture) );
|
|
|
|
/* glGenerateMipmap is defined in the FBO extension. We only allow
|
|
|
|
CoglTexture2D instances to be created if this feature is
|
|
|
|
available so we don't need to check for the extension */
|
|
|
|
_cogl_texture_driver_gl_generate_mipmaps (GL_TEXTURE_2D);
|
|
|
|
|
|
|
|
tex_2d->mipmaps_dirty = FALSE;
|
|
|
|
}
|
|
|
|
|
2010-01-18 04:22:04 -05:00
|
|
|
static void
|
|
|
|
_cogl_texture_2d_ensure_non_quad_rendering (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
/* Nothing needs to be done */
|
|
|
|
}
|
|
|
|
|
2009-11-27 13:45:36 -05:00
|
|
|
static gboolean
|
|
|
|
_cogl_texture_2d_set_region (CoglTexture *tex,
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
int bpp;
|
2009-11-27 13:45:36 -05:00
|
|
|
CoglBitmap source_bmp;
|
2010-02-01 07:11:58 -05:00
|
|
|
CoglBitmap tmp_bmp;
|
|
|
|
gboolean tmp_bmp_owner = FALSE;
|
2009-11-27 13:45:36 -05:00
|
|
|
GLenum closest_gl_format;
|
|
|
|
GLenum closest_gl_type;
|
|
|
|
|
|
|
|
/* Check for valid format */
|
|
|
|
if (format == COGL_PIXEL_FORMAT_ANY)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Shortcut out early if the image is empty */
|
|
|
|
if (width == 0 || height == 0)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* Init source bitmap */
|
|
|
|
source_bmp.width = width;
|
|
|
|
source_bmp.height = height;
|
|
|
|
source_bmp.format = format;
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
source_bmp.data = (guint8 *)data;
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
/* Rowstride from width if none specified */
|
|
|
|
bpp = _cogl_get_format_bpp (format);
|
|
|
|
source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
|
|
|
|
|
2010-02-01 07:11:58 -05:00
|
|
|
/* Prepare the bitmap so that it will do the premultiplication
|
|
|
|
conversion */
|
|
|
|
_cogl_texture_prepare_for_upload (&source_bmp,
|
|
|
|
tex_2d->format,
|
|
|
|
NULL,
|
|
|
|
&tmp_bmp,
|
|
|
|
&tmp_bmp_owner,
|
|
|
|
NULL,
|
|
|
|
&closest_gl_format,
|
|
|
|
&closest_gl_type);
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
/* Send data to GL */
|
|
|
|
_cogl_texture_driver_upload_subregion_to_gl (GL_TEXTURE_2D,
|
|
|
|
tex_2d->gl_texture,
|
|
|
|
src_x, src_y,
|
|
|
|
dst_x, dst_y,
|
|
|
|
dst_width, dst_height,
|
2010-02-01 07:11:58 -05:00
|
|
|
&tmp_bmp,
|
2009-11-27 13:45:36 -05:00
|
|
|
closest_gl_format,
|
|
|
|
closest_gl_type);
|
|
|
|
|
|
|
|
/* Free data if owner */
|
2010-02-01 07:11:58 -05:00
|
|
|
if (tmp_bmp_owner)
|
|
|
|
g_free (tmp_bmp.data);
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_cogl_texture_2d_get_data (CoglTexture *tex,
|
|
|
|
CoglPixelFormat format,
|
|
|
|
unsigned int rowstride,
|
|
|
|
guint8 *data)
|
|
|
|
{
|
|
|
|
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
int bpp;
|
|
|
|
int byte_size;
|
2009-11-27 13:45:36 -05:00
|
|
|
CoglPixelFormat closest_format;
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
int closest_bpp;
|
2009-11-27 13:45:36 -05:00
|
|
|
GLenum closest_gl_format;
|
|
|
|
GLenum closest_gl_type;
|
|
|
|
CoglBitmap target_bmp;
|
|
|
|
CoglBitmap new_bmp;
|
|
|
|
gboolean success;
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
guint8 *src;
|
|
|
|
guint8 *dst;
|
|
|
|
int y;
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
/* Default to internal format if none specified */
|
|
|
|
if (format == COGL_PIXEL_FORMAT_ANY)
|
|
|
|
format = tex_2d->format;
|
|
|
|
|
|
|
|
/* Rowstride from texture width if none specified */
|
|
|
|
bpp = _cogl_get_format_bpp (format);
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
if (rowstride == 0)
|
|
|
|
rowstride = tex_2d->width * bpp;
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
/* Return byte size if only that requested */
|
|
|
|
byte_size = tex_2d->height * rowstride;
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
if (data == NULL)
|
|
|
|
return byte_size;
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
closest_format =
|
|
|
|
_cogl_texture_driver_find_best_gl_get_data_format (format,
|
|
|
|
&closest_gl_format,
|
|
|
|
&closest_gl_type);
|
|
|
|
closest_bpp = _cogl_get_format_bpp (closest_format);
|
|
|
|
|
|
|
|
target_bmp.width = tex_2d->width;
|
|
|
|
target_bmp.height = tex_2d->height;
|
|
|
|
|
|
|
|
/* Is the requested format supported? */
|
|
|
|
if (closest_format == format)
|
|
|
|
{
|
|
|
|
/* Target user data directly */
|
|
|
|
target_bmp.format = format;
|
|
|
|
target_bmp.rowstride = rowstride;
|
|
|
|
target_bmp.data = data;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Target intermediate buffer */
|
|
|
|
target_bmp.format = closest_format;
|
|
|
|
target_bmp.rowstride = target_bmp.width * closest_bpp;
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
target_bmp.data = g_malloc (target_bmp.height * target_bmp.rowstride);
|
2009-11-27 13:45:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
GE( glBindTexture (GL_TEXTURE_2D, tex_2d->gl_texture) );
|
|
|
|
if (!_cogl_texture_driver_gl_get_tex_image (GL_TEXTURE_2D,
|
|
|
|
closest_gl_format,
|
|
|
|
closest_gl_type,
|
|
|
|
target_bmp.data))
|
|
|
|
{
|
|
|
|
/* XXX: In some cases _cogl_texture_2d_download_from_gl may
|
|
|
|
* fail to read back the texture data; such as for GLES which doesn't
|
|
|
|
* support glGetTexImage, so here we fallback to drawing the texture
|
|
|
|
* and reading the pixels from the framebuffer. */
|
|
|
|
_cogl_texture_draw_and_read (tex, &target_bmp,
|
|
|
|
closest_gl_format,
|
|
|
|
closest_gl_type);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Was intermediate used? */
|
|
|
|
if (closest_format != format)
|
|
|
|
{
|
|
|
|
/* Convert to requested format */
|
2010-01-29 10:15:08 -05:00
|
|
|
success = _cogl_bitmap_convert_format_and_premult (&target_bmp,
|
|
|
|
&new_bmp,
|
|
|
|
format);
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
/* Free intermediate data and return if failed */
|
|
|
|
g_free (target_bmp.data);
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
if (!success)
|
|
|
|
return 0;
|
2009-11-27 13:45:36 -05:00
|
|
|
|
|
|
|
/* Copy to user buffer */
|
|
|
|
for (y = 0; y < new_bmp.height; ++y)
|
|
|
|
{
|
|
|
|
src = new_bmp.data + y * new_bmp.rowstride;
|
|
|
|
dst = data + y * rowstride;
|
|
|
|
memcpy (dst, src, new_bmp.width);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free converted data */
|
|
|
|
g_free (new_bmp.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return byte_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CoglPixelFormat
|
|
|
|
_cogl_texture_2d_get_format (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return COGL_TEXTURE_2D (tex)->format;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GLenum
|
|
|
|
_cogl_texture_2d_get_gl_format (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return COGL_TEXTURE_2D (tex)->gl_format;
|
|
|
|
}
|
|
|
|
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
static int
|
2009-11-27 13:45:36 -05:00
|
|
|
_cogl_texture_2d_get_width (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return COGL_TEXTURE_2D (tex)->width;
|
|
|
|
}
|
|
|
|
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
static int
|
2009-11-27 13:45:36 -05:00
|
|
|
_cogl_texture_2d_get_height (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return COGL_TEXTURE_2D (tex)->height;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const CoglTextureVtable
|
|
|
|
cogl_texture_2d_vtable =
|
|
|
|
{
|
|
|
|
_cogl_texture_2d_set_region,
|
|
|
|
_cogl_texture_2d_get_data,
|
|
|
|
_cogl_texture_2d_foreach_sub_texture_in_region,
|
|
|
|
_cogl_texture_2d_get_max_waste,
|
|
|
|
_cogl_texture_2d_is_sliced,
|
|
|
|
_cogl_texture_2d_can_hardware_repeat,
|
|
|
|
_cogl_texture_2d_transform_coords_to_gl,
|
2010-01-18 04:22:04 -05:00
|
|
|
_cogl_texture_2d_transform_quad_coords_to_gl,
|
2009-11-27 13:45:36 -05:00
|
|
|
_cogl_texture_2d_get_gl_texture,
|
|
|
|
_cogl_texture_2d_set_filters,
|
|
|
|
_cogl_texture_2d_ensure_mipmaps,
|
2010-01-18 04:22:04 -05:00
|
|
|
_cogl_texture_2d_ensure_non_quad_rendering,
|
2009-11-27 13:45:36 -05:00
|
|
|
_cogl_texture_2d_set_wrap_mode_parameter,
|
|
|
|
_cogl_texture_2d_get_format,
|
|
|
|
_cogl_texture_2d_get_gl_format,
|
|
|
|
_cogl_texture_2d_get_width,
|
|
|
|
_cogl_texture_2d_get_height
|
|
|
|
};
|