Merge branch '1.0-integration'

* 1.0-integration: (138 commits)
  [x11] Disable XInput by default
  [xinput] Invert the XI extension version check
  [cogl-primitives] Fix an unused variable warning when building GLES
  [clutter-stage-egl] Pass -1,-1 to clutter_stage_x11_fix_window_size
  Update the GLES backend to have the layer filters in the material
  [gles/cogl-shader] Add a missing semicolon
  [cogl] Move the texture filters to be a property of the material layer
  [text] Fix Pango unit to pixels conversion
  [actor] Force unrealization on destroy only for non-toplevels
  [x11] Rework map/unmap and resizing
  [xinput] Check for the XInput entry points
  [units] Validate units against the ParamSpec
  [actor] Add the ::allocation-changed signal
  [actor] Use flags to control allocations
  [units] Rework Units into logical distance value
  Remove a stray g_value_get_int()
  Remove usage of Units and macros
  [cogl-material] Allow setting a layer with an invalid texture handle
  [timeline] Remove the concept of frames from timelines
  [gles/cogl-shader] Fix parameter spec for cogl_shader_get_info_log
  ...

Conflicts:
	configure.ac
This commit is contained in:
Emmanuele Bassi 2009-06-05 12:41:42 +01:00
commit 805fb0620a
51 changed files with 3863 additions and 1622 deletions

View File

@ -1,3 +1,9 @@
NULL =
V = @
Q = $(V:1=)
QUIET_GEN = $(Q:@=@echo ' GEN '$@;)
SUBDIRS = common $(CLUTTER_COGL) SUBDIRS = common $(CLUTTER_COGL)
BUILT_SOURCES = cogl.h BUILT_SOURCES = cogl.h
@ -23,29 +29,42 @@ CLEANFILES = $(pc_files)
AM_CPPFLAGS = $(CLUTTER_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS) AM_CPPFLAGS = $(CLUTTER_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS)
# COGL installed headers
cogl_headers = \ cogl_headers = \
$(top_srcdir)/clutter/cogl/cogl-bitmap.h \ $(top_srcdir)/clutter/cogl/cogl-bitmap.h \
$(top_srcdir)/clutter/cogl/cogl-color.h \ $(top_srcdir)/clutter/cogl/cogl-color.h \
$(top_srcdir)/clutter/cogl/cogl-debug.h \ $(top_srcdir)/clutter/cogl/cogl-debug.h \
$(top_srcdir)/clutter/cogl/cogl-fixed.h \ $(top_srcdir)/clutter/cogl/cogl-deprecated.h \
$(top_srcdir)/clutter/cogl/cogl-material.h \ $(top_srcdir)/clutter/cogl/cogl-fixed.h \
$(top_srcdir)/clutter/cogl/cogl-matrix.h \ $(top_srcdir)/clutter/cogl/cogl-material.h \
$(top_srcdir)/clutter/cogl/cogl-offscreen.h \ $(top_srcdir)/clutter/cogl/cogl-matrix.h \
$(top_srcdir)/clutter/cogl/cogl-path.h \ $(top_srcdir)/clutter/cogl/cogl-offscreen.h \
$(top_srcdir)/clutter/cogl/cogl-shader.h \ $(top_srcdir)/clutter/cogl/cogl-path.h \
$(top_srcdir)/clutter/cogl/cogl-texture.h \ $(top_srcdir)/clutter/cogl/cogl-shader.h \
$(top_srcdir)/clutter/cogl/cogl-types.h \ $(top_srcdir)/clutter/cogl/cogl-texture.h \
$(top_srcdir)/clutter/cogl/cogl-vertex-buffer.h $(top_srcdir)/clutter/cogl/cogl-types.h \
$(top_srcdir)/clutter/cogl/cogl-vertex-buffer.h \
$(top_builddir)/clutter/cogl/cogl-defines-@CLUTTER_COGL@.h \
$(top_builddir)/clutter/cogl/cogl-enum-types.h \
$(top_builddir)/clutter/cogl/cogl.h \
$(NULL)
# this is copied in from common/ to make cogl.h work, but we
# need to clean it up ourselves once we're done
DISTCLEANFILES = cogl-enum-types.h
# HACK - gobject-introspection can't scan a library in another directory # HACK - gobject-introspection can't scan a library in another directory
# so we create a libclutter-cogl.la that's just identical to the one # so we create a libclutter-cogl.la that's just identical to the one
# in the subdir # in the subdir
noinst_LTLIBRARIES = libclutter-cogl.la noinst_LTLIBRARIES = libclutter-cogl.la
libclutter_cogl_la_LIBADD = $(CLUTTER_COGL)/libclutter-cogl.la libclutter_cogl_la_LIBADD = $(CLUTTER_COGL)/libclutter-cogl-$(CLUTTER_COGL).la
libclutter_cogl_la_SOURCES = $(cogl_headers) libclutter_cogl_la_SOURCES = $(cogl_headers)
coglincludedir = $(includedir)/clutter-@CLUTTER_API_VERSION@/cogl
coglinclude_HEADERS = $(cogl_headers)
if HAVE_INTROSPECTION if HAVE_INTROSPECTION
Cogl-@CLUTTER_API_VERSION@.gir: $(INTROSPECTION_SCANNER) $(CLUTTER_COGL)/libclutter-cogl.la Cogl-@CLUTTER_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libclutter-cogl.la
$(QUIET_GEN)$(INTROSPECTION_SCANNER) -v \ $(QUIET_GEN)$(INTROSPECTION_SCANNER) -v \
--namespace Cogl --nsversion=@CLUTTER_API_VERSION@ \ --namespace Cogl --nsversion=@CLUTTER_API_VERSION@ \
-I$(top_srcdir)/clutter/cogl \ -I$(top_srcdir)/clutter/cogl \
@ -59,8 +78,6 @@ Cogl-@CLUTTER_API_VERSION@.gir: $(INTROSPECTION_SCANNER) $(CLUTTER_COGL)/libclut
--libtool="$(top_builddir)/doltlibtool" \ --libtool="$(top_builddir)/doltlibtool" \
--pkg gobject-2.0 \ --pkg gobject-2.0 \
--output $@ \ --output $@ \
$(top_builddir)/clutter/cogl/cogl-defines-@CLUTTER_COGL@.h \
$(top_builddir)/clutter/cogl/cogl.h \
$(cogl_headers) $(cogl_headers)
BUILT_GIRSOURCES = Cogl-@CLUTTER_API_VERSION@.gir BUILT_GIRSOURCES = Cogl-@CLUTTER_API_VERSION@.gir

View File

@ -29,15 +29,16 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum { typedef enum {
COGL_DEBUG_MISC = 1 << 0, COGL_DEBUG_MISC = 1 << 0,
COGL_DEBUG_TEXTURE = 1 << 1, COGL_DEBUG_TEXTURE = 1 << 1,
COGL_DEBUG_MATERIAL = 1 << 2, COGL_DEBUG_MATERIAL = 1 << 2,
COGL_DEBUG_SHADER = 1 << 3, COGL_DEBUG_SHADER = 1 << 3,
COGL_DEBUG_OFFSCREEN = 1 << 4, COGL_DEBUG_OFFSCREEN = 1 << 4,
COGL_DEBUG_DRAW = 1 << 5, COGL_DEBUG_DRAW = 1 << 5,
COGL_DEBUG_PANGO = 1 << 6, COGL_DEBUG_PANGO = 1 << 6,
COGL_DEBUG_RECTANGLES = 1 << 7, COGL_DEBUG_RECTANGLES = 1 << 7,
COGL_DEBUG_HANDLE = 1 << 8 COGL_DEBUG_HANDLE = 1 << 8,
COGL_DEBUG_BLEND_STRINGS = 1 << 9
} CoglDebugFlags; } CoglDebugFlags;
#ifdef COGL_ENABLE_DEBUG #ifdef COGL_ENABLE_DEBUG
@ -69,3 +70,4 @@ extern guint cogl_debug_flags;
G_END_DECLS G_END_DECLS
#endif /* __COGL_DEBUG_H__ */ #endif /* __COGL_DEBUG_H__ */

View File

@ -23,6 +23,14 @@
#ifndef COGL_DEPRECATED_H #ifndef COGL_DEPRECATED_H
#define cogl_color cogl_color_REPLACED_BY_cogl_set_source_color #define cogl_color cogl_color_REPLACED_BY_cogl_set_source_color
#define cogl_enable_depth_test cogl_enable_depth_test_RENAMED_TO_cogl_set_depth_test_enabled
#define cogl_enable_backface_culling cogl_enable_backface_culling_RENAMED_TO_cogl_set_backface_culling_enabled
#define cogl_texture_rectangle cogl_texture_rectangle_REPLACE_BY_cogl_set_source_texture_AND_cogl_rectangle_with_texture_coords
#define cogl_texture_multiple_rectangles cogl_texture_multiple_rectangles_REPLACED_BY_cogl_set_source_texture_AND_cogl_rectangles_with_texture_coords
#define cogl_texture_polygon cogl_texture_polygon_REPLACED_BY_cogl_set_source_texture_AND_cogl_polygon
#endif #endif

View File

