texture: Make CoglSubTexture experimental public api

This exposes cogl_sub_texture_new() and cogl_is_sub_texture() as
experimental public API. Previously sub-textures were only exposed via
cogl_texture_new_from_sub_texture() so there wasn't a corresponding
CoglSubTexture type. A CoglSubTexture is a high-level texture defined as
a sub-region of some other parent texture. CoglSubTextures are high
level textures that implement the CoglMetaTexture interface which can
be used to manually handle texture repeating.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
Robert Bragg 2011-10-21 11:36:25 +01:00
parent 1ee861a82c
commit 18fb1ffab5
8 changed files with 158 additions and 46 deletions

View File

@ -79,6 +79,7 @@ cogl_public_h = \
$(srcdir)/cogl-texture-2d.h \ $(srcdir)/cogl-texture-2d.h \
$(srcdir)/cogl-texture-rectangle.h \ $(srcdir)/cogl-texture-rectangle.h \
$(srcdir)/cogl-texture-2d-sliced.h \ $(srcdir)/cogl-texture-2d-sliced.h \
$(srcdir)/cogl-sub-texture.h \
$(srcdir)/cogl-meta-texture.h \ $(srcdir)/cogl-meta-texture.h \
$(srcdir)/cogl-types.h \ $(srcdir)/cogl-types.h \
$(srcdir)/cogl-vertex-buffer.h \ $(srcdir)/cogl-vertex-buffer.h \

View File

