mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 19:40:43 -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->path_nodes_size = 0;
|
||||||
|
|
||||||
_context->texture_handles = NULL;
|
_context->texture_handles = NULL;
|
||||||
|
_context->texture_vertices_size = 0;
|
||||||
|
_context->texture_vertices = NULL;
|
||||||
|
|
||||||
_context->fbo_handles = NULL;
|
_context->fbo_handles = NULL;
|
||||||
_context->draw_buffer = COGL_WINDOW_BUFFER;
|
_context->draw_buffer = COGL_WINDOW_BUFFER;
|
||||||
|
@ -28,6 +28,13 @@
|
|||||||
|
|
||||||
#include "cogl-primitives.h"
|
#include "cogl-primitives.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GLfloat v[3];
|
||||||
|
GLfloat t[2];
|
||||||
|
GLubyte c[4];
|
||||||
|
} CoglTextureGLVertex;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* Features cache */
|
/* Features cache */
|
||||||
@ -56,7 +63,9 @@ typedef struct
|
|||||||
GLfloat inverse_projection[16];
|
GLfloat inverse_projection[16];
|
||||||
|
|
||||||
/* Textures */
|
/* Textures */
|
||||||
GArray *texture_handles;
|
GArray *texture_handles;
|
||||||
|
CoglTextureGLVertex *texture_vertices;
|
||||||
|
gulong texture_vertices_size;
|
||||||
|
|
||||||
/* Framebuffer objects */
|
/* Framebuffer objects */
|
||||||
GArray *fbo_handles;
|
GArray *fbo_handles;
|
||||||
|
@ -56,7 +56,8 @@ const char *_cogl_error_string(GLenum errorCode);
|
|||||||
#define COGL_ENABLE_TEXTURE_RECT (1<<4)
|
#define COGL_ENABLE_TEXTURE_RECT (1<<4)
|
||||||
#define COGL_ENABLE_VERTEX_ARRAY (1<<5)
|
#define COGL_ENABLE_VERTEX_ARRAY (1<<5)
|
||||||
#define COGL_ENABLE_TEXCOORD_ARRAY (1<<6)
|
#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
|
gint
|
||||||
_cogl_get_format_bpp (CoglPixelFormat format);
|
_cogl_get_format_bpp (CoglPixelFormat format);
|
||||||
|
@ -49,10 +49,6 @@
|
|||||||
printf("err: 0x%x\n", err); \
|
printf("err: 0x%x\n", err); \
|
||||||
} */
|
} */
|
||||||
|
|
||||||
static void _cogl_texture_free (CoglTexture *tex);
|
|
||||||
|
|
||||||
COGL_HANDLE_DEFINE (Texture, texture, texture_handles);
|
|
||||||
|
|
||||||
struct _CoglSpanIter
|
struct _CoglSpanIter
|
||||||
{
|
{
|
||||||
gint index;
|
gint index;
|
||||||
@ -70,6 +66,11 @@ struct _CoglSpanIter
|
|||||||
gboolean intersects;
|
gboolean intersects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void _cogl_texture_free (CoglTexture *tex);
|
||||||
|
|
||||||
|
COGL_HANDLE_DEFINE (Texture, texture, texture_handles);
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_texture_bitmap_free (CoglTexture *tex)
|
_cogl_texture_bitmap_free (CoglTexture *tex)
|
||||||
{
|
{
|
||||||
@ -100,8 +101,8 @@ _cogl_span_iter_update (CoglSpanIter *iter)
|
|||||||
iter->index);
|
iter->index);
|
||||||
|
|
||||||
/* Offset next position by span size */
|
/* Offset next position by span size */
|
||||||
iter->next_pos = iter->pos
|
iter->next_pos = iter->pos +
|
||||||
+ COGL_FIXED_FROM_INT (iter->span->size - iter->span->waste);
|
COGL_FIXED_FROM_INT (iter->span->size - iter->span->waste);
|
||||||
|
|
||||||
/* Check if span intersects the area to cover */
|
/* Check if span intersects the area to cover */
|
||||||
if (iter->next_pos <= iter->cover_start ||
|
if (iter->next_pos <= iter->cover_start ||
|
||||||
@ -168,48 +169,37 @@ _cogl_span_iter_end (CoglSpanIter *iter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_subregion_gl_store_rules (gint bmp_rowstride,
|
prep_for_gl_pixels_upload (gint pixels_rowstride,
|
||||||
gint bmp_width,
|
gint pixels_src_x,
|
||||||
gint bmp_bpp,
|
gint pixels_src_y,
|
||||||
gint src_x,
|
gint pixels_bpp)
|
||||||
gint src_y,
|
|
||||||
gboolean pack)
|
|
||||||
{
|
{
|
||||||
const GLenum ALIGNMENT = pack ?
|
GE( glPixelStorei (GL_UNPACK_ROW_LENGTH, pixels_rowstride / pixels_bpp) );
|
||||||
GL_PACK_ALIGNMENT : GL_UNPACK_ALIGNMENT;
|
|
||||||
|
|
||||||
const GLenum ROW_LENGTH = pack ?
|
GE( glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) );
|
||||||
GL_PACK_ROW_LENGTH : GL_UNPACK_ROW_LENGTH;
|
GE( glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) );
|
||||||
|
|
||||||
const GLenum SKIP_ROWS = pack ?
|
if (!(pixels_rowstride & 0x7))
|
||||||
GL_PACK_SKIP_ROWS : GL_UNPACK_SKIP_ROWS;
|
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 8) );
|
||||||
|
else if (!(pixels_rowstride & 0x3))
|
||||||
const GLenum SKIP_PIXELS = pack ?
|
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 4) );
|
||||||
GL_PACK_SKIP_PIXELS : GL_UNPACK_SKIP_PIXELS;
|
else if (!(pixels_rowstride & 0x1))
|
||||||
|
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 2) );
|
||||||
/* 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) );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 1) );
|
||||||
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) );
|
static void
|
||||||
GE( glPixelStorei (SKIP_PIXELS, src_x) );
|
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 *
|
static guchar *
|
||||||
@ -270,17 +260,17 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
y * tex->slice_x_spans->len + x);
|
y * tex->slice_x_spans->len + x);
|
||||||
|
|
||||||
/* Setup gl alignment to match rowstride and top-left corner */
|
/* Setup gl alignment to match rowstride and top-left corner */
|
||||||
_cogl_subregion_gl_store_rules (tex->bitmap.rowstride,
|
prep_for_gl_pixels_upload (tex->bitmap.rowstride,
|
||||||
tex->bitmap.width,
|
x_span->start,
|
||||||
bpp,
|
y_span->start,
|
||||||
x_span->start,
|
bpp);
|
||||||
y_span->start,
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
/* Upload new image data */
|
/* Upload new image data */
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
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,
|
x_span->size - x_span->waste,
|
||||||
y_span->size - y_span->waste,
|
y_span->size - y_span->waste,
|
||||||
tex->gl_format, tex->gl_type,
|
tex->gl_format, tex->gl_type,
|
||||||
@ -305,13 +295,14 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
src += tex->bitmap.rowstride;
|
src += tex->bitmap.rowstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cogl_subregion_gl_store_rules (x_span->waste * bpp,
|
prep_for_gl_pixels_upload (x_span->waste * bpp,
|
||||||
x_span->waste,
|
0, /* src x */
|
||||||
bpp,
|
0, /* src y */
|
||||||
0, 0, FALSE);
|
bpp);
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
x_span->size - x_span->waste, 0,
|
x_span->size - x_span->waste,
|
||||||
|
0,
|
||||||
x_span->waste,
|
x_span->waste,
|
||||||
y_span->size - y_span->waste,
|
y_span->size - y_span->waste,
|
||||||
tex->gl_format, tex->gl_type,
|
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,
|
prep_for_gl_pixels_upload (x_span->size * bpp,
|
||||||
x_span->size,
|
0, /* src x */
|
||||||
bpp,
|
0, /* src y */
|
||||||
0, 0, FALSE);
|
bpp);
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
0, y_span->size - y_span->waste,
|
0,
|
||||||
|
y_span->size - y_span->waste,
|
||||||
x_span->size,
|
x_span->size,
|
||||||
y_span->waste,
|
y_span->waste,
|
||||||
tex->gl_format, tex->gl_type,
|
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.height = y_span->size;
|
||||||
slice_bmp.rowstride = bpp * slice_bmp.width;
|
slice_bmp.rowstride = bpp * slice_bmp.width;
|
||||||
slice_bmp.data = (guchar*) g_malloc (slice_bmp.rowstride *
|
slice_bmp.data = (guchar*) g_malloc (slice_bmp.rowstride *
|
||||||
slice_bmp.height);
|
slice_bmp.height);
|
||||||
|
|
||||||
/* Setup gl alignment to 0,0 top-left corner */
|
/* Setup gl alignment to 0,0 top-left corner */
|
||||||
_cogl_subregion_gl_store_rules (slice_bmp.rowstride,
|
prep_for_gl_pixels_download (slice_bmp.rowstride);
|
||||||
slice_bmp.width,
|
|
||||||
bpp, 0, 0, TRUE);
|
|
||||||
|
|
||||||
/* Download slice image data into temp bmp */
|
/* Download slice image data into temp bmp */
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
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_format,
|
||||||
target_gl_type,
|
target_gl_type,
|
||||||
slice_bmp.data) );
|
slice_bmp.data) );
|
||||||
@ -429,33 +420,20 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Setup gl alignment to match rowstride and top-left corner */
|
GLvoid *dst = target_bmp->data
|
||||||
|
+ x_span->start * bpp
|
||||||
|
+ y_span->start * target_bmp->rowstride;
|
||||||
|
|
||||||
/* FIXME: for some strange reason any value other than 0
|
prep_for_gl_pixels_download (target_bmp->rowstride);
|
||||||
* for GL_PACK_SKIP_PIXELS or GL_PACK_SKIP_ROWS corrupts the
|
|
||||||
* memory. As a workaround we offset data pointer manually
|
|
||||||
|
|
||||||
_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);
|
|
||||||
|
|
||||||
/* Download slice image data */
|
/* Download slice image data */
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
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_format,
|
||||||
target_gl_type,
|
target_gl_type,
|
||||||
target_bmp->data +
|
dst) );
|
||||||
x_span->start * bpp +
|
|
||||||
y_span->start * target_bmp->rowstride) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,13 +528,10 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
x_iter.index);
|
x_iter.index);
|
||||||
|
|
||||||
/* Setup gl alignment to match rowstride and top-left corner */
|
/* Setup gl alignment to match rowstride and top-left corner */
|
||||||
|
prep_for_gl_pixels_upload (source_bmp->rowstride,
|
||||||
_cogl_subregion_gl_store_rules (source_bmp->rowstride,
|
source_x,
|
||||||
source_bmp->width,
|
source_y,
|
||||||
bpp,
|
bpp);
|
||||||
source_x,
|
|
||||||
source_y,
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
/* Upload new image data */
|
/* Upload new image data */
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||||
@ -599,13 +574,14 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
src += source_bmp->rowstride;
|
src += source_bmp->rowstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cogl_subregion_gl_store_rules (x_span->waste * bpp,
|
prep_for_gl_pixels_upload (x_span->waste * bpp,
|
||||||
x_span->waste,
|
0, /* src x */
|
||||||
bpp,
|
0, /* src y */
|
||||||
0, 0, FALSE);
|
bpp);
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
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,
|
x_span->waste,
|
||||||
inter_h,
|
inter_h,
|
||||||
source_gl_format,
|
source_gl_format,
|
||||||
@ -650,13 +626,14 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_cogl_subregion_gl_store_rules (copy_width * bpp,
|
prep_for_gl_pixels_upload (copy_width * bpp,
|
||||||
copy_width,
|
0, /* src x */
|
||||||
bpp,
|
0, /* src y */
|
||||||
0, 0, FALSE);
|
bpp);
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
local_x, y_span->size - y_span->waste,
|
local_x,
|
||||||
|
y_span->size - y_span->waste,
|
||||||
copy_width,
|
copy_width,
|
||||||
y_span->waste,
|
y_span->waste,
|
||||||
source_gl_format,
|
source_gl_format,
|
||||||
@ -764,7 +741,7 @@ _cogl_texture_size_supported (GLenum gl_target,
|
|||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
if (gl_target == GL_TEXTURE_2D)
|
if (gl_target == GL_TEXTURE_2D)
|
||||||
{
|
{
|
||||||
/* Proxy texture allows for a quick check for supported size */
|
/* 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);
|
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))
|
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT))
|
||||||
{
|
{
|
||||||
max_width = tex->bitmap.width;
|
max_width = tex->bitmap.width;
|
||||||
@ -946,9 +923,12 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
|||||||
y_span->size - y_span->waste);
|
y_span->size - y_span->waste);
|
||||||
#endif
|
#endif
|
||||||
/* Setup texture parameters */
|
/* Setup texture parameters */
|
||||||
GE( glBindTexture (tex->gl_target, gl_handles[y * n_x_slices + x]) );
|
GE( glBindTexture (tex->gl_target,
|
||||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MAG_FILTER, tex->mag_filter) );
|
gl_handles[y * n_x_slices + x]) );
|
||||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER, tex->min_filter) );
|
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,
|
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_S,
|
||||||
tex->wrap_mode) );
|
tex->wrap_mode) );
|
||||||
@ -956,7 +936,8 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
|||||||
tex->wrap_mode) );
|
tex->wrap_mode) );
|
||||||
|
|
||||||
if (tex->auto_mipmap)
|
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
|
/* Use a transparent border color so that we can leave the
|
||||||
color buffer alone when using texture co-ordinates
|
color buffer alone when using texture co-ordinates
|
||||||
@ -1414,10 +1395,10 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
CoglPixelFormat format)
|
CoglPixelFormat format)
|
||||||
{
|
{
|
||||||
/* NOTE: width, height and internal format are not queriable
|
/* NOTE: width, height and internal format are not queriable
|
||||||
in GLES, hence such a function prototype. However, here
|
in GLES, hence such a function prototype. However, for
|
||||||
they are still queried from the texture for improved
|
OpenGL they are still queried from the texture for improved
|
||||||
robustness and for completeness in case GLES 1.0 gets
|
robustness and for completeness in case one day GLES gains
|
||||||
unsupported in favor of a new version and cleaner api
|
support for them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GLenum gl_error = 0;
|
GLenum gl_error = 0;
|
||||||
@ -1501,8 +1482,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bpp = _cogl_get_format_bpp (format);
|
|
||||||
|
|
||||||
/* Create new texture */
|
/* Create new texture */
|
||||||
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
|
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
|
||||||
|
|
||||||
@ -1513,6 +1492,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
tex->is_foreign = TRUE;
|
tex->is_foreign = TRUE;
|
||||||
tex->auto_mipmap = (gl_gen_mipmap == GL_TRUE) ? TRUE : FALSE;
|
tex->auto_mipmap = (gl_gen_mipmap == GL_TRUE) ? TRUE : FALSE;
|
||||||
|
|
||||||
|
bpp = _cogl_get_format_bpp (format);
|
||||||
tex->bitmap.format = format;
|
tex->bitmap.format = format;
|
||||||
tex->bitmap.width = gl_width - x_pot_waste;
|
tex->bitmap.width = gl_width - x_pot_waste;
|
||||||
tex->bitmap.height = gl_height - y_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)
|
for (i=0; i<tex->slice_gl_handles->len; ++i)
|
||||||
{
|
{
|
||||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, i);
|
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, i);
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
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_MAG_FILTER,
|
||||||
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER, tex->min_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 tx2,
|
||||||
CoglFixed ty2)
|
CoglFixed ty2)
|
||||||
{
|
{
|
||||||
CoglSpanIter iter_x , iter_y;
|
CoglSpanIter iter_x , iter_y;
|
||||||
CoglFixed tw , th;
|
CoglFixed tw , th;
|
||||||
CoglFixed tqx , tqy;
|
CoglFixed tqx , tqy;
|
||||||
CoglFixed first_tx , first_ty;
|
CoglFixed first_tx , first_ty;
|
||||||
@ -1944,8 +1926,12 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
CoglFixed slice_tx2 , slice_ty2;
|
CoglFixed slice_tx2 , slice_ty2;
|
||||||
CoglFixed slice_qx1 , slice_qy1;
|
CoglFixed slice_qx1 , slice_qy1;
|
||||||
CoglFixed slice_qx2 , slice_qy2;
|
CoglFixed slice_qx2 , slice_qy2;
|
||||||
GLuint gl_handle;
|
GLfloat tex_coords[8];
|
||||||
gulong enable_flags = 0;
|
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);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
@ -1953,9 +1939,8 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
|
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Prepare GL state */
|
|
||||||
enable_flags |= COGL_ENABLE_TEXTURE_2D;
|
|
||||||
|
|
||||||
|
/* Prepare GL state */
|
||||||
if (ctx->color_alpha < 255
|
if (ctx->color_alpha < 255
|
||||||
|| tex->bitmap.format & COGL_A_BIT)
|
|| tex->bitmap.format & COGL_A_BIT)
|
||||||
{
|
{
|
||||||
@ -1990,6 +1975,9 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
ty2 = temp;
|
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 */
|
/* Scale ratio from texture to quad widths */
|
||||||
tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
|
tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
|
||||||
th = COGL_FIXED_FROM_INT (tex->bitmap.height);
|
th = COGL_FIXED_FROM_INT (tex->bitmap.height);
|
||||||
@ -2087,21 +2075,17 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
#define CFX_F COGL_FIXED_TO_FLOAT
|
#define CFX_F COGL_FIXED_TO_FLOAT
|
||||||
|
|
||||||
/* Draw textured quad */
|
/* 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));
|
quad_coords[0] = CFX_F(slice_qx1); quad_coords[1] = CFX_F(slice_qy2);
|
||||||
glVertex2f (CFX_F(slice_qx1), CFX_F(slice_qy1));
|
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));
|
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
|
||||||
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 () );
|
|
||||||
|
|
||||||
#undef CFX_F
|
#undef CFX_F
|
||||||
}
|
}
|
||||||
@ -2119,10 +2103,14 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
|||||||
CoglFixed tx2,
|
CoglFixed tx2,
|
||||||
CoglFixed ty2)
|
CoglFixed ty2)
|
||||||
{
|
{
|
||||||
|
GLfloat tex_coords[8];
|
||||||
|
GLfloat quad_coords[8];
|
||||||
|
GLuint gl_handle;
|
||||||
CoglTexSliceSpan *x_span;
|
CoglTexSliceSpan *x_span;
|
||||||
CoglTexSliceSpan *y_span;
|
CoglTexSliceSpan *y_span;
|
||||||
GLuint gl_handle;
|
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
|
||||||
gulong enable_flags = 0;
|
| COGL_ENABLE_VERTEX_ARRAY
|
||||||
|
| COGL_ENABLE_TEXCOORD_ARRAY);
|
||||||
|
|
||||||
#if COGL_DEBUG
|
#if COGL_DEBUG
|
||||||
printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n");
|
printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n");
|
||||||
@ -2131,8 +2119,6 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
|||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
/* Prepare GL state */
|
/* Prepare GL state */
|
||||||
enable_flags |= COGL_ENABLE_TEXTURE_2D;
|
|
||||||
|
|
||||||
if (ctx->color_alpha < 255
|
if (ctx->color_alpha < 255
|
||||||
|| tex->bitmap.format & COGL_A_BIT)
|
|| tex->bitmap.format & COGL_A_BIT)
|
||||||
{
|
{
|
||||||
@ -2144,10 +2130,14 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
|||||||
|
|
||||||
cogl_enable (enable_flags);
|
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 */
|
/* Pick and bind opengl texture object */
|
||||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
|
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
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);
|
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
|
||||||
y_span = &g_array_index (tex->slice_y_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)
|
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x)
|
||||||
|
|
||||||
/* Draw textured quad */
|
/* 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));
|
quad_coords[0] = CFX_F(x1); quad_coords[1] = CFX_F(y2);
|
||||||
glVertex2f (CFX_F(x1), CFX_F(y1));
|
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));
|
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
|
||||||
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 () );
|
|
||||||
|
|
||||||
#undef CFX_F
|
#undef CFX_F
|
||||||
}
|
}
|
||||||
@ -2216,11 +2202,11 @@ cogl_texture_rectangle (CoglHandle handle,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (tex->slice_gl_handles->len == 1 &&
|
if (tex->slice_gl_handles->len == 1
|
||||||
tx1 >= -COGL_FIXED_1 &&
|
&& tx1 >= -COGL_FIXED_1
|
||||||
tx2 <= COGL_FIXED_1 &&
|
&& tx2 <= COGL_FIXED_1
|
||||||
ty1 >= -COGL_FIXED_1 &&
|
&& ty1 >= -COGL_FIXED_1
|
||||||
ty2 <= COGL_FIXED_1)
|
&& ty2 <= COGL_FIXED_1)
|
||||||
{
|
{
|
||||||
_cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
|
_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)
|
gboolean use_color)
|
||||||
{
|
{
|
||||||
CoglTexture *tex;
|
CoglTexture *tex;
|
||||||
int i, x, y, vnum;
|
int i, x, y;
|
||||||
GLuint gl_handle;
|
GLuint gl_handle;
|
||||||
CoglTexSliceSpan *y_span, *x_span;
|
CoglTexSliceSpan *y_span, *x_span;
|
||||||
gulong enable_flags;
|
gulong enable_flags;
|
||||||
|
CoglTextureGLVertex *p;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
@ -2271,14 +2258,48 @@ cogl_texture_polygon (CoglHandle handle,
|
|||||||
return;
|
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 */
|
/* 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)
|
if (ctx->enable_backface_culling)
|
||||||
enable_flags |= COGL_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);
|
cogl_enable (enable_flags);
|
||||||
|
|
||||||
/* Temporarily change the wrapping mode on all of the slices to use
|
/* 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++);
|
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, i++);
|
||||||
|
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
/* Convert the vertices into an array of GLfloats ready to pass to
|
||||||
|
OpenGL */
|
||||||
glBegin (GL_TRIANGLE_FAN);
|
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++)
|
||||||
|
|
||||||
for (vnum = 0; vnum < n_vertices; vnum++)
|
|
||||||
{
|
{
|
||||||
GLfloat tx, ty;
|
#define CFX_F COGL_FIXED_TO_FLOAT
|
||||||
|
|
||||||
if (use_color)
|
p->v[0] = CFX_F(vertices[i].x);
|
||||||
cogl_set_source_color (&vertices[vnum].color);
|
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
|
#undef CFX_F
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
COGL_ENABLE_TEXCOORD_ARRAY,
|
||||||
GL_TEXTURE_COORD_ARRAY);
|
GL_TEXTURE_COORD_ARRAY);
|
||||||
|
|
||||||
|
cogl_toggle_client_flag (ctx, flags,
|
||||||
|
COGL_ENABLE_COLOR_ARRAY,
|
||||||
|
GL_COLOR_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
gulong
|
gulong
|
||||||
|
@ -32,9 +32,9 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GLfixed v[3];
|
GLfloat v[3];
|
||||||
GLfixed t[2];
|
GLfloat t[2];
|
||||||
GLfixed c[4];
|
GLubyte c[4];
|
||||||
} CoglTextureGLVertex;
|
} CoglTextureGLVertex;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -55,6 +55,7 @@ struct _CoglTexture
|
|||||||
COGLenum min_filter;
|
COGLenum min_filter;
|
||||||
COGLenum mag_filter;
|
COGLenum mag_filter;
|
||||||
gboolean is_foreign;
|
gboolean is_foreign;
|
||||||
|
GLint wrap_mode;
|
||||||
gboolean auto_mipmap;
|
gboolean auto_mipmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,6 +39,13 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define glVertexPointer cogl_wrap_glVertexPointer
|
||||||
|
#define glTexCoordPointer cogl_wrap_glTexCoordPointer
|
||||||
|
#define glColorPointer cogl_wrap_glColorPointer
|
||||||
|
#define glDrawArrays cogl_wrap_glDrawArrays
|
||||||
|
#define glTexParameteri cogl_wrap_glTexParameteri
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define COGL_DEBUG 1
|
#define COGL_DEBUG 1
|
||||||
|
|
||||||
@ -174,6 +181,36 @@ _cogl_span_iter_end (CoglSpanIter *iter)
|
|||||||
return iter->pos >= iter->cover_end;
|
return iter->pos >= iter->cover_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prep_for_gl_pixels_upload (gint pixels_rowstride,
|
||||||
|
gint pixels_src_x,
|
||||||
|
gint pixels_src_y,
|
||||||
|
gint pixels_bpp)
|
||||||
|
{
|
||||||
|
|
||||||
|
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
|
||||||
|
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 *
|
static guchar *
|
||||||
_cogl_texture_allocate_waste_buffer (CoglTexture *tex)
|
_cogl_texture_allocate_waste_buffer (CoglTexture *tex)
|
||||||
{
|
{
|
||||||
@ -214,10 +251,6 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
guchar *waste_buf;
|
guchar *waste_buf;
|
||||||
CoglBitmap slice_bmp;
|
CoglBitmap slice_bmp;
|
||||||
|
|
||||||
/* FIXME: might optimize by not copying to intermediate slice
|
|
||||||
bitmap when source rowstride = bpp * width and the texture
|
|
||||||
image is not sliced */
|
|
||||||
|
|
||||||
bpp = _cogl_get_format_bpp (tex->bitmap.format);
|
bpp = _cogl_get_format_bpp (tex->bitmap.format);
|
||||||
|
|
||||||
waste_buf = _cogl_texture_allocate_waste_buffer (tex);
|
waste_buf = _cogl_texture_allocate_waste_buffer (tex);
|
||||||
@ -236,13 +269,23 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
|
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
|
||||||
y * tex->slice_x_spans->len + x);
|
y * tex->slice_x_spans->len + x);
|
||||||
|
|
||||||
|
/* FIXME: might optimize by not copying to intermediate slice
|
||||||
|
bitmap when source rowstride = bpp * width and the texture
|
||||||
|
image is not sliced */
|
||||||
|
|
||||||
/* Setup temp bitmap for slice subregion */
|
/* Setup temp bitmap for slice subregion */
|
||||||
slice_bmp.format = tex->bitmap.format;
|
slice_bmp.format = tex->bitmap.format;
|
||||||
slice_bmp.width = x_span->size - x_span->waste;
|
slice_bmp.width = x_span->size - x_span->waste;
|
||||||
slice_bmp.height = y_span->size - y_span->waste;
|
slice_bmp.height = y_span->size - y_span->waste;
|
||||||
slice_bmp.rowstride = bpp * slice_bmp.width;
|
slice_bmp.rowstride = bpp * slice_bmp.width;
|
||||||
slice_bmp.data = (guchar*) g_malloc (slice_bmp.rowstride *
|
slice_bmp.data = (guchar*) g_malloc (slice_bmp.rowstride *
|
||||||
slice_bmp.height);
|
slice_bmp.height);
|
||||||
|
|
||||||
|
/* Setup gl alignment to match rowstride and top-left corner */
|
||||||
|
prep_for_gl_pixels_upload (tex->bitmap.rowstride,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
bpp);
|
||||||
|
|
||||||
/* Copy subregion data */
|
/* Copy subregion data */
|
||||||
_cogl_bitmap_copy_subregion (&tex->bitmap,
|
_cogl_bitmap_copy_subregion (&tex->bitmap,
|
||||||
@ -257,9 +300,9 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
|
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
|
||||||
tex->gl_intformat) );
|
tex->gl_intformat) );
|
||||||
|
|
||||||
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 1) );
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
|
0,
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0, 0, 0,
|
0,
|
||||||
slice_bmp.width,
|
slice_bmp.width,
|
||||||
slice_bmp.height,
|
slice_bmp.height,
|
||||||
tex->gl_format, tex->gl_type,
|
tex->gl_format, tex->gl_type,
|
||||||
@ -284,8 +327,14 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
src += tex->bitmap.rowstride;
|
src += tex->bitmap.rowstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prep_for_gl_pixels_upload (x_span->waste * bpp,
|
||||||
|
0, /* src x */
|
||||||
|
0, /* src y */
|
||||||
|
bpp);
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
x_span->size - x_span->waste, 0,
|
x_span->size - x_span->waste,
|
||||||
|
0,
|
||||||
x_span->waste,
|
x_span->waste,
|
||||||
y_span->size - y_span->waste,
|
y_span->size - y_span->waste,
|
||||||
tex->gl_format, tex->gl_type,
|
tex->gl_format, tex->gl_type,
|
||||||
@ -313,8 +362,14 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prep_for_gl_pixels_upload (x_span->size * bpp,
|
||||||
|
0, /* src x */
|
||||||
|
0, /* src y */
|
||||||
|
bpp);
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
0, y_span->size - y_span->waste,
|
0,
|
||||||
|
y_span->size - y_span->waste,
|
||||||
x_span->size,
|
x_span->size,
|
||||||
y_span->waste,
|
y_span->waste,
|
||||||
tex->gl_format, tex->gl_type,
|
tex->gl_format, tex->gl_type,
|
||||||
@ -371,7 +426,7 @@ _cogl_texture_draw_and_read (CoglTexture *tex,
|
|||||||
0, 0, COGL_FIXED_1, COGL_FIXED_1);
|
0, 0, COGL_FIXED_1, COGL_FIXED_1);
|
||||||
|
|
||||||
/* Read into target bitmap */
|
/* Read into target bitmap */
|
||||||
GE( glPixelStorei (GL_PACK_ALIGNMENT, 1) );
|
prep_for_gl_pixels_download (tex->bitmap.rowstride);
|
||||||
GE( glReadPixels (viewport[0], viewport[1],
|
GE( glReadPixels (viewport[0], viewport[1],
|
||||||
tex->bitmap.width,
|
tex->bitmap.width,
|
||||||
tex->bitmap.height,
|
tex->bitmap.height,
|
||||||
@ -430,7 +485,7 @@ _cogl_texture_draw_and_read (CoglTexture *tex,
|
|||||||
rect_bmp.data = (guchar*) g_malloc (rect_bmp.rowstride *
|
rect_bmp.data = (guchar*) g_malloc (rect_bmp.rowstride *
|
||||||
rect_bmp.height);
|
rect_bmp.height);
|
||||||
|
|
||||||
GE( glPixelStorei (GL_PACK_ALIGNMENT, 1) );
|
prep_for_gl_pixels_download (rect_bmp.rowstride);
|
||||||
GE( glReadPixels (viewport[0], viewport[1],
|
GE( glReadPixels (viewport[0], viewport[1],
|
||||||
rect_bmp.width,
|
rect_bmp.width,
|
||||||
rect_bmp.height,
|
rect_bmp.height,
|
||||||
@ -603,10 +658,6 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
|
|
||||||
waste_buf = _cogl_texture_allocate_waste_buffer (tex);
|
waste_buf = _cogl_texture_allocate_waste_buffer (tex);
|
||||||
|
|
||||||
/* FIXME: might optimize by not copying to intermediate slice
|
|
||||||
bitmap when source rowstride = bpp * width and the texture
|
|
||||||
image is not sliced */
|
|
||||||
|
|
||||||
/* Iterate vertical spans */
|
/* Iterate vertical spans */
|
||||||
for (source_y = src_y,
|
for (source_y = src_y,
|
||||||
_cogl_span_iter_begin (&y_iter, tex->slice_y_spans,
|
_cogl_span_iter_begin (&y_iter, tex->slice_y_spans,
|
||||||
@ -618,12 +669,12 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
_cogl_span_iter_next (&y_iter),
|
_cogl_span_iter_next (&y_iter),
|
||||||
source_y += inter_h )
|
source_y += inter_h )
|
||||||
{
|
{
|
||||||
/* Skip non-intersecting ones */
|
/* Discard slices out of the subregion early */
|
||||||
if (!y_iter.intersects)
|
if (!y_iter.intersects)
|
||||||
{
|
{
|
||||||
inter_h = 0;
|
inter_h = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan,
|
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan,
|
||||||
y_iter.index);
|
y_iter.index);
|
||||||
@ -639,33 +690,37 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
_cogl_span_iter_next (&x_iter),
|
_cogl_span_iter_next (&x_iter),
|
||||||
source_x += inter_w )
|
source_x += inter_w )
|
||||||
{
|
{
|
||||||
/* Skip non-intersecting ones */
|
/* Discard slices out of the subregion early */
|
||||||
if (!x_iter.intersects)
|
if (!x_iter.intersects)
|
||||||
{
|
{
|
||||||
inter_w = 0;
|
inter_w = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan,
|
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan,
|
||||||
x_iter.index);
|
x_iter.index);
|
||||||
|
|
||||||
/* Pick intersection width and height */
|
/* Pick intersection width and height */
|
||||||
inter_w = COGL_FIXED_TO_INT (x_iter.intersect_end -
|
inter_w = COGL_FIXED_TO_INT (x_iter.intersect_end -
|
||||||
x_iter.intersect_start);
|
x_iter.intersect_start);
|
||||||
inter_h = COGL_FIXED_TO_INT (y_iter.intersect_end -
|
inter_h = COGL_FIXED_TO_INT (y_iter.intersect_end -
|
||||||
y_iter.intersect_start);
|
y_iter.intersect_start);
|
||||||
|
|
||||||
/* Localize intersection top-left corner to slice*/
|
/* Localize intersection top-left corner to slice*/
|
||||||
local_x = COGL_FIXED_TO_INT (x_iter.intersect_start -
|
local_x = COGL_FIXED_TO_INT (x_iter.intersect_start -
|
||||||
x_iter.pos);
|
x_iter.pos);
|
||||||
local_y = COGL_FIXED_TO_INT (y_iter.intersect_start -
|
local_y = COGL_FIXED_TO_INT (y_iter.intersect_start -
|
||||||
y_iter.pos);
|
y_iter.pos);
|
||||||
|
|
||||||
/* Pick slice GL handle */
|
/* Pick slice GL handle */
|
||||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
|
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
|
||||||
y_iter.index * tex->slice_x_spans->len +
|
y_iter.index * tex->slice_x_spans->len +
|
||||||
x_iter.index);
|
x_iter.index);
|
||||||
|
|
||||||
|
/* FIXME: might optimize by not copying to intermediate slice
|
||||||
|
bitmap when source rowstride = bpp * width and the texture
|
||||||
|
image is not sliced */
|
||||||
|
|
||||||
/* Setup temp bitmap for slice subregion */
|
/* Setup temp bitmap for slice subregion */
|
||||||
slice_bmp.format = tex->bitmap.format;
|
slice_bmp.format = tex->bitmap.format;
|
||||||
slice_bmp.width = inter_w;
|
slice_bmp.width = inter_w;
|
||||||
@ -674,6 +729,12 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
slice_bmp.data = (guchar*) g_malloc (slice_bmp.rowstride *
|
slice_bmp.data = (guchar*) g_malloc (slice_bmp.rowstride *
|
||||||
slice_bmp.height);
|
slice_bmp.height);
|
||||||
|
|
||||||
|
/* Setup gl alignment to match rowstride and top-left corner */
|
||||||
|
prep_for_gl_pixels_upload (slice_bmp.rowstride,
|
||||||
|
0, /* src x */
|
||||||
|
0, /* src y */
|
||||||
|
bpp);
|
||||||
|
|
||||||
/* Copy subregion data */
|
/* Copy subregion data */
|
||||||
_cogl_bitmap_copy_subregion (source_bmp,
|
_cogl_bitmap_copy_subregion (source_bmp,
|
||||||
&slice_bmp,
|
&slice_bmp,
|
||||||
@ -684,8 +745,6 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
slice_bmp.height);
|
slice_bmp.height);
|
||||||
|
|
||||||
/* Upload new image data */
|
/* Upload new image data */
|
||||||
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 1) );
|
|
||||||
|
|
||||||
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
|
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
|
||||||
tex->gl_intformat) );
|
tex->gl_intformat) );
|
||||||
|
|
||||||
@ -703,14 +762,20 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
&& local_x < x_span->size - x_span->waste
|
&& local_x < x_span->size - x_span->waste
|
||||||
&& local_x + inter_w >= x_span->size - x_span->waste)
|
&& local_x + inter_w >= x_span->size - x_span->waste)
|
||||||
{
|
{
|
||||||
const guchar *src = source_bmp->data
|
const guchar *src;
|
||||||
+ (src_y + COGL_FIXED_TO_INT (y_iter.intersect_start)
|
guchar *dst;
|
||||||
- dst_y) * source_bmp->rowstride
|
|
||||||
+ (src_x + x_span->start + x_span->size - x_span->waste
|
|
||||||
- dst_x - 1) * bpp;
|
|
||||||
guchar *dst = waste_buf;
|
|
||||||
guint wx, wy;
|
guint wx, wy;
|
||||||
|
|
||||||
|
src = source_bmp->data
|
||||||
|
+ (src_y + COGL_FIXED_TO_INT (y_iter.intersect_start)
|
||||||
|
- dst_y)
|
||||||
|
* source_bmp->rowstride
|
||||||
|
+ (src_x + x_span->start + x_span->size - x_span->waste
|
||||||
|
- dst_x - 1)
|
||||||
|
* bpp;
|
||||||
|
|
||||||
|
dst = waste_buf;
|
||||||
|
|
||||||
for (wy = 0; wy < inter_h; wy++)
|
for (wy = 0; wy < inter_h; wy++)
|
||||||
{
|
{
|
||||||
for (wx = 0; wx < x_span->waste; wx++)
|
for (wx = 0; wx < x_span->waste; wx++)
|
||||||
@ -721,8 +786,14 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
src += source_bmp->rowstride;
|
src += source_bmp->rowstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prep_for_gl_pixels_upload (x_span->waste * bpp,
|
||||||
|
0, /* src x */
|
||||||
|
0, /* src y */
|
||||||
|
bpp);
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
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,
|
x_span->waste,
|
||||||
inter_h,
|
inter_h,
|
||||||
source_gl_format,
|
source_gl_format,
|
||||||
@ -735,15 +806,21 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
&& local_y < y_span->size - y_span->waste
|
&& local_y < y_span->size - y_span->waste
|
||||||
&& local_y + inter_h >= y_span->size - y_span->waste)
|
&& local_y + inter_h >= y_span->size - y_span->waste)
|
||||||
{
|
{
|
||||||
const guchar *src = source_bmp->data
|
const guchar *src;
|
||||||
+ (src_x + COGL_FIXED_TO_INT (x_iter.intersect_start)
|
guchar *dst;
|
||||||
- dst_x) * bpp
|
|
||||||
+ (src_y + y_span->start + y_span->size - y_span->waste
|
|
||||||
- dst_y - 1) * source_bmp->rowstride;
|
|
||||||
guchar *dst = waste_buf;
|
|
||||||
guint wy, wx;
|
guint wy, wx;
|
||||||
guint copy_width;
|
guint copy_width;
|
||||||
|
|
||||||
|
src = source_bmp->data
|
||||||
|
+ (src_x + COGL_FIXED_TO_INT (x_iter.intersect_start)
|
||||||
|
- dst_x)
|
||||||
|
* bpp
|
||||||
|
+ (src_y + y_span->start + y_span->size - y_span->waste
|
||||||
|
- dst_y - 1)
|
||||||
|
* source_bmp->rowstride;
|
||||||
|
|
||||||
|
dst = waste_buf;
|
||||||
|
|
||||||
if (local_x + inter_w >= x_span->size - x_span->waste)
|
if (local_x + inter_w >= x_span->size - x_span->waste)
|
||||||
copy_width = x_span->size - local_x;
|
copy_width = x_span->size - local_x;
|
||||||
else
|
else
|
||||||
@ -761,8 +838,14 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prep_for_gl_pixels_upload (copy_width * bpp,
|
||||||
|
0, /* src x */
|
||||||
|
0, /* src y */
|
||||||
|
bpp);
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
local_x, y_span->size - y_span->waste,
|
local_x,
|
||||||
|
y_span->size - y_span->waste,
|
||||||
copy_width,
|
copy_width,
|
||||||
y_span->waste,
|
y_span->waste,
|
||||||
source_gl_format,
|
source_gl_format,
|
||||||
@ -784,6 +867,41 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
_cogl_rect_slices_for_size (gint size_to_fill,
|
||||||
|
gint max_span_size,
|
||||||
|
gint max_waste,
|
||||||
|
GArray *out_spans)
|
||||||
|
{
|
||||||
|
gint n_spans = 0;
|
||||||
|
CoglTexSliceSpan span;
|
||||||
|
|
||||||
|
/* Init first slice span */
|
||||||
|
span.start = 0;
|
||||||
|
span.size = max_span_size;
|
||||||
|
span.waste = 0;
|
||||||
|
|
||||||
|
/* Repeat until whole area covered */
|
||||||
|
while (size_to_fill >= span.size)
|
||||||
|
{
|
||||||
|
/* Add another slice span of same size */
|
||||||
|
if (out_spans) g_array_append_val (out_spans, span);
|
||||||
|
span.start += span.size;
|
||||||
|
size_to_fill -= span.size;
|
||||||
|
n_spans++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add one last smaller slice span */
|
||||||
|
if (size_to_fill > 0)
|
||||||
|
{
|
||||||
|
span.size = size_to_fill;
|
||||||
|
if (out_spans) g_array_append_val (out_spans, span);
|
||||||
|
n_spans++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n_spans;
|
||||||
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
_cogl_pot_slices_for_size (gint size_to_fill,
|
_cogl_pot_slices_for_size (gint size_to_fill,
|
||||||
gint max_span_size,
|
gint max_span_size,
|
||||||
@ -863,10 +981,20 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
|||||||
bpp = _cogl_get_format_bpp (tex->bitmap.format);
|
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 */
|
||||||
max_width = cogl_util_next_p2 (tex->bitmap.width);
|
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT))
|
||||||
max_height = cogl_util_next_p2 (tex->bitmap.height);
|
{
|
||||||
tex->gl_target = GL_TEXTURE_2D;
|
max_width = tex->bitmap.width;
|
||||||
slices_for_size = _cogl_pot_slices_for_size;
|
max_height = tex->bitmap.height;
|
||||||
|
tex->gl_target = GL_TEXTURE_2D;
|
||||||
|
slices_for_size = _cogl_rect_slices_for_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
max_width = cogl_util_next_p2 (tex->bitmap.width);
|
||||||
|
max_height = cogl_util_next_p2 (tex->bitmap.height);
|
||||||
|
tex->gl_target = GL_TEXTURE_2D;
|
||||||
|
slices_for_size = _cogl_pot_slices_for_size;
|
||||||
|
}
|
||||||
|
|
||||||
/* Negative number means no slicing forced by the user */
|
/* Negative number means no slicing forced by the user */
|
||||||
if (tex->max_waste <= -1)
|
if (tex->max_waste <= -1)
|
||||||
@ -961,6 +1089,14 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
|||||||
|
|
||||||
g_array_set_size (tex->slice_gl_handles, n_slices);
|
g_array_set_size (tex->slice_gl_handles, n_slices);
|
||||||
|
|
||||||
|
|
||||||
|
/* Hardware repeated tiling if supported, else tile in software*/
|
||||||
|
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
|
||||||
|
&& n_slices == 1)
|
||||||
|
tex->wrap_mode = GL_REPEAT;
|
||||||
|
else
|
||||||
|
tex->wrap_mode = GL_CLAMP_TO_EDGE;
|
||||||
|
|
||||||
/* Generate a "working set" of GL texture objects
|
/* Generate a "working set" of GL texture objects
|
||||||
* (some implementations might supported faster
|
* (some implementations might supported faster
|
||||||
* re-binding between textures inside a set) */
|
* re-binding between textures inside a set) */
|
||||||
@ -988,19 +1124,19 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
|||||||
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target,
|
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target,
|
||||||
gl_handles[y * n_x_slices + x],
|
gl_handles[y * n_x_slices + x],
|
||||||
tex->gl_intformat) );
|
tex->gl_intformat) );
|
||||||
|
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( cogl_wrap_glTexParameteri (tex->gl_target, GL_TEXTURE_MAG_FILTER,
|
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_S,
|
||||||
tex->mag_filter) );
|
tex->wrap_mode) );
|
||||||
GE( cogl_wrap_glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER,
|
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_T,
|
||||||
tex->min_filter) );
|
tex->wrap_mode) );
|
||||||
GE( cogl_wrap_glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_S,
|
|
||||||
GL_CLAMP_TO_EDGE) );
|
|
||||||
GE( cogl_wrap_glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_T,
|
|
||||||
GL_CLAMP_TO_EDGE) );
|
|
||||||
|
|
||||||
if (tex->auto_mipmap)
|
if (tex->auto_mipmap)
|
||||||
GE( cogl_wrap_glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP,
|
GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP,
|
||||||
GL_TRUE) );
|
GL_TRUE) );
|
||||||
|
|
||||||
/* Pass NULL data to init size and internal format */
|
/* Pass NULL data to init size and internal format */
|
||||||
GE( glTexImage2D (tex->gl_target, 0, tex->gl_intformat,
|
GE( glTexImage2D (tex->gl_target, 0, tex->gl_intformat,
|
||||||
@ -1033,13 +1169,20 @@ _cogl_texture_slices_free (CoglTexture *tex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_cogl_pixel_format_from_gl_internal (GLenum gl_int_format,
|
||||||
|
CoglPixelFormat *out_format)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static CoglPixelFormat
|
static CoglPixelFormat
|
||||||
_cogl_pixel_format_to_gl (CoglPixelFormat format,
|
_cogl_pixel_format_to_gl (CoglPixelFormat format,
|
||||||
GLenum *out_glintformat,
|
GLenum *out_glintformat,
|
||||||
GLenum *out_glformat,
|
GLenum *out_glformat,
|
||||||
GLenum *out_gltype)
|
GLenum *out_gltype)
|
||||||
{
|
{
|
||||||
CoglPixelFormat required_format = format;
|
CoglPixelFormat required_format;
|
||||||
GLenum glintformat = 0;
|
GLenum glintformat = 0;
|
||||||
GLenum glformat = 0;
|
GLenum glformat = 0;
|
||||||
GLenum gltype = 0;
|
GLenum gltype = 0;
|
||||||
@ -1050,6 +1193,10 @@ _cogl_pixel_format_to_gl (CoglPixelFormat format,
|
|||||||
if (format & COGL_PREMULT_BIT)
|
if (format & COGL_PREMULT_BIT)
|
||||||
format = (format & COGL_UNPREMULT_MASK);
|
format = (format & COGL_UNPREMULT_MASK);
|
||||||
|
|
||||||
|
/* Everything else accepted
|
||||||
|
* (FIXME: check YUV support) */
|
||||||
|
required_format = format;
|
||||||
|
|
||||||
/* Find GL equivalents */
|
/* Find GL equivalents */
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
@ -1213,6 +1360,7 @@ cogl_texture_new_with_size (guint width,
|
|||||||
&tex->gl_format,
|
&tex->gl_format,
|
||||||
&tex->gl_type);
|
&tex->gl_type);
|
||||||
|
|
||||||
|
/* Create slices for the given format and size */
|
||||||
if (!_cogl_texture_slices_create (tex))
|
if (!_cogl_texture_slices_create (tex))
|
||||||
{
|
{
|
||||||
_cogl_texture_free (tex);
|
_cogl_texture_free (tex);
|
||||||
@ -1294,7 +1442,7 @@ cogl_texture_new_from_data (guint width,
|
|||||||
|
|
||||||
_cogl_texture_bitmap_free (tex);
|
_cogl_texture_bitmap_free (tex);
|
||||||
|
|
||||||
return _cogl_texture_handle_new (tex);;
|
return _cogl_texture_handle_new (tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglHandle
|
CoglHandle
|
||||||
@ -1382,8 +1530,19 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
GLuint y_pot_waste,
|
GLuint y_pot_waste,
|
||||||
CoglPixelFormat format)
|
CoglPixelFormat format)
|
||||||
{
|
{
|
||||||
|
/* NOTE: width, height and internal format are not queriable
|
||||||
|
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;
|
GLenum gl_error = 0;
|
||||||
GLboolean gl_istexture;
|
GLboolean gl_istexture;
|
||||||
|
GLint gl_compressed = GL_FALSE;
|
||||||
|
GLint gl_int_format = 0;
|
||||||
|
GLint gl_width = 0;
|
||||||
|
GLint gl_height = 0;
|
||||||
GLint gl_min_filter;
|
GLint gl_min_filter;
|
||||||
GLint gl_mag_filter;
|
GLint gl_mag_filter;
|
||||||
GLint gl_gen_mipmap;
|
GLint gl_gen_mipmap;
|
||||||
@ -1410,7 +1569,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
/* Obtain texture parameters
|
/* Obtain texture parameters
|
||||||
(only level 0 we are interested in) */
|
(only level 0 we are interested in) */
|
||||||
|
|
||||||
/* These are not queriable in GLES :(
|
#if HAVE_COGL_GL
|
||||||
GE( glGetTexLevelParameteriv (gl_target, 0,
|
GE( glGetTexLevelParameteriv (gl_target, 0,
|
||||||
GL_TEXTURE_COMPRESSED,
|
GL_TEXTURE_COMPRESSED,
|
||||||
&gl_compressed) );
|
&gl_compressed) );
|
||||||
@ -1418,28 +1577,52 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
GE( glGetTexLevelParameteriv (gl_target, 0,
|
GE( glGetTexLevelParameteriv (gl_target, 0,
|
||||||
GL_TEXTURE_INTERNAL_FORMAT,
|
GL_TEXTURE_INTERNAL_FORMAT,
|
||||||
&gl_int_format) );
|
&gl_int_format) );
|
||||||
*/
|
|
||||||
|
|
||||||
|
GE( glGetTexLevelParameteriv (gl_target, 0,
|
||||||
|
GL_TEXTURE_WIDTH,
|
||||||
|
&gl_width) );
|
||||||
|
|
||||||
|
GE( glGetTexLevelParameteriv (gl_target, 0,
|
||||||
|
GL_TEXTURE_HEIGHT,
|
||||||
|
&gl_height) );
|
||||||
|
#else
|
||||||
|
gl_width = width + x_pot_waste;
|
||||||
|
gl_height = height + y_pot_waste;
|
||||||
|
#endif
|
||||||
|
|
||||||
GE( glGetTexParameteriv (gl_target,
|
GE( glGetTexParameteriv (gl_target,
|
||||||
GL_TEXTURE_MIN_FILTER,
|
GL_TEXTURE_MIN_FILTER,
|
||||||
&gl_min_filter));
|
&gl_min_filter) );
|
||||||
|
|
||||||
GE( glGetTexParameteriv (gl_target,
|
GE( glGetTexParameteriv (gl_target,
|
||||||
GL_TEXTURE_MAG_FILTER,
|
GL_TEXTURE_MAG_FILTER,
|
||||||
&gl_mag_filter));
|
&gl_mag_filter) );
|
||||||
|
|
||||||
GE( glGetTexParameteriv (gl_target,
|
GE( glGetTexParameteriv (gl_target,
|
||||||
GL_GENERATE_MIPMAP,
|
GL_GENERATE_MIPMAP,
|
||||||
&gl_gen_mipmap) );
|
&gl_gen_mipmap) );
|
||||||
|
|
||||||
/* Validate width and height */
|
/* Validate width and height */
|
||||||
if (width <= 0 || height <= 0)
|
if (gl_width <= 0 || gl_height <= 0)
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
|
|
||||||
/* Validate pot waste */
|
/* Validate pot waste */
|
||||||
if (x_pot_waste < 0 || x_pot_waste >= width ||
|
if (x_pot_waste < 0 || x_pot_waste >= gl_width ||
|
||||||
y_pot_waste < 0 || y_pot_waste >= height)
|
y_pot_waste < 0 || y_pot_waste >= gl_height)
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
|
|
||||||
|
/* Compressed texture images not supported */
|
||||||
|
if (gl_compressed == GL_TRUE)
|
||||||
|
return COGL_INVALID_HANDLE;
|
||||||
|
|
||||||
|
/* Try and match to a cogl format */
|
||||||
|
if (!_cogl_pixel_format_from_gl_internal (gl_int_format,
|
||||||
|
&format))
|
||||||
|
{
|
||||||
|
return COGL_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create new texture */
|
/* Create new texture */
|
||||||
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
|
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
|
||||||
|
|
||||||
@ -1452,15 +1635,15 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
|
|
||||||
bpp = _cogl_get_format_bpp (format);
|
bpp = _cogl_get_format_bpp (format);
|
||||||
tex->bitmap.format = format;
|
tex->bitmap.format = format;
|
||||||
tex->bitmap.width = width;
|
tex->bitmap.width = gl_width - x_pot_waste;
|
||||||
tex->bitmap.height = height;
|
tex->bitmap.height = gl_height - y_pot_waste;
|
||||||
tex->bitmap.rowstride = tex->bitmap.width * bpp;
|
tex->bitmap.rowstride = tex->bitmap.width * bpp;
|
||||||
tex->bitmap_owner = FALSE;
|
tex->bitmap_owner = FALSE;
|
||||||
|
|
||||||
tex->gl_target = gl_target;
|
tex->gl_target = gl_target;
|
||||||
tex->gl_intformat = 0;
|
tex->gl_intformat = gl_int_format;
|
||||||
tex->gl_format = 0;
|
tex->gl_format = gl_int_format;
|
||||||
tex->gl_type = 0;
|
tex->gl_type = GL_UNSIGNED_BYTE;
|
||||||
|
|
||||||
tex->min_filter = gl_min_filter;
|
tex->min_filter = gl_min_filter;
|
||||||
tex->mag_filter = gl_mag_filter;
|
tex->mag_filter = gl_mag_filter;
|
||||||
@ -1481,59 +1664,37 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
|
|
||||||
/* Store info for a single slice */
|
/* Store info for a single slice */
|
||||||
x_span.start = 0;
|
x_span.start = 0;
|
||||||
x_span.size = width + x_pot_waste;
|
x_span.size = gl_width;
|
||||||
x_span.waste = x_pot_waste;
|
x_span.waste = x_pot_waste;
|
||||||
g_array_append_val (tex->slice_x_spans, x_span);
|
g_array_append_val (tex->slice_x_spans, x_span);
|
||||||
|
|
||||||
y_span.start = 0;
|
y_span.start = 0;
|
||||||
y_span.size = height + x_pot_waste;
|
y_span.size = gl_height;
|
||||||
y_span.waste = y_pot_waste;
|
y_span.waste = y_pot_waste;
|
||||||
g_array_append_val (tex->slice_y_spans, y_span);
|
g_array_append_val (tex->slice_y_spans, y_span);
|
||||||
|
|
||||||
g_array_append_val (tex->slice_gl_handles, gl_handle);
|
g_array_append_val (tex->slice_gl_handles, gl_handle);
|
||||||
|
|
||||||
/* Force appropriate wrap parameter */
|
/* Force appropriate wrap parameter */
|
||||||
GE( cogl_wrap_glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_S,
|
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) &&
|
||||||
GL_CLAMP_TO_EDGE) );
|
gl_target == GL_TEXTURE_2D)
|
||||||
GE( cogl_wrap_glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_T,
|
{
|
||||||
GL_CLAMP_TO_EDGE) );
|
/* Hardware repeated tiling */
|
||||||
|
tex->wrap_mode = GL_REPEAT;
|
||||||
|
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_S, GL_REPEAT) );
|
||||||
|
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_T, GL_REPEAT) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Any tiling will be done in software */
|
||||||
|
tex->wrap_mode = GL_CLAMP_TO_EDGE;
|
||||||
|
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
|
||||||
|
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
|
||||||
|
}
|
||||||
|
|
||||||
return _cogl_texture_handle_new (tex);
|
return _cogl_texture_handle_new (tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
cogl_texture_get_properties (CoglHandle handle,
|
|
||||||
guint *out_width,
|
|
||||||
guint *out_height,
|
|
||||||
CoglPixelFormat *out_format,
|
|
||||||
guint *out_rowstride,
|
|
||||||
guint *out_max_waste)
|
|
||||||
{
|
|
||||||
CoglTexture *tex;
|
|
||||||
|
|
||||||
/* Check if valid texture handle */
|
|
||||||
if (!cogl_is_texture (handle))
|
|
||||||
return;
|
|
||||||
|
|
||||||
tex = _cogl_texture_pointer_from_handle (handle);
|
|
||||||
|
|
||||||
/* Output requested properties */
|
|
||||||
if (out_width != NULL)
|
|
||||||
*out_width = tex->bitmap.width;
|
|
||||||
|
|
||||||
if (out_height != NULL)
|
|
||||||
*out_height = tex->bitmap.height;
|
|
||||||
|
|
||||||
if (out_format != NULL)
|
|
||||||
*out_format = tex->bitmap.format;
|
|
||||||
|
|
||||||
if (out_rowstride != NULL)
|
|
||||||
*out_rowstride = tex->bitmap.rowstride;
|
|
||||||
|
|
||||||
if (out_max_waste != NULL)
|
|
||||||
*out_max_waste = tex->max_waste;
|
|
||||||
}
|
|
||||||
|
|
||||||
guint
|
guint
|
||||||
cogl_texture_get_width (CoglHandle handle)
|
cogl_texture_get_width (CoglHandle handle)
|
||||||
{
|
{
|
||||||
@ -1698,10 +1859,10 @@ cogl_texture_set_filters (CoglHandle handle,
|
|||||||
{
|
{
|
||||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, i);
|
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, i);
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||||
GE( cogl_wrap_glTexParameteri (tex->gl_target, GL_TEXTURE_MAG_FILTER,
|
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MAG_FILTER,
|
||||||
tex->mag_filter) );
|
tex->mag_filter) );
|
||||||
GE( cogl_wrap_glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER,
|
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER,
|
||||||
tex->min_filter) );
|
tex->min_filter) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1897,7 +2058,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
CoglFixed tx2,
|
CoglFixed tx2,
|
||||||
CoglFixed ty2)
|
CoglFixed ty2)
|
||||||
{
|
{
|
||||||
CoglSpanIter iter_x , iter_y;
|
CoglSpanIter iter_x , iter_y;
|
||||||
CoglFixed tw , th;
|
CoglFixed tw , th;
|
||||||
CoglFixed tqx , tqy;
|
CoglFixed tqx , tqy;
|
||||||
CoglFixed first_tx , first_ty;
|
CoglFixed first_tx , first_ty;
|
||||||
@ -1906,18 +2067,19 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
CoglFixed slice_tx2 , slice_ty2;
|
CoglFixed slice_tx2 , slice_ty2;
|
||||||
CoglFixed slice_qx1 , slice_qy1;
|
CoglFixed slice_qx1 , slice_qy1;
|
||||||
CoglFixed slice_qx2 , slice_qy2;
|
CoglFixed slice_qx2 , slice_qy2;
|
||||||
GLfixed tex_coords[8];
|
GLfloat tex_coords[8];
|
||||||
GLfixed quad_coords[8];
|
GLfloat quad_coords[8];
|
||||||
GLuint gl_handle;
|
GLuint gl_handle;
|
||||||
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
|
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
|
||||||
| COGL_ENABLE_VERTEX_ARRAY
|
| COGL_ENABLE_VERTEX_ARRAY
|
||||||
| COGL_ENABLE_TEXCOORD_ARRAY);
|
| COGL_ENABLE_TEXCOORD_ARRAY);
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
#if COGL_DEBUG
|
#if COGL_DEBUG
|
||||||
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
|
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
||||||
|
|
||||||
/* Prepare GL state */
|
/* Prepare GL state */
|
||||||
if (ctx->color_alpha < 255
|
if (ctx->color_alpha < 255
|
||||||
@ -1954,15 +2116,15 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
ty2 = temp;
|
ty2 = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
GE( cogl_wrap_glTexCoordPointer (2, GL_FIXED, 0, tex_coords) );
|
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
|
||||||
GE( cogl_wrap_glVertexPointer (2, GL_FIXED, 0, quad_coords) );
|
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
|
||||||
|
|
||||||
/* Scale ratio from texture to quad widths */
|
/* Scale ratio from texture to quad widths */
|
||||||
tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
|
tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
|
||||||
th = COGL_FIXED_FROM_INT (tex->bitmap.height);
|
th = COGL_FIXED_FROM_INT (tex->bitmap.height);
|
||||||
|
|
||||||
tqx = COGL_FIXED_DIV (x2-x1, COGL_FIXED_MUL (tw, (tx2 - tx1)));
|
tqx = COGL_FIXED_DIV (x2 - x1, COGL_FIXED_MUL (tw, (tx2 - tx1)));
|
||||||
tqy = COGL_FIXED_DIV (y2-y1, COGL_FIXED_MUL (th, (ty2 - ty1)));
|
tqy = COGL_FIXED_DIV (y2 - y1, COGL_FIXED_MUL (th, (ty2 - ty1)));
|
||||||
|
|
||||||
/* Integral texture coordinate for first tile */
|
/* Integral texture coordinate for first tile */
|
||||||
first_tx = COGL_FIXED_FROM_INT (COGL_FIXED_FLOOR (tx1));
|
first_tx = COGL_FIXED_FROM_INT (COGL_FIXED_FLOOR (tx1));
|
||||||
@ -2001,7 +2163,8 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
slice_ty1 = iter_y.intersect_start - iter_y.pos;
|
slice_ty1 = iter_y.intersect_start - iter_y.pos;
|
||||||
slice_ty2 = iter_y.intersect_end - iter_y.pos;
|
slice_ty2 = iter_y.intersect_end - iter_y.pos;
|
||||||
|
|
||||||
/* Normalize texture coordinates to current slice */
|
/* Normalize texture coordinates to current slice
|
||||||
|
(rectangle texture targets take denormalized) */
|
||||||
slice_ty1 /= iter_y.span->size;
|
slice_ty1 /= iter_y.span->size;
|
||||||
slice_ty2 /= iter_y.span->size;
|
slice_ty2 /= iter_y.span->size;
|
||||||
|
|
||||||
@ -2026,9 +2189,10 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
slice_tx1 = iter_x.intersect_start - iter_x.pos;
|
slice_tx1 = iter_x.intersect_start - iter_x.pos;
|
||||||
slice_tx2 = iter_x.intersect_end - iter_x.pos;
|
slice_tx2 = iter_x.intersect_end - iter_x.pos;
|
||||||
|
|
||||||
/* Normalize texture coordinates to current slice */
|
/* Normalize texture coordinates to current slice
|
||||||
slice_tx1 /= iter_x.span->size;
|
(rectangle texture targets take denormalized) */
|
||||||
slice_tx2 /= iter_x.span->size;
|
slice_tx1 /= iter_x.span->size;
|
||||||
|
slice_tx2 /= iter_x.span->size;
|
||||||
|
|
||||||
#if COGL_DEBUG
|
#if COGL_DEBUG
|
||||||
printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index);
|
printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index);
|
||||||
@ -2050,18 +2214,22 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
|
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
|
||||||
tex->gl_intformat) );
|
tex->gl_intformat) );
|
||||||
|
|
||||||
|
#define CFX_F COGL_FIXED_TO_FLOAT
|
||||||
|
|
||||||
/* Draw textured quad */
|
/* Draw textured quad */
|
||||||
tex_coords[0] = slice_tx1; tex_coords[1] = slice_ty2;
|
tex_coords[0] = CFX_F(slice_tx1); tex_coords[1] = CFX_F(slice_ty2);
|
||||||
tex_coords[2] = slice_tx2; tex_coords[3] = slice_ty2;
|
tex_coords[2] = CFX_F(slice_tx2); tex_coords[3] = CFX_F(slice_ty2);
|
||||||
tex_coords[4] = slice_tx1; tex_coords[5] = slice_ty1;
|
tex_coords[4] = CFX_F(slice_tx1); tex_coords[5] = CFX_F(slice_ty1);
|
||||||
tex_coords[6] = slice_tx2; tex_coords[7] = slice_ty1;
|
tex_coords[6] = CFX_F(slice_tx2); tex_coords[7] = CFX_F(slice_ty1);
|
||||||
|
|
||||||
quad_coords[0] = slice_qx1; quad_coords[1] = slice_qy2;
|
quad_coords[0] = CFX_F(slice_qx1); quad_coords[1] = CFX_F(slice_qy2);
|
||||||
quad_coords[2] = slice_qx2; quad_coords[3] = slice_qy2;
|
quad_coords[2] = CFX_F(slice_qx2); quad_coords[3] = CFX_F(slice_qy2);
|
||||||
quad_coords[4] = slice_qx1; quad_coords[5] = slice_qy1;
|
quad_coords[4] = CFX_F(slice_qx1); quad_coords[5] = CFX_F(slice_qy1);
|
||||||
quad_coords[6] = slice_qx2; quad_coords[7] = slice_qy1;
|
quad_coords[6] = CFX_F(slice_qx2); quad_coords[7] = CFX_F(slice_qy1);
|
||||||
|
|
||||||
GE (cogl_wrap_glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
|
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
|
||||||
|
|
||||||
|
#undef CFX_F
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2077,8 +2245,8 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
|||||||
CoglFixed tx2,
|
CoglFixed tx2,
|
||||||
CoglFixed ty2)
|
CoglFixed ty2)
|
||||||
{
|
{
|
||||||
GLfixed tex_coords[8];
|
GLfloat tex_coords[8];
|
||||||
GLfixed quad_coords[8];
|
GLfloat quad_coords[8];
|
||||||
GLuint gl_handle;
|
GLuint gl_handle;
|
||||||
CoglTexSliceSpan *x_span;
|
CoglTexSliceSpan *x_span;
|
||||||
CoglTexSliceSpan *y_span;
|
CoglTexSliceSpan *y_span;
|
||||||
@ -2104,8 +2272,8 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
|||||||
|
|
||||||
cogl_enable (enable_flags);
|
cogl_enable (enable_flags);
|
||||||
|
|
||||||
GE( cogl_wrap_glTexCoordPointer (2, GL_FIXED, 0, tex_coords) );
|
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
|
||||||
GE( cogl_wrap_glVertexPointer (2, GL_FIXED, 0, quad_coords) );
|
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
|
||||||
|
|
||||||
/* Pick and bind opengl texture object */
|
/* Pick and bind opengl texture object */
|
||||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
|
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
|
||||||
@ -2115,23 +2283,29 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
|||||||
/* Don't include the waste in the texture coordinates */
|
/* Don't include the waste in the texture coordinates */
|
||||||
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
|
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
|
||||||
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, 0);
|
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, 0);
|
||||||
|
|
||||||
|
/* Don't include the waste in the texture coordinates */
|
||||||
tx1 = tx1 * (x_span->size - x_span->waste) / x_span->size;
|
tx1 = tx1 * (x_span->size - x_span->waste) / x_span->size;
|
||||||
tx2 = tx2 * (x_span->size - x_span->waste) / x_span->size;
|
tx2 = tx2 * (x_span->size - x_span->waste) / x_span->size;
|
||||||
ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size;
|
ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size;
|
||||||
ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size;
|
ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size;
|
||||||
|
|
||||||
|
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x)
|
||||||
|
|
||||||
/* Draw textured quad */
|
/* Draw textured quad */
|
||||||
tex_coords[0] = tx1; tex_coords[1] = ty2;
|
tex_coords[0] = CFX_F(tx1); tex_coords[1] = CFX_F(ty2);
|
||||||
tex_coords[2] = tx2; tex_coords[3] = ty2;
|
tex_coords[2] = CFX_F(tx2); tex_coords[3] = CFX_F(ty2);
|
||||||
tex_coords[4] = tx1; tex_coords[5] = ty1;
|
tex_coords[4] = CFX_F(tx1); tex_coords[5] = CFX_F(ty1);
|
||||||
tex_coords[6] = tx2; tex_coords[7] = ty1;
|
tex_coords[6] = CFX_F(tx2); tex_coords[7] = CFX_F(ty1);
|
||||||
|
|
||||||
quad_coords[0] = x1; quad_coords[1] = y2;
|
quad_coords[0] = CFX_F(x1); quad_coords[1] = CFX_F(y2);
|
||||||
quad_coords[2] = x2; quad_coords[3] = y2;
|
quad_coords[2] = CFX_F(x2); quad_coords[3] = CFX_F(y2);
|
||||||
quad_coords[4] = x1; quad_coords[5] = y1;
|
quad_coords[4] = CFX_F(x1); quad_coords[5] = CFX_F(y1);
|
||||||
quad_coords[6] = x2; quad_coords[7] = y1;
|
quad_coords[6] = CFX_F(x2); quad_coords[7] = CFX_F(y1);
|
||||||
|
|
||||||
GE (cogl_wrap_glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
|
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
|
||||||
|
|
||||||
|
#undef CFX_F
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2163,16 +2337,26 @@ cogl_texture_rectangle (CoglHandle handle,
|
|||||||
if (tx1 == tx2 || ty1 == ty2)
|
if (tx1 == tx2 || ty1 == ty2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Tile textured quads */
|
/* Pick tiling mode according to hw support */
|
||||||
if (tex->slice_gl_handles->len == 1 &&
|
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
|
||||||
tx1 >= -COGL_FIXED_1 && tx2 <= COGL_FIXED_1 &&
|
&& tex->slice_gl_handles->len == 1)
|
||||||
ty1 >= -COGL_FIXED_1 && ty2 <= COGL_FIXED_1)
|
|
||||||
{
|
{
|
||||||
_cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
|
_cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_cogl_texture_quad_sw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
|
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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_cogl_texture_quad_sw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2182,13 +2366,12 @@ cogl_texture_polygon (CoglHandle handle,
|
|||||||
CoglTextureVertex *vertices,
|
CoglTextureVertex *vertices,
|
||||||
gboolean use_color)
|
gboolean use_color)
|
||||||
{
|
{
|
||||||
CoglTexture *tex;
|
CoglTexture *tex;
|
||||||
GLuint gl_handle;
|
int i;
|
||||||
gulong enable_flags;
|
GLuint gl_handle;
|
||||||
int i;
|
CoglTexSliceSpan *y_span, *x_span;
|
||||||
|
gulong enable_flags;
|
||||||
CoglTextureGLVertex *p;
|
CoglTextureGLVertex *p;
|
||||||
CoglTexSliceSpan *x_span;
|
|
||||||
CoglTexSliceSpan *y_span;
|
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
@ -2230,13 +2413,9 @@ cogl_texture_polygon (CoglHandle handle,
|
|||||||
|
|
||||||
ctx->texture_vertices_size = nsize;
|
ctx->texture_vertices_size = nsize;
|
||||||
|
|
||||||
if (ctx->texture_vertices)
|
ctx->texture_vertices = g_realloc (ctx->texture_vertices,
|
||||||
ctx->texture_vertices = g_realloc (ctx->texture_vertices,
|
nsize
|
||||||
nsize
|
* sizeof (CoglTextureGLVertex));
|
||||||
* sizeof (CoglTextureGLVertex));
|
|
||||||
else
|
|
||||||
ctx->texture_vertices = g_malloc (nsize
|
|
||||||
* sizeof (CoglTextureGLVertex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare GL state */
|
/* Prepare GL state */
|
||||||
@ -2249,7 +2428,7 @@ cogl_texture_polygon (CoglHandle handle,
|
|||||||
else if (use_color)
|
else if (use_color)
|
||||||
{
|
{
|
||||||
for (i = 0; i < n_vertices; i++)
|
for (i = 0; i < n_vertices; i++)
|
||||||
if (vertices[i].color.alpha < 255)
|
if (cogl_color_get_alpha_byte(&vertices[i].color) < 255)
|
||||||
{
|
{
|
||||||
enable_flags |= COGL_ENABLE_BLEND;
|
enable_flags |= COGL_ENABLE_BLEND;
|
||||||
break;
|
break;
|
||||||
@ -2264,14 +2443,14 @@ cogl_texture_polygon (CoglHandle handle,
|
|||||||
if (use_color)
|
if (use_color)
|
||||||
{
|
{
|
||||||
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
|
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
|
||||||
GE( cogl_wrap_glColorPointer (4, GL_FIXED, sizeof (CoglTextureGLVertex),
|
GE( glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (CoglTextureGLVertex),
|
||||||
ctx->texture_vertices[0].c) );
|
ctx->texture_vertices[0].c) );
|
||||||
}
|
}
|
||||||
|
|
||||||
GE( cogl_wrap_glVertexPointer (3, GL_FIXED, sizeof (CoglTextureGLVertex),
|
GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex),
|
||||||
ctx->texture_vertices[0].v) );
|
ctx->texture_vertices[0].v) );
|
||||||
GE( cogl_wrap_glTexCoordPointer (2, GL_FIXED, sizeof (CoglTextureGLVertex),
|
GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex),
|
||||||
ctx->texture_vertices[0].t) );
|
ctx->texture_vertices[0].t) );
|
||||||
|
|
||||||
cogl_enable (enable_flags);
|
cogl_enable (enable_flags);
|
||||||
|
|
||||||
@ -2279,25 +2458,31 @@ cogl_texture_polygon (CoglHandle handle,
|
|||||||
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
|
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
|
||||||
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, 0);
|
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, 0);
|
||||||
|
|
||||||
/* Convert the vertices into an array of GLfixeds ready to pass to
|
/* Convert the vertices into an array of GLfloats ready to pass to
|
||||||
OpenGL */
|
OpenGL */
|
||||||
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++)
|
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++)
|
||||||
{
|
{
|
||||||
p->v[0] = vertices[i].x;
|
#define CFX_F COGL_FIXED_TO_FLOAT
|
||||||
p->v[1] = vertices[i].y;
|
|
||||||
p->v[2] = vertices[i].z;
|
p->v[0] = CFX_F(vertices[i].x);
|
||||||
p->t[0] = vertices[i].tx * (x_span->size - x_span->waste) / x_span->size;
|
p->v[1] = CFX_F(vertices[i].y);
|
||||||
p->t[1] = vertices[i].ty * (y_span->size - y_span->waste) / y_span->size;
|
p->v[2] = CFX_F(vertices[i].z);
|
||||||
p->c[0] = (vertices[i].color.red << 16) / 0xff;
|
p->t[0] = CFX_F(vertices[i].tx
|
||||||
p->c[1] = (vertices[i].color.green << 16) / 0xff;
|
* (x_span->size - x_span->waste) / x_span->size);
|
||||||
p->c[2] = (vertices[i].color.blue << 16) / 0xff;
|
p->t[1] = CFX_F(vertices[i].ty
|
||||||
p->c[3] = (vertices[i].color.alpha << 16) / 0xff;
|
* (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);
|
||||||
|
|
||||||
|
#undef CFX_F
|
||||||
}
|
}
|
||||||
|
|
||||||
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
|
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
|
||||||
tex->gl_intformat) );
|
tex->gl_intformat) );
|
||||||
|
|
||||||
GE( cogl_wrap_glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices) );
|
GE( glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices) );
|
||||||
|
|
||||||
/* Set the last color so that the cache of the alpha value will work
|
/* Set the last color so that the cache of the alpha value will work
|
||||||
properly */
|
properly */
|
||||||
|
Loading…
Reference in New Issue
Block a user