@ -43,6 +43,51 @@ G_BEGIN_DECLS
* blended together. * blended together.
*/ */
/**
* CoglMaterialFilter:
* @COGL_MATERIAL_FILTER_NEAREST: Measuring in manhatten distance from the,
* current pixel center, use the nearest texture
* texel.
* @COGL_MATERIAL_FILTER_LINEAR: Use the weighted average of the 4 texels
* nearest the current pixel center.
* @COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST: Select the mimap level whose
* texel size most closely matches
* the current pixel, and use the
* COGL_MATERIAL_FILTER_NEAREST
* criterion.
* @COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST: Select the mimap level whose
* texel size most closely matches
* the current pixel, and use the
* COGL_MATERIAL_FILTER_LINEAR
* criterion.
* @COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR: Select the two mimap levels
* whose texel size most closely
* matches the current pixel, use
* the COGL_MATERIAL_FILTER_NEAREST
* criterion on each one and take
* their weighted average.
* @COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR: Select the two mimap levels
* whose texel size most closely
* matches the current pixel, use
* the COGL_MATERIAL_FILTER_LINEAR
* criterion on each one and take
* their weighted average.
*
* Texture filtering is used whenever the current pixel maps either to more
* than one texture element (texel) or less than one. These filter enums
* correspond to different strategies used to come up with a pixel color, by
* possibly referring to multiple neighbouring texels and taking a weighted
* average or simply using the nearest texel.
*/
typedef enum _CoglMaterialFilter
{
COGL_MATERIAL_FILTER_NEAREST = GL_NEAREST,
COGL_MATERIAL_FILTER_LINEAR = GL_LINEAR,
COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST,
COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST,
COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR,
COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR
} CoglMaterialFilter;
/** /**
* cogl_material_new: * cogl_material_new:
@ -367,80 +412,90 @@ void cogl_material_set_alpha_test_function (CoglHandle material,
float alpha_reference); float alpha_reference);
/** /**
* CoglMaterialBlendFactor: * cogl_material_set_blend:
* @COGL_MATERIAL_BLEND_FACTOR_ZERO: (0, 0, 0, 0) * @material: A CoglMaterial object
* @COGL_MATERIAL_BLEND_FACTOR_ONE: (1, 1, 1, 1) * @blend_string: A <link linkend="cogl-Blend-Strings">Cogl blend string</link>
* @COGL_MATERIAL_BLEND_FACTOR_SRC_COLOR: (Rs, Gs, Bs, As) * describing the desired blend function.
* @COGL_MATERIAL_BLEND_FACTOR_DST_COLOR: (Rd, Gd, Bd, Ad) * @error: A GError that may report lack of driver support if you give
* @COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: (1-Rs, 1-Gs, 1-Bs, 1-As) * separate blend string statements for the alpha channel and RGB
* @COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_DST_COLOR: (1-Rd, 1-Gd, 1-Bd, 1-Ad) * channels since some drivers or backends such as GLES 1.1 dont
* @COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA: (As, As, As, As) * support this.
* @COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: (1-As, 1-As, 1-As, 1-As) *
* @COGL_MATERIAL_BLEND_FACTOR_DST_ALPHA: (Ad, Ad, Ad, Ad) * If not already familiar; please refer
* @COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: (1-Ad, 1-Ad, 1-Ad, 1-Ad) * <link linkend="cogl-Blend-Strings">here</link> for an overview of what blend
* @COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA_SATURATE: (f,f,f,1) where f=MIN(As,1-Ad) * strings are and there syntax.
* *
* Blending occurs after the alpha test function, and combines fragments with * Blending occurs after the alpha test function, and combines fragments with
* the framebuffer. * the framebuffer.
* <para>
* A fixed function is used to determine the blended color, which is based on * Currently the only blend function Cogl exposes is ADD(). So any valid
* the incoming source color of your fragment (Rs, Gs, Bs, As), a source * blend statements will be of the form:
* factor (Sr, Sg, Sb, Sa), a destination color (Rd, Rg, Rb, Ra) and *
* a destination factor (Dr, Dg, Db, Da), and is given by these equations:
* </para>
* <programlisting> * <programlisting>
* R = Rs*Sr + Rd*Dr * &lt;channel-mask&gt;=ADD(SRC_COLOR*(&lt;factor&gt;), DST_COLOR*(&lt;factor&gt;))
* G = Gs*Sg + Gd*Dg
* B = Bs*Sb + Bd*Db
* A = As*Sa + Ad*Da
* </programlisting> * </programlisting>
* *
* All factors have a range [0, 1] * <b>NOTE: The brackets around blend factors are currently not optional!</b>
* *
* The factors are selected with the following constants: * This is the list of source-names usable as blend factors:
* <itemizedlist>
* <listitem>SRC_COLOR: The color of the in comming fragment</listitem>
* <listitem>DST_COLOR: The color of the framebuffer</listitem>
* <listitem>
* CONSTANT: The constant set via cogl_material_set_blend_constant()</listitem>
* </itemizedlist>
* The source names can be used according to the
* <link linkend="cogl-Blend-String-syntax">color-source and factor syntax</link>,
* so for example "(1-SRC_COLOR[A])" would be a valid factor, as would
* "(CONSTANT[RGB])"
*
* These can also be used as factors:
* <itemizedlist>
* <listitem>0: (0, 0, 0, 0)</listitem>
* <listitem>1: (1, 1, 1, 1)</listitem>
* <listitem>SRC_ALPHA_SATURATE_FACTOR: (f,f,f,1)
* where f=MIN(SRC_COLOR[A],1-DST_COLOR[A])</listitem>
* </itemizedlist>
* <para>
* Remember; all color components are normalized to the range [0, 1] before
* computing the result of blending.
* </para>
* <section>
* <title>Examples</title>
* Blend a non-premultiplied source over a destination with
* premultiplied alpha:
* <programlisting>
* "RGB = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))"
* "A = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))"
* </programlisting>
* Blend a premultiplied source over a destination with premultiplied alpha:
* <programlisting>
* "RGBA = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))"
* </programlisting>
* </section>
*
* Returns: TRUE if the blend string was successfully parsed, and the described
* blending is supported by the underlying driver/hardware. If there
* was an error, it returns FALSE.
*
* Since: 1.0
*/ */
typedef enum _CoglMaterialBlendFactor gboolean cogl_material_set_blend (CoglHandle material,
{ const char *blend_string,
COGL_MATERIAL_BLEND_FACTOR_ZERO = GL_ZERO, GError **error);
COGL_MATERIAL_BLEND_FACTOR_ONE = GL_ONE,
COGL_MATERIAL_BLEND_FACTOR_SRC_COLOR = GL_SRC_COLOR,
COGL_MATERIAL_BLEND_FACTOR_DST_COLOR = GL_DST_COLOR,
COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = GL_ONE_MINUS_SRC_COLOR,
COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_DST_COLOR = GL_ONE_MINUS_DST_COLOR,
COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA = GL_SRC_ALPHA,
COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = GL_ONE_MINUS_SRC_ALPHA,
COGL_MATERIAL_BLEND_FACTOR_DST_ALPHA = GL_DST_ALPHA,
COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = GL_ONE_MINUS_DST_ALPHA,
COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA_SATURATE = GL_SRC_ALPHA_SATURATE,
} CoglMaterialBlendFactor;
/** /**
* cogl_material_set_blend_factors: * cogl_material_set_blend_constant:
* @material: A CoglMaterial object * @material: A CoglMaterial object
* @src_factor: Chooses the @CoglMaterialBlendFactor you want plugged in to * @constant_color: The constant color you want
* the blend equation.
* @dst_factor: Chooses the @CoglMaterialBlendFactor you want plugged in to
* the blend equation.
* *
* This function lets you control how primitives using this material will get * When blending is setup to reference a CONSTANT blend factor then
* blended with the contents of your framebuffer. The blended RGBA components * blending will depend on the constant set with this function.
* are calculated like this:
* *
* (RsSr+RdDr, GsSg+GdDg, BsSb+BsSb, AsSa+AdDa) * Since: 1.0
*
* Where (Rs,Gs,Bs,As) represents your source - material- color,
* (Rd,Gd,Bd,Ad) represents your destination - framebuffer - color,
* (Sr,Sg,Sb,Sa) represents your source blend factor and
* (Dr,Dg,Db,Da) represents you destination blend factor.
*
* All factors lie in the range [0,1] and incoming color components are also
* normalized to the range [0,1]
*
* Since 1.0
*/ */
void cogl_material_set_blend_factors (CoglHandle material, void cogl_material_set_blend_constant (CoglHandle material,
CoglMaterialBlendFactor src_factor, CoglColor *constant_color);
CoglMaterialBlendFactor dst_factor);
/** /**
* cogl_material_set_layer: * cogl_material_set_layer:
@ -460,7 +515,7 @@ void cogl_material_set_blend_factors (CoglHandle material,
* Since 1.0 * Since 1.0
*/ */
void cogl_material_set_layer (CoglHandle material, void cogl_material_set_layer (CoglHandle material,
gint layer_index, int layer_index,
CoglHandle texture); CoglHandle texture);
/** /**
@ -473,233 +528,112 @@ void cogl_material_set_layer (CoglHandle material,
void cogl_material_remove_layer (CoglHandle material, void cogl_material_remove_layer (CoglHandle material,
gint layer_index); gint layer_index);
/** /**
* CoglMaterialLayerCombineFunc: * cogl_material_set_layer_combine:
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_REPLACE: Arg0 * @material: A CoglMaterial object
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE: Arg0 x Arg1 * @layer_index: Specifies the layer you want define a combine function for
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD: Arg0 + Arg1 * @blend_string: A <link linkend="cogl-Blend-Strings">Cogl blend string</link>
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD_SIGNED: Arg0 + Arg1 - 0.5 * describing the desired texture combine function.
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_INTERPOLATE: Arg0 x Arg + Arg1 x (1-Arg2) * @error: A GError that may report parse errors or lack of GPU/driver support.
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_SUBTRACT: Arg0 - Arg1
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_DOT3_RGB: 4 x ((Arg0r - 0.5) x (Arg1r - 0.5)) +
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_DOT3_RGBA: ((Arg0b - 0.5) x (Arg1b - 0.5)) +
* *
* A material may comprise of 1 or more layers that can be combined using a * If not already familiar; you can refer
* number of different functions. By default layers are modulated, which is * <link linkend="cogl-Blend-Strings">here</link> for an overview of what blend
* to say the components of the current source layer S are simply multipled * strings are and there syntax.
* together with the combined results of the previous layer P like this:
* *
* These are all the functions available for texture combining:
* <itemizedlist>
* <listitem>REPLACE(arg0) = arg0</listitem>
* <listitem>MODULATE(arg0, arg1) = arg0 x arg1</listitem>
* <listitem>ADD(arg0, arg1) = arg0 + arg1</listitem>
* <listitem>ADD_SIGNED(arg0, arg1) = arg0 + arg1 - 0.5</listitem>
* <listitem>INTERPOLATE(arg0, arg1, arg2) =
* arg0 x arg2 + arg1 x (1 - arg2)</listitem>
* <listitem>SUBTRACT(arg0, arg1) = arg0 - arg1</listitem>
* <listitem>
* DOT3_RGB(arg0, arg1) =
* <programlisting> * <programlisting>
* (Rs*Rp, Gs*Gp, Bs*Bp, As*Ap) * 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) +
* (arg0[G] - 0.5)) * (arg1[G] - 0.5) +
* (arg0[B] - 0.5)) * (arg1[B] - 0.5))
* </programlisting> * </programlisting>
*
* For more advanced techniques, Cogl exposes the fixed function texture
* combining capabilities of your GPU to give you greater control.
*/
typedef enum _CoglMaterialLayerCombineFunc
{
COGL_MATERIAL_LAYER_COMBINE_FUNC_REPLACE = CGL_REPLACE,
COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE = CGL_MODULATE,
COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD = CGL_ADD,
COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD_SIGNED = CGL_ADD_SIGNED,
COGL_MATERIAL_LAYER_COMBINE_FUNC_INTERPOLATE = CGL_INTERPOLATE,
COGL_MATERIAL_LAYER_COMBINE_FUNC_SUBTRACT = CGL_SUBTRACT,
COGL_MATERIAL_LAYER_COMBINE_FUNC_DOT3_RGB = CGL_DOT3_RGB,
COGL_MATERIAL_LAYER_COMBINE_FUNC_DOT3_RGBA = CGL_DOT3_RGBA
} CoglMaterialLayerCombineFunc;
/**
* CoglMaterialLayerCombineChannels:
* @COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB: Modify the function or argument
* src/op for the RGB components of a
* layer
* @COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA: Modify the function or argument
* src/op for the Alpha component of a
* layer
* @COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA: Modify the function or argument
* src/op for all the components of a
* layer
*
* Cogl optionally lets you describe 2 seperate combine modes for a single
* layer; 1 for the RGB components, and 1 for the Alpha component, so in this
* case you would repeat the 3 steps documented with the
* @cogl_material_set_layer_combine_function function for each channel
* selector.
*
* (Note: you can't have different modes for each channel, so if you need more
* control you will need to use a glsl fragment shader)
*/
typedef enum _CoglMaterialLayerCombineChannels
{
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA,
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA
} CoglMaterialLayerCombineChannels;
/**
* cogl_material_set_layer_combine_function:
* @material: A CoglMaterial object
* @layer_index: Specifies the layer whos combine mode you want to modify
* @channels: Specifies which channels combine mode you want to modify
* (RGB, ALPHA, or RGBA)
* @func: Specifies the function you want to use for combining fragments
* of the specified layer with the results of previously combined
* layers.
*
* There are three basic steps to describing how a layer should be combined:
* <orderedlist>
* <listitem>
* Choose a function.
* </listitem> * </listitem>
* <listitem> * <listitem>DOT3_RGBA(arg0, arg1) =
* Specify the source color for each argument of the chosen function. (Note
* the functions don't all take the same number of arguments)
* </listitem>
* <listitem>
* Specify an operator for each argument that can modify the corresponding
* source color before the function is applied.
* </listitem>
* </orderedlist>
*
* Cogl optionally lets you describe 2 seperate combine modes for a single
* layer; 1 for the RGB components, and 1 for the Alpha component, so in this
* case you would repeat the 3 steps for each channel selector.
*
* (Note: you can't have different modes for each channel, so if you need more
* control you will need to use a glsl fragment shader)
*
* For example here is how you could elect to use the ADD function for all
* components of layer 1 in your material:
* <programlisting> * <programlisting>
* //Step 1: Choose a function. Note the ADD function takes 2 arguments... * 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) +
* cogl_material_set_layer_combine_function (material, * (arg0[G] - 0.5)) * (arg1[G] - 0.5) +
* 1, * (arg0[B] - 0.5)) * (arg1[B] - 0.5))
* COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
* COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD);
* //Step 2: Specify the source color for the 2 ADD function arguments...
* cogl_material_set_layer_combine_arg_src (material,
* 1,//layer index
* 0,//argument index
* COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS);
* cogl_material_set_layer_combine_arg_src (material,
* 1,//layer index
* 1,//argument index
* COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
* COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE);
* //Step 3: Specify the operators used to modify the arguments...
* cogl_material_set_layer_combine_arg_op (material,
* 1,//layer index
* 0,//argument index
* COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA,
* COGL_MATERIAL_LAYER_COMBINE_OP_SRC_COLOR);
* cogl_material_set_layer_combine_arg_op (material,
* 1,//layer index
* 1,//argument index
* COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA,
* COGL_MATERIAL_LAYER_COMBINE_OP_SRC_COLOR);
* </programlisting> * </programlisting>
*/ * </listitem>
void cogl_material_set_layer_combine_function (CoglHandle material, * </itemizedlist>
gint layer_index,
CoglMaterialLayerCombineChannels channels,
CoglMaterialLayerCombineFunc func);
/**
* CoglMaterialLayerCombineSrc:
* @COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE: The fragment color of the current texture layer
* @COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE0: The fragment color of texture unit 0
* @COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE1: The fragment color of texture unit 1
* @COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE2: The fragment color of texture unit 2..7
* @COGL_MATERIAL_LAYER_COMBINE_SRC_CONSTANT: A fixed constant color (TODO: no API yet to specify the actual color!)
* @COGL_MATERIAL_LAYER_COMBINE_SRC_PRIMARY_COLOR: The basic color of the primitive ignoring texturing
* @COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS: The result of combining all previous layers
* *
* Note for the constants @COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE0..n the * Refer to the
* numbers may not correspond to the indices you choose for your layers since * <link linkend="cogl-Blend-String-syntax">color-source syntax</link> for
* your layer indices don't need to be contiguous. If you need to use these * describing the arguments. The valid source names for texture combining
* it would probably be sensible to ensure the layer indices do infact * are:
* correspond. * <itemizedlist>
* <listitem>
* TEXTURE: Use the color from the current texture layer
* </listitem>
* <listitem>
* TEXTURE_0, TEXTURE_1, etc: Use the color from the specified texture layer
* </listitem>
* <listitem>
* CONSTANT: Use the color from the constant given with
* cogl_material_set_layer_constant()
* </listitem>
* <listitem>
* PRIMARY: Use the color of the material as set with cogl_material_set_color()
* </listitem>
* <listitem>
* PREVIOUS: Either use the texture color from the previous layer, or if this
* is layer 0, use the color of the material as set with
* cogl_material_set_color()
* </listitem>
* </itemizedlist>
* <section>
* <title>Example</title>
* This is effectively what the default blending is:
* <programlisting>
* "RGBA = MODULATE (PREVIOUS, TEXTURE)"
* </programlisting>
* This could be used to cross-fade between two images, using the alpha
* component of a constant as the interpolator. The constant color
* is given by calling cogl_material_set_layer_constant.
* <programlisting>
* RGBA = INTERPOLATE (PREVIOUS, TEXTURE, CONSTANT[A])
* </programlisting>
* </section>
* <b>Note: you can't give a multiplication factor for arguments as you can
* with blending.</b>
*
* Returns: TRUE if the blend string was successfully parsed, and the described
* texture combining is supported by the underlying driver/hardware.
* If there was an error, it returns FALSE.
*
* Since: 1.0
*/ */
typedef enum _CoglMaterialLayerCombineSrc gboolean
{ cogl_material_set_layer_combine (CoglHandle material,
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE = GL_TEXTURE, gint layer_index,
const char *blend_string,
/* Can we find a nicer way... */ GError **error);
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE0 = GL_TEXTURE0,
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE1 = GL_TEXTURE1,
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE2 = GL_TEXTURE2,
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE3 = GL_TEXTURE3,
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE4 = GL_TEXTURE4,
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE5 = GL_TEXTURE5,
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE6 = GL_TEXTURE6,
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE7 = GL_TEXTURE7,
/* .. who would ever need more than 8 texture layers.. :-) */
COGL_MATERIAL_LAYER_COMBINE_SRC_CONSTANT = CGL_CONSTANT,
COGL_MATERIAL_LAYER_COMBINE_SRC_PRIMARY_COLOR = CGL_PRIMARY_COLOR,
COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS = CGL_PREVIOUS
} CoglMaterialLayerCombineSrc;
/** /**
* cogl_material_set_layer_combine_arg_src: * cogl_material_set_layer_combine_constant:
* @material: A CoglMaterial object * @material: A CoglMaterial object
* @layer_index: * @layer_index: Specifies the layer you want to specify a constant used
* @argument: * for texture combining
* @channels: * @color_constant: The constant color you want
* @src:
* *
*/ * When you are using the 'CONSTANT' color source in a layer combine
void cogl_material_set_layer_combine_arg_src (CoglHandle material, * description then you can use this function to define its value.
gint layer_index,
gint argument,
CoglMaterialLayerCombineChannels channels,
CoglMaterialLayerCombineSrc src);
typedef enum _CoglMaterialLayerCombineOp
{
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_COLOR = GL_SRC_COLOR,
COGL_MATERIAL_LAYER_COMBINE_OP_ONE_MINUS_SRC_COLOR = GL_ONE_MINUS_SRC_COLOR,
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_ALPHA = GL_SRC_ALPHA,
COGL_MATERIAL_LAYER_COMBINE_OP_ONE_MINUS_SRC_ALPHA = GL_ONE_MINUS_SRC_ALPHA
} CoglMaterialLayerCombineOp;
/**
* cogl_material_set_layer_combine_arg_op:
* @material: A CoglMaterial object
* @layer_index:
* @argument:
* @channels:
* @op:
* *
* Since 1.0
*/ */
void cogl_material_set_layer_combine_arg_op (CoglHandle material, void cogl_material_set_layer_combine_constant (CoglHandle material,
gint layer_index, int layer_index,
gint argument, CoglColor *constant);
CoglMaterialLayerCombineChannels channels,
CoglMaterialLayerCombineOp op);
/* TODO: */
#if 0
I think it would be be really neat to support a simple string description
of the fixed function texture combine modes exposed above. I think we can
consider this stuff to be set in stone from the POV that more advanced
texture combine functions are catered for with GLSL, so it seems reasonable
to find a concise string representation that can represent all the above
modes in a *much* more readable/useable fashion. I think somthing like
this would be quite nice:
"MODULATE(TEXTURE[RGB], PREVIOUS[A])"
"ADD(TEXTURE[A],PREVIOUS[RGB])"
"INTERPOLATE(TEXTURE[1-A], PREVIOUS[RGB])"
void cogl_material_set_layer_rgb_combine (CoglHandle material
gint layer_index,
const char *combine_description);
void cogl_material_set_layer_alpha_combine (CoglHandle material
gint layer_index,
const char *combine_description);
#endif
/** /**
* cogl_material_set_layer_matrix: * cogl_material_set_layer_matrix:
@ -709,38 +643,9 @@ void cogl_material_set_layer_alpha_combine (CoglHandle material
* and rotate a single layer of a material used to fill your geometry. * and rotate a single layer of a material used to fill your geometry.
*/ */
void cogl_material_set_layer_matrix (CoglHandle material, void cogl_material_set_layer_matrix (CoglHandle material,
gint layer_index, int layer_index,
CoglMatrix *matrix); CoglMatrix *matrix);
/**
* SECTION:cogl-material-internals
* @short_description: Functions for creating custom primitives that make use
* of Cogl materials for filling.
*
* Normally you shouldn't need to use this API directly, but if you need to
* developing a custom/specialised primitive - probably using raw OpenGL - then
* this API aims to expose enough of the material internals to support being
* able to fill your geometry according to a given Cogl material.
*/
/**
* cogl_material_get_cogl_enable_flags:
* @material: A CoglMaterial object
*
* This determines what flags need to be passed to cogl_enable before this
* material can be used. Normally you shouldn't need to use this function
* directly since Cogl will do this internally, but if you are developing
* custom primitives directly with OpenGL you may want to use this.
*
* Note: This API is hopfully just a stop-gap solution. Ideally cogl_enable
* will be replaced.
*/
/* TODO: find a nicer solution! */
gulong
cogl_material_get_cogl_enable_flags (CoglHandle handle);
/** /**
* cogl_material_get_layers: * cogl_material_get_layers:
* @material: A CoglMaterial object * @material: A CoglMaterial object
@ -748,24 +653,20 @@ cogl_material_get_cogl_enable_flags (CoglHandle handle);
* This function lets you access a materials internal list of layers * This function lets you access a materials internal list of layers
* for iteration. * for iteration.
* *
* Note: Normally you shouldn't need to use this function directly since * Returns: A list of #CoglHandle<!-- -->'s that can be passed to the
* Cogl will do this internally, but if you are developing custom primitives * cogl_material_layer_* functions.
* directly with OpenGL, you will need to iterate the layers that you want
* to texture with.
*
* Note: This function may return more layers than OpenGL can use at once
* so it's your responsability limit yourself to
* CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS.
*
* Note: It's a bit out of the ordinary to return a const GList *, but it
* was considered sensible to try and avoid list manipulation for every
* primitive emitted in a scene, every frame.
*/ */
const GList *cogl_material_get_layers (CoglHandle material_handle); const GList *cogl_material_get_layers (CoglHandle material_handle);
/** /**
* CoglMaterialLayerType: * CoglMaterialLayerType:
* @COGL_MATERIAL_LAYER_TYPE_TEXTURE: The layer represents a CoglTexture * @COGL_MATERIAL_LAYER_TYPE_TEXTURE: The layer represents a
* <link linkend="cogl-Textures">Cogl texture</link>
*
* Available types of layers for a #CoglMaterial. This enumeration
* might be expanded in later versions.
*
* Since: 1.0
*/ */
typedef enum _CoglMaterialLayerType typedef enum _CoglMaterialLayerType
{ {
@ -774,17 +675,12 @@ typedef enum _CoglMaterialLayerType
/** /**
* cogl_material_layer_get_type: * cogl_material_layer_get_type:
* @layer_handle: A CoglMaterialLayer handle * @layer_handle: A Cogl material layer handle
* *
* Currently there is only one type of layer defined: * Currently there is only one type of layer defined:
* COGL_MATERIAL_LAYER_TYPE_TEXTURE, but considering we may add purely GLSL * COGL_MATERIAL_LAYER_TYPE_TEXTURE, but considering we may add purely GLSL
* based layers in the future, you should write code that checks the type * based layers in the future, you should write code that checks the type
* first. * first.
*
* Note: Normally you shouldn't need to use this function directly since
* Cogl will do this internally, but if you are developing custom primitives
* directly with OpenGL, you will need to iterate the layers that you want
* to texture with, and thus should be checking the layer types.
*/ */
CoglMaterialLayerType cogl_material_layer_get_type (CoglHandle layer_handle); CoglMaterialLayerType cogl_material_layer_get_type (CoglHandle layer_handle);
@ -792,75 +688,58 @@ CoglMaterialLayerType cogl_material_layer_get_type (CoglHandle layer_handle);
* cogl_material_layer_get_texture: * cogl_material_layer_get_texture:
* @layer_handle: A CoglMaterialLayer handle * @layer_handle: A CoglMaterialLayer handle
* *
* This lets you extract a CoglTexture handle for a specific layer. Normally * This lets you extract a CoglTexture handle for a specific layer.
* you shouldn't need to use this function directly since Cogl will do this
* internally, but if you are developing custom primitives directly with
* OpenGL you may need this.
* *
* Note: In the future, we may support purely GLSL based layers which will * Note: In the future, we may support purely GLSL based layers which will
* likley return COGL_INVALID_HANDLE if you try to get the texture. * likely return COGL_INVALID_HANDLE if you try to get the texture.
* Considering this, you should always call cogl_material_layer_get_type * Considering this, you can call cogl_material_layer_get_type first,
* first, to check it is of type COGL_MATERIAL_LAYER_TYPE_TEXTURE. * to check it is of type COGL_MATERIAL_LAYER_TYPE_TEXTURE.
*
* Note: It is possible for a layer object of type
* COGL_MATERIAL_LAYER_TYPE_TEXTURE to be realized before a texture
* object has been associated with the layer. For example this happens
* if you setup layer combining for a given layer index before calling
* cogl_material_set_layer for that index.
*
* Returns: A CoglHandle to the layers texture object or COGL_INVALID_HANDLE
* if a texture has not been set yet.
*/ */
CoglHandle cogl_material_layer_get_texture (CoglHandle layer_handle); CoglHandle cogl_material_layer_get_texture (CoglHandle layer_handle);
/** /**
* CoglMaterialLayerFlags: * cogl_material_layer_get_min_filter:
* @COGL_MATERIAL_LAYER_FLAG_USER_MATRIX: Means the user has supplied a * @layer_handle: a #CoglHandle for a material layer.
* custom texture matrix. *
* Query the currently set downscaling filter for a cogl material layer.
*
* Returns: the current downscaling filter for a cogl material layer.
*/ */
typedef enum _CoglMaterialLayerFlags CoglMaterialFilter cogl_material_layer_get_min_filter (CoglHandle layer_handle);
{
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
} CoglMaterialLayerFlags;
/* XXX: NB: if you add flags here you will need to update
* CoglMaterialLayerPrivFlags!!! */
/** /**
* cogl_material_layer_get_flags: * cogl_material_layer_get_mag_filter:
* @layer_handle: A CoglMaterialLayer layer handle * @layer_handle: a #CoglHandle for a material layer.
* *
* This lets you get a number of flag attributes about the layer. Normally * Query the currently set downscaling filter for a cogl material layer.
* you shouldn't need to use this function directly since Cogl will do this *
* internally, but if you are developing custom primitives directly with * Returns: the current downscaling filter for a cogl material layer.
* OpenGL you may need this.
*/ */
gulong cogl_material_layer_get_flags (CoglHandle layer_handle); CoglMaterialFilter cogl_material_layer_get_mag_filter (CoglHandle layer_handle);
/** /**
* CoglMaterialFlushOption: * cogl_material_set_layer_filters:
* @COGL_MATERIAL_FLUSH_FALLBACK_MASK: Follow this by a guin32 mask * @handle: a #CoglHandle to a material.
* of the layers that can't be supported with the user supplied texture * @layer_index: the layer number to change.
* and need to be replaced with fallback textures. (1 = fallback, and the * @min_filter: the filter used when scaling a texture down.
* least significant bit = layer 0) * @mag_filter: the filter used when magnifying a texture.
* @COGL_MATERIAL_FLUSH_DISABLE_MASK: Follow this by a guint32 mask
* of the layers that you want to completly disable texturing for
* (1 = fallback, and the least significant bit = layer 0)
* @COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE: Follow this by a GLuint OpenGL texture
* name to override the texture used for layer 0 of the material. This is
* intended for dealing with sliced textures where you will need to point
* to each of the texture slices in turn when drawing your geometry.
* Passing a value of 0 is the same as not passing the option at all.
*/
typedef enum _CoglMaterialFlushOption
{
COGL_MATERIAL_FLUSH_FALLBACK_MASK = 1,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
} CoglMaterialFlushOption;
/**
* cogl_material_flush_gl_state:
* @material: A CoglMaterial object
* @...: A NULL terminated list of (CoglMaterialFlushOption, data) pairs
* *
* This function commits the state of the specified CoglMaterial - including * Changes the decimation and interpolation filters used when a texture is
* the texture state for all the layers - to the OpenGL[ES] driver. * drawn at other scales than 100%.
*
* Since 1.0
*/ */
void cogl_material_flush_gl_state (CoglHandle material, void cogl_material_set_layer_filters (CoglHandle handle,
...) G_GNUC_NULL_TERMINATED; gint layer_index,
CoglMaterialFilter min_filter,
CoglMaterialFilter mag_filter);
G_END_DECLS G_END_DECLS

View File

@ -199,22 +199,50 @@ void cogl_matrix_frustum (CoglMatrix *matrix,
float z_far); float z_far);
/** /**
* cogl_matrix_transform_point: * cogl_matrix_perspective:
* @matrix: A 4x4 transformation matrix * @matrix: A 4x4 transformation matrix
* @x: The X component of your points position [in:out] * @fov_y: A field of view angle for the Y axis
* @y: The Y component of your points position [in:out] * @aspect: The ratio of width to height determining the field of view angle
* @z: The Z component of your points position [in:out] * for the x axis.
* @w: The W component of your points position [in:out] * @z_near: The distance to the near clip plane.
* Never pass 0 and always pass a positive number.
* @z_far: The distance to the far clip plane. (Should always be positive)
* *
* This transforms a point whos position is given and returned * Multiplies the matrix by the described perspective matrix
* as four float components. *
* Note: you should be careful not to have to great a z_far / z_near ratio
* since that will reduce the effectiveness of depth testing since there wont
* be enough precision to identify the depth of objects near to each other.
*/ */
void void
cogl_matrix_transform_point (const CoglMatrix *matrix, cogl_matrix_perspective (CoglMatrix *matrix,
float *x, float fov_y,
float *y, float aspect,
float *z, float z_near,
float *w); float z_far);
/**
* cogl_matrix_ortho:
* @matrix: A 4x4 transformation matrix
* @left: The coordinate for the left clipping plane
* @right: The coordinate for the right clipping plane
* @bottom: The coordinate for the bottom clipping plane
* @top: The coordinate for the top clipping plane
* @z_near: The coordinate for the near clipping plane (may be negative if
* the plane is behind the viewer)
* @z_far: The coordinate for the far clipping plane (may be negative if
* the plane is behind the viewer)
*
* Multiples the matrix by a parallel projection matrix.
*/
void
cogl_matrix_ortho (CoglMatrix *matrix,
float left,
float right,
float bottom,
float top,
float z_near,
float z_far);
/** /**
* cogl_matrix_init_from_array: * cogl_matrix_init_from_array:
@ -234,6 +262,24 @@ void cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array);
*/ */
const float *cogl_matrix_get_array (const CoglMatrix *matrix); const float *cogl_matrix_get_array (const CoglMatrix *matrix);
/**
* cogl_matrix_transform_point:
* @matrix: A 4x4 transformation matrix
* @x: The X component of your points position [in:out]
* @y: The Y component of your points position [in:out]
* @z: The Z component of your points position [in:out]
* @w: The W component of your points position [in:out]
*
* This transforms a point whos position is given and returned
* as four float components.
*/
void
cogl_matrix_transform_point (const CoglMatrix *matrix,
float *x,
float *y,
float *z,
float *w);
G_END_DECLS G_END_DECLS
#endif /* __COGL_MATRIX_H */ #endif /* __COGL_MATRIX_H */

View File

@ -46,9 +46,12 @@ G_BEGIN_DECLS
* CoglShaderType: * CoglShaderType:
* @COGL_SHADER_TYPE_VERTEX: A program for proccessing vertices * @COGL_SHADER_TYPE_VERTEX: A program for proccessing vertices
* @COGL_SHADER_TYPE_FRAGMENT: A program for processing fragments * @COGL_SHADER_TYPE_FRAGMENT: A program for processing fragments
*
* Types of shaders
*
* Since: 1.0
*/ */
typedef enum _CoglShaderType typedef enum {
{
COGL_SHADER_TYPE_VERTEX, COGL_SHADER_TYPE_VERTEX,
COGL_SHADER_TYPE_FRAGMENT COGL_SHADER_TYPE_FRAGMENT
} CoglShaderType; } CoglShaderType;
@ -103,7 +106,7 @@ gboolean cogl_is_shader (CoglHandle handle);
* one. * one.
*/ */
void cogl_shader_source (CoglHandle shader, void cogl_shader_source (CoglHandle shader,
const char *source); const gchar *source);
/** /**
* cogl_shader_compile: * cogl_shader_compile:
* @handle: #CoglHandle for a shader. * @handle: #CoglHandle for a shader.
@ -111,29 +114,30 @@ void cogl_shader_source (CoglHandle shader,
* Compiles the shader, no return value, but the shader is now ready for * Compiles the shader, no return value, but the shader is now ready for
* linking into a program. * linking into a program.
*/ */
void cogl_shader_compile (CoglHandle handle); void cogl_shader_compile (CoglHandle handle);
/** /**
* cogl_shader_get_info_log: * cogl_shader_get_info_log:
* @handle: #CoglHandle for a shader. * @handle: #CoglHandle for a shader.
* @size: maximum number of bytes to retrieve.
* @buffer: location for info log.
* *
* Retrieves the information log for a coglobject, can be used in conjunction * Retrieves the information log for a coglobject, can be used in conjunction
* with #cogl_shader_get_parameteriv to retrieve the compiler warnings/error * with cogl_shader_get_parameteriv() to retrieve the compiler warnings/error
* messages that caused a shader to not compile correctly, mainly useful for * messages that caused a shader to not compile correctly, mainly useful for
* debugging purposes. * debugging purposes.
*
* Return value: a newly allocated string containing the info log. Use
* g_free() to free it
*/ */
void cogl_shader_get_info_log (CoglHandle handle, gchar * cogl_shader_get_info_log (CoglHandle handle);
size_t size,
char *buffer);
/** /**
* cogl_shader_get_type: * cogl_shader_get_type:
* @handle: #CoglHandle for a shader. * @handle: #CoglHandle for a shader.
* *
* Returns: COGL_SHADER_TYPE_VERTEX if the shader is a vertex processor * Retrieves the type of a shader #CoglHandle
* or COGL_SHADER_TYPE_FRAGMENT if the shader is a frament processor *
* Return value: %COGL_SHADER_TYPE_VERTEX if the shader is a vertex processor
* or %COGL_SHADER_TYPE_FRAGMENT if the shader is a frament processor
*/ */
CoglShaderType cogl_shader_get_type (CoglHandle handle); CoglShaderType cogl_shader_get_type (CoglHandle handle);
@ -141,7 +145,9 @@ CoglShaderType cogl_shader_get_type (CoglHandle handle);
* cogl_shader_is_compiled: * cogl_shader_is_compiled:
* @handle: #CoglHandle for a shader. * @handle: #CoglHandle for a shader.
* *
* Returns: TRUE if the shader object has sucessfully be compiled else FALSE * Retrieves whether a shader #CoglHandle has been compiled
*
* Return value: %TRUE if the shader object has sucessfully be compiled
*/ */
gboolean cogl_shader_is_compiled (CoglHandle handle); gboolean cogl_shader_is_compiled (CoglHandle handle);

View File

@ -41,12 +41,12 @@ G_BEGIN_DECLS
* loading and manipulating textures. * loading and manipulating textures.
*/ */
#define COGL_TEXTURE_MAX_WASTE 127
/** /**
* cogl_texture_new_with_size: * cogl_texture_new_with_size:
* @width: width of texture in pixels. * @width: width of texture in pixels.
* @height: height of texture in pixels. * @height: height of texture in pixels.
* @max_waste: maximum extra horizontal and|or vertical margin pixels
* to make the texture fit GPU limitations
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the * @internal_format: the #CoglPixelFormat to use for the GPU storage of the
* texture. * texture.
@ -60,15 +60,12 @@ G_BEGIN_DECLS
*/ */
CoglHandle cogl_texture_new_with_size (guint width, CoglHandle cogl_texture_new_with_size (guint width,
guint height, guint height,
gint max_waste,
CoglTextureFlags flags, CoglTextureFlags flags,
CoglPixelFormat internal_format); CoglPixelFormat internal_format);
/** /**
* cogl_texture_new_from_file: * cogl_texture_new_from_file:
* @filename: the file to load * @filename: the file to load
* @max_waste: maximum extra horizontal and|or vertical margin pixels
* to make the texture fit GPU limitations
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the * @internal_format: the #CoglPixelFormat to use for the GPU storage of the
* texture * texture
@ -82,7 +79,6 @@ CoglHandle cogl_texture_new_with_size (guint width,
* Since: 0.8 * Since: 0.8
*/ */
CoglHandle cogl_texture_new_from_file (const gchar *filename, CoglHandle cogl_texture_new_from_file (const gchar *filename,
gint max_waste,
CoglTextureFlags flags, CoglTextureFlags flags,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
GError **error); GError **error);
@ -91,8 +87,6 @@ CoglHandle cogl_texture_new_from_file (const gchar *filename,
* cogl_texture_new_from_data: * cogl_texture_new_from_data:
* @width: width of texture in pixels * @width: width of texture in pixels
* @height: height of texture in pixels * @height: height of texture in pixels
* @max_waste: maximum extra horizontal and|or vertical margin pixels
* to make the texture fit GPU limitations
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
* @format: the #CoglPixelFormat the buffer is stored in in RAM * @format: the #CoglPixelFormat the buffer is stored in in RAM
* @internal_format: the #CoglPixelFormat that will be used for storing * @internal_format: the #CoglPixelFormat that will be used for storing
@ -110,7 +104,6 @@ CoglHandle cogl_texture_new_from_file (const gchar *filename,
*/ */
CoglHandle cogl_texture_new_from_data (guint width, CoglHandle cogl_texture_new_from_data (guint width,
guint height, guint height,
gint max_waste,
CoglTextureFlags flags, CoglTextureFlags flags,
CoglPixelFormat format, CoglPixelFormat format,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
@ -136,19 +129,17 @@ CoglHandle cogl_texture_new_from_data (guint width,
* *
* Since: 0.8 * Since: 0.8
*/ */
CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle, CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle,
GLenum gl_target, GLenum gl_target,
GLuint width, GLuint width,
GLuint height, GLuint height,
GLuint x_pot_waste, GLuint x_pot_waste,
GLuint y_pot_waste, GLuint y_pot_waste,
CoglPixelFormat format); CoglPixelFormat format);
/** /**
* cogl_texture_new_from_bitmap: * cogl_texture_new_from_bitmap:
* @bmp_handle: A CoglBitmap handle * @bmp_handle: A CoglBitmap handle
* @max_waste: maximum extra horizontal and|or vertical margin pixels
* to make the texture fit GPU limitations
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the * @internal_format: the #CoglPixelFormat to use for the GPU storage of the
* texture * texture
@ -160,10 +151,9 @@ CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle,
* *
* Since: 1.0 * Since: 1.0
*/ */
CoglHandle cogl_texture_new_from_bitmap (CoglHandle bmp_handle, CoglHandle cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
gint max_waste, CoglTextureFlags flags,
CoglTextureFlags flags, CoglPixelFormat internal_format);
CoglPixelFormat internal_format);
/** /**
* cogl_is_texture: * cogl_is_texture:
@ -228,72 +218,6 @@ guint cogl_texture_get_rowstride (CoglHandle handle);
*/ */
gint cogl_texture_get_max_waste (CoglHandle handle); gint cogl_texture_get_max_waste (CoglHandle handle);
/**
* CoglTextureFilter:
* @COGL_TEXTURE_FILTER_NEAREST: Measuring in manhatten distance from the,
* current pixel center, use the nearest texture
* texel.
* @COGL_TEXTURE_FILTER_LINEAR: Use the weighted average of the 4 texels
* nearest the current pixel center.
* @COGL_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST: Select the mimap level whose
* texel size most closely matches
* the current pixel, and use the
* COGL_TEXTURE_FILTER_NEAREST
* criterion.
* @COGL_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST: Select the mimap level whose
* texel size most closely matches
* the current pixel, and use the
* COGL_TEXTURE_FILTER_LINEAR
* criterion.
* @COGL_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR: Select the two mimap levels
* whose texel size most closely
* matches the current pixel, use
* the COGL_TEXTURE_FILTER_NEAREST
* criterion on each one and take
* their weighted average.
* @COGL_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR: Select the two mimap levels
* whose texel size most closely
* matches the current pixel, use
* the COGL_TEXTURE_FILTER_LINEAR
* criterion on each one and take
* their weighted average.
*
* Texture filtering is used whenever the current pixel maps either to more
* than one texture element (texel) or less than one. These filter enums
* correspond to different strategies used to come up with a pixel color, by
* possibly referring to multiple neighbouring texels and taking a weighted
* average or simply using the nearest texel.
*/
typedef enum _CoglTextureFilter
{
COGL_TEXTURE_FILTER_NEAREST = GL_NEAREST,
COGL_TEXTURE_FILTER_LINEAR = GL_LINEAR,
COGL_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST,
COGL_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST,
COGL_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR,
COGL_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR
} CoglTextureFilter;
/**
* cogl_texture_get_min_filter:
* @handle: a #CoglHandle for a texture.
*
* Query the currently set downscaling filter for a cogl texture.
*
* Returns: the current downscaling filter for a cogl texture.
*/
CoglTextureFilter cogl_texture_get_min_filter (CoglHandle handle);
/**
* cogl_texture_get_mag_filter:
* @handle: a #CoglHandle for a texture.
*
* Query the currently set downscaling filter for a cogl texture.
*
* Returns: the current downscaling filter for a cogl texture.
*/
CoglTextureFilter cogl_texture_get_mag_filter (CoglHandle handle);
/** /**
* cogl_texture_is_sliced: * cogl_texture_is_sliced:
* @handle: a #CoglHandle for a texture. * @handle: a #CoglHandle for a texture.
@ -343,20 +267,6 @@ gint cogl_texture_get_data (CoglHandle handle,
guint rowstride, guint rowstride,
guchar *data); guchar *data);
/**
* cogl_texture_set_filters:
* @handle: a #CoglHandle.
* @min_filter: the filter used when scaling the texture down.
* @mag_filter: the filter used when magnifying the texture.
*
* Changes the decimation and interpolation filters used when the texture is
* drawn at other scales than 100%.
*/
void cogl_texture_set_filters (CoglHandle handle,
CoglTextureFilter min_filter,
CoglTextureFilter mag_filter);
/** /**
* cogl_texture_set_region: * cogl_texture_set_region:
* @handle: a #CoglHandle. * @handle: a #CoglHandle.

View File

@ -123,8 +123,7 @@ typedef struct _CoglTextureVertex CoglTextureVertex;
* *
* Since: 0.8 * Since: 0.8
*/ */
typedef enum typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
{
COGL_PIXEL_FORMAT_ANY = 0, COGL_PIXEL_FORMAT_ANY = 0,
COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT, COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT,
@ -135,60 +134,21 @@ typedef enum
COGL_PIXEL_FORMAT_G_8 = 8, COGL_PIXEL_FORMAT_G_8 = 8,
COGL_PIXEL_FORMAT_RGB_888 = COGL_PIXEL_FORMAT_24, COGL_PIXEL_FORMAT_RGB_888 = COGL_PIXEL_FORMAT_24,
COGL_PIXEL_FORMAT_BGR_888 = (COGL_PIXEL_FORMAT_24 | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_BGR_888 = (COGL_PIXEL_FORMAT_24 | COGL_PIXEL_FORMAT_RGBA_8888 = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT),
COGL_BGR_BIT), COGL_PIXEL_FORMAT_BGRA_8888 = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_ARGB_8888 = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_8888 = COGL_PIXEL_FORMAT_32 | COGL_PIXEL_FORMAT_ABGR_8888 = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
COGL_A_BIT,
COGL_PIXEL_FORMAT_BGRA_8888 = (COGL_PIXEL_FORMAT_32 |
COGL_A_BIT |
COGL_BGR_BIT),
COGL_PIXEL_FORMAT_ARGB_8888 = (COGL_PIXEL_FORMAT_32 |
COGL_A_BIT |
COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_ABGR_8888 = (COGL_PIXEL_FORMAT_32 |
COGL_A_BIT |
COGL_BGR_BIT |
COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_8888_PRE = (COGL_PIXEL_FORMAT_32 |
COGL_A_BIT |
COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_BGRA_8888_PRE = (COGL_PIXEL_FORMAT_32 |
COGL_A_BIT |
COGL_PREMULT_BIT |
COGL_BGR_BIT),
COGL_PIXEL_FORMAT_ARGB_8888_PRE = (COGL_PIXEL_FORMAT_32 |
COGL_A_BIT |
COGL_PREMULT_BIT |
COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_ABGR_8888_PRE = (COGL_PIXEL_FORMAT_32 |
COGL_A_BIT |
COGL_PREMULT_BIT |
COGL_BGR_BIT |
COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 |
COGL_A_BIT |
COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 |
COGL_A_BIT |
COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_RGBA_8888_PRE = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_BGRA_8888_PRE = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT),
COGL_PIXEL_FORMAT_ARGB_8888_PRE = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_ABGR_8888_PRE = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT),
} CoglPixelFormat; } CoglPixelFormat;
#define COGL_TYPE_PIXEL_FORMAT (cogl_pixel_format_get_type ())
GType cogl_pixel_format_get_type (void) G_GNUC_CONST;
/** /**
* CoglFeatureFlags: * CoglFeatureFlags:
* @COGL_FEATURE_TEXTURE_RECTANGLE: ARB_texture_rectangle support * @COGL_FEATURE_TEXTURE_RECTANGLE: ARB_texture_rectangle support
@ -222,9 +182,6 @@ typedef enum
COGL_FEATURE_VBOS = (1 << 11) COGL_FEATURE_VBOS = (1 << 11)
} CoglFeatureFlags; } CoglFeatureFlags;
#define COGL_TYPE_FEATURE_FLAGS (cogl_feature_flags_get_type ())
GType cogl_feature_flags_get_type (void) G_GNUC_CONST;
/** /**
* CoglBufferTarget: * CoglBufferTarget:
* @COGL_WINDOW_BUFFER: FIXME * @COGL_WINDOW_BUFFER: FIXME
@ -240,9 +197,6 @@ typedef enum
COGL_OFFSCREEN_BUFFER = (1 << 2) COGL_OFFSCREEN_BUFFER = (1 << 2)
} CoglBufferTarget; } CoglBufferTarget;
#define COGL_TYPE_BUFFER_TARGET (cogl_buffer_target_get_type ())
GType cogl_buffer_target_get_type (void) G_GNUC_CONST;
/** /**
* CoglColor: * CoglColor:
* *
@ -290,21 +244,23 @@ struct _CoglTextureVertex
/** /**
* CoglTextureFlags: * CoglTextureFlags:
* @COGL_TEXTURE_NONE: No flags specified * @COGL_TEXTURE_NONE: No flags specified
* @COGL_TEXTURE_AUTO_MIPMAP: Enables the automatic generation of the * @COGL_TEXTURE_NO_AUTO_MIPMAP: Disables the automatic generation of
* mipmap pyramid from the base level image whenever it is updated * the mipmap pyramid from the base level image whenever it is
* updated. The mipmaps are only generated when the texture is
* rendered with a mipmap filter so it should be free to leave out
* this flag when using other filtering modes.
* @COGL_TEXTURE_NO_SLICING: Disables the slicing of the texture
* *
* Flags to pass to the cogl_texture_new_* family of functions. * Flags to pass to the cogl_texture_new_* family of functions.
* *
* Since: 1.0 * Since: 1.0
*/ */
typedef enum { typedef enum {
COGL_TEXTURE_NONE = 0, COGL_TEXTURE_NONE = 0,
COGL_TEXTURE_AUTO_MIPMAP = 1 << 0 COGL_TEXTURE_NO_AUTO_MIPMAP = 1 << 0,
COGL_TEXTURE_NO_SLICING = 1 << 1
} CoglTextureFlags; } CoglTextureFlags;
#define COGL_TYPE_TEXTURE_FLAGS (cogl_texture_flags_get_type ())
GType cogl_texture_flags_get_type (void) G_GNUC_CONST;
/** /**
* CoglFogMode: * CoglFogMode:
* @COGL_FOG_MODE_LINEAR: Calculates the fog blend factor as: * @COGL_FOG_MODE_LINEAR: Calculates the fog blend factor as:
@ -333,16 +289,12 @@ GType cogl_texture_flags_get_type (void) G_GNUC_CONST;
* *
* Since: 1.0 * Since: 1.0
*/ */
typedef enum _CoglFogMode typedef enum {
{
COGL_FOG_MODE_LINEAR, COGL_FOG_MODE_LINEAR,
COGL_FOG_MODE_EXPONENTIAL, COGL_FOG_MODE_EXPONENTIAL,
COGL_FOG_MODE_EXPONENTIAL_SQUARED COGL_FOG_MODE_EXPONENTIAL_SQUARED
} CoglFogMode; } CoglFogMode;
#define COGL_TYPE_FOG_MODE (cogl_fog_mode_get_type ())
GType cogl_fog_mode_get_type (void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS
#endif /* __COGL_TYPES_H__ */ #endif /* __COGL_TYPES_H__ */

View File

@ -94,6 +94,29 @@ cogl_vertex_buffer_new (guint n_vertices);
guint guint
cogl_vertex_buffer_get_n_vertices (CoglHandle handle); cogl_vertex_buffer_get_n_vertices (CoglHandle handle);
/**
* CoglAttributeType:
* @COGL_ATTRIBUTE_TYPE_BYTE: Data is the same size of a byte
* @COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE: Data is the same size of an
* unsigned byte
* @COGL_ATTRIBUTE_TYPE_SHORT: Data is the same size of a short integer
* @COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT: Data is the same size of
* an unsigned short integer
* @COGL_ATTRIBUTE_TYPE_FLOAT: Data is the same size of a float
*
* Data types for the components of cogl_vertex_buffer_add()
*
* Since: 1.0
*/
typedef enum _CoglAttributeType
{
COGL_ATTRIBUTE_TYPE_BYTE = GL_BYTE,
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE = GL_UNSIGNED_BYTE,
COGL_ATTRIBUTE_TYPE_SHORT = GL_SHORT,
COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT = GL_UNSIGNED_SHORT,
COGL_ATTRIBUTE_TYPE_FLOAT = GL_FLOAT
} CoglAttributeType;
/** /**
* cogl_vertex_buffer_add: * cogl_vertex_buffer_add:
* @handle: A vertex buffer handle * @handle: A vertex buffer handle
@ -111,10 +134,9 @@ cogl_vertex_buffer_get_n_vertices (CoglHandle handle);
* the name can have a detail component, E.g. * the name can have a detail component, E.g.
* "gl_Color::active" or "gl_Color::inactive" * "gl_Color::active" or "gl_Color::inactive"
* @n_components: The number of components per attribute and must be 1,2,3 or 4 * @n_components: The number of components per attribute and must be 1,2,3 or 4
* @gl_type: Specifies the data type of each component (GL_BYTE, GL_UNSIGNED_BYTE, * @type: a #CoglAttributeType specifying the data type of each component.
* GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT or GL_FLOAT)
* @normalized: If GL_TRUE, this specifies that values stored in an integer * @normalized: If GL_TRUE, this specifies that values stored in an integer
* format should be mapped into the range [-1.0, 1.0] or [0.1, 1.0] * format should be mapped into the range [-1.0, 1.0] or [0.0, 1.0]
* for unsigned values. If GL_FALSE they are converted to floats * for unsigned values. If GL_FALSE they are converted to floats
* directly. * directly.
* @stride: This specifies the number of bytes from the start of one attribute * @stride: This specifies the number of bytes from the start of one attribute
@ -156,13 +178,13 @@ cogl_vertex_buffer_get_n_vertices (CoglHandle handle);
* (Though you can have multiple groups of interleved attributes) * (Though you can have multiple groups of interleved attributes)
*/ */
void void
cogl_vertex_buffer_add (CoglHandle handle, cogl_vertex_buffer_add (CoglHandle handle,
const char *attribute_name, const char *attribute_name,
guint8 n_components, guint8 n_components,
GLenum gl_type, CoglAttributeType type,
gboolean normalized, gboolean normalized,
guint16 stride, guint16 stride,
const void *pointer); const void *pointer);
/** /**
* cogl_vertex_buffer_delete: * cogl_vertex_buffer_delete:
@ -226,21 +248,37 @@ void
cogl_vertex_buffer_enable (CoglHandle handle, cogl_vertex_buffer_enable (CoglHandle handle,
const char *attribute_name); const char *attribute_name);
/**
* CoglVerticesMode:
* @COGL_VERTICES_MODE_POINTS: FIXME, equivalent to %GL_POINTS
* @COGL_VERTICES_MODE_LINE_STRIP: FIXME, equivalent to %GL_LINE_STRIP
* @COGL_VERTICES_MODE_LINE_LOOP: FIXME, equivalent to %GL_LINE_LOOP
* @COGL_VERTICES_MODE_LINES: FIXME, equivalent to %GL_LINES
* @COGL_VERTICES_MODE_TRIANGLE_STRIP: FIXME, equivalent to %GL_TRIANGLE_STRIP
* @COGL_VERTICES_MODE_TRIANGLE_FAN: FIXME, equivalent to %GL_TRIANGLE_FAN
* @COGL_VERTICES_MODE_TRIANGLES: FIXME, equivalent to %GL_TRIANGLES
*
* How vertices passed to cogl_vertex_buffer_draw() and
* cogl_vertex_buffer_draw_elements() should be interpreted
*
* Since: 1.0
*/
typedef enum _CoglVerticesMode
{
COGL_VERTICES_MODE_POINTS = GL_POINTS,
COGL_VERTICES_MODE_LINE_STRIP = GL_LINE_STRIP,
COGL_VERTICES_MODE_LINE_LOOP = GL_LINE_LOOP,
COGL_VERTICES_MODE_LINES = GL_LINES,
COGL_VERTICES_MODE_TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
COGL_VERTICES_MODE_TRIANGLE_FAN = GL_TRIANGLE_FAN,
COGL_VERTICES_MODE_TRIANGLES = GL_TRIANGLES
} CoglVerticesMode;
/** /**
* cogl_vertex_buffer_draw: * cogl_vertex_buffer_draw:
* @handle: A vertex buffer handle * @handle: A vertex buffer handle
* @mode: Specifies how the vertices should be interpreted, and should be * @mode: A #CoglVerticesMode specifying how the vertices should be
* a valid GL primitive type: * interpreted.
* <itemizedlist>
* <listitem>GL_POINTS</listitem>
* <listitem>GL_LINE_STRIP</listitem>
* <listitem>GL_LINE_LOOP</listitem>
* <listitem>GL_LINES</listitem>
* <listitem>GL_TRIANGLE_STRIP</listitem>
* <listitem>GL_TRIANGLE_FAN</listitem>
* <listitem>GL_TRIANGLES</listitem>
* </itemizedlist>
* (Note: only types available in GLES are listed)
* @first: Specifies the index of the first vertex you want to draw with * @first: Specifies the index of the first vertex you want to draw with
* @count: Specifies the number of vertices you want to draw. * @count: Specifies the number of vertices you want to draw.
* *
@ -251,52 +289,90 @@ cogl_vertex_buffer_enable (CoglHandle handle,
* drawing. * drawing.
*/ */
void void
cogl_vertex_buffer_draw (CoglHandle handle, cogl_vertex_buffer_draw (CoglHandle handle,
GLenum mode, CoglVerticesMode mode,
GLint first, int first,
GLsizei count); int count);
/**
* CoglIndicesType:
* @COGL_INDICES_TYPE_UNSIGNED_BYTE: Your indices are unsigned bytes
* @COGL_INDICES_TYPE_UNSIGNED_SHORT: Your indices are unsigned shorts
* @COGL_INDICES_TYPE_UNSIGNED_INT: You indices are unsigned integers
*
* You should aim to use the smallest data type that gives you enough
* range, since it reduces the size of your index array and can help
* reduce the demand on memory bandwidth.
*/
typedef enum _CoglIndicesType
{
COGL_INDICES_TYPE_UNSIGNED_BYTE,
COGL_INDICES_TYPE_UNSIGNED_SHORT,
COGL_INDICES_TYPE_UNSIGNED_INT
} CoglIndicesType;
/**
* cogl_vertex_buffer_indices_new:
* @indices_type: a #CoglIndicesType specifying the data type used for
* the indices.
* @indices_array: Specifies the address of your array of indices
* @indices_len: The number of indices in indices_array
*
* Depending on how much geometry you are submitting it can be worthwhile
* optimizing the number of redundant vertices you submit. Using an index
* array allows you to reference vertices multiple times, for example
* during triangle strips.
*
* Returns: A CoglHandle for the indices which you can pass to
* cogl_vertex_buffer_draw_elements().
*/
CoglHandle
cogl_vertex_buffer_indices_new (CoglIndicesType indices_type,
const void *indices_array,
int indices_len);
/**
* cogl_vertex_buffer_delete_indices:
* @handle: A vertex buffer handle
* @indices_id: The identifier for a an array of indices previously added to
* the given Cogl vertex buffer using
* cogl_vertex_buffer_add_indices().
*
* Frees the resources associated with a previously added array of vertex
* indices.
*/
void
cogl_vertex_buffer_delete_indices (CoglHandle handle,
int indices_id);
/** /**
* cogl_vertex_buffer_draw_elements: * cogl_vertex_buffer_draw_elements:
* @handle: A vertex buffer handle * @handle: A vertex buffer handle
* @mode: Specifies how the vertices should be interpreted, and should be * @mode: A #CoglVerticesMode specifying how the vertices should be
* a valid GL primitive type: * interpreted.
* <itemizedlist> * @indices: A CoglHandle for a set of indices allocated via
* <listitem>GL_POINTS</listitem> * cogl_vertex_buffer_indices_new ()
* <listitem>GL_LINE_STRIP</listitem>
* <listitem>GL_LINE_LOOP</listitem>
* <listitem>GL_LINES</listitem>
* <listitem>GL_TRIANGLE_STRIP</listitem>
* <listitem>GL_TRIANGLE_FAN</listitem>
* <listitem>GL_TRIANGLES</listitem>
* </itemizedlist>
* (Note: only types available in GLES are listed)
* @min_index: Specifies the minimum vertex index contained in indices * @min_index: Specifies the minimum vertex index contained in indices
* @max_index: Specifies the maximum vertex index contained in indices * @max_index: Specifies the maximum vertex index contained in indices
* @indices_offset: An offset into named indices. The offset marks the first
* index to use for drawing.
* @count: Specifies the number of vertices you want to draw. * @count: Specifies the number of vertices you want to draw.
* @indices_type: Specifies the data type used for the indices, and must be
* one of:
* <itemizedlist>
* <listitem>GL_UNSIGNED_BYTE</listitem>
* <listitem>GL_UNSIGNED_SHORT</listitem>
* <listitem>GL_UNSIGNED_INT</listitem>
* </itemizedlist>
* @indices: Specifies the address of your array of indices
* *
* This function lets you use an array of indices to specify the vertices * This function lets you use an array of indices to specify the vertices
* within your vertex buffer that you want to draw. * within your vertex buffer that you want to draw. The indices themselves
* are created by calling cogl_vertex_buffer_indices_new ()
* *
* Any un-submitted attribute changes are automatically submitted before * Any un-submitted attribute changes are automatically submitted before
* drawing. * drawing.
*/ */
void void
cogl_vertex_buffer_draw_elements (CoglHandle handle, cogl_vertex_buffer_draw_elements (CoglHandle handle,
GLenum mode, CoglVerticesMode mode,
GLuint min_index, CoglHandle indices,
GLuint max_index, int min_index,
GLsizei count, int max_index,
GLenum indices_type, int indices_offset,
const GLvoid *indices); int count);
/** /**
* cogl_vertex_buffer_ref: * cogl_vertex_buffer_ref:
@ -318,6 +394,46 @@ cogl_vertex_buffer_ref (CoglHandle handle);
void void
cogl_vertex_buffer_unref (CoglHandle handle); cogl_vertex_buffer_unref (CoglHandle handle);
/**
* cogl_vertex_buffer_indices_get_for_quads:
* @n_indices: the number of indices in the vertex buffer.
*
* Creates a vertex buffer containing the indices needed to draw pairs
* of triangles from a list of vertices grouped as quads. There will
* be at least @n_indices entries in the buffer (but there may be
* more).
*
* The indices will follow this pattern:
*
* 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7 ... etc
*
* For example, if you submit vertices for a quad like this:
*
* |[
* 0 3
* ########
* # #
* # #
* ########
* 1 2
* ]|
*
* Then you can request 6 indices to render two triangles like this:
*
* |[
* 0 0 3
* ## ########
* # ## ## #
* # ## ## #
* ######## ##
* 1 2 2
* ]|
*
* Returns: A %CoglHandle containing the indices. The handled is
* owned by Cogl and should not be modified or unref'd.
*/
CoglHandle
cogl_vertex_buffer_indices_get_for_quads (guint n_indices);
G_END_DECLS G_END_DECLS

125
cogl.h.in
View File

@ -45,6 +45,7 @@
#include <cogl/cogl-types.h> #include <cogl/cogl-types.h>
#include <cogl/cogl-debug.h> #include <cogl/cogl-debug.h>
#include <cogl/cogl-deprecated.h> #include <cogl/cogl-deprecated.h>
#include <cogl/cogl-enum-types.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -55,22 +56,6 @@ G_BEGIN_DECLS
* General utility functions for COGL. * General utility functions for COGL.
*/ */
/* Context manipulation */
/**
* cogl_create_context:
*
* FIXME
*/
gboolean cogl_create_context (void);
/**
* cogl_destroy_context:
*
* FIXME
*/
void cogl_destroy_context (void);
/** /**
* cogl_get_option_group: * cogl_get_option_group:
* *
@ -187,7 +172,30 @@ void cogl_frustum (float left,
float z_far); float z_far);
/** /**
* cogl_setup_viewport: * cogl_ortho:
* @left: The coordinate for the left clipping plane
* @right: The coordinate for the right clipping plane
* @bottom: The coordinate for the bottom clipping plane
* @top: The coordinate for the top clipping plane
* @near: The coordinate for the near clipping plane (may be negative if
* the plane is behind the viewer)
* @far: The coordinate for the far clipping plane (may be negative if
* the plane is behind the viewer)
*
* Replaces the current projection matrix with a parallel projection
* matrix.
*
* Since: 1.0
*/
void cogl_ortho (float left,
float right,
float bottom,
float top,
float near,
float far);
/*
* _cogl_setup_viewport:
* @width: Width of the viewport * @width: Width of the viewport
* @height: Height of the viewport * @height: Height of the viewport
* @fovy: Field of view angle in degrees * @fovy: Field of view angle in degrees
@ -201,9 +209,11 @@ void cogl_frustum (float left,
* with one that has a viewing angle of @fovy along the y-axis and a * with one that has a viewing angle of @fovy along the y-axis and a
* view scaled according to @aspect along the x-axis. The view is * view scaled according to @aspect along the x-axis. The view is
* clipped according to @z_near and @z_far on the z-axis. * clipped according to @z_near and @z_far on the z-axis.
*
* This function is used only by Clutter.
*/ */
void cogl_setup_viewport (guint width, void _cogl_setup_viewport (guint width,
guint height, guint height,
float fovy, float fovy,
float aspect, float aspect,
float z_near, float z_near,
@ -288,6 +298,14 @@ void cogl_rotate (float angle,
*/ */
void cogl_get_modelview_matrix (CoglMatrix *matrix); void cogl_get_modelview_matrix (CoglMatrix *matrix);
/**
* cogl_set_modelview_matrix:
* @matrix: pointer to a CoglMatrix to set as the new model-view matrix
*
* Loads matrix as the new model-view matrix.
*/
void cogl_set_modelview_matrix (CoglMatrix *matrix);
/** /**
* cogl_get_projection_matrix: * cogl_get_projection_matrix:
* @matrix: pointer to a CoglMatrix to recieve the matrix * @matrix: pointer to a CoglMatrix to recieve the matrix
@ -296,6 +314,14 @@ void cogl_get_modelview_matrix (CoglMatrix *matrix);
*/ */
void cogl_get_projection_matrix (CoglMatrix *matrix); void cogl_get_projection_matrix (CoglMatrix *matrix);
/**
* cogl_set_projection_matrix:
* @matrix: pointer to a CoglMatrix to set as the new projection matrix
*
* Loads matrix as the new projection matrix.
*/
void cogl_set_projection_matrix (CoglMatrix *matrix);
/** /**
* cogl_get_viewport: * cogl_get_viewport:
* @v: pointer to a 4 element array of #float<!-- -->s to * @v: pointer to a 4 element array of #float<!-- -->s to
@ -308,7 +334,7 @@ void cogl_get_projection_matrix (CoglMatrix *matrix);
void cogl_get_viewport (float v[4]); void cogl_get_viewport (float v[4]);
/** /**
* cogl_enable_depth_test: * cogl_set_depth_test_enable:
* @setting: %TRUE to enable depth testing or %FALSE to disable. * @setting: %TRUE to enable depth testing or %FALSE to disable.
* *
* Sets whether depth testing is enabled. If it is disabled then the * Sets whether depth testing is enabled. If it is disabled then the
@ -317,10 +343,19 @@ void cogl_get_viewport (float v[4]);
* clutter_actor_lower(), otherwise it will also take into account the * clutter_actor_lower(), otherwise it will also take into account the
* actor's depth. Depth testing is disabled by default. * actor's depth. Depth testing is disabled by default.
*/ */
void cogl_enable_depth_test (gboolean setting); void cogl_set_depth_test_enable (gboolean setting);
/** /**
* cogl_enable_backface_culling: * cogl_get_depth_test_enable:
*
* Queries if depth testing has been enabled via cogl_set_depth_test_enable()
*
* Returns: TRUE if depth testing is enabled else FALSE
*/
gboolean cogl_get_depth_test_enable (void);
/**
* cogl_set_backface_culling_enabled:
* @setting: %TRUE to enable backface culling or %FALSE to disable. * @setting: %TRUE to enable backface culling or %FALSE to disable.
* *
* Sets whether textures positioned so that their backface is showing * Sets whether textures positioned so that their backface is showing
@ -329,7 +364,17 @@ void cogl_enable_depth_test (gboolean setting);
* only affects calls to the cogl_rectangle* family of functions and * only affects calls to the cogl_rectangle* family of functions and
* cogl_vertex_buffer_draw*. Backface culling is disabled by default. * cogl_vertex_buffer_draw*. Backface culling is disabled by default.
*/ */
void cogl_enable_backface_culling (gboolean setting); void cogl_set_backface_culling_enabled (gboolean setting);
/**
* cogl_get_backface_culling_enabled:
*
* Queries if backface culling has been enabled via
* cogl_set_backface_culling_enabled()
*
* Returns: TRUE if backface culling is enabled else FALSE
*/
gboolean cogl_get_backface_culling_enabled (void);
/** /**
* cogl_set_fog: * cogl_set_fog:
@ -368,9 +413,12 @@ void cogl_disable_fog (void);
* @COGL_BUFFER_BIT_COLOR: Selects the primary color buffer * @COGL_BUFFER_BIT_COLOR: Selects the primary color buffer
* @COGL_BUFFER_BIT_DEPTH: Selects the depth buffer * @COGL_BUFFER_BIT_DEPTH: Selects the depth buffer
* @COGL_BUFFER_BIT_STENCIL: Selects the stencil buffer * @COGL_BUFFER_BIT_STENCIL: Selects the stencil buffer
*
* Types of auxiliary buffers
*
* Since: 1.0
*/ */
typedef enum _CoglBufferBit typedef enum {
{
COGL_BUFFER_BIT_COLOR = 1L<<0, COGL_BUFFER_BIT_COLOR = 1L<<0,
COGL_BUFFER_BIT_DEPTH = 1L<<1, COGL_BUFFER_BIT_DEPTH = 1L<<1,
COGL_BUFFER_BIT_STENCIL = 1L<<2 COGL_BUFFER_BIT_STENCIL = 1L<<2
@ -379,13 +427,14 @@ typedef enum _CoglBufferBit
/** /**
* cogl_clear: * cogl_clear:
* @color: Background color to clear to * @color: Background color to clear to
* @buffers: A mask of @CoglBufferBit<!-- -->'s identifying which auxiliary * @buffers: A mask of #CoglBufferBit<!-- -->'s identifying which auxiliary
* buffers to clear * buffers to clear
* *
* Clears all the auxiliary buffers identified in the @buffers mask, and if * Clears all the auxiliary buffers identified in the @buffers mask, and if
* that includes the color buffer then the specified @color is used. * that includes the color buffer then the specified @color is used.
*/ */
void cogl_clear (const CoglColor *color, gulong buffers); void cogl_clear (const CoglColor *color,
gulong buffers);
/** /**
* cogl_set_source: * cogl_set_source:
@ -628,7 +677,24 @@ void cogl_push_draw_buffer (void);
*/ */
void cogl_pop_draw_buffer (void); void cogl_pop_draw_buffer (void);
/**
/*
* Internal API available only to Clutter.
*
* These are typically only to deal with the poor seperation of
* responsabilities that currently exists between Clutter and Cogl.
* Eventually a lot of the backend code currently in Clutter will
* move down into Cogl and these functions will be removed.
*/
void _cogl_destroy_context (void);
/* XXX: Removed before we release Clutter 1.0 since the implementation
* wasn't complete, and so we assume no one is using this yet. Util we
* have some one with a good usecase, we can't pretend to support breaking
* out into raw OpenGL. */
#if 0
/*
* cogl_flush_gl_state: * cogl_flush_gl_state:
* @flags: flags controlling what is flushed; currently unused, pass in 0 * @flags: flags controlling what is flushed; currently unused, pass in 0
* *
@ -642,6 +708,7 @@ void cogl_pop_draw_buffer (void);
* Since: 1.0 * Since: 1.0
*/ */
void cogl_flush_gl_state (int flags); void cogl_flush_gl_state (int flags);
#endif
/* private */ /* private */
void _cogl_set_indirect_context (gboolean indirect); void _cogl_set_indirect_context (gboolean indirect);

View File

@ -1,3 +1,10 @@
NULL =
V = @
Q = $(V:1=)
QUIET_GEN = $(Q:@=@echo ' GEN '$@;)
QUIET_CP = $(Q:@=@echo ' CP '$@;)
INCLUDES = \ INCLUDES = \
-I$(top_srcdir) \ -I$(top_srcdir) \
-I$(top_srcdir)/clutter \ -I$(top_srcdir)/clutter \
@ -9,12 +16,49 @@ INCLUDES = \
-DG_LOG_DOMAIN=\"Cogl-Common\" \ -DG_LOG_DOMAIN=\"Cogl-Common\" \
-DCLUTTER_COMPILATION -DCLUTTER_COMPILATION
cogl_public_h = \
$(top_srcdir)/clutter/cogl/cogl-bitmap.h \
$(top_srcdir)/clutter/cogl/cogl-color.h \
$(top_srcdir)/clutter/cogl/cogl-debug.h \
$(top_srcdir)/clutter/cogl/cogl-fixed.h \
$(top_srcdir)/clutter/cogl/cogl-material.h \
$(top_srcdir)/clutter/cogl/cogl-matrix.h \
$(top_srcdir)/clutter/cogl/cogl-offscreen.h \
$(top_srcdir)/clutter/cogl/cogl-path.h \
$(top_srcdir)/clutter/cogl/cogl-shader.h \
$(top_srcdir)/clutter/cogl/cogl-texture.h \
$(top_srcdir)/clutter/cogl/cogl-types.h \
$(top_srcdir)/clutter/cogl/cogl-vertex-buffer.h \
$(top_builddir)/clutter/cogl/cogl.h \
$(NULL)
noinst_LTLIBRARIES = libclutter-cogl-common.la noinst_LTLIBRARIES = libclutter-cogl-common.la
EXTRA_DIST = stb_image.c
cogl-enum-types.h: stamp-cogl-enum-types.h
@true
stamp-cogl-enum-types.h: $(cogl_public_h) Makefile
$(QUIET_GEN)( $(GLIB_MKENUMS) \
--template $(srcdir)/cogl-enum-types.h.in \
$(cogl_public_h) ) > xgen-ceth \
&& (cmp -s xgen-ceth cogl-enum-types.h || cp -f xgen-ceth cogl-enum-types.h) \
&& cp -f cogl-enum-types.h $(top_builddir)/clutter/cogl/cogl-enum-types.h \
&& rm -f xgen-ceth \
&& echo timestamp > $(@F)
cogl-enum-types.c: cogl-enum-types.h
$(QUIET_GEN)( $(GLIB_MKENUMS) \
--template $(srcdir)/cogl-enum-types.c.in \
$(cogl_public_h) ) > xgen-cetc \
&& cp -f xgen-cetc cogl-enum-types.c \
&& rm -f xgen-cetc
BUILT_SOURCES = cogl-enum-types.h cogl-enum-types.c
libclutter_cogl_common_la_CPPFLAGS = $(CLUTTER_CFLAGS) $(COGL_DEBUG_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS) libclutter_cogl_common_la_CPPFLAGS = $(CLUTTER_CFLAGS) $(COGL_DEBUG_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS)
libclutter_cogl_common_la_LIBADD = -lm $(CLUTTER_LIBS) libclutter_cogl_common_la_LIBADD = -lm $(CLUTTER_LIBS)
libclutter_cogl_common_la_SOURCES = \ libclutter_cogl_common_la_SOURCES = \
$(top_builddir)/clutter/cogl/common/cogl-enum-types.h \
$(top_builddir)/clutter/cogl/common/cogl-enum-types.c \
cogl-handle.h \ cogl-handle.h \
cogl-internal.h \ cogl-internal.h \
cogl.c \ cogl.c \
@ -39,4 +83,11 @@ libclutter_cogl_common_la_SOURCES = \
cogl-matrix-stack.h \ cogl-matrix-stack.h \
cogl-material.c \ cogl-material.c \
cogl-material-private.h \ cogl-material-private.h \
cogl-debug.c cogl-blend-string.c \
cogl-blend-string.h \
cogl-debug.c \
$(NULL)
EXTRA_DIST = stb_image.c cogl-enum-types.h.in cogl-enum-types.c.in
CLEANFILES = stamp-cogl-enum-types.h
DISTCLEANFILES = cogl-enum-types.h cogl-enum-types.c

999
common/cogl-blend-string.c Normal file
View File

@ -0,0 +1,999 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "cogl.h"
#include "cogl-internal.h"
#include "cogl-context.h"
#include "cogl-debug.h"
#include "cogl-blend-string.h"
typedef enum _ParserState
{
PARSER_STATE_EXPECT_DEST_CHANNELS,
PARSER_STATE_SCRAPING_DEST_CHANNELS,
PARSER_STATE_EXPECT_FUNCTION_NAME,
PARSER_STATE_SCRAPING_FUNCTION_NAME,
PARSER_STATE_EXPECT_ARG_START,
PARSER_STATE_EXPECT_STATEMENT_END
} ParserState;
typedef enum _ParserArgState
{
PARSER_ARG_STATE_START,
PARSER_ARG_STATE_EXPECT_MINUS,
PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME,
PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME,
PARSER_ARG_STATE_MAYBE_COLOR_MASK,
PARSER_ARG_STATE_SCRAPING_MASK,
PARSER_ARG_STATE_MAYBE_MULT,
PARSER_ARG_STATE_EXPECT_OPEN_PAREN,
PARSER_ARG_STATE_EXPECT_FACTOR,
PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE,
PARSER_ARG_STATE_MAYBE_MINUS,
PARSER_ARG_STATE_EXPECT_CLOSE_PAREN,
PARSER_ARG_STATE_EXPECT_END
} ParserArgState;
#define DEFINE_COLOR_SOURCE(NAME, NAME_LEN) \
{.type = COGL_BLEND_STRING_COLOR_SOURCE_ ## NAME, \
.name = #NAME, \
.name_len = NAME_LEN}
static CoglBlendStringColorSourceInfo blending_color_sources[] = {
DEFINE_COLOR_SOURCE (SRC_COLOR, 9),
DEFINE_COLOR_SOURCE (DST_COLOR, 9),
DEFINE_COLOR_SOURCE (CONSTANT, 8)
};
static CoglBlendStringColorSourceInfo tex_combine_color_sources[] = {
DEFINE_COLOR_SOURCE (TEXTURE, 7),
/* DEFINE_COLOR_SOURCE (TEXTURE_N, *) - handled manually */
DEFINE_COLOR_SOURCE (PRIMARY, 7),
DEFINE_COLOR_SOURCE (CONSTANT, 8),
DEFINE_COLOR_SOURCE (PREVIOUS, 8)
};
static CoglBlendStringColorSourceInfo tex_combine_texture_n_color_source = {
.type = COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N,
.name = "TEXTURE_N",
.name_len = 0
};
#undef DEFINE_COLOR_SOURCE
#define DEFINE_FUNCTION(NAME, NAME_LEN, ARGC) \
{ .type = COGL_BLEND_STRING_FUNCTION_ ## NAME, \
.name = #NAME, \
.name_len = NAME_LEN, \
.argc = ARGC }
/* NB: These must be sorted so any name that's a subset of another
* comes later than the longer name. */
static CoglBlendStringFunctionInfo tex_combine_functions[] = {
DEFINE_FUNCTION (AUTO_COMPOSITE, 14, 0),
DEFINE_FUNCTION (REPLACE, 7, 1),
DEFINE_FUNCTION (MODULATE, 8, 2),
DEFINE_FUNCTION (ADD_SIGNED, 10, 2),
DEFINE_FUNCTION (ADD, 3, 2),
DEFINE_FUNCTION (INTERPOLATE, 11, 3),
DEFINE_FUNCTION (SUBTRACT, 8, 2),
DEFINE_FUNCTION (DOT3_RGBA, 9, 2),
DEFINE_FUNCTION (DOT3_RGB, 8, 2)
};
static CoglBlendStringFunctionInfo blend_functions[] = {
DEFINE_FUNCTION (AUTO_COMPOSITE, 14, 0),
DEFINE_FUNCTION (ADD, 3, 2)
};
#undef DEFINE_FUNCTION
GQuark
_cogl_blend_string_error_quark (void)
{
return g_quark_from_static_string ("cogl-blend-string-error-quark");
}
void
_cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement,
CoglBlendStringStatement *rgb,
CoglBlendStringStatement *a)
{
int i;
memcpy (rgb, statement, sizeof (CoglBlendStringStatement));
memcpy (a, statement, sizeof (CoglBlendStringStatement));
rgb->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB;
a->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA;
for (i = 0; i < statement->function->argc; i++)
{
CoglBlendStringArgument *arg = &statement->args[i];
CoglBlendStringArgument *rgb_arg = &rgb->args[i];
CoglBlendStringArgument *a_arg = &a->args[i];
if (arg->source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA)
{
rgb_arg->source.mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB;
a_arg->source.mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA;
}
if (arg->factor.is_color &&
arg->factor.source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA)
{
rgb_arg->factor.source.mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB;
a_arg->factor.source.mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA;
}
}
}
static gboolean
validate_tex_combine_statements (CoglBlendStringStatement *statements,
int n_statements,
GError **error)
{
int i, j;
const char *error_string;
CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR;
for (i = 0; i < n_statements; i++)
{
#ifdef HAVE_COGL_GLES2
if (statements[i].function->type != COGL_BLEND_STRING_FUNCTION_MODULATE)
{
error_string = "Using anything but MODULATE() for texture combining"
" under GLES 2 is currently unsupported";
detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR;
goto error;
}
#endif
for (j = 0; j < statements[i].function->argc; j++)
{
CoglBlendStringArgument *arg = &statements[i].args[j];
if (arg->source.is_zero)
{
error_string = "You can't use the constant '0' as a texture "
"combine argument";
goto error;
}
if (!arg->factor.is_one)
{
error_string = "Argument factors are only relevant to blending "
"not texture combining";
goto error;
}
#ifdef HAVE_COGL_GLES2
if (arg->source.info->type == COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT)
{
error_string = "Using a constant for texture combining isn't "
"currently supported with GLES 2 "
"(TODO: glTexEnvf)";
detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR;
goto error;
}
#endif
}
}
return TRUE;
error:
g_set_error (error,
COGL_BLEND_STRING_ERROR,
detail,
"Invalid texture combine string: %s",
error_string);
if (cogl_debug_flags & COGL_DEBUG_BLEND_STRINGS)
{
g_debug ("Invalid texture combine string: %s",
error_string);
}
return FALSE;
}
static gboolean
validate_blend_statements (CoglBlendStringStatement *statements,
int n_statements,
GError **error)
{
int i, j;
const char *error_string;
CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR;
#ifdef HAVE_COGL_GL
_COGL_GET_CONTEXT (ctx, 0);
#endif
#ifdef HAVE_COGL_GL
if (n_statements == 2)
{
/* glBlendEquationSeperate is GL 2.0 only */
if (!ctx->pf_glBlendEquationSeparate &&
statements[0].function->type != statements[1].function->type)
{
error_string = "Separate blend functions for the RGB an A "
"channels isn't supported by the driver";
detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR;
goto error;
}
}
#elif defined(HAVE_COGL_GLES)
if (n_statements != 1)
{
error_string = "Separate blend functions for the RGB an A "
"channels isn't supported by the GLES 1";
detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR;
goto error;
}
#endif
for (i = 0; i < n_statements; i++)
for (j = 0; j < statements[i].function->argc; j++)
{
CoglBlendStringArgument *arg = &statements[i].args[j];
if (arg->source.is_zero)
continue;
if ((j == 0 &&
arg->source.info->type !=
COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR)
|| (j == 1 &&
arg->source.info->type !=
COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR))
{
error_string = "For blending you must always use SRC_COLOR "
"for arg0 and DST_COLOR for arg1";
goto error;
}
#ifdef HAVE_COGL_GLES
if (arg->factor.is_color &&
arg->factor.source.info->type == COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT)
{
error_string = "GLES Doesn't support constant blend factors";
detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR;
goto error;
}
#endif
}
return TRUE;
error:
g_set_error (error,
COGL_BLEND_STRING_ERROR,
detail,
"Invalid blend string: %s",
error_string);
return FALSE;
}
static gboolean
validate_statements_for_context (CoglBlendStringStatement *statements,
int n_statements,
CoglBlendStringContext context,
GError **error)
{
const char *error_string;
if (n_statements == 1)
{
if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_ALPHA)
{
error_string = "You need to also give a blend statement for the RGB"
"channels";
goto error;
}
else if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB)
{
error_string = "You need to also give a blend statement for the "
"Alpha channel";
goto error;
}
}
if (context == COGL_BLEND_STRING_CONTEXT_BLENDING)
return validate_blend_statements (statements, n_statements, error);
else
return validate_tex_combine_statements (statements, n_statements, error);
error:
g_set_error (error,
COGL_BLEND_STRING_ERROR,
COGL_BLEND_STRING_ERROR_INVALID_ERROR,
"Invalid %s string: %s",
context == COGL_BLEND_STRING_CONTEXT_BLENDING ?
"blend" : "texture combine",
error_string);
if (cogl_debug_flags & COGL_DEBUG_BLEND_STRINGS)
{
g_debug ("Invalid %s string: %s",
context == COGL_BLEND_STRING_CONTEXT_BLENDING ?
"blend" : "texture combine",
error_string);
}
return FALSE;
}
static void
print_argument (CoglBlendStringArgument *arg)
{
const char *mask_names[] = {
"RGB",
"A",
"RGBA"
};
g_print (" Arg:\n");
g_print (" is zero = %s\n", arg->source.is_zero ? "yes" : "no");
if (!arg->source.is_zero)
{
g_print (" color source = %s\n", arg->source.info->name);
g_print (" one minus = %s\n", arg->source.one_minus ? "yes" : "no");
g_print (" mask = %s\n", mask_names[arg->source.mask]);
g_print (" texture = %d\n", arg->source.texture);
g_print ("\n");
g_print (" factor is_one = %s\n", arg->factor.is_one ? "yes" : "no");
g_print (" factor is_src_alpha_saturate = %s\n",
arg->factor.is_src_alpha_saturate ? "yes" : "no");
g_print (" factor is_color = %s\n", arg->factor.is_color ? "yes" : "no");
if (arg->factor.is_color)
{
g_print (" factor color:is zero = %s\n",
arg->factor.source.is_zero ? "yes" : "no");
g_print (" factor color:color source = %s\n",
arg->factor.source.info->name);
g_print (" factor color:one minus = %s\n",
arg->factor.source.one_minus ? "yes" : "no");
g_print (" factor color:mask = %s\n",
mask_names[arg->factor.source.mask]);
g_print (" factor color:texture = %d\n",
arg->factor.source.texture);
}
}
}
static void
print_statement (int num, CoglBlendStringStatement *statement)
{
const char *mask_names[] = {
"RGB",
"A",
"RGBA"
};
int i;
g_print ("Statement %d:\n", num);
g_print (" Destination channel mask = %s\n",
mask_names[statement->mask]);
g_print (" Function = %s\n", statement->function->name);
for (i = 0; i < statement->function->argc; i++)
print_argument (&statement->args[i]);
}
static const CoglBlendStringFunctionInfo *
get_function_info (const char *mark,
const char *p,
CoglBlendStringContext context)
{
size_t len = p - mark;
CoglBlendStringFunctionInfo *functions;
size_t array_len;
int i;
if (context == COGL_BLEND_STRING_CONTEXT_BLENDING)
{
functions = blend_functions;
array_len = G_N_ELEMENTS (blend_functions);
}
else
{
functions = tex_combine_functions;
array_len = G_N_ELEMENTS (tex_combine_functions);
}
for (i = 0; i < array_len; i++)
{
if (len >= functions[i].name_len
&& strncmp (mark, functions[i].name, functions[i].name_len) == 0)
return &functions[i];
}
return NULL;
}
static const CoglBlendStringColorSourceInfo *
get_color_src_info (const char *mark,
const char *p,
CoglBlendStringContext context)
{
size_t len = p - mark;
CoglBlendStringColorSourceInfo *sources;
size_t array_len;
int i;
if (context == COGL_BLEND_STRING_CONTEXT_BLENDING)
{
sources = blending_color_sources;
array_len = G_N_ELEMENTS (blending_color_sources);
}
else
{
sources = tex_combine_color_sources;
array_len = G_N_ELEMENTS (tex_combine_color_sources);
}
for (i = 0; i < array_len; i++)
{
if (len >= sources[i].name_len
&& strncmp (mark, sources[i].name, sources[i].name_len) == 0)
return &sources[i];
}
if (len >= 9 &&
strncmp (mark, "TEXTURE_", 8) == 0 &&
g_ascii_isdigit (mark[8]))
{
return &tex_combine_texture_n_color_source;
}
return NULL;
}
static gboolean
is_symbol_char (const char c)
{
return (g_ascii_isalpha (c) || c == '_') ? TRUE : FALSE;
}
static gboolean
parse_argument (const char *string, /* original user string */
const char **ret_p, /* start of argument IN:OUT */
const CoglBlendStringStatement *statement,
int current_arg,
CoglBlendStringArgument *arg, /* OUT */
CoglBlendStringContext context,
GError **error)
{
const char *p = *ret_p;
const char *mark;
const char *error_string;
ParserArgState state = PARSER_ARG_STATE_START;
gboolean parsing_factor = FALSE;
arg->source.is_zero = FALSE;
arg->source.info = NULL;
arg->source.texture = 0;
arg->source.one_minus = FALSE;
arg->source.mask = statement->mask;
arg->factor.is_one = FALSE;
arg->factor.is_color = FALSE;
arg->factor.is_src_alpha_saturate = FALSE;
arg->factor.source.is_zero = FALSE;
arg->factor.source.info = NULL;
arg->factor.source.texture = 0;
arg->factor.source.one_minus = FALSE;
arg->factor.source.mask = statement->mask;
do
{
if (g_ascii_isspace (*p))
continue;
if (*p == '\0')
{
error_string = "Unexpected end of string while parsing argument";
goto error;
}
switch (state)
{
case PARSER_ARG_STATE_START:
if (*p == '1')
state = PARSER_ARG_STATE_EXPECT_MINUS;
else if (*p == '0')
{
arg->source.is_zero = TRUE;
state = PARSER_ARG_STATE_EXPECT_END;
}
else
{
p--; /* backtrack */
state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME;
}
continue;
case PARSER_ARG_STATE_EXPECT_MINUS:
if (*p != '-')
{
error_string = "expected a '-' following the 1";
goto error;
}
arg->source.one_minus = TRUE;
state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME;
continue;
case PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME:
if (!is_symbol_char (*p))
{
error_string = "expected a color source name";
goto error;
}
state = PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME;
mark = p;
if (parsing_factor)
arg->factor.is_color = TRUE;
/* fall through */
case PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME:
if (!is_symbol_char (*p))
{
CoglBlendStringColorSource *source =
parsing_factor ? &arg->factor.source : &arg->source;
source->info = get_color_src_info (mark, p, context);
if (!source->info)
{
error_string = "Unknown color source name";
goto error;
}
if (source->info->type ==
COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N)
{
char *endp;
source->texture =
strtoul (&mark[strlen ("TEXTURE_")], &endp, 10);
if (mark == endp)
{
error_string = "invalid texture number given with "
"TEXTURE_N color source";
goto error;
}
p = endp;
}
state = PARSER_ARG_STATE_MAYBE_COLOR_MASK;
}
else
continue;
/* fall through */
case PARSER_ARG_STATE_MAYBE_COLOR_MASK:
if (*p != '[')
{
p--; /* backtrack */
if (!parsing_factor)
state = PARSER_ARG_STATE_MAYBE_MULT;
else
state = PARSER_ARG_STATE_EXPECT_END;
continue;
}
state = PARSER_ARG_STATE_SCRAPING_MASK;
mark = p;
/* fall through */
case PARSER_ARG_STATE_SCRAPING_MASK:
if (*p == ']')
{
size_t len = p - mark;
CoglBlendStringColorSource *source =
parsing_factor ? &arg->factor.source : &arg->source;
if (len == 5 && strncmp (mark, "[RGBA", len) == 0)
{
if (statement->mask != COGL_BLEND_STRING_CHANNEL_MASK_RGBA)
{
error_string = "You can't use an RGBA color mask if the "
"statement hasn't also got an RGBA= mask";
goto error;
}
source->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGBA;
}
else if (len == 4 && strncmp (mark, "[RGB", len) == 0)
source->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB;
else if (len == 2 && strncmp (mark, "[A", len) == 0)
source->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA;
else
{
error_string = "Expected a channel mask of [RGBA]"
"[RGB] or [A]";
goto error;
}
if (parsing_factor)
state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN;
else
state = PARSER_ARG_STATE_MAYBE_MULT;
}
continue;
case PARSER_ARG_STATE_EXPECT_OPEN_PAREN:
if (*p != '(')
{
error_string = "Expected '(' before blend factor - the parser "
"currently requires that all blend factors "
"following a '*' be surrounded in brackets";
goto error;
}
parsing_factor = TRUE;
state = PARSER_ARG_STATE_EXPECT_FACTOR;
continue;
case PARSER_ARG_STATE_EXPECT_FACTOR:
if (*p == '1')
state = PARSER_ARG_STATE_MAYBE_MINUS;
else if (*p == '0')
{
arg->source.is_zero = TRUE;
state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN;
}
else
{
state = PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE;
mark = p;
}
continue;
case PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE:
if (!is_symbol_char (*p))
{
size_t len = p - mark;
if (len >= strlen ("SRC_ALPHA_SATURATE") &&
strncmp (mark, "SRC_ALPHA_SATURATE", len) == 0)
{
arg->factor.is_src_alpha_saturate = TRUE;
state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN;
}
else
{
state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME;
p = mark - 1; /* backtrack */
}
}
continue;
case PARSER_ARG_STATE_MAYBE_MINUS:
if (*p == '-')
{
arg->factor.source.one_minus = TRUE;
state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME;
}
else
{
arg->factor.is_one = TRUE;
state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN;
}
continue;
case PARSER_ARG_STATE_EXPECT_CLOSE_PAREN:
if (*p != ')')
{
error_string = "Expected closing parenthesis after blend factor";
goto error;
}
state = PARSER_ARG_STATE_EXPECT_END;
continue;
case PARSER_ARG_STATE_MAYBE_MULT:
if (*p == '*')
{
state = PARSER_ARG_STATE_EXPECT_OPEN_PAREN;
continue;
}
arg->factor.is_one = TRUE;
state = PARSER_ARG_STATE_EXPECT_END;
/* fall through */
case PARSER_ARG_STATE_EXPECT_END:
if (*p != ',' && *p != ')')
{
error_string = "expected , or )";
goto error;
}
*ret_p = p - 1;
return TRUE;
}
}
while (p++);
error:
{
int offset = p - string;
g_set_error (error,
COGL_BLEND_STRING_ERROR,
COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR,
"Syntax error for argument %d at offset %d: %s",
current_arg,
offset,
error_string);
if (cogl_debug_flags & COGL_DEBUG_BLEND_STRINGS)
{
g_debug ("Syntax error for argument %d at offset %d: %s",
current_arg, offset, error_string);
}
return FALSE;
}
}
int
_cogl_blend_string_compile (const char *string,
CoglBlendStringContext context,
CoglBlendStringStatement *statements,
GError **error)
{
const char *p = string;
const char *mark;
const char *error_string;
ParserState state = PARSER_STATE_EXPECT_DEST_CHANNELS;
CoglBlendStringStatement *statement = statements;
int current_statement = 0;
int current_arg = 0;
int remaining_argc;
#if 0
cogl_debug_flags |= COGL_DEBUG_BLEND_STRINGS;
#endif
if (cogl_debug_flags & COGL_DEBUG_BLEND_STRINGS)
{
COGL_NOTE (BLEND_STRINGS, "Compiling %s string:\n%s\n",
context == COGL_BLEND_STRING_CONTEXT_BLENDING ?
"blend" : "texture combine",
string);
}
do
{
if (g_ascii_isspace (*p))
continue;
if (*p == '\0')
{
switch (state)
{
case PARSER_STATE_EXPECT_DEST_CHANNELS:
if (current_statement != 0)
goto finished;
error_string = "Empty statement";
goto error;
case PARSER_STATE_SCRAPING_DEST_CHANNELS:
error_string = "Expected an '=' following the destination "
"channel mask";
goto error;
case PARSER_STATE_EXPECT_FUNCTION_NAME:
error_string = "Expected a function name";
goto error;
case PARSER_STATE_SCRAPING_FUNCTION_NAME:
error_string = "Expected parenthesis after the function name";
goto error;
case PARSER_STATE_EXPECT_ARG_START:
error_string = "Expected to find the start of an argument";
goto error;
case PARSER_STATE_EXPECT_STATEMENT_END:
error_string = "Expected closing parenthesis for statement";
goto error;
}
}
switch (state)
{
case PARSER_STATE_EXPECT_DEST_CHANNELS:
mark = p;
state = PARSER_STATE_SCRAPING_DEST_CHANNELS;
/* fall through */
case PARSER_STATE_SCRAPING_DEST_CHANNELS:
if (*p != '=')
continue;
if (strncmp (mark, "RGBA", 4) == 0)
statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGBA;
else if (strncmp (mark, "RGB", 3) == 0)
statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB;
else if (strncmp (mark, "A", 1) == 0)
statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA;
else
{
error_string = "Unknown destination channel mask; "
"expected RGBA=, RGB= or A=";
goto error;
}
state = PARSER_STATE_EXPECT_FUNCTION_NAME;
continue;
case PARSER_STATE_EXPECT_FUNCTION_NAME:
mark = p;
state = PARSER_STATE_SCRAPING_FUNCTION_NAME;
/* fall through */
case PARSER_STATE_SCRAPING_FUNCTION_NAME:
if (*p != '(')
{
if (!is_symbol_char (*p))
{
error_string = "non alpha numeric character in function"
"name";
goto error;
}
continue;
}
statement->function = get_function_info (mark, p, context);
if (!statement->function)
{
error_string = "Unknown function name";
goto error;
}
remaining_argc = statement->function->argc;
current_arg = 0;
state = PARSER_STATE_EXPECT_ARG_START;
/* fall through */
case PARSER_STATE_EXPECT_ARG_START:
if (*p != '(' && *p != ',')
continue;
if (remaining_argc)
{
p++; /* parse_argument expects to see the first char of the arg */
if (!parse_argument (string, &p, statement,
current_arg, &statement->args[current_arg],
context, error))
return 0;
current_arg++;
remaining_argc--;
}
if (!remaining_argc)
state = PARSER_STATE_EXPECT_STATEMENT_END;
continue;
case PARSER_STATE_EXPECT_STATEMENT_END:
if (*p != ')')
{
error_string = "Expected end of statement";
goto error;
}
state = PARSER_STATE_EXPECT_DEST_CHANNELS;
if (current_statement++ == 1)
goto finished;
statement = &statements[current_statement];
}
}
while (p++);
finished:
if (cogl_debug_flags & COGL_DEBUG_BLEND_STRINGS)
{
if (current_statement > 0)
print_statement (0, &statements[0]);
if (current_statement > 1)
print_statement (1, &statements[1]);
}
if (!validate_statements_for_context (statements,
current_statement,
context,
error))
return 0;
return current_statement;
error:
{
int offset = p - string;
g_set_error (error,
COGL_BLEND_STRING_ERROR,
COGL_BLEND_STRING_ERROR_PARSE_ERROR,
"Syntax error at offset %d: %s",
offset,
error_string);
if (cogl_debug_flags & COGL_DEBUG_BLEND_STRINGS)
{
g_debug ("Syntax error at offset %d: %s",
offset, error_string);
}
return 0;
}
}
/*
* INTERNAL TESTING CODE ...
*/
struct _TestString
{
const char *string;
CoglBlendStringContext context;
};
int
_cogl_blend_string_test (void)
{
struct _TestString strings[] = {
{" A = MODULATE ( TEXTURE[RGB], PREVIOUS[A], PREVIOUS[A] ) ",
COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE },
{" RGB = MODULATE ( TEXTURE[RGB], PREVIOUS[A] ) ",
COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE },
{"A=ADD(TEXTURE[A],PREVIOUS[RGB])",
COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE },
{"A=ADD(TEXTURE[A],PREVIOUS[RGB])",
COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE },
{"RGBA = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))",
COGL_BLEND_STRING_CONTEXT_BLENDING },
{"RGB = ADD(SRC_COLOR, DST_COLOR*(0))",
COGL_BLEND_STRING_CONTEXT_BLENDING },
{"RGB = ADD(SRC_COLOR, 0)",
COGL_BLEND_STRING_CONTEXT_BLENDING },
{"RGB = ADD()",
COGL_BLEND_STRING_CONTEXT_BLENDING },
{"RGB = ADD(SRC_COLOR, 0, DST_COLOR)",
COGL_BLEND_STRING_CONTEXT_BLENDING },
{NULL}
};
int i;
GError *error = NULL;
for (i = 0; strings[i].string; i++)
{
CoglBlendStringStatement statements[2];
int count = _cogl_blend_string_compile (strings[i].string,
strings[i].context,
statements,
&error);
if (!count)
{
g_print ("Failed to parse string:\n%s\n%s\n",
strings[i].string,
error->message);
g_error_free (error);
error = NULL;
continue;
}
g_print ("Original:\n");
g_print ("%s\n", strings[i].string);
if (count > 0)
print_statement (0, &statements[0]);
if (count > 1)
print_statement (1, &statements[1]);
}
return 0;
}

151
common/cogl-blend-string.h Normal file
View File

@ -0,0 +1,151 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef COGL_BLEND_STRING_H
#define COGL_BLEND_STRING_H
#include <stdlib.h>
#include <glib.h>
typedef enum _CoglBlendStringContext
{
COGL_BLEND_STRING_CONTEXT_BLENDING,
COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE
} CoglBlendStringContext;
#define COGL_BLEND_STRING_ERROR _cogl_blend_string_error_quark ()
typedef enum _CoglBlendStringError
{
COGL_BLEND_STRING_ERROR_PARSE_ERROR,
COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR,
COGL_BLEND_STRING_ERROR_INVALID_ERROR,
COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR
} CoglBlendStringError;
/* NB: debug stringify code will get upset if these
* are re-ordered */
typedef enum _CoglBlendStringChannelMask
{
COGL_BLEND_STRING_CHANNEL_MASK_RGB,
COGL_BLEND_STRING_CHANNEL_MASK_ALPHA,
COGL_BLEND_STRING_CHANNEL_MASK_RGBA
} CoglBlendStringChannelMask;
typedef enum _CoglBlendStringColorSourceType
{
/* blending */
COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR,
COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR,
/* shared */
COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT,
/* texture combining */
COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE,
COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N,
COGL_BLEND_STRING_COLOR_SOURCE_PRIMARY,
COGL_BLEND_STRING_COLOR_SOURCE_PREVIOUS
} CoglBlendStringColorSourceType;
typedef struct _CoglBlendStringColorSourceInfo
{
CoglBlendStringColorSourceType type;
const char *name;
size_t name_len;
} CoglBlendStringColorSourceInfo;
typedef struct _CoglBlendStringColorSource
{
gboolean is_zero;
const CoglBlendStringColorSourceInfo *info;
int texture; /* for the TEXTURE_N color source */
gboolean one_minus;
CoglBlendStringChannelMask mask;
} CoglBlendStringColorSource;
typedef struct _CoglBlendStringFactor
{
gboolean is_one;
gboolean is_src_alpha_saturate;
gboolean is_color;
CoglBlendStringColorSource source;
} CoglBlendStringFactor;
typedef struct _CoglBlendStringArgument
{
CoglBlendStringColorSource source;
CoglBlendStringFactor factor;
} CoglBlendStringArgument;
typedef enum _CoglBlendStringFunctionType
{
/* shared */
COGL_BLEND_STRING_FUNCTION_AUTO_COMPOSITE,
COGL_BLEND_STRING_FUNCTION_ADD,
/* texture combine only */
COGL_BLEND_STRING_FUNCTION_REPLACE,
COGL_BLEND_STRING_FUNCTION_MODULATE,
COGL_BLEND_STRING_FUNCTION_ADD_SIGNED,
COGL_BLEND_STRING_FUNCTION_INTERPOLATE,
COGL_BLEND_STRING_FUNCTION_SUBTRACT,
COGL_BLEND_STRING_FUNCTION_DOT3_RGB,
COGL_BLEND_STRING_FUNCTION_DOT3_RGBA
} CoglBlendStringFunctionType;
typedef struct _CoglBlendStringFunctionInfo
{
enum _CoglBlendStringFunctionType type;
const char *name;
size_t name_len;
int argc;
} CoglBlendStringFunctionInfo;
typedef struct _CoglBlendStringStatement
{
CoglBlendStringChannelMask mask;
const CoglBlendStringFunctionInfo *function;
CoglBlendStringArgument args[3];
} CoglBlendStringStatement;
gboolean
_cogl_blend_string_compile (const char *string,
CoglBlendStringContext context,
CoglBlendStringStatement *statements,
GError **error);
void
_cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement,
CoglBlendStringStatement *rgb,
CoglBlendStringStatement *a);
GQuark
_cogl_blend_string_error_quark (void);
#endif /* COGL_BLEND_STRING_H */

View File

@ -45,6 +45,9 @@
#define glFrustum(L,R,B,T,N,F) \ #define glFrustum(L,R,B,T,N,F) \
glFrustumf((GLfloat)L, (GLfloat)R, (GLfloat)B, \ glFrustumf((GLfloat)L, (GLfloat)R, (GLfloat)B, \
(GLfloat)T, (GLfloat)N, (GLfloat)F) (GLfloat)T, (GLfloat)N, (GLfloat)F)
#define glOrtho glOrthof
#endif #endif
#include <string.h> #include <string.h>
@ -209,30 +212,57 @@ _cogl_current_matrix_frustum (float left,
} }
void void
_cogl_current_matrix_ortho (float left, _cogl_current_matrix_perspective (float fov_y,
float right, float aspect,
float bottom, float z_near,
float top, float z_far)
float near_val, {
float far_val) _COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_perspective (current_stack,
fov_y, aspect, z_near, z_far);
else
{
/* NB: There is no glPerspective() (only gluPerspective()) so we use
* cogl_matrix_perspective: */
CoglMatrix matrix;
_cogl_get_matrix (ctx->matrix_mode, &matrix);
cogl_matrix_perspective (&matrix,
fov_y, aspect, z_near, z_far);
_cogl_current_matrix_load (&matrix);
}
}
void
_cogl_current_matrix_ortho (float left,
float right,
float bottom,
float top,
float near_val,
float far_val)
{ {
#if 0
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL); _COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL) if (current_stack != NULL)
_cogl_matrix_stack_ortho (current_stack, _cogl_matrix_stack_ortho (current_stack,
left, right, left, right,
top, bottom, bottom, top,
near_val, near_val,
far_val); far_val);
else else
GE (glOrtho (left, right, bottom, top, near_val, far_val)); {
#ifdef HAVE_COGL_GLES2
/* NB: GLES 2 has no glOrtho(): */
CoglMatrix matrix;
_cogl_get_matrix (ctx->matrix_mode, &matrix);
cogl_matrix_ortho (&matrix,
left, right, bottom, top, near_val, far_val);
_cogl_current_matrix_load (&matrix);
#else #else
/* Nobody is using glOrtho right now anyway, so not bothering */ GE (glOrtho (left, right, bottom, top, near_val, far_val));
g_warning ("%s not implemented, need to code cogl_matrix_ortho() if you need"
" this function",
G_STRFUNC);
#endif #endif
}
} }
void void
@ -276,6 +306,12 @@ _cogl_get_matrix (CoglMatrixMode mode,
} }
} }
void
_cogl_set_matrix (const CoglMatrix *matrix)
{
_cogl_current_matrix_load (matrix);
}
void void
_cogl_current_matrix_state_init (void) _cogl_current_matrix_state_init (void)
{ {
@ -354,85 +390,19 @@ cogl_rotate (float angle, float x, float y, float z)
} }
void void
_cogl_set_matrix (const CoglMatrix *matrix) cogl_perspective (float fov_y,
{
_cogl_current_matrix_load (matrix);
}
void
cogl_get_modelview_matrix (CoglMatrix *matrix)
{
_cogl_get_matrix (COGL_MATRIX_MODELVIEW,
matrix);
}
void
cogl_get_projection_matrix (CoglMatrix *matrix)
{
_cogl_get_matrix (COGL_MATRIX_PROJECTION,
matrix);
}
void
cogl_perspective (float fovy,
float aspect, float aspect,
float zNear, float z_near,
float zFar) float z_far)
{ {
float xmax, ymax; float ymax = z_near * tanf (fov_y * G_PI / 360.0);
float x, y, c, d;
float fovy_rad_half = (fovy * G_PI) / 360;
CoglMatrix perspective;
GLfloat m[16];
_COGL_GET_CONTEXT (ctx, NO_RETVAL); cogl_frustum (-ymax * aspect, /* left */
ymax * aspect, /* right */
memset (&m[0], 0, sizeof (m)); -ymax, /* bottom */
ymax, /* top */
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION); z_near,
_cogl_current_matrix_identity (); z_far);
/*
* Based on the original algorithm in perspective():
*
* 1) xmin = -xmax => xmax + xmin == 0 && xmax - xmin == 2 * xmax
* same true for y, hence: a == 0 && b == 0;
*
* 2) When working with small numbers, we are loosing significant
* precision
*/
ymax = (zNear * (sinf (fovy_rad_half) / cosf (fovy_rad_half)));
xmax = (ymax * aspect);
x = (zNear / xmax);
y = (zNear / ymax);
c = (-(zFar + zNear) / ( zFar - zNear));
d = (-(2 * zFar) * zNear) / (zFar - zNear);
#define M(row,col) m[col*4+row]
M(0,0) = x;
M(1,1) = y;
M(2,2) = c;
M(2,3) = d;
M(3,2) = -1.0;
cogl_matrix_init_from_array (&perspective, m);
_cogl_current_matrix_multiply (&perspective);
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
/* Calculate and store the inverse of the matrix */
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
#define m ctx->inverse_projection
M(0, 0) = (1.0 / x);
M(1, 1) = (1.0 / y);
M(2, 3) = -1.0;
M(3, 2) = (1.0 / d);
M(3, 3) = (c / d);
#undef m
#undef M
} }
void void
@ -474,4 +444,65 @@ cogl_frustum (float left,
M(3,2) = 1.0 / d; M(3,2) = 1.0 / d;
M(3,3) = c / d; M(3,3) = c / d;
#undef M #undef M
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
} }
void
cogl_ortho (float left,
float right,
float bottom,
float top,
float z_near,
float z_far)
{
CoglMatrix ortho;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
cogl_matrix_init_identity (&ortho);
cogl_matrix_ortho (&ortho, left, right, bottom, top, z_near, z_far);
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_load (&ortho);
/* Calculate and store the inverse of the matrix */
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
#define M(row,col) ctx->inverse_projection[col*4+row]
M(0,0) = 1.0 / ortho.xx;
M(0,3) = -ortho.xw;
M(1,1) = 1.0 / ortho.yy;
M(1,3) = -ortho.yw;
M(2,2) = 1.0 / ortho.zz;
M(2,3) = -ortho.zw;
M(3,3) = 1.0;
#undef M
}
void
cogl_get_modelview_matrix (CoglMatrix *matrix)
{
_cogl_get_matrix (COGL_MATRIX_MODELVIEW,
matrix);
}
void
cogl_set_modelview_matrix (CoglMatrix *matrix)
{
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_load (matrix);
}
void
cogl_get_projection_matrix (CoglMatrix *matrix)
{
_cogl_get_matrix (COGL_MATRIX_PROJECTION,
matrix);
}
void
cogl_set_projection_matrix (CoglMatrix *matrix)
{
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_load (matrix);
}

