diff --git a/ChangeLog b/ChangeLog index 322a949f2..38bc499d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2008-05-07 Ivan Leben + + * clutter/cogl/cogl.h.in: + * clutter/cogl/gl(es)/cogl-texture.h: + * clutter/cogl/gl(es)/cogl-texture.c: + cogl_texture_new_* functions take a gboolean auto_mipmap argument. + If TRUE automatic mipmap generation is enabled during the process + of slice texture object creation. + (cogl_texture_new_from_foreign:) now allows mipmap min filter + flags. + + * clutter/clutter-texture.c: + * clutter/glx/clutter-glx-texture-pixmap.c: + * tests/test-cogl-offscreen.c: + * tests/test-cogl-tex-tile.c: + * tests/test-cogl-tex-convert.c: + * tests/test-cogl-tex-polygon.c: + * tests/test-cogl-tex-getset.c: + Pass FALSE for auto_mipmap to cogl_texture_new_*. + + * clutter/pango/pangoclutter-render.c: + (tc_get:) Pass TRUE to cogl_texture_new_with_size and use mipmap + min filter for nicer glyphs at small scales. As a result test-text + has gone all beautiful now. + 2008-05-07 Neil Roberts * clutter/clutter-frame-source.h: Added the missing G_BEGIN_DECLS diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index ae3084b31..8ff297fbb 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -221,6 +221,7 @@ clutter_texture_realize (ClutterActor *actor) (priv->width, priv->height, priv->no_slice ? -1 : priv->max_tile_waste, + FALSE, COGL_PIXEL_FORMAT_RGBA_8888); cogl_texture_set_filters (priv->texture, @@ -946,6 +947,7 @@ clutter_texture_set_from_data (ClutterTexture *texture, if ((new_texture = cogl_texture_new_from_data (width, height, priv->no_slice ? -1 : priv->max_tile_waste, + FALSE, source_format, COGL_PIXEL_FORMAT_ANY, rowstride, @@ -1128,6 +1130,7 @@ clutter_texture_set_from_file (ClutterTexture *texture, if ((new_texture = cogl_texture_new_from_file (filename, priv->no_slice ? -1 : priv->max_tile_waste, + FALSE, COGL_PIXEL_FORMAT_ANY, error)) == COGL_INVALID_HANDLE) @@ -1477,6 +1480,7 @@ on_fbo_source_size_change (GObject *object, priv->texture = cogl_texture_new_with_size (priv->width, priv->height, priv->max_tile_waste, + FALSE, COGL_PIXEL_FORMAT_RGBA_8888); cogl_texture_set_filters (priv->texture, diff --git a/clutter/cogl/cogl.h.in b/clutter/cogl/cogl.h.in index d0247c1b8..3e2e7208a 100644 --- a/clutter/cogl/cogl.h.in +++ b/clutter/cogl/cogl.h.in @@ -563,6 +563,8 @@ void cogl_paint_init (const ClutterColor *color); * @height: height of texture in pixels. * @max_waste: maximum extra horizontal and|or vertical margin pixels to make * texture fit GPU limitations. + * @auto_mipmap: enable or disable automatic generation of mipmap pyramid + * from the base level image whenever it is updated. * @internal_format: the #CoglPixelFormat to use for the GPU storage of the * texture. * @@ -574,6 +576,7 @@ void cogl_paint_init (const ClutterColor *color); CoglHandle cogl_texture_new_with_size (guint width, guint height, gint max_waste, + gboolean auto_mipmap, CoglPixelFormat internal_format); /** @@ -581,6 +584,8 @@ CoglHandle cogl_texture_new_with_size (guint width, * @filename: the file to load * @max_waste: maximum extra horizontal and|or vertical margin pixels to make * texture fit GPU limitations. + * @auto_mipmap: enable or disable automatic generation of mipmap pyramid + * from the base level image whenever it is updated. * @internal_format: the #CoglPixelFormat to use for the GPU storage of the * texture. * @error: a #GError or NULL. @@ -592,6 +597,7 @@ CoglHandle cogl_texture_new_with_size (guint width, */ CoglHandle cogl_texture_new_from_file (const gchar *filename, gint max_waste, + gboolean auto_mipmap, CoglPixelFormat internal_format, GError **error); @@ -600,6 +606,8 @@ CoglHandle cogl_texture_new_from_file (const gchar *filename, * @width: width of texture in pixels. * @height: height of texture in pixels. * @max_waste: maximum extra horizontal and|or vertical margin pixels to make + * @auto_mipmap: enable or disable automatic generation of mipmap pyramid + * from the base level image whenever it is updated. * @format: the #CoglPixelFormat the buffer is stored in in RAM * @internal_format: the #CoglPixelFormat that will be used for storing the * buffer on the GPU. @@ -615,6 +623,7 @@ CoglHandle cogl_texture_new_from_file (const gchar *filename, CoglHandle cogl_texture_new_from_data (guint width, guint height, gint max_waste, + gboolean auto_mipmap, CoglPixelFormat format, CoglPixelFormat internal_format, guint rowstride, diff --git a/clutter/cogl/gl/cogl-texture.c b/clutter/cogl/gl/cogl-texture.c index 04590da68..d4ff9de6e 100644 --- a/clutter/cogl/gl/cogl-texture.c +++ b/clutter/cogl/gl/cogl-texture.c @@ -749,7 +749,10 @@ _cogl_texture_slices_create (CoglTexture *tex) 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) ); + /* Use a transparent border color so that we can leave the color buffer alone when using texture co-ordinates outside of the texture */ @@ -989,6 +992,7 @@ CoglHandle cogl_texture_new_with_size (guint width, guint height, gint max_waste, + gboolean auto_mipmap, CoglPixelFormat internal_format) { CoglTexture *tex; @@ -1010,6 +1014,7 @@ cogl_texture_new_with_size (guint width, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; + tex->auto_mipmap = auto_mipmap; tex->bitmap.width = width; tex->bitmap.height = height; @@ -1047,6 +1052,7 @@ CoglHandle cogl_texture_new_from_data (guint width, guint height, gint max_waste, + gboolean auto_mipmap, CoglPixelFormat format, CoglPixelFormat internal_format, guint rowstride, @@ -1072,6 +1078,7 @@ cogl_texture_new_from_data (guint width, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; + tex->auto_mipmap = auto_mipmap; tex->bitmap.width = width; tex->bitmap.height = height; @@ -1119,6 +1126,7 @@ cogl_texture_new_from_data (guint width, CoglHandle cogl_texture_new_from_file (const gchar *filename, gint max_waste, + gboolean auto_mipmap, CoglPixelFormat internal_format, GError **error) { @@ -1147,6 +1155,7 @@ cogl_texture_new_from_file (const gchar *filename, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; + tex->auto_mipmap = auto_mipmap; tex->bitmap = bmp; tex->bitmap_owner = TRUE; @@ -1214,6 +1223,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle, GLint gl_height = 0; GLint gl_min_filter; GLint gl_mag_filter; + GLint gl_gen_mipmap; guint bpp; CoglTexture *tex; CoglTexSliceSpan x_span; @@ -1257,11 +1267,15 @@ cogl_texture_new_from_foreign (GLuint gl_handle, GE( glGetTexParameteriv (gl_target, GL_TEXTURE_MIN_FILTER, - &gl_min_filter)); + &gl_min_filter) ); GE( glGetTexParameteriv (gl_target, GL_TEXTURE_MAG_FILTER, - &gl_mag_filter)); + &gl_mag_filter) ); + + GE( glGetTexParameteriv (gl_target, + GL_GENERATE_MIPMAP, + &gl_gen_mipmap) ); /* Validate width and height */ if (gl_width <= 0 || gl_height <= 0) @@ -1293,6 +1307,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle, /* Setup bitmap info */ tex->is_foreign = TRUE; + tex->auto_mipmap = (gl_gen_mipmap == GL_TRUE) ? TRUE : FALSE; tex->bitmap.format = format; tex->bitmap.width = gl_width - x_pot_waste; @@ -1335,21 +1350,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle, g_array_append_val (tex->slice_gl_handles, gl_handle); - /* Replace mipmap min filter modes with single level ones */ - if (gl_min_filter != GL_NEAREST && gl_min_filter != GL_LINEAR) - { - if (gl_min_filter == GL_NEAREST_MIPMAP_NEAREST) - { - GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST) ); - tex->min_filter = CGL_NEAREST; - } - else - { - GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR) ); - tex->min_filter = CGL_LINEAR; - } - } - /* Force appropriate wrap parameter */ if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && gl_target == GL_TEXTURE_2D) diff --git a/clutter/cogl/gl/cogl-texture.h b/clutter/cogl/gl/cogl-texture.h index d4104804b..117437458 100644 --- a/clutter/cogl/gl/cogl-texture.h +++ b/clutter/cogl/gl/cogl-texture.h @@ -56,6 +56,7 @@ struct _CoglTexture COGLenum mag_filter; gboolean is_foreign; GLint wrap_mode; + gboolean auto_mipmap; }; CoglTexture* diff --git a/clutter/cogl/gles/cogl-texture.c b/clutter/cogl/gles/cogl-texture.c index a28aa9c1c..1dcb882fe 100644 --- a/clutter/cogl/gles/cogl-texture.c +++ b/clutter/cogl/gles/cogl-texture.c @@ -731,11 +731,14 @@ _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( 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) ); + 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, GL_CLAMP_TO_EDGE) ); + GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) ); + + if (tex->auto_mipmap) + GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP, GL_TRUE) ); /* Pass NULL data to init size and internal format */ GE( glTexImage2D (tex->gl_target, 0, tex->gl_intformat, @@ -938,6 +941,7 @@ CoglHandle cogl_texture_new_with_size (guint width, guint height, gint max_waste, + gboolean auto_mipmap, CoglPixelFormat internal_format) { CoglTexture *tex; @@ -959,6 +963,7 @@ cogl_texture_new_with_size (guint width, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; + tex->auto_mipmap = auto_mipmap; tex->bitmap.width = width; tex->bitmap.height = height; @@ -995,6 +1000,7 @@ CoglHandle cogl_texture_new_from_data (guint width, guint height, gint max_waste, + gboolean auto_mipmap, CoglPixelFormat format, CoglPixelFormat internal_format, guint rowstride, @@ -1020,6 +1026,7 @@ cogl_texture_new_from_data (guint width, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; + tex->auto_mipmap = auto_mipmap; tex->bitmap.width = width; tex->bitmap.height = height; @@ -1067,6 +1074,7 @@ cogl_texture_new_from_data (guint width, CoglHandle cogl_texture_new_from_file (const gchar *filename, gint max_waste, + gboolean auto_mipmap, CoglPixelFormat internal_format, GError **error) { @@ -1095,6 +1103,7 @@ cogl_texture_new_from_file (const gchar *filename, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; + tex->auto_mipmap = auto_mipmap; tex->bitmap = bmp; tex->bitmap_owner = TRUE; @@ -1151,6 +1160,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle, GLboolean gl_istexture; GLint gl_min_filter; GLint gl_mag_filter; + GLint gl_gen_mipmap; guint bpp; CoglTexture *tex; CoglTexSliceSpan x_span; @@ -1191,6 +1201,10 @@ cogl_texture_new_from_foreign (GLuint gl_handle, GL_TEXTURE_MAG_FILTER, &gl_mag_filter)); + GE( glGetTexParameteriv (gl_target, + GL_GENERATE_MIPMAP, + &gl_gen_mipmap) ); + /* Validate width and height */ if (width <= 0 || height <= 0) return COGL_INVALID_HANDLE; @@ -1208,6 +1222,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle, /* Setup bitmap info */ tex->is_foreign = TRUE; + tex->auto_mipmap = (gl_gen_mipmap == GL_TRUE) ? TRUE : FALSE; bpp = _cogl_get_format_bpp (format); tex->bitmap.format = format; @@ -1251,21 +1266,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle, g_array_append_val (tex->slice_gl_handles, gl_handle); - /* Replace mipmap min filter modes with single level ones */ - if (gl_min_filter != GL_NEAREST && gl_min_filter != GL_LINEAR) - { - if (gl_min_filter == GL_NEAREST_MIPMAP_NEAREST) - { - GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST) ); - tex->min_filter = CGL_NEAREST; - } - else - { - GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR) ); - tex->min_filter = CGL_LINEAR; - } - } - /* Force appropriate wrap parameter */ 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) ); diff --git a/clutter/cogl/gles/cogl-texture.h b/clutter/cogl/gles/cogl-texture.h index e2401be07..9811d55b2 100644 --- a/clutter/cogl/gles/cogl-texture.h +++ b/clutter/cogl/gles/cogl-texture.h @@ -55,6 +55,7 @@ struct _CoglTexture COGLenum min_filter; COGLenum mag_filter; gboolean is_foreign; + gboolean auto_mipmap; }; CoglTexture* diff --git a/clutter/glx/clutter-glx-texture-pixmap.c b/clutter/glx/clutter-glx-texture-pixmap.c index 458ec3cf6..9faf6a2b7 100644 --- a/clutter/glx/clutter-glx-texture-pixmap.c +++ b/clutter/glx/clutter-glx-texture-pixmap.c @@ -172,7 +172,7 @@ create_cogl_texture (ClutterTexture *texture, handle = cogl_texture_new_with_size (width, height, - -1, + -1, FALSE, COGL_PIXEL_FORMAT_RGBA_8888|COGL_BGR_BIT); if (handle) diff --git a/clutter/pango/pangoclutter-render.c b/clutter/pango/pangoclutter-render.c index 6e3df481c..c65e047e7 100644 --- a/clutter/pango/pangoclutter-render.c +++ b/clutter/pango/pangoclutter-render.c @@ -121,15 +121,16 @@ tc_get (tc_area *area, int width, int height) first_texture = match; match->avail = TC_HEIGHT; - match->cogl_tex = cogl_texture_new_with_size (TC_WIDTH, TC_HEIGHT, 0, - COGL_PIXEL_FORMAT_A_8); + match->cogl_tex = cogl_texture_new_with_size (TC_WIDTH, TC_HEIGHT, 0, TRUE, + COGL_PIXEL_FORMAT_A_8); - /* We might even want to use mipmapping instead of - * CGL_LINEAR here that should allow rerendering of glyphs - * to look nice even at scales far below 50%. + /* We use mipmapping instead of just CGL_LINEAR here + * which allows rendering of glyphs to look nice even at + * scales far below 50%. */ - cogl_texture_set_filters (match->cogl_tex, - CGL_LINEAR, CGL_NEAREST); + cogl_texture_set_filters (match->cogl_tex, + CGL_LINEAR_MIPMAP_LINEAR, + CGL_LINEAR); } match->avail -= slice_height; diff --git a/tests/test-cogl-offscreen.c b/tests/test-cogl-offscreen.c index c27c1ca94..a9c2c6512 100644 --- a/tests/test-cogl-offscreen.c +++ b/tests/test-cogl-offscreen.c @@ -156,12 +156,12 @@ test_coglbox_init (TestCoglbox *self) self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self); printf ("Loading redhand.png\n"); - priv->texhand_id = cogl_texture_new_from_file ("redhand.png", 0, + priv->texhand_id = cogl_texture_new_from_file ("redhand.png", 0, FALSE, COGL_PIXEL_FORMAT_ANY, - NULL); + NULL); printf ("Creating texture with size\n"); - priv->texture_id = cogl_texture_new_with_size (200,200,0, + priv->texture_id = cogl_texture_new_with_size (200,200,0, FALSE, COGL_PIXEL_FORMAT_RGB_888); if (priv->texture_id == COGL_INVALID_HANDLE) diff --git a/tests/test-cogl-tex-convert.c b/tests/test-cogl-tex-convert.c index 78ebfc979..20d91332c 100644 --- a/tests/test-cogl-tex-convert.c +++ b/tests/test-cogl-tex-convert.c @@ -161,19 +161,19 @@ test_coglbox_init (TestCoglbox *self) self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self); priv->cogl_tex_id[0] = - cogl_texture_new_from_file ("redhand.png", 0, + cogl_texture_new_from_file ("redhand.png", 0, FALSE, COGL_PIXEL_FORMAT_ANY, NULL); priv->cogl_tex_id[1] = - cogl_texture_new_from_file ("redhand.png", 0, + cogl_texture_new_from_file ("redhand.png", 0, FALSE, COGL_PIXEL_FORMAT_BGRA_8888, NULL); priv->cogl_tex_id[2] = - cogl_texture_new_from_file ("redhand.png", 0, + cogl_texture_new_from_file ("redhand.png", 0, FALSE, COGL_PIXEL_FORMAT_ARGB_8888, NULL); priv->cogl_tex_id[3] = - cogl_texture_new_from_file ("redhand.png", 0, + cogl_texture_new_from_file ("redhand.png", 0, FALSE, COGL_PIXEL_FORMAT_G_8, NULL); } diff --git a/tests/test-cogl-tex-getset.c b/tests/test-cogl-tex-getset.c index 5726d5930..ce5d1ba6f 100644 --- a/tests/test-cogl-tex-getset.c +++ b/tests/test-cogl-tex-getset.c @@ -142,7 +142,8 @@ test_coglbox_init (TestCoglbox *self) /* Load image from file */ priv->cogl_tex_id[0] = - cogl_texture_new_from_file ("redhand.png", 40, COGL_PIXEL_FORMAT_ANY, NULL); + cogl_texture_new_from_file ("redhand.png", 40, FALSE, + COGL_PIXEL_FORMAT_ANY, NULL); if (priv->cogl_tex_id[0] == COGL_INVALID_HANDLE) { @@ -172,8 +173,8 @@ test_coglbox_init (TestCoglbox *self) /* Create new texture from modified data */ priv->cogl_tex_id[1] = - cogl_texture_new_from_data (width, height, 0, - format, format, + cogl_texture_new_from_data (width, height, 0, FALSE, + format, format, 0, data); if (priv->cogl_tex_id[1] == COGL_INVALID_HANDLE) diff --git a/tests/test-cogl-tex-polygon.c b/tests/test-cogl-tex-polygon.c index 4d9aa272e..cd2888ff2 100644 --- a/tests/test-cogl-tex-polygon.c +++ b/tests/test-cogl-tex-polygon.c @@ -249,7 +249,7 @@ test_coglbox_init (TestCoglbox *self) priv->use_sliced = FALSE; priv->sliced_tex = cogl_texture_new_from_file - ("redhand.png", 10, COGL_PIXEL_FORMAT_ANY, &error); + ("redhand.png", 10, FALSE, COGL_PIXEL_FORMAT_ANY, &error); if (priv->sliced_tex == NULL) { g_warning ("Texture loading failed: %s", error->message); @@ -258,7 +258,7 @@ test_coglbox_init (TestCoglbox *self) } priv->not_sliced_tex = cogl_texture_new_from_file - ("redhand.png", -1, COGL_PIXEL_FORMAT_ANY, &error); + ("redhand.png", -1, FALSE, COGL_PIXEL_FORMAT_ANY, &error); if (priv->not_sliced_tex == NULL) { g_warning ("Texture loading failed: %s", error->message); diff --git a/tests/test-cogl-tex-tile.c b/tests/test-cogl-tex-tile.c index 277238622..05a1eb03c 100644 --- a/tests/test-cogl-tex-tile.c +++ b/tests/test-cogl-tex-tile.c @@ -154,12 +154,12 @@ test_coglbox_init (TestCoglbox *self) TestCoglboxPrivate *priv; self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self); - priv->cogl_tex_id = cogl_texture_new_from_file ("redhand.png", 0, - COGL_PIXEL_FORMAT_ANY, - NULL); + priv->cogl_tex_id = cogl_texture_new_from_file ("redhand.png", 0, FALSE, + COGL_PIXEL_FORMAT_ANY, + NULL); cogl_texture_set_filters (priv->cogl_tex_id, - CGL_LINEAR, CGL_LINEAR); + CGL_LINEAR, CGL_LINEAR); } static void