@ -58,11 +58,13 @@ _cogl_atlas_texture_create_sub_texture (CoglHandle full_texture,
{ {
/* Create a subtexture for the given rectangle not including the /* Create a subtexture for the given rectangle not including the
1-pixel border */ 1-pixel border */
return _cogl_sub_texture_new (full_texture, _COGL_GET_CONTEXT (ctx, NULL);
rectangle->x + 1, return cogl_sub_texture_new (ctx,
rectangle->y + 1, full_texture,
rectangle->width - 2, rectangle->x + 1,
rectangle->height - 2); rectangle->y + 1,
rectangle->width - 2,
rectangle->height - 2);
} }
static void static void

View File

@ -21,15 +21,12 @@
* *
*/ */
#ifndef __COGL_SUB_TEXTURE_H #ifndef __COGL_SUB_TEXTURE_PRIVATE_H
#define __COGL_SUB_TEXTURE_H #define __COGL_SUB_TEXTURE_PRIVATE_H
#include "cogl-handle.h"
#include "cogl-texture-private.h" #include "cogl-texture-private.h"
#define COGL_SUB_TEXTURE(tex) ((CoglSubTexture *) tex) #include <glib.h>
typedef struct _CoglSubTexture CoglSubTexture;
struct _CoglSubTexture struct _CoglSubTexture
{ {
@ -40,12 +37,12 @@ struct _CoglSubTexture
use the full texture from that to render instead of making a use the full texture from that to render instead of making a
chain. However we want to preserve the next texture in case the chain. However we want to preserve the next texture in case the
user is expecting us to keep a reference and also so that we can user is expecting us to keep a reference and also so that we can
later add a cogl_sub_texture_get_full_texture() function. */ later add a cogl_sub_texture_get_parent_texture() function. */
CoglHandle next_texture; CoglTexture *next_texture;
/* This is the texture that will actually be used to draw. It will /* This is the texture that will actually be used to draw. It will
point to the end of the chain if a sub texture of a sub texture point to the end of the chain if a sub texture of a sub texture
is created */ is created */
CoglHandle full_texture; CoglTexture *full_texture;
/* The region represented by this sub-texture. This is the region of /* The region represented by this sub-texture. This is the region of
full_texture which won't necessarily be the same as the region full_texture which won't necessarily be the same as the region
@ -60,11 +57,4 @@ struct _CoglSubTexture
GQuark GQuark
_cogl_handle_sub_texture_get_type (void); _cogl_handle_sub_texture_get_type (void);
CoglHandle #endif /* __COGL_SUB_TEXTURE_PRIVATE_H */
_cogl_sub_texture_new (CoglHandle next_texture,
int sub_x,
int sub_y,
int sub_width,
int sub_height);
#endif /* __COGL_SUB_TEXTURE_H */

View File

@ -3,7 +3,7 @@
* *
* An object oriented GL/GLES Abstraction/Utility Layer * An object oriented GL/GLES Abstraction/Utility Layer
* *
* Copyright (C) 2009,2010 Intel Corporation. * Copyright (C) 2009,2010,2011 Intel Corporation.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -34,7 +34,7 @@
#include "cogl-texture-private.h" #include "cogl-texture-private.h"
#include "cogl-sub-texture-private.h" #include "cogl-sub-texture-private.h"
#include "cogl-context-private.h" #include "cogl-context-private.h"
#include "cogl-handle.h" #include "cogl-object.h"
#include "cogl-texture-driver.h" #include "cogl-texture-driver.h"
#include "cogl-texture-rectangle-private.h" #include "cogl-texture-rectangle-private.h"
@ -43,7 +43,7 @@
static void _cogl_sub_texture_free (CoglSubTexture *sub_tex); static void _cogl_sub_texture_free (CoglSubTexture *sub_tex);
COGL_TEXTURE_INTERNAL_DEFINE (SubTexture, sub_texture); COGL_TEXTURE_DEFINE (SubTexture, sub_texture);
static const CoglTextureVtable cogl_sub_texture_vtable; static const CoglTextureVtable cogl_sub_texture_vtable;
@ -198,19 +198,20 @@ _cogl_sub_texture_set_wrap_mode_parameters (CoglTexture *tex,
static void static void
_cogl_sub_texture_free (CoglSubTexture *sub_tex) _cogl_sub_texture_free (CoglSubTexture *sub_tex)
{ {
cogl_handle_unref (sub_tex->next_texture); cogl_object_unref (sub_tex->next_texture);
cogl_handle_unref (sub_tex->full_texture); cogl_object_unref (sub_tex->full_texture);
/* Chain up */ /* Chain up */
_cogl_texture_free (COGL_TEXTURE (sub_tex)); _cogl_texture_free (COGL_TEXTURE (sub_tex));
} }
CoglHandle CoglSubTexture *
_cogl_sub_texture_new (CoglHandle next_texture, cogl_sub_texture_new (CoglContext *ctx,
int sub_x, int sub_y, CoglTexture *next_texture,
int sub_width, int sub_height) int sub_x, int sub_y,
int sub_width, int sub_height)
{ {
CoglHandle full_texture; CoglTexture *full_texture;
CoglSubTexture *sub_tex; CoglSubTexture *sub_tex;
CoglTexture *tex; CoglTexture *tex;
unsigned int next_width, next_height; unsigned int next_width, next_height;
@ -219,13 +220,10 @@ _cogl_sub_texture_new (CoglHandle next_texture,
next_height = cogl_texture_get_height (next_texture); next_height = cogl_texture_get_height (next_texture);
/* The region must specify a non-zero subset of the full texture */ /* The region must specify a non-zero subset of the full texture */
_COGL_RETURN_VAL_IF_FAIL (sub_x >= 0 && sub_y >= 0, COGL_INVALID_HANDLE); _COGL_RETURN_VAL_IF_FAIL (sub_x >= 0 && sub_y >= 0, NULL);
_COGL_RETURN_VAL_IF_FAIL (sub_width > 0 && sub_height > 0, _COGL_RETURN_VAL_IF_FAIL (sub_width > 0 && sub_height > 0, NULL);
COGL_INVALID_HANDLE); _COGL_RETURN_VAL_IF_FAIL (sub_x + sub_width <= next_width, NULL);
_COGL_RETURN_VAL_IF_FAIL (sub_x + sub_width <= next_width, _COGL_RETURN_VAL_IF_FAIL (sub_y + sub_height <= next_height, NULL);
COGL_INVALID_HANDLE);
_COGL_RETURN_VAL_IF_FAIL (sub_y + sub_height <= next_height,
COGL_INVALID_HANDLE);
sub_tex = g_new (CoglSubTexture, 1); sub_tex = g_new (CoglSubTexture, 1);
@ -236,7 +234,7 @@ _cogl_sub_texture_new (CoglHandle next_texture,
/* If the next texture is also a sub texture we can avoid one level /* If the next texture is also a sub texture we can avoid one level
of indirection by referencing the full texture of that texture of indirection by referencing the full texture of that texture
instead. */ instead. */
if (_cogl_is_sub_texture (next_texture)) if (cogl_is_sub_texture (next_texture))
{ {
CoglSubTexture *other_sub_tex = CoglSubTexture *other_sub_tex =
_cogl_sub_texture_pointer_from_handle (next_texture); _cogl_sub_texture_pointer_from_handle (next_texture);
@ -247,8 +245,8 @@ _cogl_sub_texture_new (CoglHandle next_texture,
else else
full_texture = next_texture; full_texture = next_texture;
sub_tex->next_texture = cogl_handle_ref (next_texture); sub_tex->next_texture = cogl_object_ref (next_texture);
sub_tex->full_texture = cogl_handle_ref (full_texture); sub_tex->full_texture = cogl_object_ref (full_texture);
sub_tex->sub_x = sub_x; sub_tex->sub_x = sub_x;
sub_tex->sub_y = sub_y; sub_tex->sub_y = sub_y;

110
cogl/cogl-sub-texture.h Normal file
View File

@ -0,0 +1,110 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010 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>
*/
#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cogl/cogl.h> can be included directly."
#endif
#ifndef __COGL_SUB_TEXTURE_H
#define __COGL_SUB_TEXTURE_H
#include <glib.h>
G_BEGIN_DECLS
/**
* SECTION:cogl-sub-texture
* @short_description: Functions for creating and manipulating
* sub-textures.
*
* These functions allow high-level textures to be created that
* represent a sub-region of another texture. For example these
* can be used to implement custom texture atlasing schemes.
*/
#define COGL_SUB_TEXTURE(tex) ((CoglSubTexture *) tex)
typedef struct _CoglSubTexture CoglSubTexture;
#define cogl_sub_texture_new cogl_sub_texture_new_EXP
/**
* cogl_sub_texture_new:
* @context: A #CoglContext pointer
* @parent_texture: The full texture containing a sub-region you want
* to make a #CoglSubTexture from.
* @sub_x: The top-left x coordinate of the parent region to make
* a texture from.
* @sub_y: The top-left y coordinate of the parent region to make
* a texture from.
* @sub_width: The width of the parent region to make a texture from.
* @sub_height: The height of the parent region to make a texture
* from.
*
* Creates a high-level #CoglSubTexture representing a sub-region of
* any other #CoglTexture. The sub-region must strictly lye within the
* bounds of the @parent_texture. The returned texture implements the
* #CoglMetaTexture interface because it's not a low level texture
* that hardware can understand natively.
*
* <note>Remember: Unless you are using high level drawing APIs such
* as cogl_rectangle() or other APIs documented to understand the
* #CoglMetaTexture interface then you need to use the
* #CoglMetaTexture interface to resolve a #CoglSubTexture into a
* low-level texture before drawing.</note>
*
* Returns: A newly allocated #CoglSubTexture representing a
* sub-region of @parent_texture.
*
* Since: 1.10
* Stability: unstable
*/
CoglSubTexture *
cogl_sub_texture_new (CoglContext *ctx,
CoglTexture *parent_texture,
int sub_x,
int sub_y,
int sub_width,
int sub_height);
#define cogl_is_sub_texture cogl_is_sub_texture_EXP
/**
* cogl_is_sub_texture:
* @object: a #CoglObject
*
* Checks whether @object is a #CoglSubTexture.
*
* Return value: %TRUE if the passed @object represents a
* #CoglSubTexture and %FALSE otherwise.
*
* Since: 1.10
* Stability: unstable
*/
gboolean
cogl_is_sub_texture (void *object);
G_END_DECLS
#endif /* __COGL_SUB_TEXTURE_H */

View File

@ -454,8 +454,9 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
* coordinates, but the semantics for this function that people * coordinates, but the semantics for this function that people
* depend on are that all returned texture works with normalized * depend on are that all returned texture works with normalized
* coordinates so we wrap with a CoglSubTexture... */ * coordinates so we wrap with a CoglSubTexture... */
sub_texture = _cogl_sub_texture_new (COGL_TEXTURE (texture_rectangle), sub_texture = cogl_sub_texture_new (ctx,
0, 0, width, height); COGL_TEXTURE (texture_rectangle),
0, 0, width, height);
return COGL_TEXTURE (sub_texture); return COGL_TEXTURE (sub_texture);
} }
#endif #endif
@ -496,8 +497,10 @@ cogl_texture_new_from_sub_texture (CoglTexture *full_texture,
int sub_width, int sub_width,
int sub_height) int sub_height)
{ {
return _cogl_sub_texture_new (full_texture, sub_x, sub_y, _COGL_GET_CONTEXT (ctx, NULL);
sub_width, sub_height); return COGL_TEXTURE (cogl_sub_texture_new (ctx,
full_texture, sub_x, sub_y,
sub_width, sub_height));
} }
CoglTexture * CoglTexture *

View File

@ -83,6 +83,7 @@ typedef struct _CoglFramebuffer CoglFramebuffer;
#include <cogl/cogl-texture-rectangle.h> #include <cogl/cogl-texture-rectangle.h>
#include <cogl/cogl-texture-3d.h> #include <cogl/cogl-texture-3d.h>
#include <cogl/cogl-texture-2d-sliced.h> #include <cogl/cogl-texture-2d-sliced.h>
#include <cogl/cogl-sub-texture.h>
#include <cogl/cogl-meta-texture.h> #include <cogl/cogl-meta-texture.h>
#include <cogl/cogl-index-buffer.h> #include <cogl/cogl-index-buffer.h>
#include <cogl/cogl-attribute-buffer.h> #include <cogl/cogl-attribute-buffer.h>

View File

@ -328,6 +328,13 @@ cogl_texture_3d_new_from_data
cogl_is_texture_3d cogl_is_texture_3d
</SECTION> </SECTION>
<SECTION>
<FILE>cogl-sub-texture</FILE>
<TITLE>Sub Textures</TITLE>
cogl_sub_texture_new
cogl_is_sub_texture
</SECTION>
<SECTION> <SECTION>
<FILE>cogl-framebuffer</FILE> <FILE>cogl-framebuffer</FILE>
<TITLE>CoglFramebuffer: The Framebuffer Interface</TITLE> <TITLE>CoglFramebuffer: The Framebuffer Interface</TITLE>