View File

@ -39,7 +39,8 @@ static const GDebugKey cogl_debug_keys[] = {
{ "draw", COGL_DEBUG_DRAW }, { "draw", COGL_DEBUG_DRAW },
{ "pango", COGL_DEBUG_PANGO }, { "pango", COGL_DEBUG_PANGO },
{ "rectangles", COGL_DEBUG_RECTANGLES }, { "rectangles", COGL_DEBUG_RECTANGLES },
{ "handle", COGL_DEBUG_HANDLE } { "handle", COGL_DEBUG_HANDLE },
{ "blend-strings", COGL_DEBUG_BLEND_STRINGS }
}; };
static const gint n_cogl_debug_keys = G_N_ELEMENTS (cogl_debug_keys); static const gint n_cogl_debug_keys = G_N_ELEMENTS (cogl_debug_keys);

View File

@ -0,0 +1,41 @@
/*** BEGIN file-header ***/
#include "cogl-enum-types.h"
#include "cogl.h"
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
#include "@filename@"
/*** END file-production ***/
/*** BEGIN value-header ***/
GType
@enum_name@_get_type (void)
{
static volatile gsize g_enum_type_id__volatile = 0;
if (g_once_init_enter (&g_enum_type_id__volatile))
{
static const G@Type@Value values[] = {
/*** END value-header ***/
/*** BEGIN value-production ***/
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
/*** END value-production ***/
/*** BEGIN value-tail ***/
{ 0, NULL, NULL }
};
GType g_enum_type_id;
g_enum_type_id =
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
}
return g_enum_type_id__volatile;
}
/*** END value-tail ***/

