cogl: Make CoglSubTexture only work for quad rendering

The sub texture backend doesn't work well as a completely general
texture backend because for example when rendering with cogl_polygon
it needs to be able to tranform arbitrary texture coordinates without
reference to the other coordintes. This can't be done when the texture
coordinates are a multiple of one because sometimes the coordinate
should represent the left or top edge and sometimes it should
represent the bottom or top edge. For example if the s coordinates are
0 and 1 then 1 represents the right edge but if they are 1 and 2 then
1 represents the left edge.

Instead the sub-textures are now documented not to support coordinates
outside the range [0,1]. The coordinates for the sub-region are now
represented as integers as this helps avoid rounding issues. The
region can no longer be a super-region of the texture as this
simplifies the code quite a lot.

There are two new texture virtual functions:

transform_quad_coords_to_gl - This transforms two pairs of coordinates
     representing a quad. It will return FALSE if the coordinates can
     not be transformed. The sub texture backend uses this to detect
     coordinates that require repeating which causes cogl-primitives
     to use manual repeating.

ensure_non_quad_rendering - This is used in cogl_polygon and
     cogl_vertex_buffer to inform the texture backend that
     transform_quad_to_gl is going to be used. The atlas backend
     migrates the texture out of the atlas when it hits this.
This commit is contained in:
Neil Roberts
2010-01-18 09:22:04 +00:00
parent 963afa88c5
commit ae7825275e
10 changed files with 324 additions and 373 deletions

View File

@ -34,6 +34,7 @@
#include "cogl-texture-private.h"
#include "cogl-atlas-texture-private.h"
#include "cogl-texture-2d-private.h"
#include "cogl-sub-texture-private.h"
#include "cogl-context.h"
#include "cogl-handle.h"
#include "cogl-texture-driver.h"
@ -312,6 +313,17 @@ _cogl_atlas_texture_transform_coords_to_gl (CoglTexture *tex,
_cogl_texture_transform_coords_to_gl (atlas_tex->sub_texture, s, t);
}
static gboolean
_cogl_atlas_texture_transform_quad_coords_to_gl (CoglTexture *tex,
float *coords)
{
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
/* Forward on to the sub texture */
return _cogl_texture_transform_quad_coords_to_gl (atlas_tex->sub_texture,
coords);
}
static gboolean
_cogl_atlas_texture_get_gl_texture (CoglTexture *tex,
GLuint *out_gl_handle,
@ -337,12 +349,9 @@ _cogl_atlas_texture_set_filters (CoglTexture *tex,
}
static void
_cogl_atlas_texture_ensure_mipmaps (CoglTexture *tex)
_cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex)
{
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
/* Mipmaps do not work well with the current atlas so instead we'll
just migrate the texture out and use a regular texture */
/* Make sure this texture is not in the atlas */
if (atlas_tex->in_atlas)
{
CoglHandle atlas_texture;
@ -382,11 +391,34 @@ _cogl_atlas_texture_ensure_mipmaps (CoglTexture *tex)
_cogl_atlas_texture_remove_from_atlas (atlas_tex);
}
}
static void
_cogl_atlas_texture_ensure_mipmaps (CoglTexture *tex)
{
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
/* Mipmaps do not work well with the current atlas so instead we'll
just migrate the texture out and use a regular texture */
_cogl_atlas_texture_migrate_out_of_atlas (atlas_tex);
/* Forward on to the sub texture */
_cogl_texture_ensure_mipmaps (atlas_tex->sub_texture);
}
static void
_cogl_atlas_texture_ensure_non_quad_rendering (CoglTexture *tex)
{
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
/* Sub textures can't support non-quad rendering so we'll just
migrate the texture out */
_cogl_atlas_texture_migrate_out_of_atlas (atlas_tex);
/* Forward on to the sub texture */
_cogl_texture_ensure_non_quad_rendering (atlas_tex->sub_texture);
}
static gboolean
_cogl_atlas_texture_set_region (CoglTexture *tex,
int src_x,
@ -546,14 +578,11 @@ _cogl_atlas_texture_create_sub_texture (CoglHandle full_texture,
{
/* Create a subtexture for the given rectangle not including the
1-pixel border */
gfloat tex_width = cogl_texture_get_width (full_texture);
gfloat tex_height = cogl_texture_get_height (full_texture);
gfloat tx1 = (rectangle->x + 1) / tex_width;
gfloat ty1 = (rectangle->y + 1) / tex_height;
gfloat tx2 = (rectangle->x + rectangle->width - 1) / tex_width;
gfloat ty2 = (rectangle->y + rectangle->height - 1) / tex_height;
return cogl_texture_new_from_sub_texture (full_texture, tx1, ty1, tx2, ty2);
return _cogl_sub_texture_new (full_texture,
rectangle->x + 1,
rectangle->y + 1,
rectangle->width - 2,
rectangle->height - 2);
}
typedef struct _CoglAtlasTextureRepositionData
@ -958,9 +987,11 @@ cogl_atlas_texture_vtable =
_cogl_atlas_texture_is_sliced,
_cogl_atlas_texture_can_hardware_repeat,
_cogl_atlas_texture_transform_coords_to_gl,
_cogl_atlas_texture_transform_quad_coords_to_gl,
_cogl_atlas_texture_get_gl_texture,
_cogl_atlas_texture_set_filters,
_cogl_atlas_texture_ensure_mipmaps,
_cogl_atlas_texture_ensure_non_quad_rendering,
_cogl_atlas_texture_set_wrap_mode_parameter,
_cogl_atlas_texture_get_format,
_cogl_atlas_texture_get_gl_format,