mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 10:00:45 -05:00
A comparison of gl/cogl-texture.c and gles/cogl-texture.c, to reduce
differences and improve maintainability. * clutter/cogl/gl/cogl-context.h: Adds a CoglTextureGLVertex typedef + texture_vertices and texture_vertices_size members to CoglContext for using vertex arrays like GLES does * clutter/cogl/gl/cogl-context.c: Initializes texture_vertices + texture_vertices_size members * clutter/cogl/gl/cogl-internal.h: Adds COGL_ENABLE_COLOR_ARRAY * clutter/cogl/gl/cogl.c: Add COGL_ENABLE_COLOR_ARRAY support to cogl_enable * clutter/cogl/gles/cogl-context.h: Change the CoglTextureGLVertex to use GLfloat for the position and texture coord attributes and GLubyte for the color. * clutter/cogl/gles/cogl-texture-private.h: Adds a wrap_mode member like GL has. * clutter/cogl/gl/cogl-texture.c * clutter/cogl/gles/cogl-texture.c: Improves the comparability of the files, such that the remaining differences, better reflect the fundamental differences needed between GL and GLES. Notably GL no longer uses glBegin/glEnd for submitting vertices, it uses vertex arrays like GLES and this gives a small but measurable fps improvement for test-text.
This commit is contained in:
parent
6731dfa468
commit
8b557c6c13
@ -57,6 +57,8 @@ cogl_create_context ()
|
||||
_context->path_nodes_size = 0;
|
||||
|
||||
_context->texture_handles = NULL;
|
||||
_context->texture_vertices_size = 0;
|
||||
_context->texture_vertices = NULL;
|
||||
|
||||
_context->fbo_handles = NULL;
|
||||
_context->draw_buffer = COGL_WINDOW_BUFFER;
|
||||
|
@ -28,6 +28,13 @@
|
||||
|
||||
#include "cogl-primitives.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLfloat v[3];
|
||||
GLfloat t[2];
|
||||
GLubyte c[4];
|
||||
} CoglTextureGLVertex;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Features cache */
|
||||
@ -56,7 +63,9 @@ typedef struct
|
||||
GLfloat inverse_projection[16];
|
||||
|
||||
/* Textures */
|
||||
GArray *texture_handles;
|
||||
GArray *texture_handles;
|
||||
CoglTextureGLVertex *texture_vertices;
|
||||
gulong texture_vertices_size;
|
||||
|
||||
/* Framebuffer objects */
|
||||
GArray *fbo_handles;
|
||||
|
@ -56,7 +56,8 @@ const char *_cogl_error_string(GLenum errorCode);
|
||||
#define COGL_ENABLE_TEXTURE_RECT (1<<4)
|
||||
#define COGL_ENABLE_VERTEX_ARRAY (1<<5)
|
||||
#define COGL_ENABLE_TEXCOORD_ARRAY (1<<6)
|
||||
#define COGL_ENABLE_BACKFACE_CULLING (1<<7)
|
||||
#define COGL_ENABLE_COLOR_ARRAY (1<<7)
|
||||
#define COGL_ENABLE_BACKFACE_CULLING (1<<8)
|
||||
|
||||
gint
|
||||
_cogl_get_format_bpp (CoglPixelFormat format);
|
||||
|
@ -49,10 +49,6 @@
|
||||
printf("err: 0x%x\n", err); \
|
||||
} */
|
||||
|
||||
static void _cogl_texture_free (CoglTexture *tex);
|
||||
|
||||
COGL_HANDLE_DEFINE (Texture, texture, texture_handles);
|
||||
|
||||
struct _CoglSpanIter
|
||||
{
|
||||
gint index;
|
||||
@ -70,6 +66,11 @@ struct _CoglSpanIter
|
||||
gboolean intersects;
|
||||
};
|
||||
|
||||
static void _cogl_texture_free (CoglTexture *tex);
|
||||
|
||||
COGL_HANDLE_DEFINE (Texture, texture, texture_handles);
|
||||
|
||||
|
||||
static void
|
||||
_cogl_texture_bitmap_free (CoglTexture *tex)
|
||||
{
|
||||
@ -100,8 +101,8 @@ _cogl_span_iter_update (CoglSpanIter *iter)
|
||||
iter->index);
|
||||
|
||||
/* Offset next position by span size */
|
||||
iter->next_pos = iter->pos
|
||||
+ COGL_FIXED_FROM_INT (iter->span->size - iter->span->waste);
|
||||
iter->next_pos = iter->pos +
|
||||
COGL_FIXED_FROM_INT (iter->span->size - iter->span->waste);
|
||||
|
||||
/* Check if span intersects the area to cover */
|
||||
if (iter->next_pos <= iter->cover_start ||
|
||||
@ -168,48 +169,37 @@ _cogl_span_iter_end (CoglSpanIter *iter)
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_subregion_gl_store_rules (gint bmp_rowstride,
|
||||
gint bmp_width,
|
||||
gint bmp_bpp,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gboolean pack)
|
||||
prep_for_gl_pixels_upload (gint pixels_rowstride,
|
||||
gint pixels_src_x,
|
||||
gint pixels_src_y,
|
||||
gint pixels_bpp)
|
||||
{
|
||||
const GLenum ALIGNMENT = pack ?
|
||||
GL_PACK_ALIGNMENT : GL_UNPACK_ALIGNMENT;
|
||||
GE( glPixelStorei (GL_UNPACK_ROW_LENGTH, pixels_rowstride / pixels_bpp) );
|
||||
|
||||
const GLenum ROW_LENGTH = pack ?
|
||||
GL_PACK_ROW_LENGTH : GL_UNPACK_ROW_LENGTH;
|
||||
GE( glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) );
|
||||
GE( glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) );
|
||||
|
||||
const GLenum SKIP_ROWS = pack ?
|
||||
GL_PACK_SKIP_ROWS : GL_UNPACK_SKIP_ROWS;
|
||||
|
||||
const GLenum SKIP_PIXELS = pack ?
|
||||
GL_PACK_SKIP_PIXELS : GL_UNPACK_SKIP_PIXELS;
|
||||
|
||||
/* Encode the part of the rowstride that is a multiple of bmp_bpp in
|
||||
ROW_LENGTH and the remainder in ALIGNMENT */
|
||||
GE( glPixelStorei (ROW_LENGTH, bmp_rowstride / bmp_bpp) );
|
||||
|
||||
if (bmp_rowstride == bmp_width * bmp_bpp)
|
||||
{
|
||||
GE( glPixelStorei (ALIGNMENT, 1) );
|
||||
}
|
||||
if (!(pixels_rowstride & 0x7))
|
||||
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 8) );
|
||||
else if (!(pixels_rowstride & 0x3))
|
||||
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 4) );
|
||||
else if (!(pixels_rowstride & 0x1))
|
||||
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 2) );
|
||||
else
|
||||
{
|
||||
if ((bmp_rowstride % 4) == 0)
|
||||
{
|
||||
GE( glPixelStorei (ALIGNMENT, 4) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((bmp_rowstride % 2) == 0)
|
||||
GE( glPixelStorei (ALIGNMENT, 2) );
|
||||
}
|
||||
}
|
||||
|
||||
GE( glPixelStorei (SKIP_ROWS, src_y) );
|
||||
GE( glPixelStorei (SKIP_PIXELS, src_x) );
|
||||
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 1) );
|
||||
}
|
||||
|
||||
static void
|
||||
prep_for_gl_pixels_download (gint pixels_rowstride)
|
||||
{
|
||||
if (!(pixels_rowstride & 0x7))
|
||||
GE( glPixelStorei (GL_PACK_ALIGNMENT, 8) );
|
||||
else if (!(pixels_rowstride & 0x3))
|
||||
GE( glPixelStorei (GL_PACK_ALIGNMENT, 4) );
|
||||
else if (!(pixels_rowstride & 0x1))
|
||||
GE( glPixelStorei (GL_PACK_ALIGNMENT, 2) );
|
||||
else
|
||||
GE( glPixelStorei (GL_PACK_ALIGNMENT, 1) );
|
||||
}
|
||||
|
||||
static guchar *
|
||||
@ -270,17 +260,17 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
||||
y * tex->slice_x_spans->len + x);
|
||||
|
||||
/* Setup gl alignment to match rowstride and top-left corner */
|
||||
_cogl_subregion_gl_store_rules (tex->bitmap.rowstride,
|
||||
tex->bitmap.width,
|
||||
bpp,
|
||||
x_span->start,
|
||||
y_span->start,
|
||||
FALSE);
|
||||
prep_for_gl_pixels_upload (tex->bitmap.rowstride,
|
||||
x_span->start,
|
||||
y_span->start,
|
||||
bpp);
|
||||
|
||||
/* Upload new image data */
|
||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||
|
||||
GE( glTexSubImage2D (tex->gl_target, 0, 0, 0,
|
||||
|
||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||
0,
|
||||
0,
|
||||
x_span->size - x_span->waste,
|
||||
y_span->size - y_span->waste,
|
||||
tex->gl_format, tex->gl_type,
|
||||
@ -305,13 +295,14 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
||||
src += tex->bitmap.rowstride;
|
||||
}
|
||||
|
||||
_cogl_subregion_gl_store_rules (x_span->waste * bpp,
|
||||
x_span->waste,
|
||||
bpp,
|
||||
0, 0, FALSE);
|
||||
prep_for_gl_pixels_upload (x_span->waste * bpp,
|
||||
0, /* src x */
|
||||
0, /* src y */
|
||||
bpp);
|
||||
|
||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||
x_span->size - x_span->waste, 0,
|
||||
x_span->size - x_span->waste,
|
||||
0,
|
||||
x_span->waste,
|
||||
y_span->size - y_span->waste,
|
||||
tex->gl_format, tex->gl_type,
|
||||
@ -339,13 +330,14 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
||||
}
|
||||
}
|
||||
|
||||
_cogl_subregion_gl_store_rules (x_span->size * bpp,
|
||||
x_span->size,
|
||||
bpp,
|
||||
0, 0, FALSE);
|
||||
prep_for_gl_pixels_upload (x_span->size * bpp,
|
||||
0, /* src x */
|
||||
0, /* src y */
|
||||
bpp);
|
||||
|
||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||
0, y_span->size - y_span->waste,
|
||||
0,
|
||||
y_span->size - y_span->waste,
|
||||
x_span->size,
|
||||
y_span->waste,
|
||||
tex->gl_format, tex->gl_type,
|
||||
@ -401,17 +393,16 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
|
||||
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);
|
||||
slice_bmp.height);
|
||||
|
||||
/* Setup gl alignment to 0,0 top-left corner */
|
||||
_cogl_subregion_gl_store_rules (slice_bmp.rowstride,
|
||||
slice_bmp.width,
|
||||
bpp, 0, 0, TRUE);
|
||||
prep_for_gl_pixels_download (slice_bmp.rowstride);
|
||||
|
||||
/* Download slice image data into temp bmp */
|
||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||
|
||||
GE (glGetTexImage (tex->gl_target, 0,
|
||||
GE (glGetTexImage (tex->gl_target,
|
||||
0, /* level */
|
||||
target_gl_format,
|
||||
target_gl_type,
|
||||
slice_bmp.data) );
|
||||
@ -428,34 +419,21 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
|
||||
g_free (slice_bmp.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Setup gl alignment to match rowstride and top-left corner */
|
||||
|
||||
/* FIXME: for some strange reason any value other than 0
|
||||
* for GL_PACK_SKIP_PIXELS or GL_PACK_SKIP_ROWS corrupts the
|
||||
* memory. As a workaround we offset data pointer manually
|
||||
{
|
||||
GLvoid *dst = target_bmp->data
|
||||
+ x_span->start * bpp
|
||||
+ y_span->start * target_bmp->rowstride;
|
||||
|
||||
_cogl_subregion_gl_store_rules (target_bmp->rowstride,
|
||||
target_bmp->width,
|
||||
bpp,
|
||||
x_span->start,
|
||||
y_span->start,
|
||||
TRUE);*/
|
||||
_cogl_subregion_gl_store_rules (target_bmp->rowstride,
|
||||
target_bmp->width,
|
||||
bpp,
|
||||
0, 0,
|
||||
TRUE);
|
||||
prep_for_gl_pixels_download (target_bmp->rowstride);
|
||||
|
||||
/* Download slice image data */
|
||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||
|
||||
GE( glGetTexImage (tex->gl_target, 0,
|
||||
GE( glGetTexImage (tex->gl_target,
|
||||
0, /* level */
|
||||
target_gl_format,
|
||||
target_gl_type,
|
||||
target_bmp->data +
|
||||
x_span->start * bpp +
|
||||
y_span->start * target_bmp->rowstride) );
|
||||
dst) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -487,7 +465,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
||||
guchar *waste_buf;
|
||||
|
||||
bpp = _cogl_get_format_bpp (source_bmp->format);
|
||||
|
||||
|
||||
waste_buf = _cogl_texture_allocate_waste_buffer (tex);
|
||||
|
||||
/* Iterate vertical spans */
|
||||
@ -550,13 +528,10 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
||||
x_iter.index);
|
||||
|
||||
/* Setup gl alignment to match rowstride and top-left corner */
|
||||
|
||||
_cogl_subregion_gl_store_rules (source_bmp->rowstride,
|
||||
source_bmp->width,
|
||||
bpp,
|
||||
source_x,
|
||||
source_y,
|
||||
FALSE);
|
||||
prep_for_gl_pixels_upload (source_bmp->rowstride,
|
||||
source_x,
|
||||
source_y,
|
||||
bpp);
|
||||
|
||||
/* Upload new image data */
|
||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||
@ -599,13 +574,14 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
||||
src += source_bmp->rowstride;
|
||||
}
|
||||
|
||||
_cogl_subregion_gl_store_rules (x_span->waste * bpp,
|
||||
x_span->waste,
|
||||
bpp,
|
||||
0, 0, FALSE);
|
||||
prep_for_gl_pixels_upload (x_span->waste * bpp,
|
||||
0, /* src x */
|
||||
0, /* src y */
|
||||
bpp);
|
||||
|
||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||
x_span->size - x_span->waste, local_y,
|
||||
x_span->size - x_span->waste,
|
||||
local_y,
|
||||
x_span->waste,
|
||||
inter_h,
|
||||
source_gl_format,
|
||||
@ -650,13 +626,14 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
||||
}
|
||||
}
|
||||
|
||||
_cogl_subregion_gl_store_rules (copy_width * bpp,
|
||||
copy_width,
|
||||
bpp,
|
||||
0, 0, FALSE);
|
||||
prep_for_gl_pixels_upload (copy_width * bpp,
|
||||
0, /* src x */
|
||||
0, /* src y */
|
||||
bpp);
|
||||
|
||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||
local_x, y_span->size - y_span->waste,
|
||||
local_x,
|
||||
y_span->size - y_span->waste,
|
||||
copy_width,
|
||||
y_span->waste,
|
||||
source_gl_format,
|
||||
@ -764,7 +741,7 @@ _cogl_texture_size_supported (GLenum gl_target,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (gl_target == GL_TEXTURE_2D)
|
||||
if (gl_target == GL_TEXTURE_2D)
|
||||
{
|
||||
/* Proxy texture allows for a quick check for supported size */
|
||||
|
||||
@ -805,7 +782,7 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
||||
|
||||
bpp = _cogl_get_format_bpp (tex->bitmap.format);
|
||||
|
||||
/* Initialize size of largest slice according to supported features*/
|
||||
/* Initialize size of largest slice according to supported features */
|
||||
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT))
|
||||
{
|
||||
max_width = tex->bitmap.width;
|
||||
@ -904,7 +881,7 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
||||
max_height, tex->max_waste,
|
||||
tex->slice_y_spans);
|
||||
}
|
||||
|
||||
|
||||
/* Init and resize GL handle array */
|
||||
n_slices = n_x_slices * n_y_slices;
|
||||
|
||||
@ -946,18 +923,22 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
||||
y_span->size - y_span->waste);
|
||||
#endif
|
||||
/* Setup texture parameters */
|
||||
GE( glBindTexture (tex->gl_target, gl_handles[y * n_x_slices + x]) );
|
||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MAG_FILTER, tex->mag_filter) );
|
||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER, tex->min_filter) );
|
||||
|
||||
GE( glBindTexture (tex->gl_target,
|
||||
gl_handles[y * n_x_slices + x]) );
|
||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MAG_FILTER,
|
||||
tex->mag_filter) );
|
||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER,
|
||||
tex->min_filter) );
|
||||
|
||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_S,
|
||||
tex->wrap_mode) );
|
||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_T,
|
||||
tex->wrap_mode) );
|
||||
|
||||
if (tex->auto_mipmap)
|
||||
GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP, GL_TRUE) );
|
||||
|
||||
GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP,
|
||||
GL_TRUE) );
|
||||
|
||||
/* Use a transparent border color so that we can leave the
|
||||
color buffer alone when using texture co-ordinates
|
||||
outside of the texture */
|
||||
@ -1284,7 +1265,7 @@ cogl_texture_new_from_data (guint width,
|
||||
|
||||
tex->is_foreign = FALSE;
|
||||
tex->auto_mipmap = auto_mipmap;
|
||||
|
||||
|
||||
tex->bitmap.width = width;
|
||||
tex->bitmap.height = height;
|
||||
tex->bitmap.data = (guchar*)data;
|
||||
@ -1361,7 +1342,7 @@ cogl_texture_new_from_file (const gchar *filename,
|
||||
|
||||
tex->is_foreign = FALSE;
|
||||
tex->auto_mipmap = auto_mipmap;
|
||||
|
||||
|
||||
tex->bitmap = bmp;
|
||||
tex->bitmap_owner = TRUE;
|
||||
|
||||
@ -1414,10 +1395,10 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
||||
CoglPixelFormat format)
|
||||
{
|
||||
/* NOTE: width, height and internal format are not queriable
|
||||
in GLES, hence such a function prototype. However, here
|
||||
they are still queried from the texture for improved
|
||||
robustness and for completeness in case GLES 1.0 gets
|
||||
unsupported in favor of a new version and cleaner api
|
||||
in GLES, hence such a function prototype. However, for
|
||||
OpenGL they are still queried from the texture for improved
|
||||
robustness and for completeness in case one day GLES gains
|
||||
support for them.
|
||||
*/
|
||||
|
||||
GLenum gl_error = 0;
|
||||
@ -1468,7 +1449,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
||||
GE( glGetTexLevelParameteriv (gl_target, 0,
|
||||
GL_TEXTURE_HEIGHT,
|
||||
&gl_height) );
|
||||
|
||||
|
||||
GE( glGetTexParameteriv (gl_target,
|
||||
GL_TEXTURE_MIN_FILTER,
|
||||
&gl_min_filter) );
|
||||
@ -1501,8 +1482,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
||||
return COGL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
bpp = _cogl_get_format_bpp (format);
|
||||
|
||||
/* Create new texture */
|
||||
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
|
||||
|
||||
@ -1513,6 +1492,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
||||
tex->is_foreign = TRUE;
|
||||
tex->auto_mipmap = (gl_gen_mipmap == GL_TRUE) ? TRUE : FALSE;
|
||||
|
||||
bpp = _cogl_get_format_bpp (format);
|
||||
tex->bitmap.format = format;
|
||||
tex->bitmap.width = gl_width - x_pot_waste;
|
||||
tex->bitmap.height = gl_height - y_pot_waste;
|
||||
@ -1737,9 +1717,11 @@ cogl_texture_set_filters (CoglHandle handle,
|
||||
for (i=0; i<tex->slice_gl_handles->len; ++i)
|
||||
{
|
||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, i);
|
||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MAG_FILTER, tex->mag_filter) );
|
||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER, tex->min_filter) );
|
||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MAG_FILTER,
|
||||
tex->mag_filter) );
|
||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER,
|
||||
tex->min_filter) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1935,7 +1917,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
CoglFixed tx2,
|
||||
CoglFixed ty2)
|
||||
{
|
||||
CoglSpanIter iter_x , iter_y;
|
||||
CoglSpanIter iter_x , iter_y;
|
||||
CoglFixed tw , th;
|
||||
CoglFixed tqx , tqy;
|
||||
CoglFixed first_tx , first_ty;
|
||||
@ -1944,18 +1926,21 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
CoglFixed slice_tx2 , slice_ty2;
|
||||
CoglFixed slice_qx1 , slice_qy1;
|
||||
CoglFixed slice_qx2 , slice_qy2;
|
||||
GLuint gl_handle;
|
||||
gulong enable_flags = 0;
|
||||
GLfloat tex_coords[8];
|
||||
GLfloat quad_coords[8];
|
||||
GLuint gl_handle;
|
||||
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
|
||||
| COGL_ENABLE_VERTEX_ARRAY
|
||||
| COGL_ENABLE_TEXCOORD_ARRAY);
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
|
||||
#if COGL_DEBUG
|
||||
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
|
||||
#endif
|
||||
|
||||
/* Prepare GL state */
|
||||
enable_flags |= COGL_ENABLE_TEXTURE_2D;
|
||||
|
||||
/* Prepare GL state */
|
||||
if (ctx->color_alpha < 255
|
||||
|| tex->bitmap.format & COGL_A_BIT)
|
||||
{
|
||||
@ -1964,9 +1949,9 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
|
||||
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
|
||||
/* If the texture coordinates are backwards then swap both the
|
||||
geometry and texture coordinates so that the texture will be
|
||||
flipped but we can still use the same algorithm to iterate the
|
||||
@ -1990,6 +1975,9 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
ty2 = temp;
|
||||
}
|
||||
|
||||
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
|
||||
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
|
||||
|
||||
/* Scale ratio from texture to quad widths */
|
||||
tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
|
||||
th = COGL_FIXED_FROM_INT (tex->bitmap.height);
|
||||
@ -2083,25 +2071,21 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
iter_x.index);
|
||||
|
||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||
|
||||
|
||||
#define CFX_F COGL_FIXED_TO_FLOAT
|
||||
|
||||
/* Draw textured quad */
|
||||
glBegin (GL_QUADS);
|
||||
tex_coords[0] = CFX_F(slice_tx1); tex_coords[1] = CFX_F(slice_ty2);
|
||||
tex_coords[2] = CFX_F(slice_tx2); tex_coords[3] = CFX_F(slice_ty2);
|
||||
tex_coords[4] = CFX_F(slice_tx1); tex_coords[5] = CFX_F(slice_ty1);
|
||||
tex_coords[6] = CFX_F(slice_tx2); tex_coords[7] = CFX_F(slice_ty1);
|
||||
|
||||
glTexCoord2f (CFX_F(slice_tx1), CFX_F(slice_ty1));
|
||||
glVertex2f (CFX_F(slice_qx1), CFX_F(slice_qy1));
|
||||
quad_coords[0] = CFX_F(slice_qx1); quad_coords[1] = CFX_F(slice_qy2);
|
||||
quad_coords[2] = CFX_F(slice_qx2); quad_coords[3] = CFX_F(slice_qy2);
|
||||
quad_coords[4] = CFX_F(slice_qx1); quad_coords[5] = CFX_F(slice_qy1);
|
||||
quad_coords[6] = CFX_F(slice_qx2); quad_coords[7] = CFX_F(slice_qy1);
|
||||
|
||||
glTexCoord2f (CFX_F(slice_tx1), CFX_F(slice_ty2));
|
||||
glVertex2f (CFX_F(slice_qx1), CFX_F(slice_qy2));
|
||||
|
||||
glTexCoord2f (CFX_F(slice_tx2), CFX_F(slice_ty2));
|
||||
glVertex2f (CFX_F(slice_qx2), CFX_F(slice_qy2));
|
||||
|
||||
glTexCoord2f (CFX_F(slice_tx2), CFX_F(slice_ty1));
|
||||
glVertex2f (CFX_F(slice_qx2), CFX_F(slice_qy1));
|
||||
|
||||
GE( glEnd () );
|
||||
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
|
||||
|
||||
#undef CFX_F
|
||||
}
|
||||
@ -2119,11 +2103,15 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
||||
CoglFixed tx2,
|
||||
CoglFixed ty2)
|
||||
{
|
||||
GLfloat tex_coords[8];
|
||||
GLfloat quad_coords[8];
|
||||
GLuint gl_handle;
|
||||
CoglTexSliceSpan *x_span;
|
||||
CoglTexSliceSpan *y_span;
|
||||
GLuint gl_handle;
|
||||
gulong enable_flags = 0;
|
||||
|
||||
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
|
||||
| COGL_ENABLE_VERTEX_ARRAY
|
||||
| COGL_ENABLE_TEXCOORD_ARRAY);
|
||||
|
||||
#if COGL_DEBUG
|
||||
printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n");
|
||||
#endif
|
||||
@ -2131,8 +2119,6 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* Prepare GL state */
|
||||
enable_flags |= COGL_ENABLE_TEXTURE_2D;
|
||||
|
||||
if (ctx->color_alpha < 255
|
||||
|| tex->bitmap.format & COGL_A_BIT)
|
||||
{
|
||||
@ -2144,10 +2130,14 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
||||
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
|
||||
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
|
||||
|
||||
/* Pick and bind opengl texture object */
|
||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
|
||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||
|
||||
/* Don't include the waste in the texture coordinates */
|
||||
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
|
||||
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, 0);
|
||||
|
||||
@ -2160,21 +2150,17 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
||||
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x)
|
||||
|
||||
/* Draw textured quad */
|
||||
glBegin (GL_QUADS);
|
||||
tex_coords[0] = CFX_F(tx1); tex_coords[1] = CFX_F(ty2);
|
||||
tex_coords[2] = CFX_F(tx2); tex_coords[3] = CFX_F(ty2);
|
||||
tex_coords[4] = CFX_F(tx1); tex_coords[5] = CFX_F(ty1);
|
||||
tex_coords[6] = CFX_F(tx2); tex_coords[7] = CFX_F(ty1);
|
||||
|
||||
glTexCoord2f (CFX_F(tx1), CFX_F(ty1));
|
||||
glVertex2f (CFX_F(x1), CFX_F(y1));
|
||||
quad_coords[0] = CFX_F(x1); quad_coords[1] = CFX_F(y2);
|
||||
quad_coords[2] = CFX_F(x2); quad_coords[3] = CFX_F(y2);
|
||||
quad_coords[4] = CFX_F(x1); quad_coords[5] = CFX_F(y1);
|
||||
quad_coords[6] = CFX_F(x2); quad_coords[7] = CFX_F(y1);
|
||||
|
||||
glTexCoord2f (CFX_F(tx1), CFX_F(ty2));
|
||||
glVertex2f (CFX_F(x1), CFX_F(y2));
|
||||
|
||||
glTexCoord2f (CFX_F(tx2), CFX_F(ty2));
|
||||
glVertex2f (CFX_F(x2), CFX_F(y2));
|
||||
|
||||
glTexCoord2f (CFX_F(tx2), CFX_F(ty1));
|
||||
glVertex2f (CFX_F(x2), CFX_F(y1));
|
||||
|
||||
GE( glEnd () );
|
||||
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
|
||||
|
||||
#undef CFX_F
|
||||
}
|
||||
@ -2216,11 +2202,11 @@ cogl_texture_rectangle (CoglHandle handle,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tex->slice_gl_handles->len == 1 &&
|
||||
tx1 >= -COGL_FIXED_1 &&
|
||||
tx2 <= COGL_FIXED_1 &&
|
||||
ty1 >= -COGL_FIXED_1 &&
|
||||
ty2 <= COGL_FIXED_1)
|
||||
if (tex->slice_gl_handles->len == 1
|
||||
&& tx1 >= -COGL_FIXED_1
|
||||
&& tx2 <= COGL_FIXED_1
|
||||
&& ty1 >= -COGL_FIXED_1
|
||||
&& ty2 <= COGL_FIXED_1)
|
||||
{
|
||||
_cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
|
||||
}
|
||||
@ -2238,10 +2224,11 @@ cogl_texture_polygon (CoglHandle handle,
|
||||
gboolean use_color)
|
||||
{
|
||||
CoglTexture *tex;
|
||||
int i, x, y, vnum;
|
||||
int i, x, y;
|
||||
GLuint gl_handle;
|
||||
CoglTexSliceSpan *y_span, *x_span;
|
||||
gulong enable_flags;
|
||||
CoglTextureGLVertex *p;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -2250,7 +2237,7 @@ cogl_texture_polygon (CoglHandle handle,
|
||||
return;
|
||||
|
||||
tex = _cogl_texture_pointer_from_handle (handle);
|
||||
|
||||
|
||||
/* The polygon will have artifacts where the slices join if the wrap
|
||||
mode is GL_LINEAR because the filtering will pull in pixels from
|
||||
the transparent border. To make it clear that the function
|
||||
@ -2271,14 +2258,48 @@ cogl_texture_polygon (CoglHandle handle,
|
||||
return;
|
||||
}
|
||||
|
||||
tex = _cogl_texture_pointer_from_handle (handle);
|
||||
/* Make sure there is enough space in the global texture vertex
|
||||
array. This is used so we can render the polygon with a single
|
||||
call to OpenGL but still support any number of vertices */
|
||||
if (ctx->texture_vertices_size < n_vertices)
|
||||
{
|
||||
guint nsize = ctx->texture_vertices_size;
|
||||
|
||||
if (nsize == 0)
|
||||
nsize = 1;
|
||||
do
|
||||
nsize *= 2;
|
||||
while (nsize < n_vertices);
|
||||
|
||||
ctx->texture_vertices_size = nsize;
|
||||
|
||||
ctx->texture_vertices = g_realloc (ctx->texture_vertices,
|
||||
nsize
|
||||
* sizeof (CoglTextureGLVertex));
|
||||
}
|
||||
|
||||
/* Prepare GL state */
|
||||
enable_flags = COGL_ENABLE_TEXTURE_2D | COGL_ENABLE_BLEND;
|
||||
enable_flags = (COGL_ENABLE_TEXTURE_2D
|
||||
| COGL_ENABLE_VERTEX_ARRAY
|
||||
| COGL_ENABLE_TEXCOORD_ARRAY
|
||||
| COGL_ENABLE_BLEND);
|
||||
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
|
||||
if (use_color)
|
||||
{
|
||||
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
|
||||
GE( glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (CoglTextureGLVertex),
|
||||
ctx->texture_vertices[0].c) );
|
||||
}
|
||||
|
||||
GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex),
|
||||
ctx->texture_vertices[0].v) );
|
||||
GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex),
|
||||
ctx->texture_vertices[0].t) );
|
||||
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
/* Temporarily change the wrapping mode on all of the slices to use
|
||||
@ -2308,34 +2329,30 @@ cogl_texture_polygon (CoglHandle handle,
|
||||
|
||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, i++);
|
||||
|
||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
|
||||
for (vnum = 0; vnum < n_vertices; vnum++)
|
||||
/* Convert the vertices into an array of GLfloats ready to pass to
|
||||
OpenGL */
|
||||
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++)
|
||||
{
|
||||
GLfloat tx, ty;
|
||||
#define CFX_F COGL_FIXED_TO_FLOAT
|
||||
|
||||
if (use_color)
|
||||
cogl_set_source_color (&vertices[vnum].color);
|
||||
p->v[0] = CFX_F(vertices[i].x);
|
||||
p->v[1] = CFX_F(vertices[i].y);
|
||||
p->v[2] = CFX_F(vertices[i].z);
|
||||
p->t[0] = CFX_F(vertices[i].tx
|
||||
* (x_span->size - x_span->waste) / x_span->size);
|
||||
p->t[1] = CFX_F(vertices[i].ty
|
||||
* (y_span->size - y_span->waste) / y_span->size);
|
||||
p->c[0] = cogl_color_get_red_byte(&vertices[i].color);
|
||||
p->c[1] = cogl_color_get_green_byte(&vertices[i].color);
|
||||
p->c[2] = cogl_color_get_blue_byte(&vertices[i].color);
|
||||
p->c[3] = cogl_color_get_alpha_byte(&vertices[i].color);
|
||||
|
||||
/* Transform the texture co-ordinates so they are
|
||||
relative to the slice */
|
||||
tx = (COGL_FIXED_TO_FLOAT (vertices[vnum].tx)
|
||||
- x_span->start / (GLfloat) tex->bitmap.width)
|
||||
* tex->bitmap.width / x_span->size;
|
||||
ty = (COGL_FIXED_TO_FLOAT (vertices[vnum].ty)
|
||||
- y_span->start / (GLfloat) tex->bitmap.height)
|
||||
* tex->bitmap.height / y_span->size;
|
||||
|
||||
glTexCoord2f (tx, ty);
|
||||
|
||||
glVertex3f (COGL_FIXED_TO_FLOAT (vertices[vnum].x),
|
||||
COGL_FIXED_TO_FLOAT (vertices[vnum].y),
|
||||
COGL_FIXED_TO_FLOAT (vertices[vnum].z));
|
||||
#undef CFX_F
|
||||
}
|
||||
|
||||
GE( glEnd () );
|
||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||
|
||||
GE( glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,6 +327,9 @@ cogl_enable (gulong flags)
|
||||
COGL_ENABLE_TEXCOORD_ARRAY,
|
||||
GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
cogl_toggle_client_flag (ctx, flags,
|
||||
COGL_ENABLE_COLOR_ARRAY,
|
||||
GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
gulong
|
||||
|
@ -32,9 +32,9 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLfixed v[3];
|
||||
GLfixed t[2];
|
||||
GLfixed c[4];
|
||||
GLfloat v[3];
|
||||
GLfloat t[2];
|
||||
GLubyte c[4];
|
||||
} CoglTextureGLVertex;
|
||||
|
||||
typedef struct
|
||||
|
@ -55,6 +55,7 @@ struct _CoglTexture
|
||||
COGLenum min_filter;
|
||||
COGLenum mag_filter;
|
||||
gboolean is_foreign;
|
||||
GLint wrap_mode;
|
||||
gboolean auto_mipmap;
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user