View File

@ -0,0 +1,25 @@
/*** BEGIN file-header ***/
#ifndef __COGL_ENUM_TYPES_H__
#define __COGL_ENUM_TYPES_H__
#include <glib-object.h>
G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN file-tail ***/
G_END_DECLS
#endif /* !__CLUTTER_ENUM_TYPES_H__ */
/*** END file-tail ***/
/*** BEGIN value-header ***/
GType @enum_name@_get_type (void) G_GNUC_CONST;
#define COGL_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
/*** END value-header ***/

View File

@ -82,7 +82,7 @@ typedef struct _CoglHandleObject
static CoglHandleClass _cogl_##type_name##_class; \ static CoglHandleClass _cogl_##type_name##_class; \
\ \
static GQuark \ static GQuark \
_cogl_##type_name##_get_type (void) \ _cogl_handle_##type_name##_get_type (void) \
{ \ { \
static GQuark type = 0; \ static GQuark type = 0; \
if (!type) \ if (!type) \
@ -99,13 +99,13 @@ _cogl_##type_name##_handle_new (Cogl##TypeName *new_obj) \
obj->klass = &_cogl_##type_name##_class; \ obj->klass = &_cogl_##type_name##_class; \
if (!obj->klass->type) \ if (!obj->klass->type) \
{ \ { \
obj->klass->type = _cogl_##type_name##_get_type (); \ obj->klass->type = _cogl_handle_##type_name##_get_type ();\
obj->klass->virt_free = _cogl_##type_name##_free; \ obj->klass->virt_free = _cogl_##type_name##_free; \
} \ } \
\ \
_COGL_HANDLE_DEBUG_NEW (TypeName, obj); \ _COGL_HANDLE_DEBUG_NEW (TypeName, obj); \
return (CoglHandle) new_obj; \ return (CoglHandle) new_obj; \
} \ } \
\ \
Cogl##TypeName * \ Cogl##TypeName * \
_cogl_##type_name##_pointer_from_handle (CoglHandle handle) \ _cogl_##type_name##_pointer_from_handle (CoglHandle handle) \
@ -121,7 +121,8 @@ cogl_is_##type_name (CoglHandle handle) \
if (handle == COGL_INVALID_HANDLE) \ if (handle == COGL_INVALID_HANDLE) \
return FALSE; \ return FALSE; \
\ \
return (obj->klass->type == _cogl_##type_name##_get_type ()); \ return (obj->klass->type == \
_cogl_handle_##type_name##_get_type ()); \
} \ } \
\ \
CoglHandle G_GNUC_DEPRECATED \ CoglHandle G_GNUC_DEPRECATED \

View File

@ -68,15 +68,20 @@ struct _CoglMaterialLayer
CoglHandle texture; /*!< The texture for this layer, or COGL_INVALID_HANDLE CoglHandle texture; /*!< The texture for this layer, or COGL_INVALID_HANDLE
for an empty layer */ for an empty layer */
CoglMaterialFilter mag_filter;
CoglMaterialFilter min_filter;
/* Determines how the color of individual texture fragments /* Determines how the color of individual texture fragments
* are calculated. */ * are calculated. */
CoglMaterialLayerCombineFunc texture_combine_rgb_func; GLint texture_combine_rgb_func;
CoglMaterialLayerCombineSrc texture_combine_rgb_src[3]; GLint texture_combine_rgb_src[3];
CoglMaterialLayerCombineOp texture_combine_rgb_op[3]; GLint texture_combine_rgb_op[3];
CoglMaterialLayerCombineFunc texture_combine_alpha_func; GLint texture_combine_alpha_func;
CoglMaterialLayerCombineSrc texture_combine_alpha_src[3]; GLint texture_combine_alpha_src[3];
CoglMaterialLayerCombineOp texture_combine_alpha_op[3]; GLint texture_combine_alpha_op[3];
GLfloat texture_combine_constant[4];
/* TODO: Support purely GLSL based material layers */ /* TODO: Support purely GLSL based material layers */
@ -114,11 +119,104 @@ struct _CoglMaterial
GLfloat alpha_func_reference; GLfloat alpha_func_reference;
/* Determines how this material is blended with other primitives */ /* Determines how this material is blended with other primitives */
CoglMaterialBlendFactor blend_src_factor; #ifndef HAVE_COGL_GLES
CoglMaterialBlendFactor blend_dst_factor; GLenum blend_equation_rgb;
GLenum blend_equation_alpha;
GLint blend_src_factor_alpha;
GLint blend_dst_factor_alpha;
GLfloat blend_constant[4];
#endif
GLint blend_src_factor_rgb;
GLint blend_dst_factor_rgb;
GList *layers; GList *layers;
}; };
/*
* SECTION:cogl-material-internals
* @short_description: Functions for creating custom primitives that make use
* of Cogl materials for filling.
*
* Normally you shouldn't need to use this API directly, but if you need to
* developing a custom/specialised primitive - probably using raw OpenGL - then
* this API aims to expose enough of the material internals to support being
* able to fill your geometry according to a given Cogl material.
*/
/*
* cogl_material_get_cogl_enable_flags:
* @material: A CoglMaterial object
*
* This determines what flags need to be passed to cogl_enable before this
* material can be used. Normally you shouldn't need to use this function
* directly since Cogl will do this internally, but if you are developing
* custom primitives directly with OpenGL you may want to use this.
*
* Note: This API is hopfully just a stop-gap solution. Ideally cogl_enable
* will be replaced.
*/
/* TODO: find a nicer solution! */
gulong _cogl_material_get_cogl_enable_flags (CoglHandle handle);
/*
* CoglMaterialLayerFlags:
* @COGL_MATERIAL_LAYER_FLAG_USER_MATRIX: Means the user has supplied a
* custom texture matrix.
*/
typedef enum _CoglMaterialLayerFlags
{
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
} CoglMaterialLayerFlags;
/* XXX: NB: if you add flags here you will need to update
* CoglMaterialLayerPrivFlags!!! */
/*
* cogl_material_layer_get_flags:
* @layer_handle: A CoglMaterialLayer layer handle
*
* This lets you get a number of flag attributes about the layer. Normally
* you shouldn't need to use this function directly since Cogl will do this
* internally, but if you are developing custom primitives directly with
* OpenGL you may need this.
*/
gulong _cogl_material_layer_get_flags (CoglHandle layer_handle);
/*
* CoglMaterialFlushOption:
* @COGL_MATERIAL_FLUSH_FALLBACK_MASK: Follow this by a guin32 mask
* of the layers that can't be supported with the user supplied texture
* and need to be replaced with fallback textures. (1 = fallback, and the
* least significant bit = layer 0)
* @COGL_MATERIAL_FLUSH_DISABLE_MASK: Follow this by a guint32 mask
* of the layers that you want to completly disable texturing for
* (1 = fallback, and the least significant bit = layer 0)
* @COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE: Follow this by a GLuint OpenGL texture
* name to override the texture used for layer 0 of the material. This is
* intended for dealing with sliced textures where you will need to point
* to each of the texture slices in turn when drawing your geometry.
* Passing a value of 0 is the same as not passing the option at all.
*/
typedef enum _CoglMaterialFlushOption
{
COGL_MATERIAL_FLUSH_FALLBACK_MASK = 1,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
} CoglMaterialFlushOption;
/*
* cogl_material_flush_gl_state:
* @material: A CoglMaterial object
* @...: A NULL terminated list of (CoglMaterialFlushOption, data) pairs
*
* This function commits the state of the specified CoglMaterial - including
* the texture state for all the layers - to the OpenGL[ES] driver.
*
* Since 1.0
*/
void _cogl_material_flush_gl_state (CoglHandle material,
...) G_GNUC_NULL_TERMINATED;
#endif /* __COGL_MATERIAL_PRIVATE_H */ #endif /* __COGL_MATERIAL_PRIVATE_H */

View File

@ -35,6 +35,7 @@
#include "cogl-material-private.h" #include "cogl-material-private.h"
#include "cogl-texture-private.h" #include "cogl-texture-private.h"
#include "cogl-blend-string.h"
#include <glib.h> #include <glib.h>
#include <string.h> #include <string.h>
@ -50,6 +51,10 @@
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
#define glActiveTexture ctx->pf_glActiveTexture #define glActiveTexture ctx->pf_glActiveTexture
#define glClientActiveTexture ctx->pf_glClientActiveTexture #define glClientActiveTexture ctx->pf_glClientActiveTexture
#define glBlendFuncSeparate ctx->pf_glBlendFuncSeparate
#define glBlendEquation ctx->pf_glBlendEquation
#define glBlendColor ctx->pf_glBlendColor
#define glBlendEquationSeparate ctx->pf_glBlendEquationSeparate
#endif #endif
static void _cogl_material_free (CoglMaterial *tex); static void _cogl_material_free (CoglMaterial *tex);
@ -60,6 +65,12 @@ COGL_HANDLE_DEFINE (MaterialLayer, material_layer);
/* #define DISABLE_MATERIAL_CACHE 1 */ /* #define DISABLE_MATERIAL_CACHE 1 */
GQuark
_cogl_material_error_quark (void)
{
return g_quark_from_static_string ("cogl-material-error-quark");
}
CoglHandle CoglHandle
cogl_material_new (void) cogl_material_new (void)
{ {
@ -88,8 +99,18 @@ cogl_material_new (void)
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC; material->flags |= COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC;
/* Not the same as the GL default, but seems saner... */ /* Not the same as the GL default, but seems saner... */
material->blend_src_factor = COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA; #ifndef HAVE_COGL_GLES
material->blend_dst_factor = COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; material->blend_equation_rgb = GL_FUNC_ADD;
material->blend_equation_alpha = GL_FUNC_ADD;
material->blend_src_factor_alpha = GL_SRC_ALPHA;
material->blend_dst_factor_alpha = GL_ONE_MINUS_SRC_ALPHA;
material->blend_constant[0] = 0;
material->blend_constant[1] = 0;
material->blend_constant[2] = 0;
material->blend_constant[3] = 0;
#endif
material->blend_src_factor_rgb = GL_SRC_ALPHA;
material->blend_dst_factor_rgb = GL_ONE_MINUS_SRC_ALPHA;
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC; material->flags |= COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
material->layers = NULL; material->layers = NULL;
@ -408,20 +429,177 @@ cogl_material_set_alpha_test_function (CoglHandle handle,
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC; material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC;
} }
GLenum
arg_to_gl_blend_factor (CoglBlendStringArgument *arg)
{
if (arg->source.is_zero)
return GL_ZERO;
if (arg->factor.is_one)
return GL_ONE;
else if (arg->factor.is_src_alpha_saturate)
return GL_SRC_ALPHA_SATURATE;
else if (arg->factor.source.info->type ==
COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR)
{
if (arg->factor.source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB)
{
if (arg->factor.source.one_minus)
return GL_ONE_MINUS_SRC_COLOR;
else
return GL_SRC_COLOR;
}
else
{
if (arg->factor.source.one_minus)
return GL_ONE_MINUS_SRC_ALPHA;
else
return GL_SRC_ALPHA;
}
}
else if (arg->factor.source.info->type ==
COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR)
{
if (arg->factor.source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB)
{
if (arg->factor.source.one_minus)
return GL_ONE_MINUS_DST_COLOR;
else
return GL_DST_COLOR;
}
else
{
if (arg->factor.source.one_minus)
return GL_ONE_MINUS_DST_ALPHA;
else
return GL_DST_ALPHA;
}
}
#ifndef HAVE_COGL_GLES
else if (arg->factor.source.info->type ==
COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT)
{
if (arg->factor.source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB)
{
if (arg->factor.source.one_minus)
return GL_ONE_MINUS_CONSTANT_COLOR;
else
return GL_CONSTANT_COLOR;
}
else
{
if (arg->factor.source.one_minus)
return GL_ONE_MINUS_CONSTANT_ALPHA;
else
return GL_CONSTANT_ALPHA;
}
}
#endif
g_warning ("Unable to determine valid blend factor from blend string\n");
return GL_ONE;
}
void void
cogl_material_set_blend_factors (CoglHandle handle, setup_blend_state (CoglBlendStringStatement *statement,
CoglMaterialBlendFactor src_factor, GLenum *blend_equation,
CoglMaterialBlendFactor dst_factor) GLint *blend_src_factor,
GLint *blend_dst_factor)
{
#ifndef HAVE_COGL_GLES
switch (statement->function->type)
{
case COGL_BLEND_STRING_FUNCTION_ADD:
*blend_equation = GL_FUNC_ADD;
break;
/* TODO - add more */
default:
g_warning ("Unsupported blend function given");
*blend_equation = GL_FUNC_ADD;
}
#endif
*blend_src_factor = arg_to_gl_blend_factor (&statement->args[0]);
*blend_dst_factor = arg_to_gl_blend_factor (&statement->args[1]);
}
gboolean
cogl_material_set_blend (CoglHandle handle,
const char *blend_description,
GError **error)
{ {
CoglMaterial *material; CoglMaterial *material;
CoglBlendStringStatement statements[2];
CoglBlendStringStatement split[2];
CoglBlendStringStatement *rgb;
CoglBlendStringStatement *a;
int count;
g_return_val_if_fail (cogl_is_material (handle), FALSE);
material = _cogl_material_pointer_from_handle (handle);
count =
_cogl_blend_string_compile (blend_description,
COGL_BLEND_STRING_CONTEXT_BLENDING,
statements,
error);
if (!count)
return FALSE;
if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA)
{
_cogl_blend_string_split_rgba_statement (statements,
&split[0], &split[1]);
rgb = &split[0];
a = &split[1];
}
else
{
rgb = &statements[0];
a = &statements[1];
}
#ifndef HAVE_COGL_GLES
setup_blend_state (rgb,
&material->blend_equation_rgb,
&material->blend_src_factor_rgb,
&material->blend_dst_factor_rgb);
setup_blend_state (a,
&material->blend_equation_alpha,
&material->blend_src_factor_alpha,
&material->blend_dst_factor_alpha);
#else
setup_blend_state (rgb,
NULL,
&material->blend_src_factor_rgb,
&material->blend_dst_factor_rgb);
#endif
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
return TRUE;
}
void
cogl_material_set_blend_constant (CoglHandle handle,
CoglColor *constant_color)
{
#ifndef HAVE_COGL_GLES
CoglMaterial *material;
GLfloat *constant;
g_return_if_fail (cogl_is_material (handle)); g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle); material = _cogl_material_pointer_from_handle (handle);
material->blend_src_factor = src_factor;
material->blend_dst_factor = dst_factor; constant = material->blend_constant;
constant[0] = cogl_color_get_red_float (constant_color);
constant[1] = cogl_color_get_green_float (constant_color);
constant[2] = cogl_color_get_blue_float (constant_color);
constant[3] = cogl_color_get_alpha_float (constant_color);
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC; material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
#endif
} }
/* Asserts that a layer corresponding to the given index exists. If no /* Asserts that a layer corresponding to the given index exists. If no
@ -459,25 +637,22 @@ _cogl_material_get_layer (CoglMaterial *material,
layer_handle = _cogl_material_layer_handle_new (layer); layer_handle = _cogl_material_layer_handle_new (layer);
layer->index = index_; layer->index = index_;
layer->flags = COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE; layer->flags = COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
layer->mag_filter = COGL_MATERIAL_FILTER_LINEAR;
layer->min_filter = COGL_MATERIAL_FILTER_LINEAR;
layer->texture = COGL_INVALID_HANDLE; layer->texture = COGL_INVALID_HANDLE;
/* Choose the same default combine mode as OpenGL: /* Choose the same default combine mode as OpenGL:
* MODULATE(PREVIOUS[RGBA],TEXTURE[RGBA]) */ * MODULATE(PREVIOUS[RGBA],TEXTURE[RGBA]) */
layer->texture_combine_rgb_func = COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE; layer->texture_combine_rgb_func = GL_MODULATE;
layer->texture_combine_rgb_src[0] = COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS; layer->texture_combine_rgb_src[0] = GL_PREVIOUS;
layer->texture_combine_rgb_src[1] = COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE; layer->texture_combine_rgb_src[1] = GL_TEXTURE;
layer->texture_combine_rgb_op[0] = COGL_MATERIAL_LAYER_COMBINE_OP_SRC_COLOR; layer->texture_combine_rgb_op[0] = GL_SRC_COLOR;
layer->texture_combine_rgb_op[1] = COGL_MATERIAL_LAYER_COMBINE_OP_SRC_COLOR; layer->texture_combine_rgb_op[1] = GL_SRC_COLOR;
layer->texture_combine_alpha_func = layer->texture_combine_alpha_func = GL_MODULATE;
COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE; layer->texture_combine_alpha_src[0] = GL_PREVIOUS;
layer->texture_combine_alpha_src[0] = layer->texture_combine_alpha_src[1] = GL_TEXTURE;
COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS; layer->texture_combine_alpha_op[0] = GL_SRC_ALPHA;
layer->texture_combine_alpha_src[1] = layer->texture_combine_alpha_op[1] = GL_SRC_ALPHA;
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE;
layer->texture_combine_alpha_op[0] =
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_ALPHA;
layer->texture_combine_alpha_op[1] =
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_ALPHA;
cogl_matrix_init_identity (&layer->matrix); cogl_matrix_init_identity (&layer->matrix);
@ -498,7 +673,8 @@ cogl_material_set_layer (CoglHandle material_handle,
int n_layers; int n_layers;
g_return_if_fail (cogl_is_material (material_handle)); g_return_if_fail (cogl_is_material (material_handle));
g_return_if_fail (cogl_is_texture (texture_handle)); g_return_if_fail (texture_handle == COGL_INVALID_HANDLE
|| cogl_is_texture (texture_handle));
material = _cogl_material_pointer_from_handle (material_handle); material = _cogl_material_pointer_from_handle (material_handle);
layer = _cogl_material_get_layer (material_handle, layer_index, TRUE); layer = _cogl_material_get_layer (material_handle, layer_index, TRUE);
@ -519,7 +695,8 @@ cogl_material_set_layer (CoglHandle material_handle,
* MAX_COMBINED_TEXTURE_IMAGE_UNITS layers. */ * MAX_COMBINED_TEXTURE_IMAGE_UNITS layers. */
} }
cogl_handle_ref (texture_handle); if (texture_handle)
cogl_handle_ref (texture_handle);
if (layer->texture) if (layer->texture)
cogl_handle_unref (layer->texture); cogl_handle_unref (layer->texture);
@ -530,104 +707,164 @@ cogl_material_set_layer (CoglHandle material_handle,
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY; layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
} }
void static void
cogl_material_set_layer_combine_function ( setup_texture_combine_state (CoglBlendStringStatement *statement,
CoglHandle handle, GLint *texture_combine_func,
gint layer_index, GLint *texture_combine_src,
CoglMaterialLayerCombineChannels channels, GLint *texture_combine_op)
CoglMaterialLayerCombineFunc func) {
int i;
switch (statement->function->type)
{
case COGL_BLEND_STRING_FUNCTION_AUTO_COMPOSITE:
*texture_combine_func = GL_MODULATE; /* FIXME */
break;
case COGL_BLEND_STRING_FUNCTION_REPLACE:
*texture_combine_func = GL_REPLACE;
break;
case COGL_BLEND_STRING_FUNCTION_MODULATE:
*texture_combine_func = GL_MODULATE;
break;
case COGL_BLEND_STRING_FUNCTION_ADD:
*texture_combine_func = GL_ADD;
break;
case COGL_BLEND_STRING_FUNCTION_ADD_SIGNED:
*texture_combine_func = GL_ADD_SIGNED;
break;
case COGL_BLEND_STRING_FUNCTION_INTERPOLATE:
*texture_combine_func = GL_INTERPOLATE;
break;
case COGL_BLEND_STRING_FUNCTION_SUBTRACT:
*texture_combine_func = GL_SUBTRACT;
break;
case COGL_BLEND_STRING_FUNCTION_DOT3_RGB:
*texture_combine_func = GL_DOT3_RGB;
break;
case COGL_BLEND_STRING_FUNCTION_DOT3_RGBA:
*texture_combine_func = GL_DOT3_RGBA;
break;
}
for (i = 0; i < statement->function->argc; i++)
{
CoglBlendStringArgument *arg = &statement->args[i];
switch (arg->source.info->type)
{
case COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT:
texture_combine_src[i] = GL_CONSTANT;
break;
case COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE:
texture_combine_src[i] = GL_TEXTURE;
break;
case COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N:
texture_combine_src[i] =
GL_TEXTURE0 + arg->source.texture;
break;
case COGL_BLEND_STRING_COLOR_SOURCE_PRIMARY:
texture_combine_src[i] = GL_PRIMARY_COLOR;
break;
case COGL_BLEND_STRING_COLOR_SOURCE_PREVIOUS:
texture_combine_src[i] = GL_PREVIOUS;
break;
default:
g_warning ("Unexpected texture combine source");
texture_combine_src[i] = GL_TEXTURE;
}
if (arg->source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB)
{
if (statement->args[i].source.one_minus)
texture_combine_op[i] = GL_ONE_MINUS_SRC_COLOR;
else
texture_combine_op[i] = GL_SRC_COLOR;
}
else
{
if (statement->args[i].source.one_minus)
texture_combine_op[i] = GL_ONE_MINUS_SRC_ALPHA;
else
texture_combine_op[i] = GL_SRC_ALPHA;
}
}
}
gboolean
cogl_material_set_layer_combine (CoglHandle handle,
gint layer_index,
const char *combine_description,
GError **error)
{ {
CoglMaterial *material; CoglMaterial *material;
CoglMaterialLayer *layer; CoglMaterialLayer *layer;
gboolean set_alpha_func = FALSE; CoglBlendStringStatement statements[2];
gboolean set_rgb_func = FALSE; CoglBlendStringStatement split[2];
CoglBlendStringStatement *rgb;
CoglBlendStringStatement *a;
int count;
g_return_val_if_fail (cogl_is_material (handle), FALSE);
material = _cogl_material_pointer_from_handle (handle);
layer = _cogl_material_get_layer (material, layer_index, TRUE);
count =
_cogl_blend_string_compile (combine_description,
COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE,
statements,
error);
if (!count)
return FALSE;
if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA)
{
_cogl_blend_string_split_rgba_statement (statements,
&split[0], &split[1]);
rgb = &split[0];
a = &split[1];
}
else
{
rgb = &statements[0];
a = &statements[1];
}
setup_texture_combine_state (rgb,
&layer->texture_combine_rgb_func,
layer->texture_combine_rgb_src,
layer->texture_combine_rgb_op);
setup_texture_combine_state (a,
&layer->texture_combine_alpha_func,
layer->texture_combine_alpha_src,
layer->texture_combine_alpha_op);
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
return TRUE;
}
void
cogl_material_set_layer_combine_constant (CoglHandle handle,
gint layer_index,
CoglColor *constant_color)
{
CoglMaterial *material;
CoglMaterialLayer *layer;
GLfloat *constant;
g_return_if_fail (cogl_is_material (handle)); g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle); material = _cogl_material_pointer_from_handle (handle);
layer = _cogl_material_get_layer (material, layer_index, TRUE); layer = _cogl_material_get_layer (material, layer_index, TRUE);
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA) constant = layer->texture_combine_constant;
set_alpha_func = set_rgb_func = TRUE; constant[0] = cogl_color_get_red_float (constant_color);
else if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB) constant[1] = cogl_color_get_green_float (constant_color);
set_rgb_func = TRUE; constant[2] = cogl_color_get_blue_float (constant_color);
else if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA) constant[3] = cogl_color_get_alpha_float (constant_color);
set_alpha_func = TRUE;
if (set_rgb_func)
layer->texture_combine_rgb_func = func;
if (set_alpha_func)
layer->texture_combine_alpha_func = func;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
}
void
cogl_material_set_layer_combine_arg_src (
CoglHandle handle,
gint layer_index,
gint argument,
CoglMaterialLayerCombineChannels channels,
CoglMaterialLayerCombineSrc src)
{
CoglMaterial *material;
CoglMaterialLayer *layer;
gboolean set_arg_alpha_src = FALSE;
gboolean set_arg_rgb_src = FALSE;
g_return_if_fail (cogl_is_material (handle));
g_return_if_fail (argument >=0 && argument <= 3);
material = _cogl_material_pointer_from_handle (handle);
layer = _cogl_material_get_layer (material, layer_index, TRUE);
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
set_arg_alpha_src = set_arg_rgb_src = TRUE;
else if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB)
set_arg_rgb_src = TRUE;
else if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA)
set_arg_alpha_src = TRUE;
if (set_arg_rgb_src)
layer->texture_combine_rgb_src[argument] = src;
if (set_arg_alpha_src)
layer->texture_combine_alpha_src[argument] = src;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
}
void
cogl_material_set_layer_combine_arg_op (
CoglHandle material_handle,
gint layer_index,
gint argument,
CoglMaterialLayerCombineChannels channels,
CoglMaterialLayerCombineOp op)
{
CoglMaterial *material;
CoglMaterialLayer *layer;
gboolean set_arg_alpha_op = FALSE;
gboolean set_arg_rgb_op = FALSE;
g_return_if_fail (cogl_is_material (material_handle));
g_return_if_fail (argument >=0 && argument <= 3);
material = _cogl_material_pointer_from_handle (material_handle);
layer = _cogl_material_get_layer (material, layer_index, TRUE);
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
set_arg_alpha_op = set_arg_rgb_op = TRUE;
else if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB)
set_arg_rgb_op = TRUE;
else if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA)
set_arg_alpha_op = TRUE;
if (set_arg_rgb_op)
layer->texture_combine_rgb_op[argument] = op;
if (set_arg_alpha_op)
layer->texture_combine_alpha_op[argument] = op;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY; layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE; layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
@ -690,7 +927,7 @@ cogl_material_remove_layer (CoglHandle material_handle,
/* XXX: This API is hopfully just a stop-gap solution. Ideally cogl_enable /* XXX: This API is hopfully just a stop-gap solution. Ideally cogl_enable
* will be replaced. */ * will be replaced. */
gulong gulong
cogl_material_get_cogl_enable_flags (CoglHandle material_handle) _cogl_material_get_cogl_enable_flags (CoglHandle material_handle)
{ {
CoglMaterial *material; CoglMaterial *material;
gulong enable_flags = 0; gulong enable_flags = 0;
@ -713,7 +950,7 @@ cogl_material_get_cogl_enable_flags (CoglHandle material_handle)
* probably sensible to try and avoid list manipulation for every * probably sensible to try and avoid list manipulation for every
* primitive emitted in a scene, every frame. * primitive emitted in a scene, every frame.
* *
* Alternativly; we could either add a _foreach function, or maybe * Alternatively; we could either add a _foreach function, or maybe
* a function that gets a passed a buffer (that may be stack allocated) * a function that gets a passed a buffer (that may be stack allocated)
* by the caller. * by the caller.
*/ */
@ -748,7 +985,7 @@ cogl_material_layer_get_texture (CoglHandle layer_handle)
} }
gulong gulong
cogl_material_layer_get_flags (CoglHandle layer_handle) _cogl_material_layer_get_flags (CoglHandle layer_handle)
{ {
CoglMaterialLayer *layer; CoglMaterialLayer *layer;
@ -760,25 +997,34 @@ cogl_material_layer_get_flags (CoglHandle layer_handle)
} }
static guint static guint
get_n_args_for_combine_func (CoglMaterialLayerCombineFunc func) get_n_args_for_combine_func (GLint func)
{ {
switch (func) switch (func)
{ {
case COGL_MATERIAL_LAYER_COMBINE_FUNC_REPLACE: case GL_REPLACE:
return 1; return 1;
case COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE: case GL_MODULATE:
case COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD: case GL_ADD:
case COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD_SIGNED: case GL_ADD_SIGNED:
case COGL_MATERIAL_LAYER_COMBINE_FUNC_SUBTRACT: case GL_SUBTRACT:
case COGL_MATERIAL_LAYER_COMBINE_FUNC_DOT3_RGB: case GL_DOT3_RGB:
case COGL_MATERIAL_LAYER_COMBINE_FUNC_DOT3_RGBA: case GL_DOT3_RGBA:
return 2; return 2;
case COGL_MATERIAL_LAYER_COMBINE_FUNC_INTERPOLATE: case GL_INTERPOLATE:
return 3; return 3;
} }
return 0; return 0;
} }
static gboolean
is_mipmap_filter (CoglMaterialFilter filter)
{
return (filter == COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST
|| filter == COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST
|| filter == COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR
|| filter == COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR);
}
static void static void
_cogl_material_layer_flush_gl_sampler_state (CoglMaterialLayer *layer, _cogl_material_layer_flush_gl_sampler_state (CoglMaterialLayer *layer,
CoglLayerInfo *gl_layer_info) CoglLayerInfo *gl_layer_info)
@ -851,6 +1097,9 @@ _cogl_material_layer_flush_gl_sampler_state (CoglMaterialLayer *layer,
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
layer->texture_combine_alpha_op[2])); layer->texture_combine_alpha_op[2]));
} }
GE (glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
layer->texture_combine_constant));
} }
#ifndef DISABLE_MATERIAL_CACHE #ifndef DISABLE_MATERIAL_CACHE
@ -976,6 +1225,13 @@ _cogl_material_flush_layers_gl_state (CoglMaterial *material,
GE (glActiveTexture (GL_TEXTURE0 + i)); GE (glActiveTexture (GL_TEXTURE0 + i));
_cogl_texture_set_filters (layer->texture,
layer->min_filter,
layer->mag_filter);
if (is_mipmap_filter (layer->min_filter)
|| is_mipmap_filter (layer->mag_filter))
_cogl_texture_ensure_mipmaps (layer->texture);
/* FIXME: We could be more clever here and only bind the texture /* FIXME: We could be more clever here and only bind the texture
if it is different from gl_layer_info->gl_texture to avoid if it is different from gl_layer_info->gl_texture to avoid
redundant GL calls. However a few other places in Cogl and redundant GL calls. However a few other places in Cogl and
@ -1122,12 +1378,44 @@ _cogl_material_flush_base_gl_state (CoglMaterial *material)
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC)) && material->flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC))
{ {
GE (glBlendFunc (material->blend_src_factor, material->blend_dst_factor)); #if defined (HAVE_COGL_GLES2)
gboolean have_blend_equation_seperate = TRUE;
#elif defined (HAVE_COGL_GL)
gboolean have_blend_equation_seperate = FALSE;
if (ctx->pf_glBlendEquationSeparate) /* Only GL 2.0 + */
have_blend_equation_seperate = TRUE;
#endif
#ifndef HAVE_COGL_GLES /* GLES 1 only has glBlendFunc */
if (material->blend_src_factor_rgb != material->blend_src_factor_alpha
|| (material->blend_src_factor_rgb !=
material->blend_src_factor_alpha))
{
if (have_blend_equation_seperate &&
material->blend_equation_rgb != material->blend_equation_alpha)
GE (glBlendEquationSeparate (material->blend_equation_rgb,
material->blend_equation_alpha));
else
GE (glBlendEquation (material->blend_equation_rgb));
GE (glBlendFuncSeparate (material->blend_src_factor_rgb,
material->blend_dst_factor_rgb,
material->blend_src_factor_alpha,
material->blend_dst_factor_alpha));
GE (glBlendColor (material->blend_constant[0],
material->blend_constant[1],
material->blend_constant[2],
material->blend_constant[3]));
}
else
#endif
GE (glBlendFunc (material->blend_src_factor_rgb,
material->blend_dst_factor_rgb));
} }
} }
void void
cogl_material_flush_gl_state (CoglHandle handle, ...) _cogl_material_flush_gl_state (CoglHandle handle, ...)
{ {
CoglMaterial *material; CoglMaterial *material;
va_list ap; va_list ap;
@ -1204,3 +1492,44 @@ cogl_set_source_texture (CoglHandle texture_handle)
cogl_set_source (ctx->default_material); cogl_set_source (ctx->default_material);
} }
CoglMaterialFilter
cogl_material_layer_get_min_filter (CoglHandle layer_handle)
{
CoglMaterialLayer *layer;
g_return_val_if_fail (cogl_is_material_layer (layer_handle), 0);
layer = _cogl_material_layer_pointer_from_handle (layer_handle);
return layer->min_filter;
}
CoglMaterialFilter
cogl_material_layer_get_mag_filter (CoglHandle layer_handle)
{
CoglMaterialLayer *layer;
g_return_val_if_fail (cogl_is_material_layer (layer_handle), 0);
layer = _cogl_material_layer_pointer_from_handle (layer_handle);
return layer->mag_filter;
}
void
cogl_material_set_layer_filters (CoglHandle handle,
gint layer_index,
CoglMaterialFilter min_filter,
CoglMaterialFilter mag_filter)
{
CoglMaterial *material;
CoglMaterialLayer *layer;
g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle);
layer = _cogl_material_get_layer (material, layer_index, TRUE);
layer->min_filter = min_filter;
layer->mag_filter = mag_filter;
}

View File

@ -257,6 +257,59 @@ _cogl_matrix_stack_multiply (CoglMatrixStack *stack,
stack->flushed_state = NULL; stack->flushed_state = NULL;
} }
void
_cogl_matrix_stack_frustum (CoglMatrixStack *stack,
float left,
float right,
float bottom,
float top,
float z_near,
float z_far)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
cogl_matrix_frustum (&state->matrix,
left, right, bottom, top,
z_near, z_far);
/* mark dirty */
stack->flushed_state = NULL;
}
void
_cogl_matrix_stack_perspective (CoglMatrixStack *stack,
float fov_y,
float aspect,
float z_near,
float z_far)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
cogl_matrix_perspective (&state->matrix,
fov_y, aspect, z_near, z_far);
/* mark dirty */
stack->flushed_state = NULL;
}
void
_cogl_matrix_stack_ortho (CoglMatrixStack *stack,
float left,
float right,
float bottom,
float top,
float z_near,
float z_far)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
cogl_matrix_ortho (&state->matrix,
left, right, bottom, top, z_near, z_far);
/* mark dirty */
stack->flushed_state = NULL;
}
void void
_cogl_matrix_stack_get (CoglMatrixStack *stack, _cogl_matrix_stack_get (CoglMatrixStack *stack,
CoglMatrix *matrix) CoglMatrix *matrix)
@ -280,25 +333,6 @@ _cogl_matrix_stack_set (CoglMatrixStack *stack,
stack->flushed_state = NULL; stack->flushed_state = NULL;
} }
void
_cogl_matrix_stack_frustum (CoglMatrixStack *stack,
float left,
float right,
float bottom,
float top,
float z_near,
float z_far)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
cogl_matrix_frustum (&state->matrix,
left, right, bottom, top,
z_near, z_far);
/* mark dirty */
stack->flushed_state = NULL;
}
void void
_cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack, _cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack,
GLenum gl_mode) GLenum gl_mode)

View File

@ -51,10 +51,6 @@ void _cogl_matrix_stack_rotate (CoglMatrixStack *stack,
float z); float z);
void _cogl_matrix_stack_multiply (CoglMatrixStack *stack, void _cogl_matrix_stack_multiply (CoglMatrixStack *stack,
const CoglMatrix *matrix); const CoglMatrix *matrix);
void _cogl_matrix_stack_get (CoglMatrixStack *stack,
CoglMatrix *matrix);
void _cogl_matrix_stack_set (CoglMatrixStack *stack,
const CoglMatrix *matrix);
void _cogl_matrix_stack_frustum (CoglMatrixStack *stack, void _cogl_matrix_stack_frustum (CoglMatrixStack *stack,
float left, float left,
float right, float right,
@ -62,6 +58,22 @@ void _cogl_matrix_stack_frustum (CoglMatrixStack *stack,
float top, float top,
float z_near, float z_near,
float z_far); float z_far);
void _cogl_matrix_stack_perspective (CoglMatrixStack *stack,
float fov_y,
float aspect,
float z_near,
float z_far);
void _cogl_matrix_stack_ortho (CoglMatrixStack *stack,
float left,
float right,
float bottom,
float top,
float z_near,
float z_far);
void _cogl_matrix_stack_get (CoglMatrixStack *stack,
CoglMatrix *matrix);
void _cogl_matrix_stack_set (CoglMatrixStack *stack,
const CoglMatrix *matrix);
void _cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack, void _cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack,
GLenum gl_mode); GLenum gl_mode);

View File

@ -151,21 +151,6 @@ cogl_matrix_invert (CoglMatrix *matrix)
} }
#endif #endif
void
cogl_matrix_transform_point (const CoglMatrix *matrix,
float *x,
float *y,
float *z,
float *w)
{
float _x = *x, _y = *y, _z = *z, _w = *w;
*x = matrix->xx * _x + matrix->xy * _y + matrix->xz * _z + matrix->xw * _w;
*y = matrix->yx * _x + matrix->yy * _y + matrix->yz * _z + matrix->yw * _w;
*z = matrix->zx * _x + matrix->zy * _y + matrix->zz * _z + matrix->zw * _w;
*w = matrix->wx * _x + matrix->wy * _y + matrix->wz * _z + matrix->ww * _w;
}
void void
cogl_matrix_frustum (CoglMatrix *matrix, cogl_matrix_frustum (CoglMatrix *matrix,
float left, float left,
@ -208,6 +193,62 @@ cogl_matrix_frustum (CoglMatrix *matrix,
cogl_matrix_multiply (matrix, matrix, &frustum); cogl_matrix_multiply (matrix, matrix, &frustum);
} }
void
cogl_matrix_perspective (CoglMatrix *matrix,
float fov_y,
float aspect,
float z_near,
float z_far)
{
float ymax = z_near * tan (fov_y * G_PI / 360.0);
cogl_matrix_frustum (matrix,
-ymax * aspect, /* left */
ymax * aspect, /* right */
-ymax, /* bottom */
ymax, /* top */
z_near,
z_far);
}
void
cogl_matrix_ortho (CoglMatrix *matrix,
float left,
float right,
float bottom,
float top,
float near,
float far)
{
CoglMatrix ortho;
/* column 0 */
ortho.xx = 2.0 / (right - left);
ortho.yx = 0.0;
ortho.zx = 0.0;
ortho.wx = 0.0;
/* column 1 */
ortho.xy = 0.0;
ortho.yy = 2.0 / (top - bottom);
ortho.zy = 0.0;
ortho.wy = 0.0;
/* column 2 */
ortho.xz = 0.0;
ortho.yz = 0.0;
ortho.zz = -2.0 / (far - near);
ortho.wz = 0.0;
/* column 3 */
ortho.xw = -(right + left) / (right - left);
ortho.yw = -(top + bottom) / (top - bottom);
ortho.zw = -(far + near) / (far - near);
ortho.ww = 1.0;
cogl_matrix_multiply (matrix, matrix, &ortho);
}
void void
cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array) cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array)
{ {
@ -220,3 +261,19 @@ cogl_matrix_get_array (const CoglMatrix *matrix)
return (float *)matrix; return (float *)matrix;
} }
void
cogl_matrix_transform_point (const CoglMatrix *matrix,
float *x,
float *y,
float *z,
float *w)
{
float _x = *x, _y = *y, _z = *z, _w = *w;
*x = matrix->xx * _x + matrix->xy * _y + matrix->xz * _z + matrix->xw * _w;
*y = matrix->yx * _x + matrix->yy * _y + matrix->yz * _z + matrix->yw * _w;
*z = matrix->zx * _x + matrix->zy * _y + matrix->zz * _z + matrix->zw * _w;
*w = matrix->wx * _x + matrix->wy * _y + matrix->wz * _z + matrix->ww * _w;
}

View File

@ -29,7 +29,8 @@
#include "cogl-internal.h" #include "cogl-internal.h"
#include "cogl-context.h" #include "cogl-context.h"
#include "cogl-texture-private.h" #include "cogl-texture-private.h"
#include "cogl-material.h" #include "cogl-material-private.h"
#include "cogl-vertex-buffer-private.h"
#include <string.h> #include <string.h>
#include <gmodule.h> #include <gmodule.h>
@ -39,16 +40,8 @@
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
#define glDrawRangeElements ctx->pf_glDrawRangeElements
#define glClientActiveTexture ctx->pf_glClientActiveTexture #define glClientActiveTexture ctx->pf_glClientActiveTexture
#else
/* GLES doesn't have glDrawRangeElements, so we simply pretend it does
* but that it makes no use of the start, end constraints: */
#define glDrawRangeElements(mode, start, end, count, type, indices) \
glDrawElements (mode, count, type, indices)
#endif #endif
/* these are defined in the particular backend */ /* these are defined in the particular backend */
@ -63,7 +56,6 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
gint batch_len, gint batch_len,
GLfloat *vertex_pointer) GLfloat *vertex_pointer)
{ {
int needed_indices;
gsize stride; gsize stride;
int i; int i;
gulong enable_flags = 0; gulong enable_flags = 0;
@ -72,35 +64,6 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* The indices are always the same sequence regardless of the vertices so we
* only need to change it if there are more vertices than ever before. */
needed_indices = batch_len * 6;
if (needed_indices > ctx->static_indices->len)
{
int old_len = ctx->static_indices->len;
int vert_num = old_len / 6 * 4;
GLushort *q;
/* Add two triangles for each quad to the list of
indices. That makes six new indices but two of the
vertices in the triangles are shared. */
g_array_set_size (ctx->static_indices, needed_indices);
q = &g_array_index (ctx->static_indices, GLushort, old_len);
for (i = old_len;
i < ctx->static_indices->len;
i += 6, vert_num += 4)
{
*(q++) = vert_num + 0;
*(q++) = vert_num + 1;
*(q++) = vert_num + 3;
*(q++) = vert_num + 1;
*(q++) = vert_num + 2;
*(q++) = vert_num + 3;
}
}
/* XXX NB: /* XXX NB:
* Our vertex data is arranged as follows: * Our vertex data is arranged as follows:
* 4 vertices per quad: 2 GLfloats per position, * 4 vertices per quad: 2 GLfloats per position,
@ -112,16 +75,16 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
disable_mask = (1 << batch_start->n_layers) - 1; disable_mask = (1 << batch_start->n_layers) - 1;
disable_mask = ~disable_mask; disable_mask = ~disable_mask;
cogl_material_flush_gl_state (ctx->source_material, _cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_FALLBACK_MASK, COGL_MATERIAL_FLUSH_FALLBACK_MASK,
batch_start->fallback_mask, batch_start->fallback_mask,
COGL_MATERIAL_FLUSH_DISABLE_MASK, COGL_MATERIAL_FLUSH_DISABLE_MASK,
disable_mask, disable_mask,
/* Redundant when dealing with unsliced /* Redundant when dealing with unsliced
* textures but does no harm... */ * textures but does no harm... */
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE, COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
batch_start->layer0_override_texture, batch_start->layer0_override_texture,
NULL); NULL);
for (i = 0; i < batch_start->n_layers; i++) for (i = 0; i < batch_start->n_layers; i++)
{ {
@ -140,7 +103,7 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
/* FIXME: This api is a bit yukky, ideally it will be removed if we /* FIXME: This api is a bit yukky, ideally it will be removed if we
* re-work the cogl_enable mechanism */ * re-work the cogl_enable mechanism */
enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material); enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
if (ctx->enable_backface_culling) if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING; enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
@ -150,12 +113,32 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
GE (glVertexPointer (2, GL_FLOAT, stride, vertex_pointer)); GE (glVertexPointer (2, GL_FLOAT, stride, vertex_pointer));
_cogl_current_matrix_state_flush (); _cogl_current_matrix_state_flush ();
GE (glDrawRangeElements (GL_TRIANGLES,
0, ctx->static_indices->len - 1,
6 * batch_len,
GL_UNSIGNED_SHORT,
ctx->static_indices->data));
#ifdef HAVE_COGL_GL
GE( glDrawArrays (GL_QUADS, 0, batch_len * 4) );
#else /* HAVE_COGL_GL */
/* GLES doesn't support GL_QUADS so we will use GL_TRIANGLES and
indices */
{
int needed_indices = batch_len * 6;
CoglHandle indices_handle
= cogl_vertex_buffer_indices_get_for_quads (needed_indices);
CoglVertexBufferIndices *indices
= _cogl_vertex_buffer_indices_pointer_from_handle (indices_handle);
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER,
GPOINTER_TO_UINT (indices->vbo_name)));
GE (glDrawElements (GL_TRIANGLES,
6 * batch_len,
indices->type,
NULL));
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0));
}
#endif /* HAVE_COGL_GL */
/* DEBUGGING CODE XXX: /* DEBUGGING CODE XXX:
* This path will cause all rectangles to be drawn with a red, green * This path will cause all rectangles to be drawn with a red, green
@ -177,7 +160,7 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
color == 1 ? 0xff : 0x00, color == 1 ? 0xff : 0x00,
color == 2 ? 0xff : 0x00, color == 2 ? 0xff : 0x00,
0xff); 0xff);
cogl_material_flush_gl_state (outline, NULL); _cogl_material_flush_gl_state (outline, NULL);
_cogl_current_matrix_state_flush (); _cogl_current_matrix_state_flush ();
GE( glDrawArrays (GL_LINE_LOOP, 4 * i, 4) ); GE( glDrawArrays (GL_LINE_LOOP, 4 * i, 4) );
} }
@ -791,7 +774,7 @@ _cogl_rectangles_with_multitexture_coords (
/* We don't support multi texturing using textures with any waste if the /* We don't support multi texturing using textures with any waste if the
* user has supplied a custom texture matrix, since we don't know if * user has supplied a custom texture matrix, since we don't know if
* the result will end up trying to texture from the waste area. */ * the result will end up trying to texture from the waste area. */
flags = cogl_material_layer_get_flags (layer); flags = _cogl_material_layer_get_flags (layer);
if (flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX if (flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX
&& _cogl_texture_span_has_waste (texture, 0, 0)) && _cogl_texture_span_has_waste (texture, 0, 0))
{ {
@ -1041,13 +1024,13 @@ _cogl_texture_sliced_polygon (CoglTextureVertex *vertices,
v += stride; v += stride;
} }
cogl_material_flush_gl_state (ctx->source_material, _cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_DISABLE_MASK, COGL_MATERIAL_FLUSH_DISABLE_MASK,
(guint32)~1, /* disable all except the (guint32)~1, /* disable all except the
first layer */ first layer */
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE, COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
gl_handle, gl_handle,
NULL); NULL);
_cogl_current_matrix_state_flush (); _cogl_current_matrix_state_flush ();
GE( glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices) ); GE( glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices) );
@ -1136,10 +1119,10 @@ _cogl_multitexture_unsliced_polygon (CoglTextureVertex *vertices,
c[3] = cogl_color_get_alpha_float (&vertices[i].color); c[3] = cogl_color_get_alpha_float (&vertices[i].color);
} }
cogl_material_flush_gl_state (ctx->source_material, _cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_FALLBACK_MASK, COGL_MATERIAL_FLUSH_FALLBACK_MASK,
fallback_mask, fallback_mask,
NULL); NULL);
_cogl_current_matrix_state_flush (); _cogl_current_matrix_state_flush ();
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices)); GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
@ -1175,7 +1158,6 @@ cogl_polygon (CoglTextureVertex *vertices,
{ {
CoglHandle layer = (CoglHandle)tmp->data; CoglHandle layer = (CoglHandle)tmp->data;
CoglHandle tex_handle = cogl_material_layer_get_texture (layer); CoglHandle tex_handle = cogl_material_layer_get_texture (layer);
CoglTexture *tex = _cogl_texture_pointer_from_handle (tex_handle);
if (i == 0 && cogl_texture_is_sliced (tex_handle)) if (i == 0 && cogl_texture_is_sliced (tex_handle))
{ {
@ -1203,7 +1185,8 @@ cogl_polygon (CoglTextureVertex *vertices,
use_sliced_polygon_fallback = TRUE; use_sliced_polygon_fallback = TRUE;
n_layers = 1; n_layers = 1;
if (tex->min_filter != GL_NEAREST || tex->mag_filter != GL_NEAREST) if (cogl_material_layer_get_min_filter (layer) != GL_NEAREST
|| cogl_material_layer_get_mag_filter (layer) != GL_NEAREST)
{ {
static gboolean warning_seen = FALSE; static gboolean warning_seen = FALSE;
if (!warning_seen) if (!warning_seen)
@ -1217,11 +1200,14 @@ cogl_polygon (CoglTextureVertex *vertices,
} }
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
/* Temporarily change the wrapping mode on all of the slices to use {
* a transparent border CoglTexture *tex = _cogl_texture_pointer_from_handle (tex_handle);
* XXX: it's doesn't look like we save/restore this, like the comment /* Temporarily change the wrapping mode on all of the slices to use
* implies? */ * a transparent border
_cogl_texture_set_wrap_mode_parameter (tex, GL_CLAMP_TO_BORDER); * XXX: it's doesn't look like we save/restore this, like
* the comment implies? */
_cogl_texture_set_wrap_mode_parameter (tex, GL_CLAMP_TO_BORDER);
}
#endif #endif
break; break;
} }
@ -1254,7 +1240,7 @@ cogl_polygon (CoglTextureVertex *vertices,
/* Prepare GL state */ /* Prepare GL state */
enable_flags = COGL_ENABLE_VERTEX_ARRAY; enable_flags = COGL_ENABLE_VERTEX_ARRAY;
enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material); enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
if (ctx->enable_backface_culling) if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING; enable_flags |= COGL_ENABLE_BACKFACE_CULLING;

View File

@ -103,159 +103,6 @@ cogl_handle_get_type (void)
return our_type; return our_type;
} }
GType
cogl_pixel_format_get_type (void)
{
static GType gtype = 0;
if (G_UNLIKELY (gtype == 0))
{
static const GEnumValue values[] = {
{ COGL_PIXEL_FORMAT_ANY, "COGL_PIXEL_FORMAT_ANY", "any" },
{ COGL_PIXEL_FORMAT_A_8, "COGL_PIXEL_FORMAT_A_8", "a-8" },
{ COGL_PIXEL_FORMAT_RGB_565, "COGL_PIXEL_FORMAT_RGB_565", "rgb-565" },
{ COGL_PIXEL_FORMAT_RGBA_4444, "COGL_PIXEL_FORMAT_RGBA_4444", "rgba-4444" },
{ COGL_PIXEL_FORMAT_RGBA_5551, "COGL_PIXEL_FORMAT_RGBA_5551", "rgba-5551" },
{ COGL_PIXEL_FORMAT_YUV, "COGL_PIXEL_FORMAT_YUV", "yuv" },
{ COGL_PIXEL_FORMAT_G_8, "COGL_PIXEL_FORMAT_G_8", "g-8" },
{ COGL_PIXEL_FORMAT_RGB_888, "COGL_PIXEL_FORMAT_RGB_888", "rgb-888" },
{ COGL_PIXEL_FORMAT_BGR_888, "COGL_PIXEL_FORMAT_BGR_888", "bgr-888" },
{ COGL_PIXEL_FORMAT_RGBA_8888, "COGL_PIXEL_FORMAT_RGBA_8888", "rgba-8888" },
{ COGL_PIXEL_FORMAT_BGRA_8888, "COGL_PIXEL_FORMAT_BGRA_8888", "bgra-8888" },
{ COGL_PIXEL_FORMAT_ARGB_8888, "COGL_PIXEL_FORMAT_ARGB_8888", "argb-8888" },
{ COGL_PIXEL_FORMAT_ABGR_8888, "COGL_PIXEL_FORMAT_ABGR_8888", "abgr-8888" },
{ COGL_PIXEL_FORMAT_RGBA_8888_PRE, "COGL_PIXEL_FORMAT_RGBA_8888_PRE", "rgba-8888-pre" },
{ COGL_PIXEL_FORMAT_BGRA_8888_PRE, "COGL_PIXEL_FORMAT_BGRA_8888_PRE", "bgra-8888-pre" },
{ COGL_PIXEL_FORMAT_ARGB_8888_PRE, "COGL_PIXEL_FORMAT_ARGB_8888_PRE", "argb-8888-pre" },
{ COGL_PIXEL_FORMAT_ABGR_8888_PRE, "COGL_PIXEL_FORMAT_ABGR_8888_PRE", "abgr-8888-pre" },
{ COGL_PIXEL_FORMAT_RGBA_4444_PRE, "COGL_PIXEL_FORMAT_RGBA_4444_PRE", "rgba-4444-pre" },
{ COGL_PIXEL_FORMAT_RGBA_5551_PRE, "COGL_PIXEL_FORMAT_RGBA_5551_PRE", "rgba-5551-pre" },
{ 0, NULL, NULL }
};
gtype =
g_enum_register_static (g_intern_static_string ("CoglPixelFormat"),
values);
}
return gtype;
}
GType
cogl_feature_flags_get_type (void)
{
static GType gtype = 0;
if (G_UNLIKELY (gtype == 0))
{
static const GFlagsValue values[] = {
{ COGL_FEATURE_TEXTURE_RECTANGLE, "COGL_FEATURE_TEXTURE_RECTANGLE", "texture-rectangle" },
{ COGL_FEATURE_TEXTURE_NPOT, "COGL_FEATURE_TEXTURE_NPOT", "texture-npot" },
{ COGL_FEATURE_TEXTURE_YUV, "COGL_FEATURE_TEXTURE_YUV", "yuv" },
{ COGL_FEATURE_TEXTURE_READ_PIXELS, "COGL_FEATURE_TEXTURE_READ_PIXELS", "read-pixels" },
{ COGL_FEATURE_SHADERS_GLSL, "COGL_FEATURE_SHADERS_GLSL", "shaders-glsl" },
{ COGL_FEATURE_OFFSCREEN, "COGL_FEATURE_OFFSCREEN", "offscreen" },
{ COGL_FEATURE_OFFSCREEN_MULTISAMPLE, "COGL_FEATURE_OFFSCREEN_MULTISAMPLE", "offscreen-multisample" },
{ COGL_FEATURE_OFFSCREEN_BLIT, "COGL_FEATURE_OFFSCREEN_BLIT", "offscreen-blit" },
{ COGL_FEATURE_FOUR_CLIP_PLANES, "COGL_FEATURE_FOUR_CLIP_PLANES", "four-clip-planes" },
{ COGL_FEATURE_STENCIL_BUFFER, "COGL_FEATURE_STENCIL_BUFFER", "stencil-buffer" },
{ 0, NULL, NULL }
};
gtype =
g_flags_register_static (g_intern_static_string ("CoglFeatureFlags"),
values);
}
return gtype;
}
GType
cogl_buffer_target_get_type (void)
{
static GType gtype = 0;
if (G_UNLIKELY (gtype == 0))
{
static const GFlagsValue values[] = {
{ COGL_WINDOW_BUFFER, "COGL_WINDOW_BUFFER", "window-buffer" },
{ COGL_OFFSCREEN_BUFFER, "COGL_OFFSCREEN_BUFFER", "offscreen-buffer" },
{ 0, NULL, NULL }
};
gtype =
g_flags_register_static (g_intern_static_string ("CoglBufferTarget"),
values);
}
return gtype;
}
GType
cogl_matrix_mode_get_type (void)
{
static GType gtype = 0;
if (G_UNLIKELY (gtype == 0))
{
static const GEnumValue values[] = {
{ COGL_MATRIX_MODELVIEW, "COGL_MATRIX_MODELVIEW", "modelview" },
{ COGL_MATRIX_PROJECTION, "COGL_MATRIX_PROJECTION", "projection" },
{ COGL_MATRIX_TEXTURE, "COGL_MATRIX_TEXTURE", "texture" },
{ 0, NULL, NULL }
};
gtype =
g_enum_register_static (g_intern_static_string ("CoglMatrixMode"),
values);
}
return gtype;
}
GType
cogl_texture_flags_get_type (void)
{
static GType gtype = 0;
if (G_UNLIKELY (gtype == 0))
{
static const GFlagsValue values[] = {
{ COGL_TEXTURE_NONE, "COGL_TEXTURE_NONE", "none" },
{ COGL_TEXTURE_AUTO_MIPMAP, "COGL_TEXTURE_AUTO_MIPMAP", "auto-mipmap" },
{ 0, NULL, NULL }
};
gtype =
g_flags_register_static (g_intern_static_string ("CoglTextureFlags"),
values);
}
return gtype;
}
GType
cogl_fog_mode_get_type (void)
{
static GType gtype = 0;
if (G_UNLIKELY (gtype == 0))
{
static const GEnumValue values[] = {
{ COGL_FOG_MODE_LINEAR, "COGL_FOG_MODE_LINEAR", "linear" },
{ COGL_FOG_MODE_EXPONENTIAL, "COGL_FOG_MODE_EXPONENTIAL", "exponential" },
{ COGL_FOG_MODE_EXPONENTIAL_SQUARED, "COGL_FOG_MODE_EXPONENTIAL_SQUARED", "exponential-squared" },
{ 0, NULL, NULL }
};
gtype =
g_enum_register_static (g_intern_static_string ("CoglFogMode"),
values);
}
return gtype;
}
/* /*
* CoglFixed * CoglFixed
*/ */

View File

@ -99,9 +99,9 @@ typedef struct _CoglVertexBufferAttrib
union _u union _u
{ {
const void *pointer; const void *pointer;
gsize vbo_offset; size_t vbo_offset;
} u; } u;
gsize span_bytes; size_t span_bytes;
guint16 stride; guint16 stride;
guint8 n_components; guint8 n_components;
guint8 texture_unit; guint8 texture_unit;
@ -129,25 +129,41 @@ typedef struct _CoglVertexBufferVBO
{ {
CoglVertexBufferVBOFlags flags; CoglVertexBufferVBOFlags flags;
/* Note: this is a pointer to handle fallbacks, and normally holds /* Note: this is a pointer to handle fallbacks. It normally holds
* a GLuint value */ * a GLuint VBO name, but when the driver doesn't support VBOs then
gpointer vbo_name; /*!< The name of the corresponding buffer object */ * this simply points to an malloc'd buffer. */
gsize vbo_bytes; /*!< The lengh of the allocated buffer object in bytes */ void *vbo_name; /*!< The name of the corresponding buffer object */
size_t vbo_bytes; /*!< The lengh of the allocated buffer object in bytes */
GList *attributes; GList *attributes;
} CoglVertexBufferVBO; } CoglVertexBufferVBO;
typedef struct _CoglVertexBufferIndices
{
CoglHandleObject _parent;
/* Note: this is a pointer to handle fallbacks. It normally holds
* a GLuint VBO name, but when the driver doesn't support VBOs then
* this simply points to an malloc'd buffer. */
void *vbo_name;
GLenum type;
} CoglVertexBufferIndices;
typedef struct _CoglVertexBuffer typedef struct _CoglVertexBuffer
{ {
CoglHandleObject _parent; CoglHandleObject _parent;
guint n_vertices; /*!< The number of vertices in the buffer */ int n_vertices; /*!< The number of vertices in the buffer */
GList *submitted_vbos; /* The VBOs currently submitted to the GPU */ GList *submitted_vbos; /* The VBOs currently submitted to the GPU */
/* Note: new_attributes is normally NULL and only valid while /* Note: new_attributes is normally NULL and only valid while
* modifying a buffer. */ * modifying a buffer. */
GList *new_attributes; /*!< attributes pending submission */ GList *new_attributes; /*!< attributes pending submission */
} CoglVertexBuffer; } CoglVertexBuffer;
CoglVertexBuffer *_cogl_vertex_buffer_pointer_from_handle (CoglHandle handle);
CoglVertexBufferIndices *
_cogl_vertex_buffer_indices_pointer_from_handle (CoglHandle handle);
#endif /* __COGL_VERTEX_BUFFER_H */ #endif /* __COGL_VERTEX_BUFFER_H */

View File

@ -136,6 +136,7 @@
#include "cogl-handle.h" #include "cogl-handle.h"
#include "cogl-vertex-buffer-private.h" #include "cogl-vertex-buffer-private.h"
#include "cogl-texture-private.h" #include "cogl-texture-private.h"
#include "cogl-material-private.h"
#define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \ #define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \
(VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1))) (VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1)))
@ -200,8 +201,10 @@
#endif /* HAVE_COGL_GL */ #endif /* HAVE_COGL_GL */
static void _cogl_vertex_buffer_free (CoglVertexBuffer *buffer); static void _cogl_vertex_buffer_free (CoglVertexBuffer *buffer);
static void _cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *buffer_indices);
COGL_HANDLE_DEFINE (VertexBuffer, vertex_buffer); COGL_HANDLE_DEFINE (VertexBuffer, vertex_buffer);
COGL_HANDLE_DEFINE (VertexBufferIndices, vertex_buffer_indices);
CoglHandle CoglHandle
cogl_vertex_buffer_new (guint n_vertices) cogl_vertex_buffer_new (guint n_vertices)
@ -411,13 +414,13 @@ get_gl_type_size (CoglVertexBufferAttribFlags flags)
} }
void void
cogl_vertex_buffer_add (CoglHandle handle, cogl_vertex_buffer_add (CoglHandle handle,
const char *attribute_name, const char *attribute_name,
guint8 n_components, guint8 n_components,
GLenum gl_type, CoglAttributeType type,
gboolean normalized, gboolean normalized,
guint16 stride, guint16 stride,
const void *pointer) const void *pointer)
{ {
CoglVertexBuffer *buffer; CoglVertexBuffer *buffer;
GQuark name_quark = g_quark_from_string (attribute_name); GQuark name_quark = g_quark_from_string (attribute_name);
@ -485,7 +488,7 @@ cogl_vertex_buffer_add (CoglHandle handle,
attribute->u.pointer = pointer; attribute->u.pointer = pointer;
attribute->texture_unit = texture_unit; attribute->texture_unit = texture_unit;
flags |= get_attribute_gl_type_flag_from_gl_type (gl_type); flags |= get_attribute_gl_type_flag_from_gl_type (type);
flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED;
/* Note: We currently just assume, if an attribute is *ever* updated /* Note: We currently just assume, if an attribute is *ever* updated
@ -1638,14 +1641,14 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
} }
} }
cogl_material_flush_gl_state (ctx->source_material, _cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_FALLBACK_MASK, COGL_MATERIAL_FLUSH_FALLBACK_MASK,
fallback_mask, fallback_mask,
COGL_MATERIAL_FLUSH_DISABLE_MASK, COGL_MATERIAL_FLUSH_DISABLE_MASK,
disable_mask, disable_mask,
NULL); NULL);
enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material); enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
if (ctx->enable_backface_culling) if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING; enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
@ -1716,23 +1719,21 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
} }
void void
cogl_vertex_buffer_draw (CoglHandle handle, cogl_vertex_buffer_draw (CoglHandle handle,
GLenum mode, CoglVerticesMode mode,
GLint first, int first,
GLsizei count) int count)
{ {
CoglVertexBuffer *buffer; CoglVertexBuffer *buffer;
if (!cogl_is_vertex_buffer (handle)) if (!cogl_is_vertex_buffer (handle))
return; return;
cogl_clip_ensure ();
buffer = _cogl_vertex_buffer_pointer_from_handle (handle); buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
enable_state_for_drawing_buffer (buffer); cogl_clip_ensure ();
_cogl_current_matrix_state_flush (); _cogl_current_matrix_state_flush ();
enable_state_for_drawing_buffer (buffer);
/* FIXME: flush cogl cache */ /* FIXME: flush cogl cache */
GE (glDrawArrays (mode, first, count)); GE (glDrawArrays (mode, first, count));
@ -1740,35 +1741,127 @@ cogl_vertex_buffer_draw (CoglHandle handle,
disable_state_for_drawing_buffer (buffer); disable_state_for_drawing_buffer (buffer);
} }
static int
get_indices_type_size (GLuint indices_type)
{
if (indices_type == GL_UNSIGNED_BYTE)
return sizeof (GLubyte);
if (indices_type == GL_UNSIGNED_SHORT)
return sizeof (GLushort);
else
{
g_critical ("Unknown indices type %d\n", indices_type);
return 0;
}
}
CoglHandle
cogl_vertex_buffer_indices_new (CoglIndicesType indices_type,
const void *indices_array,
int indices_len)
{
gboolean fallback =
(cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
size_t indices_bytes;
CoglVertexBufferIndices *indices;
_COGL_GET_CONTEXT (ctx, 0);
indices = g_slice_alloc (sizeof (CoglVertexBufferIndices));
if (indices_type == COGL_INDICES_TYPE_UNSIGNED_BYTE)
indices->type = GL_UNSIGNED_BYTE;
else if (indices_type == COGL_INDICES_TYPE_UNSIGNED_SHORT)
indices->type = GL_UNSIGNED_SHORT;
else
{
g_critical ("unknown indices type %d", indices_type);
g_slice_free (CoglVertexBufferIndices, indices);
return 0;
}
indices_bytes = get_indices_type_size (indices->type) * indices_len;
if (fallback)
{
indices->vbo_name = g_malloc (indices_len);
memcpy (indices->vbo_name, indices_array, indices_bytes);
}
else
{
GE (glGenBuffers (1, (GLuint *)&indices->vbo_name));
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER,
GPOINTER_TO_UINT (indices->vbo_name)));
GE (glBufferData (GL_ELEMENT_ARRAY_BUFFER,
indices_bytes,
indices_array,
GL_STATIC_DRAW));
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0));
}
return _cogl_vertex_buffer_indices_handle_new (indices);
}
void void
cogl_vertex_buffer_draw_elements (CoglHandle handle, _cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *indices)
GLenum mode, {
GLuint min_index, gboolean fallback =
GLuint max_index, (cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
GLsizei count,
GLenum indices_type, _COGL_GET_CONTEXT (ctx, NO_RETVAL);
const GLvoid *indices)
if (fallback)
g_free (indices->vbo_name);
else
GE (glDeleteBuffers (1, (GLuint *)&indices->vbo_name));
g_slice_free (CoglVertexBufferIndices, indices);
}
void
cogl_vertex_buffer_draw_elements (CoglHandle handle,
CoglVerticesMode mode,
CoglHandle indices_handle,
int min_index,
int max_index,
int indices_offset,
int count)
{ {
CoglVertexBuffer *buffer; CoglVertexBuffer *buffer;
gboolean fallback =
(cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
size_t byte_offset;
CoglVertexBufferIndices *indices = NULL;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_vertex_buffer (handle)) if (!cogl_is_vertex_buffer (handle))
return; return;
cogl_clip_ensure ();
buffer = _cogl_vertex_buffer_pointer_from_handle (handle); buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
if (!cogl_is_vertex_buffer_indices (indices_handle))
return;
indices = _cogl_vertex_buffer_indices_pointer_from_handle (indices_handle);
cogl_clip_ensure ();
_cogl_current_matrix_state_flush ();
enable_state_for_drawing_buffer (buffer); enable_state_for_drawing_buffer (buffer);
_cogl_current_matrix_state_flush (); byte_offset = indices_offset * get_indices_type_size (indices->type);
if (fallback)
byte_offset = (size_t)(((char *)indices->vbo_name) + byte_offset);
else
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER,
GPOINTER_TO_UINT (indices->vbo_name)));
/* FIXME: flush cogl cache */ /* FIXME: flush cogl cache */
GE (glDrawRangeElements (mode, min_index, max_index, GE (glDrawRangeElements (mode, min_index, max_index,
count, indices_type, indices)); count, indices->type, (void *)byte_offset));
disable_state_for_drawing_buffer (buffer); disable_state_for_drawing_buffer (buffer);
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0));
} }
static void static void
@ -1778,8 +1871,92 @@ _cogl_vertex_buffer_free (CoglVertexBuffer *buffer)
for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next)
cogl_vertex_buffer_vbo_free (tmp->data, TRUE); cogl_vertex_buffer_vbo_free (tmp->data, TRUE);
g_list_free (buffer->submitted_vbos);
for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next)
cogl_vertex_buffer_attribute_free (tmp->data); cogl_vertex_buffer_attribute_free (tmp->data);
g_list_free (buffer->new_attributes);
g_slice_free (CoglVertexBuffer, buffer); g_slice_free (CoglVertexBuffer, buffer);
} }
CoglHandle
cogl_vertex_buffer_indices_get_for_quads (guint n_indices)
{
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
/* Check if the indices would fit in a byte array */
if (n_indices <= 256 / 4 * 6)
{
/* Generate the byte array if we haven't already */
if (ctx->quad_indices_byte == COGL_INVALID_HANDLE)
{
guint8 *byte_array = g_malloc (256 / 4 * 6 * sizeof (guint8));
guint8 *p = byte_array;
int i, vert_num = 0;
for (i = 0; i < 256 / 4; i++)
{
*(p++) = vert_num + 0;
*(p++) = vert_num + 1;
*(p++) = vert_num + 2;
*(p++) = vert_num + 0;
*(p++) = vert_num + 2;
*(p++) = vert_num + 3;
vert_num += 4;
}
ctx->quad_indices_byte
= cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_BYTE,
byte_array,
256 / 4 * 6);
g_free (byte_array);
}
return ctx->quad_indices_byte;
}
else
{
if (ctx->quad_indices_short_len < n_indices)
{
guint16 *short_array;
guint16 *p;
int i, vert_num = 0;
if (ctx->quad_indices_short != COGL_INVALID_HANDLE)
cogl_handle_unref (ctx->quad_indices_short);
/* Pick a power of two >= MAX (512, n_indices) */
if (ctx->quad_indices_short_len == 0)
ctx->quad_indices_short_len = 512;
while (ctx->quad_indices_short_len < n_indices)
ctx->quad_indices_short_len *= 2;
/* Over-allocate to generate a whole number of quads */
p = short_array = g_malloc ((ctx->quad_indices_short_len
+ 5) / 6 * 6
* sizeof (guint16));
/* Fill in the complete quads */
for (i = 0; i < ctx->quad_indices_short_len; i += 6)
{
*(p++) = vert_num + 0;
*(p++) = vert_num + 1;
*(p++) = vert_num + 2;
*(p++) = vert_num + 0;
*(p++) = vert_num + 2;
*(p++) = vert_num + 3;
vert_num += 4;
}
ctx->quad_indices_short
= cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT,
short_array,
ctx->quad_indices_short_len);
g_free (short_array);
}
return ctx->quad_indices_short;
}
}

View File

@ -42,6 +42,7 @@ typedef CoglFuncPtr (*GLXGetProcAddressProc) (const guint8 *procName);
#include "cogl-internal.h" #include "cogl-internal.h"
#include "cogl-util.h" #include "cogl-util.h"
#include "cogl-context.h" #include "cogl-context.h"
#include "cogl-material-private.h"
#if defined (HAVE_COGL_GLES2) || defined (HAVE_COGL_GLES) #if defined (HAVE_COGL_GLES2) || defined (HAVE_COGL_GLES)
#include "cogl-gles2-wrapper.h" #include "cogl-gles2-wrapper.h"
@ -213,30 +214,39 @@ cogl_get_enable ()
} }
void void
cogl_enable_depth_test (gboolean setting) cogl_set_depth_test_enabled (gboolean setting)
{ {
if (setting) if (setting)
{ {
glEnable (GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
glEnable (GL_ALPHA_TEST);
glDepthFunc (GL_LEQUAL); glDepthFunc (GL_LEQUAL);
glAlphaFunc (GL_GREATER, 0.1);
} }
else else
{ glDisable (GL_DEPTH_TEST);
glDisable (GL_DEPTH_TEST); }
glDisable (GL_ALPHA_TEST);
} gboolean
cogl_get_depth_test_enabled (void)
{
return glIsEnabled (GL_DEPTH_TEST) == GL_TRUE ? TRUE : FALSE;
} }
void void
cogl_enable_backface_culling (gboolean setting) cogl_set_backface_culling_enabled (gboolean setting)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
ctx->enable_backface_culling = setting; ctx->enable_backface_culling = setting;
} }
gboolean
cogl_get_backface_culling_enabled (void)
{
_COGL_GET_CONTEXT (ctx, FALSE);
return ctx->enable_backface_culling;
}
void void
cogl_set_source_color (const CoglColor *color) cogl_set_source_color (const CoglColor *color)
{ {
@ -375,7 +385,7 @@ _cogl_add_stencil_clip (float x_offset,
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
cogl_material_flush_gl_state (ctx->stencil_material, NULL); _cogl_material_flush_gl_state (ctx->stencil_material, NULL);
if (first) if (first)
{ {
@ -465,12 +475,12 @@ cogl_viewport (guint width,
} }
void void
cogl_setup_viewport (guint width, _cogl_setup_viewport (guint width,
guint height, guint height,
float fovy, float fovy,
float aspect, float aspect,
float z_near, float z_near,
float z_far) float z_far)
{ {
float z_camera; float z_camera;
CoglMatrix projection_matrix; CoglMatrix projection_matrix;
@ -478,7 +488,7 @@ cogl_setup_viewport (guint width,
GE( glViewport (0, 0, width, height) ); GE( glViewport (0, 0, width, height) );
/* For Ortho projection. /* For Ortho projection.
* _cogl_current_matrix_ortho (0, width << 16, 0, height << 16, -1 << 16, 1 << 16); * _cogl_current_matrix_ortho (0, width, 0, height, -1, 1);
*/ */
cogl_perspective (fovy, aspect, z_near, z_far); cogl_perspective (fovy, aspect, z_near, z_far);
@ -532,7 +542,7 @@ cogl_setup_viewport (guint width,
} }
CoglFeatureFlags CoglFeatureFlags
cogl_get_features () cogl_get_features (void)
{ {
_COGL_GET_CONTEXT (ctx, 0); _COGL_GET_CONTEXT (ctx, 0);
@ -653,9 +663,11 @@ cogl_disable_fog (void)
glDisable (GL_FOG); glDisable (GL_FOG);
} }
#if 0
void void
cogl_flush_gl_state (int flags) cogl_flush_gl_state (int flags)
{ {
_cogl_current_matrix_state_flush (); _cogl_current_matrix_state_flush ();
} }
#endif

View File

@ -24,7 +24,7 @@ DOC_SOURCE_DIR=../../../clutter/cogl
SCANGOBJ_OPTIONS=--type-init-func="g_type_init()" SCANGOBJ_OPTIONS=--type-init-func="g_type_init()"
# Extra options to supply to gtkdoc-scan. # Extra options to supply to gtkdoc-scan.
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
SCAN_OPTIONS=--deprecated-guards="COGL_DISABLE_DEPRECATED" SCAN_OPTIONS=--deprecated-guards="COGL_DISABLE_DEPRECATED"
# Extra options to supply to gtkdoc-mkdb. # Extra options to supply to gtkdoc-mkdb.
@ -70,12 +70,14 @@ HTML_IMAGES=
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml # e.g. content_files=running.sgml building.sgml changes-2.0.sgml
content_files= version.xml content_files = \
blend-strings.xml
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
# These files must be listed here *and* in content_files # These files must be listed here *and* in content_files
# e.g. expand_content_files=running.sgml # e.g. expand_content_files=running.sgml
expand_content_files= expand_content_files = \
blend-strings.xml
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
# Only needed if you are using gtkdoc-scangobj to dynamically query widget # Only needed if you are using gtkdoc-scangobj to dynamically query widget
@ -91,4 +93,3 @@ include $(top_srcdir)/gtk-doc.make
# Other files to distribute # Other files to distribute
# e.g. EXTRA_DIST += version.xml.in # e.g. EXTRA_DIST += version.xml.in
EXTRA_DIST += version.xml.in

View File

@ -0,0 +1,130 @@
<?xml version="1.0"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY version SYSTEM "version.xml">
]>
<refentry id="cogl-Blend-Strings">
<refmeta>
<refentrytitle role="top_of_page" id="cogl-Blend-Strings.top_of_page">Material Blend Strings</refentrytitle>
<manvolnum>3</manvolnum>
<refmiscinfo>COGL Library</refmiscinfo>
</refmeta>
<refnamediv>
<refname>Material Blend Strings</refname>
<refpurpose>A simple syntax and grammar for describing blending and texture
combining functions.</refpurpose>
</refnamediv>
<refsect1 id="cogl-Blend-Strings.description" role="desc">
<title>Cogl Blend Strings</title>
<para>
Describing GPU blending and texture combining states is rather awkward to do
in a consise but also readable fashion. Cogl helps by supporting
string based descriptions using a simple syntax.
</para>
<section>
<title>Some examples</title>
<para>Here is an example used for blending:</para>
<programlisting>
"RGBA = ADD (SRC_COLOR * (SRC_COLOR[A]), DST_COLOR * (1-SRC_COLOR[A]))"
</programlisting>
<para>In OpenGL terms this replaces glBlendFunc[Separate] and
glBlendEquation[Separate]</para>
<para>
Actually in this case it's more verbose than the GL equivalent:
</para>
<programlisting>
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
</programlisting>
<para>
But unless you are familiar with OpenGL or refer to its API documentation
you wouldn't know that the default function used by OpenGL is GL_FUNC_ADD
nor would you know that the above arguments determine what the source color
and destination color will be multiplied by before being adding.
</para>
<para>Here is an example used for texture combining:</para>
<programlisting>
"RGB = REPLACE (PREVIOUS)"
"A = MODULATE (PREVIOUS, TEXTURE)"
</programlisting>
<para>
In OpenGL terms this replaces glTexEnv, and the above example is equivalent
to this OpenGL code:
</para>
<programlisting>
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
</programlisting>
</section>
<section id="cogl-Blend-String-syntax">
<title>Here's the syntax</title>
<programlisting>
&lt;statement&gt;:
&lt;channel-mask&gt;=&lt;function-name&gt;(&lt;arg-list&gt;)
You can either use a single statement with an RGBA channel-mask or you can use
two statements; one with an A channel-mask and the other with an RGB
channel-mask.
&lt;channel-mask&gt;:
A or RGB or RGBA
&lt;function-name&gt;:
[A-Za-z_]*
&lt;arg-list&gt;:
&lt;arg&gt;,&lt;arg&gt;
or &lt;arg&gt;
or ""
I.e. functions may take 0 or more arguments
&lt;arg&gt;:
&lt;color-source&gt;
1 - &lt;color-source&gt; : Only intended for texture combining
&lt;color-source&gt; * ( &lt;factor&gt; ) : Only intended for blending
0 : Only intended for blending
See the blending or texture combining sections for further notes and examples.
&lt;color-source&gt;:
&lt;source-name&gt;[&lt;channel-mask&gt;]
&lt;source-name&gt;
See the blending or texture combining sections for the list of source-names
valid in each context.
If a channel mask is not given then the channel mask of the statement
is assumed instead.
&lt;factor&gt;:
0
1
&lt;color-source&gt;
1-&lt;color-source&gt;
SRC_ALPHA_SATURATE
</programlisting>
</section>
</refsect1>
</refentry>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY version SYSTEM "version.xml"> <!ENTITY version "@VERSION@">
]> ]>
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude"> <book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
@ -55,6 +55,7 @@
<xi:include href="xml/cogl.xml"/> <xi:include href="xml/cogl.xml"/>
<xi:include href="xml/cogl-color.xml"/> <xi:include href="xml/cogl-color.xml"/>
<xi:include href="xml/cogl-texture.xml"/> <xi:include href="xml/cogl-texture.xml"/>
<xi:include href="blend-strings.xml"/>
<xi:include href="xml/cogl-material.xml"/> <xi:include href="xml/cogl-material.xml"/>
<xi:include href="xml/cogl-primitives.xml"/> <xi:include href="xml/cogl-primitives.xml"/>
<xi:include href="xml/cogl-vertex-buffer.xml"/> <xi:include href="xml/cogl-vertex-buffer.xml"/>

View File

@ -15,33 +15,35 @@ COGL_UNPREMULT_MASK
CoglPixelFormat CoglPixelFormat
CoglBufferTarget CoglBufferTarget
<SUBSECTION> <SUBSECTION>
cogl_create_context
cogl_destroy_context
<SUBSECTION>
CoglFeatureFlags CoglFeatureFlags
cogl_get_features cogl_get_features
cogl_features_available cogl_features_available
cogl_check_extension cogl_check_extension
cogl_get_proc_address cogl_get_proc_address
<SUBSECTION> <SUBSECTION>
cogl_perspective
cogl_frustum
cogl_setup_viewport
cogl_viewport
cogl_get_modelview_matrix
cogl_get_projection_matrix
cogl_get_viewport
<SUBSECTION>
cogl_push_matrix cogl_push_matrix
cogl_pop_matrix cogl_pop_matrix
cogl_scale cogl_scale
cogl_translate cogl_translate
cogl_rotate cogl_rotate
cogl_frustum
cogl_perspective
cogl_ortho
<SUBSECTION>
cogl_get_modelview_matrix
cogl_set_modelview_matrix
cogl_get_projection_matrix
cogl_set_projection_matrix
cogl_viewport
cogl_setup_viewport
cogl_get_viewport
<SUBSECTION> <SUBSECTION>
cogl_clear cogl_clear
cogl_get_bitmasks cogl_get_bitmasks
cogl_enable_depth_test cogl_set_depth_test_enabled
cogl_enable_backface_culling cogl_get_depth_test_enabled
cogl_set_backface_culling_enabled
cogl_get_backface_culling_enabled
<SUBSECTION> <SUBSECTION>
CoglFogMode CoglFogMode
cogl_set_fog cogl_set_fog
@ -130,12 +132,9 @@ cogl_texture_get_height
cogl_texture_get_format cogl_texture_get_format
cogl_texture_get_rowstride cogl_texture_get_rowstride
cogl_texture_get_max_waste cogl_texture_get_max_waste
cogl_texture_get_min_filter
cogl_texture_get_mag_filter
cogl_texture_is_sliced cogl_texture_is_sliced
cogl_texture_get_gl_texture cogl_texture_get_gl_texture
cogl_texture_get_data cogl_texture_get_data
cogl_texture_set_filters
cogl_texture_set_region cogl_texture_set_region
</SECTION> </SECTION>
@ -307,7 +306,11 @@ cogl_vertex_buffer_submit
cogl_vertex_buffer_disable cogl_vertex_buffer_disable
cogl_vertex_buffer_enable cogl_vertex_buffer_enable
cogl_vertex_buffer_draw cogl_vertex_buffer_draw
CoglIndicesType
cogl_vertex_buffer_add_indices
cogl_vertex_buffer_delete_indices
cogl_vertex_buffer_draw_elements cogl_vertex_buffer_draw_elements
cogl_vertex_buffer_indices_get_for_quads
<SUBSECTION Private> <SUBSECTION Private>
CoglVertexBufferAttribFlags CoglVertexBufferAttribFlags
COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_MASK COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_MASK
@ -349,41 +352,35 @@ cogl_material_set_specular
cogl_material_get_specular cogl_material_get_specular
cogl_material_set_shininess cogl_material_set_shininess
cogl_material_get_shininess cogl_material_get_shininess
<SUBSECTION Advanced Blending>
CoglMaterialAlphaFunc CoglMaterialAlphaFunc
cogl_material_set_alpha_test_function cogl_material_set_alpha_test_function
CoglMaterialBlendFactor CoglMaterialBlendFactor
cogl_material_set_blend_factors cogl_material_set_blend
cogl_material_set_blend_constant
cogl_material_set_layer cogl_material_set_layer
cogl_material_remove_layer cogl_material_remove_layer
CoglMaterialLayerCombineFunc cogl_material_set_layer_combine
cogl_material_set_layer_combine_function cogl_material_set_layer_combine_constant
CoglMaterialLayerCombineChannels
CoglMaterialLayerCombineSrc
cogl_material_set_layer_combine_arg_src
CoglMaterialLayerCombineOp
cogl_material_set_layer_combine_arg_op
cogl_material_set_layer_matrix cogl_material_set_layer_matrix
cogl_material_get_layers
CoglMaterialFilter
cogl_material_set_layer_filters
cogl_material_layer_get_type
cogl_material_layer_get_texture
cogl_material_layer_get_min_filter
cogl_material_layer_get_mag_filter
<SUBSECTION Private> <SUBSECTION Private>
CoglMaterial CoglMaterial
CoglMaterialFlags CoglMaterialFlags
CoglMaterialLayerPrivFlags CoglMaterialLayerPrivFlags
cogl_material_set_layer_alpha_combine
cogl_material_set_layer_rgb_combine
</SECTION> </SECTION>
<SECTION> <SECTION>
<FILE>cogl-material-internals</FILE> <FILE>cogl-material-internals</FILE>
<TITLE>Material Internals</TITLE> <TITLE>Material Internals</TITLE>
cogl_material_get_cogl_enable_flags
CoglMaterialFlushOption
cogl_material_flush_gl_state
CoglMaterialLayer CoglMaterialLayer
cogl_material_get_layers cogl_material_get_layers
CoglMaterialLayerType CoglMaterialLayerType
cogl_material_layer_get_type cogl_material_layer_get_type
CoglMaterialLayerFlags
cogl_material_layer_get_flags
cogl_material_layer_get_texture cogl_material_layer_get_texture
cogl_material_layer_flush_gl_sampler_state
</SECTION> </SECTION>

View File

@ -1 +0,0 @@
@CLUTTER_VERSION@

View File

@ -35,11 +35,6 @@ cogl_sources = \
cogl-context.c \ cogl-context.c \
$(NULL) $(NULL)
coglincludedir = $(includedir)/clutter-@CLUTTER_API_VERSION@/cogl
coglinclude_HEADERS = \
$(cogl_headers) \
$(top_builddir)/clutter/cogl/cogl.h
INCLUDES = \ INCLUDES = \
-I$(top_srcdir)/clutter/cogl \ -I$(top_srcdir)/clutter/cogl \
-I$(top_srcdir)/clutter/cogl/common \ -I$(top_srcdir)/clutter/cogl/common \
@ -50,12 +45,12 @@ INCLUDES = \
-DG_LOG_DOMAIN=\"Cogl-GL\" \ -DG_LOG_DOMAIN=\"Cogl-GL\" \
-DCLUTTER_COMPILATION -DCLUTTER_COMPILATION
noinst_LTLIBRARIES = libclutter-cogl.la noinst_LTLIBRARIES = libclutter-cogl-gl.la
libclutter_cogl_la_CPPFLAGS = $(CLUTTER_CFLAGS) $(COGL_DEBUG_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS) libclutter_cogl_gl_la_CPPFLAGS = $(CLUTTER_CFLAGS) $(COGL_DEBUG_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS)
libclutter_cogl_la_LIBADD = -lm $(CLUTTER_LIBS) $(top_builddir)/clutter/cogl/common/libclutter-cogl-common.la libclutter_cogl_gl_la_LIBADD = -lm $(CLUTTER_LIBS) $(top_builddir)/clutter/cogl/common/libclutter-cogl-common.la
libclutter_cogl_la_DEPENDENCIES = $(top_builddir)/clutter/cogl/common/libclutter-cogl-common.la libclutter_cogl_gl_la_DEPENDENCIES = $(top_builddir)/clutter/cogl/common/libclutter-cogl-common.la
libclutter_cogl_la_SOURCES = \ libclutter_cogl_gl_la_SOURCES = \
$(top_builddir)/clutter/cogl/cogl.h \ $(top_builddir)/clutter/cogl/cogl.h \
$(cogl_headers) \ $(cogl_headers) \
$(cogl_priv_headers) \ $(cogl_priv_headers) \

View File

@ -37,7 +37,7 @@
static CoglContext *_context = NULL; static CoglContext *_context = NULL;
static gboolean gl_is_indirect = FALSE; static gboolean gl_is_indirect = FALSE;
gboolean static gboolean
cogl_create_context () cogl_create_context ()
{ {
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 }; GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
@ -69,7 +69,6 @@ cogl_create_context ()
_context->journal = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry)); _context->journal = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry));
_context->logged_vertices = g_array_new (FALSE, FALSE, sizeof (GLfloat)); _context->logged_vertices = g_array_new (FALSE, FALSE, sizeof (GLfloat));
_context->static_indices = g_array_new (FALSE, FALSE, sizeof (GLushort));
_context->polygon_vertices = g_array_new (FALSE, FALSE, _context->polygon_vertices = g_array_new (FALSE, FALSE,
sizeof (CoglTextureGLVertex)); sizeof (CoglTextureGLVertex));
@ -136,6 +135,9 @@ cogl_create_context ()
_context->pf_glActiveTexture = NULL; _context->pf_glActiveTexture = NULL;
_context->pf_glClientActiveTexture = NULL; _context->pf_glClientActiveTexture = NULL;
_context->pf_glBlendFuncSeparate = NULL;
_context->pf_glBlendEquationSeparate = NULL;
/* Initialise the clip stack */ /* Initialise the clip stack */
_cogl_clip_stack_state_init (); _cogl_clip_stack_state_init ();
@ -146,8 +148,7 @@ cogl_create_context ()
_context->default_gl_texture_2d_tex = _context->default_gl_texture_2d_tex =
cogl_texture_new_from_data (1, /* width */ cogl_texture_new_from_data (1, /* width */
1, /* height */ 1, /* height */
-1, /* max waste */ COGL_TEXTURE_NO_SLICING,
COGL_TEXTURE_NONE, /* flags */
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */ COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
/* internal format */ /* internal format */
COGL_PIXEL_FORMAT_RGBA_8888, COGL_PIXEL_FORMAT_RGBA_8888,
@ -156,8 +157,7 @@ cogl_create_context ()
_context->default_gl_texture_rect_tex = _context->default_gl_texture_rect_tex =
cogl_texture_new_from_data (1, /* width */ cogl_texture_new_from_data (1, /* width */
1, /* height */ 1, /* height */
-1, /* max waste */ COGL_TEXTURE_NO_SLICING,
COGL_TEXTURE_NONE, /* flags */
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */ COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
/* internal format */ /* internal format */
COGL_PIXEL_FORMAT_RGBA_8888, COGL_PIXEL_FORMAT_RGBA_8888,
@ -165,16 +165,20 @@ cogl_create_context ()
default_texture_data); default_texture_data);
cogl_set_source (_context->default_material); cogl_set_source (_context->default_material);
cogl_material_flush_gl_state (_context->source_material, NULL); _cogl_material_flush_gl_state (_context->source_material, NULL);
enable_flags = enable_flags =
cogl_material_get_cogl_enable_flags (_context->source_material); _cogl_material_get_cogl_enable_flags (_context->source_material);
cogl_enable (enable_flags); cogl_enable (enable_flags);
_context->quad_indices_byte = COGL_INVALID_HANDLE;
_context->quad_indices_short = COGL_INVALID_HANDLE;
_context->quad_indices_short_len = 0;
return TRUE; return TRUE;
} }
void void
cogl_destroy_context () _cogl_destroy_context ()
{ {
if (_context == NULL) if (_context == NULL)
return; return;
@ -199,13 +203,16 @@ cogl_destroy_context ()
if (_context->logged_vertices) if (_context->logged_vertices)
g_array_free (_context->logged_vertices, TRUE); g_array_free (_context->logged_vertices, TRUE);
if (_context->static_indices)
g_array_free (_context->static_indices, TRUE);
if (_context->polygon_vertices) if (_context->polygon_vertices)
g_array_free (_context->polygon_vertices, TRUE); g_array_free (_context->polygon_vertices, TRUE);
if (_context->current_layers) if (_context->current_layers)
g_array_free (_context->current_layers, TRUE); g_array_free (_context->current_layers, TRUE);
if (_context->quad_indices_byte)
cogl_handle_unref (_context->quad_indices_byte);
if (_context->quad_indices_short)
cogl_handle_unref (_context->quad_indices_short);
g_free (_context); g_free (_context);
} }

View File

@ -78,7 +78,6 @@ typedef struct
* can batch things together. */ * can batch things together. */
GArray *journal; GArray *journal;
GArray *logged_vertices; GArray *logged_vertices;
GArray *static_indices;
GArray *polygon_vertices; GArray *polygon_vertices;
/* Some simple caching, to minimize state changes... */ /* Some simple caching, to minimize state changes... */
@ -102,6 +101,12 @@ typedef struct
floatVec2 path_nodes_max; floatVec2 path_nodes_max;
CoglHandle stencil_material; CoglHandle stencil_material;
/* Pre-generated VBOs containing indices to generate GL_TRIANGLES
out of a vertex array of quads */
CoglHandle quad_indices_byte;
guint quad_indices_short_len;
CoglHandle quad_indices_short;
/* Relying on glext.h to define these */ /* Relying on glext.h to define these */
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT; COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;
COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT; COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT;
@ -115,6 +120,7 @@ typedef struct
COGL_PFNGLDELETEFRAMEBUFFERSEXTPROC pf_glDeleteFramebuffersEXT; COGL_PFNGLDELETEFRAMEBUFFERSEXTPROC pf_glDeleteFramebuffersEXT;
COGL_PFNGLBLITFRAMEBUFFEREXTPROC pf_glBlitFramebufferEXT; COGL_PFNGLBLITFRAMEBUFFEREXTPROC pf_glBlitFramebufferEXT;
COGL_PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC pf_glRenderbufferStorageMultisampleEXT; COGL_PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC pf_glRenderbufferStorageMultisampleEXT;
COGL_PFNGLGENERATEMIPMAPEXTPROC pf_glGenerateMipmapEXT;
COGL_PFNGLCREATEPROGRAMOBJECTARBPROC pf_glCreateProgramObjectARB; COGL_PFNGLCREATEPROGRAMOBJECTARBPROC pf_glCreateProgramObjectARB;
COGL_PFNGLCREATESHADEROBJECTARBPROC pf_glCreateShaderObjectARB; COGL_PFNGLCREATESHADEROBJECTARBPROC pf_glCreateShaderObjectARB;
@ -164,6 +170,11 @@ typedef struct
COGL_PFNGLACTIVETEXTUREPROC pf_glActiveTexture; COGL_PFNGLACTIVETEXTUREPROC pf_glActiveTexture;
COGL_PFNGLCLIENTACTIVETEXTUREPROC pf_glClientActiveTexture; COGL_PFNGLCLIENTACTIVETEXTUREPROC pf_glClientActiveTexture;
COGL_PFNGLBLENDEQUATIONPROC pf_glBlendEquation;
COGL_PFNGLBLENDCOLORPROC pf_glBlendColor;
COGL_PFNGLBLENDFUNCSEPARATEPROC pf_glBlendFuncSeparate;
COGL_PFNGLBLENDEQUATIONSEPARATEPROC pf_glBlendEquationSeparate;
} CoglContext; } CoglContext;
CoglContext * CoglContext *

View File

@ -773,6 +773,10 @@ typedef void
GLsizei width, GLsizei width,
GLsizei height); GLsizei height);
typedef void
(APIENTRYP COGL_PFNGLGENERATEMIPMAPEXTPROC)
(GLenum target);
typedef GLhandleARB typedef GLhandleARB
(APIENTRYP COGL_PFNGLCREATEPROGRAMOBJECTARBPROC) (APIENTRYP COGL_PFNGLCREATEPROGRAMOBJECTARBPROC)
(void); (void);
@ -1020,6 +1024,29 @@ typedef void
(APIENTRYP COGL_PFNGLCLIENTACTIVETEXTUREPROC) (APIENTRYP COGL_PFNGLCLIENTACTIVETEXTUREPROC)
(GLenum texture); (GLenum texture);
typedef void
(APIENTRYP COGL_PFNGLBLENDFUNCSEPARATEPROC)
(GLenum srcRGB,
GLenum dstRGB,
GLenum srcAlpha,
GLenum dstAlpha);
typedef void
(APIENTRYP COGL_PFNGLBLENDEQUATIONSEPARATEPROC)
(GLenum modeRGB,
GLenum modeAlpha);
typedef void
(APIENTRYP COGL_PFNGLBLENDEQUATIONPROC)
(GLenum mode);
typedef void
(APIENTRYP COGL_PFNGLBLENDCOLORPROC)
(GLclampf red,
GLclampf green,
GLclampf blue,
GLclampf alpha);
G_END_DECLS G_END_DECLS
#endif #endif

View File

@ -29,6 +29,7 @@
#include "cogl-internal.h" #include "cogl-internal.h"
#include "cogl-context.h" #include "cogl-context.h"
#include "cogl-clip-stack.h" #include "cogl-clip-stack.h"
#include "cogl-material-private.h"
#include <string.h> #include <string.h>
#include <gmodule.h> #include <gmodule.h>
@ -78,13 +79,13 @@ _cogl_path_stroke_nodes ()
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material); enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
cogl_enable (enable_flags); cogl_enable (enable_flags);
cogl_material_flush_gl_state (ctx->source_material, _cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_DISABLE_MASK, COGL_MATERIAL_FLUSH_DISABLE_MASK,
(guint32)~0, /* disable all texture layers */ (guint32)~0, /* disable all texture layers */
NULL); NULL);
_cogl_current_matrix_state_flush (); _cogl_current_matrix_state_flush ();
while (path_start < ctx->path_nodes->len) while (path_start < ctx->path_nodes->len)
@ -133,10 +134,10 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Just setup a simple material that doesn't use texturing... */ /* Just setup a simple material that doesn't use texturing... */
cogl_material_flush_gl_state (ctx->stencil_material, NULL); _cogl_material_flush_gl_state (ctx->stencil_material, NULL);
enable_flags |= enable_flags |=
cogl_material_get_cogl_enable_flags (ctx->source_material); _cogl_material_get_cogl_enable_flags (ctx->source_material);
cogl_enable (enable_flags); cogl_enable (enable_flags);
_cogl_path_get_bounds (nodes_min, nodes_max, _cogl_path_get_bounds (nodes_min, nodes_max,

View File

@ -108,22 +108,23 @@ cogl_shader_compile (CoglHandle handle)
glCompileShaderARB (shader->gl_handle); glCompileShaderARB (shader->gl_handle);
} }
void gchar *
cogl_shader_get_info_log (CoglHandle handle, cogl_shader_get_info_log (CoglHandle handle)
size_t size,
char *buffer)
{ {
CoglShader *shader; CoglShader *shader;
char buffer[512];
int len; int len;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NULL);
if (!cogl_is_shader (handle)) if (!cogl_is_shader (handle))
return; return NULL;
shader = _cogl_shader_pointer_from_handle (handle); shader = _cogl_shader_pointer_from_handle (handle);
glGetInfoLogARB (shader->gl_handle, size-1, &len, buffer); glGetInfoLogARB (shader->gl_handle, 511, &len, buffer);
buffer[len]='\0'; buffer[len]='\0';
return g_strdup (buffer);
} }
CoglShaderType CoglShaderType

View File

@ -30,6 +30,7 @@
typedef struct _CoglTexture CoglTexture; typedef struct _CoglTexture CoglTexture;
typedef struct _CoglTexSliceSpan CoglTexSliceSpan; typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
typedef struct _CoglSpanIter CoglSpanIter; typedef struct _CoglSpanIter CoglSpanIter;
typedef struct _CoglTexturePixel CoglTexturePixel;
struct _CoglTexSliceSpan struct _CoglTexSliceSpan
{ {
@ -55,6 +56,18 @@ struct _CoglSpanIter
gboolean intersects; gboolean intersects;
}; };
/* This is used to store the first pixel of each slice. This is only
used when glGenerateMipmap is not available */
struct _CoglTexturePixel
{
/* We need to store the format of the pixel because we store the
data in the source format which might end up being different for
each slice if a subregion is updated with a different format */
GLenum gl_format;
GLenum gl_type;
guint8 data[4];
};
struct _CoglTexture struct _CoglTexture
{ {
CoglHandleObject _parent; CoglHandleObject _parent;
@ -68,11 +81,17 @@ struct _CoglTexture
GArray *slice_y_spans; GArray *slice_y_spans;
GArray *slice_gl_handles; GArray *slice_gl_handles;
gint max_waste; gint max_waste;
CoglTextureFilter min_filter; GLenum min_filter;
CoglTextureFilter mag_filter; GLenum mag_filter;
gboolean is_foreign; gboolean is_foreign;
GLint wrap_mode; GLint wrap_mode;
gboolean auto_mipmap; gboolean auto_mipmap;
gboolean mipmaps_dirty;
/* This holds a copy of the first pixel in each slice. It is only
used to force an automatic update of the mipmaps when
glGenerateMipmap is not available. */
CoglTexturePixel *first_pixels;
}; };
/* To improve batching of geometry when submitting vertices to OpenGL we /* To improve batching of geometry when submitting vertices to OpenGL we
@ -93,6 +112,14 @@ void
_cogl_texture_set_wrap_mode_parameter (CoglTexture *tex, _cogl_texture_set_wrap_mode_parameter (CoglTexture *tex,
GLenum wrap_mode); GLenum wrap_mode);
void
_cogl_texture_set_filters (CoglHandle handle,
GLenum min_filter,
GLenum mag_filter);
void
_cogl_texture_ensure_mipmaps (CoglHandle handle);
gboolean gboolean
_cogl_texture_span_has_waste (CoglTexture *tex, _cogl_texture_span_has_waste (CoglTexture *tex,
gint x_span_index, gint x_span_index,

View File

@ -49,6 +49,7 @@
#define glDrawRangeElements ctx->pf_glDrawRangeElements #define glDrawRangeElements ctx->pf_glDrawRangeElements
#define glActiveTexture ctx->pf_glActiveTexture #define glActiveTexture ctx->pf_glActiveTexture
#define glClientActiveTexture ctx->pf_glClientActiveTexture #define glClientActiveTexture ctx->pf_glClientActiveTexture
#define glGenerateMipmap ctx->pf_glGenerateMipmapEXT
#else #else
@ -247,11 +248,12 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
/* Iterate horizontal slices */ /* Iterate horizontal slices */
for (x = 0; x < tex->slice_x_spans->len; ++x) for (x = 0; x < tex->slice_x_spans->len; ++x)
{ {
gint slice_num = y * tex->slice_x_spans->len + x;
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, x); x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, x);
/* Pick the gl texture object handle */ /* Pick the gl texture object handle */
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, gl_handle = g_array_index (tex->slice_gl_handles, GLuint, slice_num);
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 */
prep_for_gl_pixels_upload (tex->bitmap.rowstride, prep_for_gl_pixels_upload (tex->bitmap.rowstride,
@ -259,6 +261,17 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
y_span->start, y_span->start,
bpp); bpp);
/* Keep a copy of the first pixel if needed */
if (tex->first_pixels)
{
memcpy (tex->first_pixels[slice_num].data,
tex->bitmap.data + x_span->start * bpp
+ y_span->start * tex->bitmap.rowstride,
bpp);
tex->first_pixels[slice_num].gl_format = tex->gl_format;
tex->first_pixels[slice_num].gl_type = tex->gl_type;
}
/* Upload new image data */ /* Upload new image data */
GE( glBindTexture (tex->gl_target, gl_handle) ); GE( glBindTexture (tex->gl_target, gl_handle) );
@ -343,6 +356,8 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
if (waste_buf) if (waste_buf)
g_free (waste_buf); g_free (waste_buf);
tex->mipmaps_dirty = TRUE;
return TRUE; return TRUE;
} }
@ -494,6 +509,8 @@ _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 )
{ {
gint slice_num;
/* Discard slices out of the subregion early */ /* Discard slices out of the subregion early */
if (!x_iter.intersects) if (!x_iter.intersects)
{ {
@ -516,10 +533,10 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
local_y = (y_iter.intersect_start - local_y = (y_iter.intersect_start -
y_iter.pos); y_iter.pos);
slice_num = y_iter.index * tex->slice_x_spans->len + x_iter.index;
/* 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, slice_num);
y_iter.index * tex->slice_x_spans->len +
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, prep_for_gl_pixels_upload (source_bmp->rowstride,
@ -527,6 +544,17 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
source_y, source_y,
bpp); bpp);
/* Keep a copy of the first pixel if needed */
if (tex->first_pixels && local_x == 0 && local_y == 0)
{
memcpy (tex->first_pixels[slice_num].data,
source_bmp->data + source_x * bpp
+ source_y * source_bmp->rowstride,
bpp);
tex->first_pixels[slice_num].gl_format = source_gl_format;
tex->first_pixels[slice_num].gl_type = source_gl_type;
}
/* Upload new image data */ /* Upload new image data */
GE( glBindTexture (tex->gl_target, gl_handle) ); GE( glBindTexture (tex->gl_target, gl_handle) );
@ -640,14 +668,16 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
if (waste_buf) if (waste_buf)
g_free (waste_buf); g_free (waste_buf);
tex->mipmaps_dirty = TRUE;
return TRUE; return TRUE;
} }
static gint static gint
_cogl_rect_slices_for_size (gint size_to_fill, _cogl_rect_slices_for_size (gint size_to_fill,
gint max_span_size, gint max_span_size,
gint max_waste, gint max_waste,
GArray *out_spans) GArray *out_spans)
{ {
gint n_spans = 0; gint n_spans = 0;
CoglTexSliceSpan span; CoglTexSliceSpan span;
@ -679,10 +709,10 @@ _cogl_rect_slices_for_size (gint size_to_fill,
} }
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,
gint max_waste, gint max_waste,
GArray *out_spans) GArray *out_spans)
{ {
gint n_spans = 0; gint n_spans = 0;
CoglTexSliceSpan span; CoglTexSliceSpan span;
@ -693,7 +723,8 @@ _cogl_pot_slices_for_size (gint size_to_fill,
span.waste = 0; span.waste = 0;
/* Fix invalid max_waste */ /* Fix invalid max_waste */
if (max_waste < 0) max_waste = 0; if (max_waste < 0)
max_waste = 0;
while (TRUE) while (TRUE)
{ {
@ -826,10 +857,10 @@ _cogl_texture_slices_create (CoglTexture *tex)
/* Check if size supported else bail out */ /* Check if size supported else bail out */
if (!_cogl_texture_size_supported (tex->gl_target, if (!_cogl_texture_size_supported (tex->gl_target,
tex->gl_format, tex->gl_format,
tex->gl_type, tex->gl_type,
max_width, max_width,
max_height)) max_height))
{ {
return FALSE; return FALSE;
} }
@ -912,6 +943,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);
/* Allocate some space to store a copy of the first pixel of each
slice. This is only needed to glGenerateMipmap (which is part of
the FBO extension) is not available */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
tex->first_pixels = NULL;
else
tex->first_pixels = g_new (CoglTexturePixel, n_slices);
/* Wrap mode not yet set */ /* Wrap mode not yet set */
tex->wrap_mode = GL_FALSE; tex->wrap_mode = GL_FALSE;
@ -940,14 +979,6 @@ _cogl_texture_slices_create (CoglTexture *tex)
/* Setup texture parameters */ /* Setup texture parameters */
GE( glBindTexture (tex->gl_target, GE( glBindTexture (tex->gl_target,
gl_handles[y * n_x_slices + x]) ); 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) );
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 /* 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
@ -984,6 +1015,9 @@ _cogl_texture_slices_free (CoglTexture *tex)
g_array_free (tex->slice_gl_handles, TRUE); g_array_free (tex->slice_gl_handles, TRUE);
} }
if (tex->first_pixels != NULL)
g_free (tex->first_pixels);
} }
gboolean gboolean
@ -1199,11 +1233,10 @@ _cogl_texture_free (CoglTexture *tex)
} }
CoglHandle CoglHandle
cogl_texture_new_with_size (guint width, cogl_texture_new_with_size (guint width,
guint height, guint height,
gint max_waste, CoglTextureFlags flags,
CoglTextureFlags flags, CoglPixelFormat internal_format)
CoglPixelFormat internal_format)
{ {
CoglTexture *tex; CoglTexture *tex;
gint bpp; gint bpp;
@ -1221,7 +1254,8 @@ cogl_texture_new_with_size (guint width,
tex = (CoglTexture*) g_malloc (sizeof (CoglTexture)); tex = (CoglTexture*) g_malloc (sizeof (CoglTexture));
tex->is_foreign = FALSE; tex->is_foreign = FALSE;
tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); tex->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
tex->mipmaps_dirty = TRUE;
tex->bitmap.width = width; tex->bitmap.width = width;
tex->bitmap.height = height; tex->bitmap.height = height;
@ -1234,9 +1268,14 @@ cogl_texture_new_with_size (guint width,
tex->slice_y_spans = NULL; tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL; tex->slice_gl_handles = NULL;
tex->max_waste = max_waste; if (flags & COGL_TEXTURE_NO_SLICING)
tex->min_filter = COGL_TEXTURE_FILTER_NEAREST; tex->max_waste = -1;
tex->mag_filter = COGL_TEXTURE_FILTER_NEAREST; else
tex->max_waste = COGL_TEXTURE_MAX_WASTE;
/* Unknown filter */
tex->min_filter = GL_FALSE;
tex->mag_filter = GL_FALSE;
/* Find closest GL format match */ /* Find closest GL format match */
tex->bitmap.format = tex->bitmap.format =
@ -1258,7 +1297,6 @@ cogl_texture_new_with_size (guint width,
CoglHandle CoglHandle
cogl_texture_new_from_data (guint width, cogl_texture_new_from_data (guint width,
guint height, guint height,
gint max_waste,
CoglTextureFlags flags, CoglTextureFlags flags,
CoglPixelFormat format, CoglPixelFormat format,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
@ -1282,7 +1320,8 @@ cogl_texture_new_from_data (guint width,
tex = (CoglTexture*) g_malloc (sizeof (CoglTexture)); tex = (CoglTexture*) g_malloc (sizeof (CoglTexture));
tex->is_foreign = FALSE; tex->is_foreign = FALSE;
tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); tex->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
tex->mipmaps_dirty = TRUE;
tex->bitmap.width = width; tex->bitmap.width = width;
tex->bitmap.height = height; tex->bitmap.height = height;
@ -1295,9 +1334,14 @@ cogl_texture_new_from_data (guint width,
tex->slice_y_spans = NULL; tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL; tex->slice_gl_handles = NULL;
tex->max_waste = max_waste; if (flags & COGL_TEXTURE_NO_SLICING)
tex->min_filter = COGL_TEXTURE_FILTER_NEAREST; tex->max_waste = -1;
tex->mag_filter = COGL_TEXTURE_FILTER_NEAREST; else
tex->max_waste = COGL_TEXTURE_MAX_WASTE;
/* Unknown filter */
tex->min_filter = GL_FALSE;
tex->mag_filter = GL_FALSE;
/* FIXME: If upload fails we should set some kind of /* FIXME: If upload fails we should set some kind of
* error flag but still return texture handle (this * error flag but still return texture handle (this
@ -1328,10 +1372,9 @@ cogl_texture_new_from_data (guint width,
} }
CoglHandle CoglHandle
cogl_texture_new_from_bitmap (CoglHandle bmp_handle, cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
gint max_waste, CoglTextureFlags flags,
CoglTextureFlags flags, CoglPixelFormat internal_format)
CoglPixelFormat internal_format)
{ {
CoglTexture *tex; CoglTexture *tex;
CoglBitmap *bmp = (CoglBitmap *)bmp_handle; CoglBitmap *bmp = (CoglBitmap *)bmp_handle;
@ -1342,7 +1385,8 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
tex->is_foreign = FALSE; tex->is_foreign = FALSE;
tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); tex->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
tex->mipmaps_dirty = TRUE;
tex->bitmap = *bmp; tex->bitmap = *bmp;
tex->bitmap_owner = FALSE; tex->bitmap_owner = FALSE;
@ -1351,9 +1395,14 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
tex->slice_y_spans = NULL; tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL; tex->slice_gl_handles = NULL;
tex->max_waste = max_waste; if (flags & COGL_TEXTURE_NO_SLICING)
tex->min_filter = COGL_TEXTURE_FILTER_NEAREST; tex->max_waste = -1;
tex->mag_filter = COGL_TEXTURE_FILTER_NEAREST; else
tex->max_waste = COGL_TEXTURE_MAX_WASTE;
/* Unknown filter */
tex->min_filter = GL_FALSE;
tex->mag_filter = GL_FALSE;
/* FIXME: If upload fails we should set some kind of /* FIXME: If upload fails we should set some kind of
* error flag but still return texture handle if the * error flag but still return texture handle if the
@ -1388,13 +1437,12 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
CoglHandle CoglHandle
cogl_texture_new_from_file (const gchar *filename, cogl_texture_new_from_file (const gchar *filename,
gint max_waste,
CoglTextureFlags flags, CoglTextureFlags flags,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
GError **error) GError **error)
{ {
CoglHandle bmp; CoglHandle bmp;
CoglHandle handle; CoglHandle handle;
g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE);
@ -1402,10 +1450,7 @@ cogl_texture_new_from_file (const gchar *filename,
if (bmp == COGL_INVALID_HANDLE) if (bmp == COGL_INVALID_HANDLE)
return COGL_INVALID_HANDLE; return COGL_INVALID_HANDLE;
handle = cogl_texture_new_from_bitmap (bmp, handle = cogl_texture_new_from_bitmap (bmp, flags, internal_format);
max_waste,
flags,
internal_format);
cogl_handle_unref (bmp); cogl_handle_unref (bmp);
return handle; return handle;
@ -1433,8 +1478,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
GLint gl_int_format = 0; GLint gl_int_format = 0;
GLint gl_width = 0; GLint gl_width = 0;
GLint gl_height = 0; GLint gl_height = 0;
GLint gl_min_filter;
GLint gl_mag_filter;
GLint gl_gen_mipmap; GLint gl_gen_mipmap;
guint bpp; guint bpp;
CoglTexture *tex; CoglTexture *tex;
@ -1482,14 +1525,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
GL_TEXTURE_HEIGHT, GL_TEXTURE_HEIGHT,
&gl_height) ); &gl_height) );
GE( glGetTexParameteriv (gl_target,
GL_TEXTURE_MIN_FILTER,
&gl_min_filter) );
GE( glGetTexParameteriv (gl_target,
GL_TEXTURE_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) );
@ -1508,18 +1543,16 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
return COGL_INVALID_HANDLE; return COGL_INVALID_HANDLE;
/* Try and match to a cogl format */ /* Try and match to a cogl format */
if (!_cogl_pixel_format_from_gl_internal (gl_int_format, if (!_cogl_pixel_format_from_gl_internal (gl_int_format, &format))
&format)) return COGL_INVALID_HANDLE;
{
return COGL_INVALID_HANDLE;
}
/* Create new texture */ /* Create new texture */
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); tex = (CoglTexture *) g_malloc (sizeof (CoglTexture));
/* Setup bitmap info */ /* Setup bitmap info */
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;
tex->mipmaps_dirty = TRUE;
bpp = _cogl_get_format_bpp (format); bpp = _cogl_get_format_bpp (format);
tex->bitmap.format = format; tex->bitmap.format = format;
@ -1533,8 +1566,9 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
tex->gl_format = gl_int_format; tex->gl_format = gl_int_format;
tex->gl_type = GL_UNSIGNED_BYTE; tex->gl_type = GL_UNSIGNED_BYTE;
tex->min_filter = gl_min_filter; /* Unknown filter */
tex->mag_filter = gl_mag_filter; tex->min_filter = GL_FALSE;
tex->mag_filter = GL_FALSE;
tex->max_waste = 0; tex->max_waste = 0;
/* Wrap mode not yet set */ /* Wrap mode not yet set */
@ -1680,36 +1714,10 @@ cogl_texture_get_gl_texture (CoglHandle handle,
return TRUE; return TRUE;
} }
CoglTextureFilter
cogl_texture_get_min_filter (CoglHandle handle)
{
CoglTexture *tex;
if (!cogl_is_texture (handle))
return 0;
tex = _cogl_texture_pointer_from_handle (handle);
return tex->min_filter;
}
CoglTextureFilter
cogl_texture_get_mag_filter (CoglHandle handle)
{
CoglTexture *tex;
if (!cogl_is_texture (handle))
return 0;
tex = _cogl_texture_pointer_from_handle (handle);
return tex->mag_filter;
}
void void
cogl_texture_set_filters (CoglHandle handle, _cogl_texture_set_filters (CoglHandle handle,
CoglTextureFilter min_filter, GLenum min_filter,
CoglTextureFilter mag_filter) GLenum mag_filter)
{ {
CoglTexture *tex; CoglTexture *tex;
GLuint gl_handle; GLuint gl_handle;
@ -1720,14 +1728,18 @@ cogl_texture_set_filters (CoglHandle handle,
tex = _cogl_texture_pointer_from_handle (handle); tex = _cogl_texture_pointer_from_handle (handle);
/* Store new values */
tex->min_filter = min_filter;
tex->mag_filter = mag_filter;
/* Make sure slices were created */ /* Make sure slices were created */
if (tex->slice_gl_handles == NULL) if (tex->slice_gl_handles == NULL)
return; return;
if (min_filter == tex->min_filter
&& mag_filter == tex->mag_filter)
return;
/* Store new values */
tex->min_filter = min_filter;
tex->mag_filter = mag_filter;
/* Apply new filters to every slice */ /* Apply new filters to every slice */
for (i=0; i<tex->slice_gl_handles->len; ++i) for (i=0; i<tex->slice_gl_handles->len; ++i)
{ {
@ -1740,6 +1752,52 @@ cogl_texture_set_filters (CoglHandle handle,
} }
} }
void
_cogl_texture_ensure_mipmaps (CoglHandle handle)
{
CoglTexture *tex;
int i;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_texture (handle))
return;
tex = _cogl_texture_pointer_from_handle (handle);
/* Only update if the mipmaps are dirty */
if (!tex->auto_mipmap || !tex->mipmaps_dirty)
return;
/* Make sure slices were created */
if (tex->slice_gl_handles == NULL)
return;
/* Regenerate the mipmaps on every slice */
for (i = 0; i < tex->slice_gl_handles->len; i++)
{
GLuint gl_handle = g_array_index (tex->slice_gl_handles, GLuint, i);
GE( glBindTexture (tex->gl_target, gl_handle) );
/* glGenerateMipmap is defined in the FBO extension */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
GE( glGenerateMipmap (tex->gl_target) );
else
{
CoglTexturePixel *pixel = tex->first_pixels + i;
/* Temporarily enable automatic mipmap generation and
re-upload the first pixel to cause a regeneration */
GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP, GL_TRUE) );
GE( glTexSubImage2D (tex->gl_target, 0, 0, 0, 1, 1,
pixel->gl_format, pixel->gl_type,
pixel->data) );
GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP, GL_FALSE) );
}
}
tex->mipmaps_dirty = FALSE;
}
gboolean gboolean
cogl_texture_set_region (CoglHandle handle, cogl_texture_set_region (CoglHandle handle,
gint src_x, gint src_x,

View File

@ -399,6 +399,10 @@ _cogl_features_init (void)
(COGL_PFNGLDELETEFRAMEBUFFERSEXTPROC) (COGL_PFNGLDELETEFRAMEBUFFERSEXTPROC)
cogl_get_proc_address ("glDeleteFramebuffersEXT"); cogl_get_proc_address ("glDeleteFramebuffersEXT");
ctx->pf_glGenerateMipmapEXT =
(COGL_PFNGLGENERATEMIPMAPEXTPROC)
cogl_get_proc_address ("glGenerateMipmapEXT");
if (ctx->pf_glGenRenderbuffersEXT && if (ctx->pf_glGenRenderbuffersEXT &&
ctx->pf_glBindRenderbufferEXT && ctx->pf_glBindRenderbufferEXT &&
ctx->pf_glRenderbufferStorageEXT && ctx->pf_glRenderbufferStorageEXT &&
@ -407,7 +411,8 @@ _cogl_features_init (void)
ctx->pf_glFramebufferTexture2DEXT && ctx->pf_glFramebufferTexture2DEXT &&
ctx->pf_glFramebufferRenderbufferEXT && ctx->pf_glFramebufferRenderbufferEXT &&
ctx->pf_glCheckFramebufferStatusEXT && ctx->pf_glCheckFramebufferStatusEXT &&
ctx->pf_glDeleteFramebuffersEXT) ctx->pf_glDeleteFramebuffersEXT &&
ctx->pf_glGenerateMipmapEXT)
flags |= COGL_FEATURE_OFFSCREEN; flags |= COGL_FEATURE_OFFSCREEN;
} }
@ -486,6 +491,23 @@ _cogl_features_init (void)
(COGL_PFNGLCLIENTACTIVETEXTUREPROC) (COGL_PFNGLCLIENTACTIVETEXTUREPROC)
cogl_get_proc_address ("glClientActiveTexture"); cogl_get_proc_address ("glClientActiveTexture");
ctx->pf_glBlendEquation =
(COGL_PFNGLBLENDEQUATIONPROC)
cogl_get_proc_address ("glBlendEquation");
ctx->pf_glBlendColor =
(COGL_PFNGLBLENDCOLORPROC)
cogl_get_proc_address ("glBlendColor");
/* Available in 1.4 */
ctx->pf_glBlendFuncSeparate =
(COGL_PFNGLBLENDFUNCSEPARATEPROC)
cogl_get_proc_address ("glBlendFuncSeparate");
/* Available in 2.0 */
ctx->pf_glBlendEquationSeparate =
(COGL_PFNGLBLENDEQUATIONSEPARATEPROC)
cogl_get_proc_address ("glBlendEquationSeparate");
/* Cache features */ /* Cache features */
ctx->feature_flags = flags; ctx->feature_flags = flags;
ctx->features_cached = TRUE; ctx->features_cached = TRUE;

View File

@ -27,12 +27,12 @@ INCLUDES = \
-DG_LOG_DOMAIN=\"Cogl-GLES\" \ -DG_LOG_DOMAIN=\"Cogl-GLES\" \
-DCLUTTER_COMPILATION -DCLUTTER_COMPILATION
noinst_LTLIBRARIES = libclutter-cogl.la noinst_LTLIBRARIES = libclutter-cogl-gles.la
libclutter_cogl_la_CPPFLAGS = $(CLUTTER_CFLAGS) $(COGL_DEBUG_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS) libclutter_cogl_gles_la_CPPFLAGS = $(CLUTTER_CFLAGS) $(COGL_DEBUG_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS)
libclutter_cogl_la_LIBADD = -lm $(CLUTTER_LIBS) $(top_builddir)/clutter/cogl/common/libclutter-cogl-common.la libclutter_cogl_gles_la_LIBADD = -lm $(CLUTTER_LIBS) $(top_builddir)/clutter/cogl/common/libclutter-cogl-common.la
libclutter_cogl_la_DEPENDENCIES = $(top_builddir)/clutter/cogl/common/libclutter-cogl-common.la libclutter_cogl_gles_la_DEPENDENCIES = $(top_builddir)/clutter/cogl/common/libclutter-cogl-common.la
libclutter_cogl_la_SOURCES = \ libclutter_cogl_gles_la_SOURCES = \
$(top_builddir)/clutter/cogl/cogl.h \ $(top_builddir)/clutter/cogl/cogl.h \
$(top_builddir)/clutter/cogl/cogl-defines-gles.h \ $(top_builddir)/clutter/cogl/cogl-defines-gles.h \
$(top_builddir)/clutter/cogl/cogl-color.h \ $(top_builddir)/clutter/cogl/cogl-color.h \
@ -60,7 +60,7 @@ libclutter_cogl_la_SOURCES = \
cogl-shader.c cogl-shader.c
if USE_GLES2_WRAPPER if USE_GLES2_WRAPPER
libclutter_cogl_la_SOURCES += \ libclutter_cogl_gles_la_SOURCES += \
cogl-gles2-wrapper.c \ cogl-gles2-wrapper.c \
cogl-fixed-vertex-shader.h \ cogl-fixed-vertex-shader.h \
cogl-fixed-vertex-shader.c \ cogl-fixed-vertex-shader.c \

View File

@ -39,7 +39,7 @@
static CoglContext *_context = NULL; static CoglContext *_context = NULL;
static gboolean gl_is_indirect = FALSE; static gboolean gl_is_indirect = FALSE;
gboolean static gboolean
cogl_create_context () cogl_create_context ()
{ {
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 }; GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
@ -72,7 +72,6 @@ cogl_create_context ()
_context->journal = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry)); _context->journal = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry));
_context->logged_vertices = g_array_new (FALSE, FALSE, sizeof (GLfloat)); _context->logged_vertices = g_array_new (FALSE, FALSE, sizeof (GLfloat));
_context->static_indices = g_array_new (FALSE, FALSE, sizeof (GLushort));
_context->polygon_vertices = g_array_new (FALSE, FALSE, _context->polygon_vertices = g_array_new (FALSE, FALSE,
sizeof (CoglTextureGLVertex)); sizeof (CoglTextureGLVertex));
@ -107,8 +106,7 @@ cogl_create_context ()
_context->default_gl_texture_2d_tex = _context->default_gl_texture_2d_tex =
cogl_texture_new_from_data (1, /* width */ cogl_texture_new_from_data (1, /* width */
1, /* height */ 1, /* height */
-1, /* max waste */ COGL_TEXTURE_NO_SLICING, /* flags */
COGL_TEXTURE_NONE, /* flags */
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */ COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
/* internal format */ /* internal format */
COGL_PIXEL_FORMAT_RGBA_8888, COGL_PIXEL_FORMAT_RGBA_8888,
@ -117,8 +115,7 @@ cogl_create_context ()
_context->default_gl_texture_rect_tex = _context->default_gl_texture_rect_tex =
cogl_texture_new_from_data (1, /* width */ cogl_texture_new_from_data (1, /* width */
1, /* height */ 1, /* height */
-1, /* max waste */ COGL_TEXTURE_NO_SLICING, /* flags */
COGL_TEXTURE_NONE, /* flags */
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */ COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
/* internal format */ /* internal format */
COGL_PIXEL_FORMAT_RGBA_8888, COGL_PIXEL_FORMAT_RGBA_8888,
@ -126,16 +123,20 @@ cogl_create_context ()
default_texture_data); default_texture_data);
cogl_set_source (_context->default_material); cogl_set_source (_context->default_material);
cogl_material_flush_gl_state (_context->source_material, NULL); _cogl_material_flush_gl_state (_context->source_material, NULL);
enable_flags = enable_flags =
cogl_material_get_cogl_enable_flags (_context->source_material); _cogl_material_get_cogl_enable_flags (_context->source_material);
cogl_enable (enable_flags); cogl_enable (enable_flags);
_context->quad_indices_byte = COGL_INVALID_HANDLE;
_context->quad_indices_short = COGL_INVALID_HANDLE;
_context->quad_indices_short_len = 0;
return TRUE; return TRUE;
} }
void void
cogl_destroy_context () _cogl_destroy_context ()
{ {
if (_context == NULL) if (_context == NULL)
return; return;
@ -160,13 +161,16 @@ cogl_destroy_context ()
if (_context->logged_vertices) if (_context->logged_vertices)
g_array_free (_context->logged_vertices, TRUE); g_array_free (_context->logged_vertices, TRUE);
if (_context->static_indices)
g_array_free (_context->static_indices, TRUE);
if (_context->polygon_vertices) if (_context->polygon_vertices)
g_array_free (_context->polygon_vertices, TRUE); g_array_free (_context->polygon_vertices, TRUE);
if (_context->current_layers) if (_context->current_layers)
g_array_free (_context->current_layers, TRUE); g_array_free (_context->current_layers, TRUE);
if (_context->quad_indices_byte)
cogl_handle_unref (_context->quad_indices_byte);
if (_context->quad_indices_short)
cogl_handle_unref (_context->quad_indices_short);
g_free (_context); g_free (_context);
} }

View File

@ -80,7 +80,6 @@ typedef struct
* can batch things together. */ * can batch things together. */
GArray *journal; GArray *journal;
GArray *logged_vertices; GArray *logged_vertices;
GArray *static_indices;
GArray *polygon_vertices; GArray *polygon_vertices;
/* Some simple caching, to minimize state changes... */ /* Some simple caching, to minimize state changes... */
@ -104,6 +103,12 @@ typedef struct
floatVec2 path_nodes_max; floatVec2 path_nodes_max;
CoglHandle stencil_material; CoglHandle stencil_material;
/* Pre-generated VBOs containing indices to generate GL_TRIANGLES
out of a vertex array of quads */
CoglHandle quad_indices_byte;
guint quad_indices_short_len;
CoglHandle quad_indices_short;
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
CoglGles2Wrapper gles2; CoglGles2Wrapper gles2;
@ -111,7 +116,6 @@ typedef struct
supported */ supported */
GLint viewport_store[4]; GLint viewport_store[4];
#endif #endif
} CoglContext; } CoglContext;
CoglContext * CoglContext *

View File

@ -89,13 +89,13 @@ cogl_gles2_wrapper_create_shader (GLenum type, const char *source)
if (!status) if (!status)
{ {
char log[1024]; char shader_log[1024];
GLint len; GLint len;
glGetShaderInfoLog (shader, sizeof (log) - 1, &len, log); glGetShaderInfoLog (shader, sizeof (shader_log) - 1, &len, shader_log);
log[len] = '\0'; shader_log[len] = '\0';
g_critical ("%s", log); g_critical ("%s", shader_log);
glDeleteShader (shader); glDeleteShader (shader);
@ -538,9 +538,9 @@ cogl_gles2_wrapper_get_program (const CoglGles2WrapperSettings *settings)
CoglShader *shader CoglShader *shader
= _cogl_shader_pointer_from_handle ((CoglHandle) node->data); = _cogl_shader_pointer_from_handle ((CoglHandle) node->data);
if (shader->type == CGL_VERTEX_SHADER) if (shader->type == COGL_SHADER_TYPE_VERTEX)
custom_vertex_shader = TRUE; custom_vertex_shader = TRUE;
else if (shader->type == CGL_FRAGMENT_SHADER) else if (shader->type == COGL_SHADER_TYPE_FRAGMENT)
custom_fragment_shader = TRUE; custom_fragment_shader = TRUE;
} }
} }
@ -581,13 +581,13 @@ cogl_gles2_wrapper_get_program (const CoglGles2WrapperSettings *settings)
if (!status) if (!status)
{ {
char log[1024]; char shader_log[1024];
GLint len; GLint len;
glGetProgramInfoLog (program->program, sizeof (log) - 1, &len, log); glGetProgramInfoLog (program->program, sizeof (shader_log) - 1, &len, shader_log);
log[len] = '\0'; shader_log[len] = '\0';
g_critical ("%s", log); g_critical ("%s", shader_log);
glDeleteProgram (program->program); glDeleteProgram (program->program);
g_slice_free (CoglGles2WrapperProgram, program); g_slice_free (CoglGles2WrapperProgram, program);
@ -1300,13 +1300,20 @@ cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture,
} }
void void
cogl_wrap_glTexEnvi (GLenum target, GLenum pname, GLfloat param) cogl_wrap_glTexEnvi (GLenum target, GLenum pname, GLint param)
{ {
/* This function is only used to set the texture mode once to /* This function is only used to set the texture mode once to
GL_MODULATE. The shader is hard-coded to modulate the texture so GL_MODULATE. The shader is hard-coded to modulate the texture so
nothing needs to be done here. */ nothing needs to be done here. */
} }
void
cogl_wrap_glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params)
{
/* FIXME: Currently needed to support texture combining using
* COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT */
}
void void
cogl_wrap_glClientActiveTexture (GLenum texture) cogl_wrap_glClientActiveTexture (GLenum texture)
{ {

View File

@ -259,6 +259,7 @@ struct _CoglGles2WrapperShader
#define GL_TEXTURE_ENV 0x2300 #define GL_TEXTURE_ENV 0x2300
#define GL_TEXTURE_ENV_MODE 0x2200 #define GL_TEXTURE_ENV_MODE 0x2200
#define GL_TEXTURE_ENV_COLOR 0x2201
#define GL_MODULATE 0x2100 #define GL_MODULATE 0x2100
#define GL_EXP 0x8000 #define GL_EXP 0x8000
@ -327,7 +328,8 @@ void cogl_wrap_glColorPointer (GLint size, GLenum type, GLsizei stride,
void cogl_wrap_glNormalPointer (GLenum type, GLsizei stride, void cogl_wrap_glNormalPointer (GLenum type, GLsizei stride,
const GLvoid *pointer); const GLvoid *pointer);
void cogl_wrap_glTexEnvi (GLenum target, GLenum pname, GLfloat param); void cogl_wrap_glTexEnvi (GLenum target, GLenum pname, GLint param);
void cogl_wrap_glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params);
void cogl_wrap_glClientActiveTexture (GLenum texture); void cogl_wrap_glClientActiveTexture (GLenum texture);
void cogl_wrap_glActiveTexture (GLenum texture); void cogl_wrap_glActiveTexture (GLenum texture);
@ -384,6 +386,7 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program);
#define glColorPointer cogl_wrap_glColorPointer #define glColorPointer cogl_wrap_glColorPointer
#define glNormalPointer cogl_wrap_glNormalPointer #define glNormalPointer cogl_wrap_glNormalPointer
#define glTexEnvi cogl_wrap_glTexEnvi #define glTexEnvi cogl_wrap_glTexEnvi
#define glTexEnvfv cogl_wrap_glTexEnvfv
#define glActiveTexture cogl_wrap_glActiveTexture #define glActiveTexture cogl_wrap_glActiveTexture
#define glClientActiveTexture cogl_wrap_glClientActiveTexture #define glClientActiveTexture cogl_wrap_glClientActiveTexture
#define glEnableClientState cogl_wrap_glEnableClientState #define glEnableClientState cogl_wrap_glEnableClientState

View File

@ -29,6 +29,7 @@
#include "cogl-internal.h" #include "cogl-internal.h"
#include "cogl-context.h" #include "cogl-context.h"
#include "cogl-clip-stack.h" #include "cogl-clip-stack.h"
#include "cogl-material-private.h"
#include <string.h> #include <string.h>
#include <gmodule.h> #include <gmodule.h>
@ -78,13 +79,13 @@ _cogl_path_stroke_nodes ()
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material); enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
cogl_enable (enable_flags); cogl_enable (enable_flags);
cogl_material_flush_gl_state (ctx->source_material, _cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_DISABLE_MASK, COGL_MATERIAL_FLUSH_DISABLE_MASK,
(guint32)~0, /* disable all texture layers */ (guint32)~0, /* disable all texture layers */
NULL); NULL);
_cogl_current_matrix_state_flush (); _cogl_current_matrix_state_flush ();
while (path_start < ctx->path_nodes->len) while (path_start < ctx->path_nodes->len)
@ -139,10 +140,10 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Just setup a simple material that doesn't use texturing... */ /* Just setup a simple material that doesn't use texturing... */
cogl_material_flush_gl_state (ctx->stencil_material, NULL); _cogl_material_flush_gl_state (ctx->stencil_material, NULL);
enable_flags |= enable_flags |=
cogl_material_get_cogl_enable_flags (ctx->source_material); _cogl_material_get_cogl_enable_flags (ctx->source_material);
cogl_enable (enable_flags); cogl_enable (enable_flags);
_cogl_path_get_bounds (nodes_min, nodes_max, _cogl_path_get_bounds (nodes_min, nodes_max,
@ -361,30 +362,30 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
while (iter) while (iter)
{ {
GSList *next = iter->next; GSList *next = iter->next;
GLfloat x0, x1; GLfloat x_0, x_1;
GLfloat y0, y1; GLfloat y_0, y_1;
if (!next) if (!next)
break; break;
x0 = GPOINTER_TO_INT (iter->data); x_0 = GPOINTER_TO_INT (iter->data);
x1 = GPOINTER_TO_INT (next->data); x_1 = GPOINTER_TO_INT (next->data);
y0 = bounds_y + i; y_0 = bounds_y + i;
y1 = bounds_y + i + 1.0625f; y_1 = bounds_y + i + 1.0625f;
/* render scanlines 1.0625 high to avoid gaps when /* render scanlines 1.0625 high to avoid gaps when
transformed */ transformed */
coords[span_no * 12 + 0] = x0; coords[span_no * 12 + 0] = x_0;
coords[span_no * 12 + 1] = y0; coords[span_no * 12 + 1] = y_0;
coords[span_no * 12 + 2] = x1; coords[span_no * 12 + 2] = x_1;
coords[span_no * 12 + 3] = y0; coords[span_no * 12 + 3] = y_0;
coords[span_no * 12 + 4] = x1; coords[span_no * 12 + 4] = x_1;
coords[span_no * 12 + 5] = y1; coords[span_no * 12 + 5] = y_1;
coords[span_no * 12 + 6] = x0; coords[span_no * 12 + 6] = x_0;
coords[span_no * 12 + 7] = y0; coords[span_no * 12 + 7] = y_0;
coords[span_no * 12 + 8] = x0; coords[span_no * 12 + 8] = x_0;
coords[span_no * 12 + 9] = y1; coords[span_no * 12 + 9] = y_1;
coords[span_no * 12 + 10] = x1; coords[span_no * 12 + 10] = x_1;
coords[span_no * 12 + 11] = y1; coords[span_no * 12 + 11] = y_1;
span_no ++; span_no ++;
iter = next->next; iter = next->next;
} }

View File

@ -99,22 +99,23 @@ cogl_shader_compile (CoglHandle handle)
glCompileShader (shader->gl_handle); glCompileShader (shader->gl_handle);
} }
void gchar *
cogl_shader_get_info_log (CoglHandle handle, cogl_shader_get_info_log (CoglHandle handle)
size_t size,
char *buffer)
{ {
CoglShader *shader; CoglShader *shader;
char buffer[512];
int len = 0; int len = 0;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NULL);
if (!cogl_is_shader (handle)) if (!cogl_is_shader (handle))
return; return NULL;
shader = _cogl_shader_pointer_from_handle (handle); shader = _cogl_shader_pointer_from_handle (handle);
glGetShaderInfoLog (shader->gl_handle, size - 1, &len, buffer); glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
buffer[len] = '\0'; buffer[len] = '\0';
return g_strdup (buffer);
} }
CoglShaderType CoglShaderType
@ -199,11 +200,10 @@ cogl_shader_compile (CoglHandle shader_handle)
{ {
} }
void gchar *
cogl_shader_get_info_log (CoglHandle handle, cogl_shader_get_info_log (CoglHandle handle)
size_t size,
char *buffer)
{ {
return NULL;
} }
CoglShaderType CoglShaderType

View File

@ -30,6 +30,7 @@
typedef struct _CoglTexture CoglTexture; typedef struct _CoglTexture CoglTexture;
typedef struct _CoglTexSliceSpan CoglTexSliceSpan; typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
typedef struct _CoglSpanIter CoglSpanIter; typedef struct _CoglSpanIter CoglSpanIter;
typedef struct _CoglTexturePixel CoglTexturePixel;
struct _CoglTexSliceSpan struct _CoglTexSliceSpan
{ {
@ -55,6 +56,18 @@ struct _CoglSpanIter
gboolean intersects; gboolean intersects;
}; };
/* This is used to store the first pixel of each slice. This is only
used when glGenerateMipmap is not available */
struct _CoglTexturePixel
{
/* We need to store the format of the pixel because we store the
data in the source format which might end up being different for
each slice if a subregion is updated with a different format */
GLenum gl_format;
GLenum gl_type;
guint8 data[4];
};
struct _CoglTexture struct _CoglTexture
{ {
CoglHandleObject _parent; CoglHandleObject _parent;
@ -68,11 +81,17 @@ struct _CoglTexture
GArray *slice_y_spans; GArray *slice_y_spans;
GArray *slice_gl_handles; GArray *slice_gl_handles;
gint max_waste; gint max_waste;
CoglTextureFilter min_filter; GLenum min_filter;
CoglTextureFilter mag_filter; GLenum mag_filter;
gboolean is_foreign; gboolean is_foreign;
GLint wrap_mode; GLint wrap_mode;
gboolean auto_mipmap; gboolean auto_mipmap;
gboolean mipmaps_dirty;
/* This holds a copy of the first pixel in each slice. It is only
used to force an automatic update of the mipmaps when
glGenerateMipmap is not available. */
CoglTexturePixel *first_pixels;
}; };
/* To improve batching of geometry when submitting vertices to OpenGL we /* To improve batching of geometry when submitting vertices to OpenGL we
@ -93,6 +112,14 @@ void
_cogl_texture_set_wrap_mode_parameter (CoglTexture *tex, _cogl_texture_set_wrap_mode_parameter (CoglTexture *tex,
GLenum wrap_mode); GLenum wrap_mode);
void
_cogl_texture_set_filters (CoglHandle handle,
GLenum min_filter,
GLenum mag_filter);
void
_cogl_texture_ensure_mipmaps (CoglHandle handle);
gboolean gboolean
_cogl_texture_span_has_waste (CoglTexture *tex, _cogl_texture_span_has_waste (CoglTexture *tex,
gint x_span_index, gint x_span_index,

View File

@ -225,11 +225,12 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
/* Iterate horizontal slices */ /* Iterate horizontal slices */
for (x = 0; x < tex->slice_x_spans->len; ++x) for (x = 0; x < tex->slice_x_spans->len; ++x)
{ {
gint slice_num = y * tex->slice_x_spans->len + x;
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, x); x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, x);
/* Pick the gl texture object handle */ /* Pick the gl texture object handle */
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, gl_handle = g_array_index (tex->slice_gl_handles, GLuint, slice_num);
y * tex->slice_x_spans->len + x);
/* FIXME: might optimize by not copying to intermediate slice /* FIXME: might optimize by not copying to intermediate slice
bitmap when source rowstride = bpp * width and the texture bitmap when source rowstride = bpp * width and the texture
@ -258,6 +259,16 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
slice_bmp.width, slice_bmp.width,
slice_bmp.height); slice_bmp.height);
/* Keep a copy of the first pixel if needed */
if (tex->first_pixels)
{
memcpy (tex->first_pixels[slice_num].data,
slice_bmp.data,
bpp);
tex->first_pixels[slice_num].gl_format = tex->gl_format;
tex->first_pixels[slice_num].gl_type = tex->gl_type;
}
/* Upload new image data */ /* Upload new image data */
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) );
@ -338,9 +349,6 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
waste_buf) ); waste_buf) );
} }
if (tex->auto_mipmap)
cogl_wrap_glGenerateMipmap (tex->gl_target);
/* Free temp bitmap */ /* Free temp bitmap */
g_free (slice_bmp.data); g_free (slice_bmp.data);
} }
@ -349,6 +357,8 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
if (waste_buf) if (waste_buf)
g_free (waste_buf); g_free (waste_buf);
tex->mipmaps_dirty = TRUE;
return TRUE; return TRUE;
} }
@ -442,6 +452,7 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
gint bpp; gint bpp;
GLint viewport[4]; GLint viewport[4];
CoglBitmap alpha_bmp; CoglBitmap alpha_bmp;
CoglHandle prev_source;
_COGL_GET_CONTEXT (ctx, FALSE); _COGL_GET_CONTEXT (ctx, FALSE);
@ -477,31 +488,21 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
if (ctx->texture_download_material == COGL_INVALID_HANDLE) if (ctx->texture_download_material == COGL_INVALID_HANDLE)
{ {
ctx->texture_download_material = cogl_material_new (); ctx->texture_download_material = cogl_material_new ();
cogl_material_set_layer_combine_function ( cogl_material_set_blend (ctx->texture_download_material,
ctx->texture_download_material, "RGBA = ADD (SRC_COLOR, 0)",
0, /* layer */ NULL);
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
COGL_MATERIAL_LAYER_COMBINE_FUNC_REPLACE);
cogl_material_set_layer_combine_arg_src (
ctx->texture_download_material,
0, /* layer */
0, /* arg */
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE);
cogl_material_set_blend_factors (ctx->texture_download_material,
COGL_MATERIAL_BLEND_FACTOR_ONE,
COGL_MATERIAL_BLEND_FACTOR_ZERO);
} }
prev_source = cogl_handle_ref (ctx->source_material);
cogl_set_source (ctx->texture_download_material);
cogl_material_set_layer (ctx->texture_download_material, 0, tex); cogl_material_set_layer (ctx->texture_download_material, 0, tex);
cogl_material_set_layer_combine_arg_op ( cogl_material_set_layer_combine (ctx->texture_download_material,
ctx->texture_download_material, 0, /* layer */
0, /* layer */ "RGBA = REPLACE (TEXTURE)",
0, /* arg */ NULL);
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_COLOR);
cogl_material_flush_gl_state (ctx->texture_download_material, NULL);
_cogl_texture_draw_and_read (tex, target_bmp, viewport); _cogl_texture_draw_and_read (tex, target_bmp, viewport);
/* Check whether texture has alpha and framebuffer not */ /* Check whether texture has alpha and framebuffer not */
@ -534,13 +535,11 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
alpha_bmp.height); alpha_bmp.height);
/* Draw alpha values into RGB channels */ /* Draw alpha values into RGB channels */
cogl_material_set_layer_combine_arg_op ( cogl_material_set_layer_combine (ctx->texture_download_material,
ctx->texture_download_material, 0, /* layer */
0, /* layer */ "RGBA = REPLACE (TEXTURE[A])",
0, /* arg */ NULL);
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_ALPHA);
cogl_material_flush_gl_state (ctx->texture_download_material, NULL);
_cogl_texture_draw_and_read (tex, &alpha_bmp, viewport); _cogl_texture_draw_and_read (tex, &alpha_bmp, viewport);
/* Copy temp R to target A */ /* Copy temp R to target A */
@ -568,6 +567,10 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW); _cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_pop (); _cogl_current_matrix_pop ();
/* restore the original material */
cogl_set_source (prev_source);
cogl_handle_unref (prev_source);
return TRUE; return TRUE;
} }
@ -631,6 +634,8 @@ _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 )
{ {
gint slice_num;
/* Discard slices out of the subregion early */ /* Discard slices out of the subregion early */
if (!x_iter.intersects) if (!x_iter.intersects)
{ {
@ -653,10 +658,10 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
local_y = (y_iter.intersect_start - local_y = (y_iter.intersect_start -
y_iter.pos); y_iter.pos);
slice_num = y_iter.index * tex->slice_x_spans->len + x_iter.index;
/* 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, slice_num);
y_iter.index * tex->slice_x_spans->len +
x_iter.index);
/* FIXME: might optimize by not copying to intermediate slice /* FIXME: might optimize by not copying to intermediate slice
bitmap when source rowstride = bpp * width and the texture bitmap when source rowstride = bpp * width and the texture
@ -685,6 +690,15 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
slice_bmp.width, slice_bmp.width,
slice_bmp.height); slice_bmp.height);
/* Keep a copy of the first pixel if needed */
if (tex->first_pixels && local_x == 0 && local_y == 0)
{
memcpy (tex->first_pixels[slice_num].data,
slice_bmp.data, bpp);
tex->first_pixels[slice_num].gl_format = source_gl_format;
tex->first_pixels[slice_num].gl_type = source_gl_type;
}
/* Upload new image data */ /* Upload new image data */
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) );
@ -794,9 +808,6 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
waste_buf) ); waste_buf) );
} }
if (tex->auto_mipmap)
cogl_wrap_glGenerateMipmap (tex->gl_target);
/* Free temp bitmap */ /* Free temp bitmap */
g_free (slice_bmp.data); g_free (slice_bmp.data);
} }
@ -805,6 +816,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
if (waste_buf) if (waste_buf)
g_free (waste_buf); g_free (waste_buf);
tex->mipmaps_dirty = TRUE;
return TRUE; return TRUE;
} }
@ -858,7 +871,8 @@ _cogl_pot_slices_for_size (gint size_to_fill,
span.waste = 0; span.waste = 0;
/* Fix invalid max_waste */ /* Fix invalid max_waste */
if (max_waste < 0) max_waste = 0; if (max_waste < 0)
max_waste = 0;
while (TRUE) while (TRUE)
{ {
@ -866,7 +880,9 @@ _cogl_pot_slices_for_size (gint size_to_fill,
if (size_to_fill > span.size) if (size_to_fill > span.size)
{ {
/* Not yet - add a span of this size */ /* Not yet - add a span of this size */
if (out_spans) g_array_append_val (out_spans, span); if (out_spans)
g_array_append_val (out_spans, span);
span.start += span.size; span.start += span.size;
size_to_fill -= span.size; size_to_fill -= span.size;
n_spans++; n_spans++;
@ -875,7 +891,9 @@ _cogl_pot_slices_for_size (gint size_to_fill,
{ {
/* Yes and waste is small enough */ /* Yes and waste is small enough */
span.waste = span.size - size_to_fill; span.waste = span.size - size_to_fill;
if (out_spans) g_array_append_val (out_spans, span); if (out_spans)
g_array_append_val (out_spans, span);
return ++n_spans; return ++n_spans;
} }
else else
@ -971,10 +989,10 @@ _cogl_texture_slices_create (CoglTexture *tex)
/* Check if size supported else bail out */ /* Check if size supported else bail out */
if (!_cogl_texture_size_supported (tex->gl_target, if (!_cogl_texture_size_supported (tex->gl_target,
tex->gl_format, tex->gl_format,
tex->gl_type, tex->gl_type,
max_width, max_width,
max_height)) max_height))
{ {
return FALSE; return FALSE;
} }
@ -1057,6 +1075,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);
/* Allocate some space to store a copy of the first pixel of each
slice. This is only needed to glGenerateMipmap (which is part of
the FBO extension) is not available */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
tex->first_pixels = NULL;
else
tex->first_pixels = g_new (CoglTexturePixel, n_slices);
/* Wrap mode not yet set */ /* Wrap mode not yet set */
tex->wrap_mode = GL_FALSE; tex->wrap_mode = GL_FALSE;
@ -1087,20 +1113,11 @@ _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( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_S, GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_S,
tex->wrap_mode) ); tex->wrap_mode) );
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_T, GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_T,
tex->wrap_mode) ); tex->wrap_mode) );
if (tex->auto_mipmap)
GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP,
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,
x_span->size, y_span->size, 0, x_span->size, y_span->size, 0,
@ -1130,6 +1147,9 @@ _cogl_texture_slices_free (CoglTexture *tex)
g_array_free (tex->slice_gl_handles, TRUE); g_array_free (tex->slice_gl_handles, TRUE);
} }
if (tex->first_pixels != NULL)
g_free (tex->first_pixels);
} }
gboolean gboolean
@ -1288,11 +1308,10 @@ _cogl_texture_free (CoglTexture *tex)
} }
CoglHandle CoglHandle
cogl_texture_new_with_size (guint width, cogl_texture_new_with_size (guint width,
guint height, guint height,
gint max_waste, CoglTextureFlags flags,
CoglTextureFlags flags, CoglPixelFormat internal_format)
CoglPixelFormat internal_format)
{ {
CoglTexture *tex; CoglTexture *tex;
gint bpp; gint bpp;
@ -1310,7 +1329,8 @@ cogl_texture_new_with_size (guint width,
tex = (CoglTexture*) g_malloc (sizeof (CoglTexture)); tex = (CoglTexture*) g_malloc (sizeof (CoglTexture));
tex->is_foreign = FALSE; tex->is_foreign = FALSE;
tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); tex->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
tex->mipmaps_dirty = TRUE;
tex->bitmap.width = width; tex->bitmap.width = width;
tex->bitmap.height = height; tex->bitmap.height = height;
@ -1323,9 +1343,14 @@ cogl_texture_new_with_size (guint width,
tex->slice_y_spans = NULL; tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL; tex->slice_gl_handles = NULL;
tex->max_waste = max_waste; if (flags & COGL_TEXTURE_NO_SLICING)
tex->min_filter = CGL_NEAREST; tex->max_waste = -1;
tex->mag_filter = CGL_NEAREST; else
tex->max_waste = COGL_TEXTURE_MAX_WASTE;
/* Unknown filter */
tex->min_filter = GL_FALSE;
tex->mag_filter = GL_FALSE;
/* Find closest GL format match */ /* Find closest GL format match */
tex->bitmap.format = tex->bitmap.format =
@ -1347,7 +1372,6 @@ cogl_texture_new_with_size (guint width,
CoglHandle CoglHandle
cogl_texture_new_from_data (guint width, cogl_texture_new_from_data (guint width,
guint height, guint height,
gint max_waste,
CoglTextureFlags flags, CoglTextureFlags flags,
CoglPixelFormat format, CoglPixelFormat format,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
@ -1371,7 +1395,8 @@ cogl_texture_new_from_data (guint width,
tex = (CoglTexture*) g_malloc (sizeof (CoglTexture)); tex = (CoglTexture*) g_malloc (sizeof (CoglTexture));
tex->is_foreign = FALSE; tex->is_foreign = FALSE;
tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); tex->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
tex->mipmaps_dirty = TRUE;
tex->bitmap.width = width; tex->bitmap.width = width;
tex->bitmap.height = height; tex->bitmap.height = height;
@ -1384,9 +1409,14 @@ cogl_texture_new_from_data (guint width,
tex->slice_y_spans = NULL; tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL; tex->slice_gl_handles = NULL;
tex->max_waste = max_waste; if (flags & COGL_TEXTURE_NO_SLICING)
tex->min_filter = CGL_NEAREST; tex->max_waste = -1;
tex->mag_filter = CGL_NEAREST; else
tex->max_waste = COGL_TEXTURE_MAX_WASTE;
/* Unknown filter */
tex->min_filter = GL_FALSE;
tex->mag_filter = GL_FALSE;
/* FIXME: If upload fails we should set some kind of /* FIXME: If upload fails we should set some kind of
* error flag but still return texture handle (this * error flag but still return texture handle (this
@ -1417,10 +1447,9 @@ cogl_texture_new_from_data (guint width,
} }
CoglHandle CoglHandle
cogl_texture_new_from_bitmap (CoglHandle bmp_handle, cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
gint max_waste, CoglTextureFlags flags,
CoglTextureFlags flags, CoglPixelFormat internal_format)
CoglPixelFormat internal_format)
{ {
CoglTexture *tex; CoglTexture *tex;
CoglBitmap *bmp = (CoglBitmap *)bmp_handle; CoglBitmap *bmp = (CoglBitmap *)bmp_handle;
@ -1429,7 +1458,8 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
tex->is_foreign = FALSE; tex->is_foreign = FALSE;
tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); tex->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0;
tex->mipmaps_dirty = TRUE;
tex->bitmap = *bmp; tex->bitmap = *bmp;
tex->bitmap_owner = TRUE; tex->bitmap_owner = TRUE;
@ -1439,9 +1469,14 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
tex->slice_y_spans = NULL; tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL; tex->slice_gl_handles = NULL;
tex->max_waste = max_waste; if (flags & COGL_TEXTURE_NO_SLICING)
tex->min_filter = CGL_NEAREST; tex->max_waste = -1;
tex->mag_filter = CGL_NEAREST; else
tex->max_waste = COGL_TEXTURE_MAX_WASTE;
/* Unknown filter */
tex->min_filter = GL_FALSE;
tex->mag_filter = GL_FALSE;
/* FIXME: If upload fails we should set some kind of /* FIXME: If upload fails we should set some kind of
* error flag but still return texture handle if the * error flag but still return texture handle if the
@ -1476,7 +1511,6 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
CoglHandle CoglHandle
cogl_texture_new_from_file (const gchar *filename, cogl_texture_new_from_file (const gchar *filename,
gint max_waste,
CoglTextureFlags flags, CoglTextureFlags flags,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
GError **error) GError **error)
@ -1490,10 +1524,7 @@ cogl_texture_new_from_file (const gchar *filename,
if (bmp == COGL_INVALID_HANDLE) if (bmp == COGL_INVALID_HANDLE)
return COGL_INVALID_HANDLE; return COGL_INVALID_HANDLE;
handle = cogl_texture_new_from_bitmap (bmp, handle = cogl_texture_new_from_bitmap (bmp, flags, internal_format);
max_waste,
flags,
internal_format);
cogl_handle_unref (bmp); cogl_handle_unref (bmp);
return handle; return handle;
@ -1521,8 +1552,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
GLint gl_int_format = 0; GLint gl_int_format = 0;
GLint gl_width = 0; GLint gl_width = 0;
GLint gl_height = 0; GLint gl_height = 0;
GLint gl_min_filter;
GLint gl_mag_filter;
GLint gl_gen_mipmap; GLint gl_gen_mipmap;
guint bpp; guint bpp;
CoglTexture *tex; CoglTexture *tex;
@ -1569,14 +1598,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
gl_height = height + y_pot_waste; gl_height = height + y_pot_waste;
#endif #endif
GE( glGetTexParameteriv (gl_target,
GL_TEXTURE_MIN_FILTER,
&gl_min_filter) );
GE( glGetTexParameteriv (gl_target,
GL_TEXTURE_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) );
@ -1607,6 +1628,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
/* Setup bitmap info */ /* Setup bitmap info */
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;
tex->mipmaps_dirty = TRUE;
bpp = _cogl_get_format_bpp (format); bpp = _cogl_get_format_bpp (format);
tex->bitmap.format = format; tex->bitmap.format = format;
@ -1620,8 +1642,9 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
tex->gl_format = gl_int_format; tex->gl_format = gl_int_format;
tex->gl_type = GL_UNSIGNED_BYTE; tex->gl_type = GL_UNSIGNED_BYTE;
tex->min_filter = gl_min_filter; /* Unknown filter */
tex->mag_filter = gl_mag_filter; tex->min_filter = GL_FALSE;
tex->mag_filter = GL_FALSE;
tex->max_waste = 0; tex->max_waste = 0;
/* Wrap mode not yet set */ /* Wrap mode not yet set */
@ -1767,36 +1790,10 @@ cogl_texture_get_gl_texture (CoglHandle handle,
return TRUE; return TRUE;
} }
CoglTextureFilter
cogl_texture_get_min_filter (CoglHandle handle)
{
CoglTexture *tex;
if (!cogl_is_texture (handle))
return 0;
tex = _cogl_texture_pointer_from_handle (handle);
return tex->min_filter;
}
CoglTextureFilter
cogl_texture_get_mag_filter (CoglHandle handle)
{
CoglTexture *tex;
if (!cogl_is_texture (handle))
return 0;
tex = _cogl_texture_pointer_from_handle (handle);
return tex->mag_filter;
}
void void
cogl_texture_set_filters (CoglHandle handle, _cogl_texture_set_filters (CoglHandle handle,
CoglTextureFilter min_filter, GLenum min_filter,
CoglTextureFilter mag_filter) GLenum mag_filter)
{ {
CoglTexture *tex; CoglTexture *tex;
GLuint gl_handle; GLuint gl_handle;
@ -1807,14 +1804,18 @@ cogl_texture_set_filters (CoglHandle handle,
tex = _cogl_texture_pointer_from_handle (handle); tex = _cogl_texture_pointer_from_handle (handle);
/* Store new values */
tex->min_filter = min_filter;
tex->mag_filter = mag_filter;
/* Make sure slices were created */ /* Make sure slices were created */
if (tex->slice_gl_handles == NULL) if (tex->slice_gl_handles == NULL)
return; return;
if (min_filter == tex->min_filter
&& mag_filter == tex->mag_filter)
return;
/* Store new values */
tex->min_filter = min_filter;
tex->mag_filter = mag_filter;
/* Apply new filters to every slice */ /* Apply new filters to every slice */
for (i=0; i<tex->slice_gl_handles->len; ++i) for (i=0; i<tex->slice_gl_handles->len; ++i)
{ {
@ -1827,6 +1828,52 @@ cogl_texture_set_filters (CoglHandle handle,
} }
} }
void
_cogl_texture_ensure_mipmaps (CoglHandle handle)
{
CoglTexture *tex;
int i;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_texture (handle))
return;
tex = _cogl_texture_pointer_from_handle (handle);
/* Only update if the mipmaps are dirty */
if (!tex->auto_mipmap || !tex->mipmaps_dirty)
return;
/* Make sure slices were created */
if (tex->slice_gl_handles == NULL)
return;
/* Regenerate the mipmaps on every slice */
for (i = 0; i < tex->slice_gl_handles->len; i++)
{
GLuint gl_handle = g_array_index (tex->slice_gl_handles, GLuint, i);
GE( glBindTexture (tex->gl_target, gl_handle) );
/* glGenerateMipmap is defined in the FBO extension */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
GE( cogl_wrap_glGenerateMipmap (tex->gl_target) );
else
{
CoglTexturePixel *pixel = tex->first_pixels + i;
/* Temporarily enable automatic mipmap generation and
re-upload the first pixel to cause a regeneration */
GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP, GL_TRUE) );
GE( glTexSubImage2D (tex->gl_target, 0, 0, 0, 1, 1,
pixel->gl_format, pixel->gl_type,
pixel->data) );
GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP, GL_FALSE) );
}
}
tex->mipmaps_dirty = FALSE;
}
gboolean gboolean
cogl_texture_set_region (CoglHandle handle, cogl_texture_set_region (CoglHandle handle,
gint src_x, gint src_x,