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)
BUILT_SOURCES = cogl.h
@ -23,29 +29,42 @@ CLEANFILES = $(pc_files)
AM_CPPFLAGS = $(CLUTTER_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS)
# COGL installed headers
cogl_headers = \
$(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_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-deprecated.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-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
# so we create a libclutter-cogl.la that's just identical to the one
# in the subdir
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)
coglincludedir = $(includedir)/clutter-@CLUTTER_API_VERSION@/cogl
coglinclude_HEADERS = $(cogl_headers)
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 \
--namespace Cogl --nsversion=@CLUTTER_API_VERSION@ \
-I$(top_srcdir)/clutter/cogl \
@ -59,8 +78,6 @@ Cogl-@CLUTTER_API_VERSION@.gir: $(INTROSPECTION_SCANNER) $(CLUTTER_COGL)/libclut
--libtool="$(top_builddir)/doltlibtool" \
--pkg gobject-2.0 \
--output $@ \
$(top_builddir)/clutter/cogl/cogl-defines-@CLUTTER_COGL@.h \
$(top_builddir)/clutter/cogl/cogl.h \
$(cogl_headers)
BUILT_GIRSOURCES = Cogl-@CLUTTER_API_VERSION@.gir

View File

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

View File

@ -23,6 +23,14 @@
#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

View File

@ -43,6 +43,51 @@ G_BEGIN_DECLS
* 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:
@ -367,80 +412,90 @@ void cogl_material_set_alpha_test_function (CoglHandle material,
float alpha_reference);
/**
* CoglMaterialBlendFactor:
* @COGL_MATERIAL_BLEND_FACTOR_ZERO: (0, 0, 0, 0)
* @COGL_MATERIAL_BLEND_FACTOR_ONE: (1, 1, 1, 1)
* @COGL_MATERIAL_BLEND_FACTOR_SRC_COLOR: (Rs, Gs, Bs, As)
* @COGL_MATERIAL_BLEND_FACTOR_DST_COLOR: (Rd, Gd, Bd, Ad)
* @COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: (1-Rs, 1-Gs, 1-Bs, 1-As)
* @COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_DST_COLOR: (1-Rd, 1-Gd, 1-Bd, 1-Ad)
* @COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA: (As, As, As, As)
* @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)
* @COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: (1-Ad, 1-Ad, 1-Ad, 1-Ad)
* @COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA_SATURATE: (f,f,f,1) where f=MIN(As,1-Ad)
* cogl_material_set_blend:
* @material: A CoglMaterial object
* @blend_string: A <link linkend="cogl-Blend-Strings">Cogl blend string</link>
* describing the desired blend function.
* @error: A GError that may report lack of driver support if you give
* separate blend string statements for the alpha channel and RGB
* channels since some drivers or backends such as GLES 1.1 dont
* support this.
*
* If not already familiar; please refer
* <link linkend="cogl-Blend-Strings">here</link> for an overview of what blend
* strings are and there syntax.
*
* Blending occurs after the alpha test function, and combines fragments with
* the framebuffer.
* <para>
* A fixed function is used to determine the blended color, which is based on
* the incoming source color of your fragment (Rs, Gs, Bs, As), a source
* 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>
* Currently the only blend function Cogl exposes is ADD(). So any valid
* blend statements will be of the form:
*
* <programlisting>
* R = Rs*Sr + Rd*Dr
* G = Gs*Sg + Gd*Dg
* B = Bs*Sb + Bd*Db
* A = As*Sa + Ad*Da
* &lt;channel-mask&gt;=ADD(SRC_COLOR*(&lt;factor&gt;), DST_COLOR*(&lt;factor&gt;))
* </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
{
COGL_MATERIAL_BLEND_FACTOR_ZERO = GL_ZERO,
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;
gboolean cogl_material_set_blend (CoglHandle material,
const char *blend_string,
GError **error);
/**
* cogl_material_set_blend_factors:
* cogl_material_set_blend_constant:
* @material: A CoglMaterial object
* @src_factor: Chooses the @CoglMaterialBlendFactor you want plugged in to
* the blend equation.
* @dst_factor: Chooses the @CoglMaterialBlendFactor you want plugged in to
* the blend equation.
* @constant_color: The constant color you want
*
* This function lets you control how primitives using this material will get
* blended with the contents of your framebuffer. The blended RGBA components
* are calculated like this:
* When blending is setup to reference a CONSTANT blend factor then
* blending will depend on the constant set with this function.
*
* (RsSr+RdDr, GsSg+GdDg, BsSb+BsSb, AsSa+AdDa)
*
* 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
* Since: 1.0
*/
void cogl_material_set_blend_factors (CoglHandle material,
CoglMaterialBlendFactor src_factor,
CoglMaterialBlendFactor dst_factor);
void cogl_material_set_blend_constant (CoglHandle material,
CoglColor *constant_color);
/**
* cogl_material_set_layer:
@ -460,7 +515,7 @@ void cogl_material_set_blend_factors (CoglHandle material,
* Since 1.0
*/
void cogl_material_set_layer (CoglHandle material,
gint layer_index,
int layer_index,
CoglHandle texture);
/**
@ -473,233 +528,112 @@ void cogl_material_set_layer (CoglHandle material,
void cogl_material_remove_layer (CoglHandle material,
gint layer_index);
/**
* CoglMaterialLayerCombineFunc:
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_REPLACE: Arg0
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE: Arg0 x Arg1
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD: Arg0 + Arg1
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD_SIGNED: Arg0 + Arg1 - 0.5
* @COGL_MATERIAL_LAYER_COMBINE_FUNC_INTERPOLATE: Arg0 x Arg + Arg1 x (1-Arg2)
* @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)) +
* cogl_material_set_layer_combine:
* @material: A CoglMaterial object
* @layer_index: Specifies the layer you want define a combine function for
* @blend_string: A <link linkend="cogl-Blend-Strings">Cogl blend string</link>
* describing the desired texture combine function.
* @error: A GError that may report parse errors or lack of GPU/driver support.
*
* A material may comprise of 1 or more layers that can be combined using a
* number of different functions. By default layers are modulated, which is
* to say the components of the current source layer S are simply multipled
* together with the combined results of the previous layer P like this:
* If not already familiar; you can refer
* <link linkend="cogl-Blend-Strings">here</link> for an overview of what blend
* strings are and there syntax.
*
* 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>
* (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>
*
* 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>
* 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:
* <listitem>DOT3_RGBA(arg0, arg1) =
* <programlisting>
* //Step 1: Choose a function. Note the ADD function takes 2 arguments...
* cogl_material_set_layer_combine_function (material,
* 1,
* 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);
* 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>
*/
void cogl_material_set_layer_combine_function (CoglHandle material,
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
* </listitem>
* </itemizedlist>
*
* Note for the constants @COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE0..n the
* numbers may not correspond to the indices you choose for your layers since
* your layer indices don't need to be contiguous. If you need to use these
* it would probably be sensible to ensure the layer indices do infact
* correspond.
* Refer to the
* <link linkend="cogl-Blend-String-syntax">color-source syntax</link> for
* describing the arguments. The valid source names for texture combining
* are:
* <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
{
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE = GL_TEXTURE,
/* Can we find a nicer way... */
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;
gboolean
cogl_material_set_layer_combine (CoglHandle material,
gint layer_index,
const char *blend_string,
GError **error);
/**
* cogl_material_set_layer_combine_arg_src:
* cogl_material_set_layer_combine_constant:
* @material: A CoglMaterial object
* @layer_index:
* @argument:
* @channels:
* @src:
* @layer_index: Specifies the layer you want to specify a constant used
* for texture combining
* @color_constant: The constant color you want
*
*/
void cogl_material_set_layer_combine_arg_src (CoglHandle material,
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:
* When you are using the 'CONSTANT' color source in a layer combine
* description then you can use this function to define its value.
*
* Since 1.0
*/
void cogl_material_set_layer_combine_arg_op (CoglHandle material,
gint layer_index,
gint argument,
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
void cogl_material_set_layer_combine_constant (CoglHandle material,
int layer_index,
CoglColor *constant);
/**
* 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.
*/
void cogl_material_set_layer_matrix (CoglHandle material,
gint layer_index,
int layer_index,
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:
* @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
* for iteration.
*
* 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.
*
* 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.
* Returns: A list of #CoglHandle<!-- -->'s that can be passed to the
* cogl_material_layer_* functions.
*/
const GList *cogl_material_get_layers (CoglHandle material_handle);
/**
* 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
{
@ -774,17 +675,12 @@ typedef enum _CoglMaterialLayerType
/**
* 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:
* 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
* 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);
@ -792,75 +688,58 @@ CoglMaterialLayerType cogl_material_layer_get_type (CoglHandle layer_handle);
* cogl_material_layer_get_texture:
* @layer_handle: A CoglMaterialLayer handle
*
* This lets you extract a CoglTexture handle for a specific 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.
* This lets you extract a CoglTexture handle for a specific layer.
*
* 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.
* Considering this, you should always call cogl_material_layer_get_type
* first, to check it is of type COGL_MATERIAL_LAYER_TYPE_TEXTURE.
* likely return COGL_INVALID_HANDLE if you try to get the texture.
* Considering this, you can call cogl_material_layer_get_type first,
* 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);
/**
* CoglMaterialLayerFlags:
* @COGL_MATERIAL_LAYER_FLAG_USER_MATRIX: Means the user has supplied a
* custom texture matrix.
* cogl_material_layer_get_min_filter:
* @layer_handle: a #CoglHandle for a material layer.
*
* Query the currently set downscaling filter for a cogl material layer.
*
* Returns: the current downscaling filter for a cogl material layer.
*/
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!!! */
CoglMaterialFilter cogl_material_layer_get_min_filter (CoglHandle layer_handle);
/**
* cogl_material_layer_get_flags:
* @layer_handle: A CoglMaterialLayer layer handle
* cogl_material_layer_get_mag_filter:
* @layer_handle: a #CoglHandle for a material layer.
*
* 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.
* Query the currently set downscaling filter for a cogl material layer.
*
* Returns: the current downscaling filter for a cogl material layer.
*/
gulong cogl_material_layer_get_flags (CoglHandle layer_handle);
CoglMaterialFilter cogl_material_layer_get_mag_filter (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
* cogl_material_set_layer_filters:
* @handle: a #CoglHandle to a material.
* @layer_index: the layer number to change.
* @min_filter: the filter used when scaling a texture down.
* @mag_filter: the filter used when magnifying a texture.
*
* 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
* Changes the decimation and interpolation filters used when a texture is
* drawn at other scales than 100%.
*/
void cogl_material_flush_gl_state (CoglHandle material,
...) G_GNUC_NULL_TERMINATED;
void cogl_material_set_layer_filters (CoglHandle handle,
gint layer_index,
CoglMaterialFilter min_filter,
CoglMaterialFilter mag_filter);
G_END_DECLS

View File

@ -199,22 +199,50 @@ void cogl_matrix_frustum (CoglMatrix *matrix,
float z_far);
/**
* cogl_matrix_transform_point:
* cogl_matrix_perspective:
* @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]
* @fov_y: A field of view angle for the Y axis
* @aspect: The ratio of width to height determining the field of view angle
* for the x axis.
* @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
* as four float components.
* Multiplies the matrix by the described perspective matrix
*
* 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
cogl_matrix_transform_point (const CoglMatrix *matrix,
float *x,
float *y,
float *z,
float *w);
cogl_matrix_perspective (CoglMatrix *matrix,
float fov_y,
float aspect,
float z_near,
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:
@ -234,6 +262,24 @@ void cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array);
*/
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
#endif /* __COGL_MATRIX_H */

View File

@ -46,9 +46,12 @@ G_BEGIN_DECLS
* CoglShaderType:
* @COGL_SHADER_TYPE_VERTEX: A program for proccessing vertices
* @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_FRAGMENT
} CoglShaderType;
@ -103,7 +106,7 @@ gboolean cogl_is_shader (CoglHandle handle);
* one.
*/
void cogl_shader_source (CoglHandle shader,
const char *source);
const gchar *source);
/**
* cogl_shader_compile:
* @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
* linking into a program.
*/
void cogl_shader_compile (CoglHandle handle);
void cogl_shader_compile (CoglHandle handle);
/**
* cogl_shader_get_info_log:
* @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
* 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
* 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,
size_t size,
char *buffer);
gchar * cogl_shader_get_info_log (CoglHandle handle);
/**
* cogl_shader_get_type:
* @handle: #CoglHandle for a shader.
*
* Returns: COGL_SHADER_TYPE_VERTEX if the shader is a vertex processor
* or COGL_SHADER_TYPE_FRAGMENT if the shader is a frament processor
* Retrieves the type of a shader #CoglHandle
*
* 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);
@ -141,7 +145,9 @@ CoglShaderType cogl_shader_get_type (CoglHandle handle);
* cogl_shader_is_compiled:
* @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);

View File

@ -41,12 +41,12 @@ G_BEGIN_DECLS
* loading and manipulating textures.
*/
#define COGL_TEXTURE_MAX_WASTE 127
/**
* cogl_texture_new_with_size:
* @width: width 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
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the
* texture.
@ -60,15 +60,12 @@ G_BEGIN_DECLS
*/
CoglHandle cogl_texture_new_with_size (guint width,
guint height,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat internal_format);
/**
* cogl_texture_new_from_file:
* @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
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the
* texture
@ -82,7 +79,6 @@ CoglHandle cogl_texture_new_with_size (guint width,
* Since: 0.8
*/
CoglHandle cogl_texture_new_from_file (const gchar *filename,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat internal_format,
GError **error);
@ -91,8 +87,6 @@ CoglHandle cogl_texture_new_from_file (const gchar *filename,
* cogl_texture_new_from_data:
* @width: width 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
* @format: the #CoglPixelFormat the buffer is stored in in RAM
* @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,
guint height,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat format,
CoglPixelFormat internal_format,
@ -136,19 +129,17 @@ CoglHandle cogl_texture_new_from_data (guint width,
*
* Since: 0.8
*/
CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle,
GLenum gl_target,
GLuint width,
GLuint height,
GLuint x_pot_waste,
GLuint y_pot_waste,
CoglPixelFormat format);
CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle,
GLenum gl_target,
GLuint width,
GLuint height,
GLuint x_pot_waste,
GLuint y_pot_waste,
CoglPixelFormat format);
/**
* cogl_texture_new_from_bitmap:
* @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
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the
* texture
@ -160,10 +151,9 @@ CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle,
*
* Since: 1.0
*/
CoglHandle cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat internal_format);
CoglHandle cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
CoglTextureFlags flags,
CoglPixelFormat internal_format);
/**
* cogl_is_texture:
@ -228,72 +218,6 @@ guint cogl_texture_get_rowstride (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:
* @handle: a #CoglHandle for a texture.
@ -343,20 +267,6 @@ gint cogl_texture_get_data (CoglHandle handle,
guint rowstride,
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:
* @handle: a #CoglHandle.

View File

@ -123,8 +123,7 @@ typedef struct _CoglTextureVertex CoglTextureVertex;
*
* Since: 0.8
*/
typedef enum
{
typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
COGL_PIXEL_FORMAT_ANY = 0,
COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT,
@ -135,60 +134,21 @@ typedef enum
COGL_PIXEL_FORMAT_G_8 = 8,
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_BGR_BIT),
COGL_PIXEL_FORMAT_RGBA_8888 = COGL_PIXEL_FORMAT_32 |
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 = (COGL_PIXEL_FORMAT_32 | 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),
} CoglPixelFormat;
#define COGL_TYPE_PIXEL_FORMAT (cogl_pixel_format_get_type ())
GType cogl_pixel_format_get_type (void) G_GNUC_CONST;
/**
* CoglFeatureFlags:
* @COGL_FEATURE_TEXTURE_RECTANGLE: ARB_texture_rectangle support
@ -222,9 +182,6 @@ typedef enum
COGL_FEATURE_VBOS = (1 << 11)
} CoglFeatureFlags;
#define COGL_TYPE_FEATURE_FLAGS (cogl_feature_flags_get_type ())
GType cogl_feature_flags_get_type (void) G_GNUC_CONST;
/**
* CoglBufferTarget:
* @COGL_WINDOW_BUFFER: FIXME
@ -240,9 +197,6 @@ typedef enum
COGL_OFFSCREEN_BUFFER = (1 << 2)
} CoglBufferTarget;
#define COGL_TYPE_BUFFER_TARGET (cogl_buffer_target_get_type ())
GType cogl_buffer_target_get_type (void) G_GNUC_CONST;
/**
* CoglColor:
*
@ -290,21 +244,23 @@ struct _CoglTextureVertex
/**
* CoglTextureFlags:
* @COGL_TEXTURE_NONE: No flags specified
* @COGL_TEXTURE_AUTO_MIPMAP: Enables the automatic generation of the
* mipmap pyramid from the base level image whenever it is updated
* @COGL_TEXTURE_NO_AUTO_MIPMAP: Disables the automatic generation of
* 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.
*
* Since: 1.0
*/
typedef enum {
COGL_TEXTURE_NONE = 0,
COGL_TEXTURE_AUTO_MIPMAP = 1 << 0
COGL_TEXTURE_NONE = 0,
COGL_TEXTURE_NO_AUTO_MIPMAP = 1 << 0,
COGL_TEXTURE_NO_SLICING = 1 << 1
} CoglTextureFlags;
#define COGL_TYPE_TEXTURE_FLAGS (cogl_texture_flags_get_type ())
GType cogl_texture_flags_get_type (void) G_GNUC_CONST;
/**
* CoglFogMode:
* @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
*/
typedef enum _CoglFogMode
{
typedef enum {
COGL_FOG_MODE_LINEAR,
COGL_FOG_MODE_EXPONENTIAL,
COGL_FOG_MODE_EXPONENTIAL_SQUARED
} CoglFogMode;
#define COGL_TYPE_FOG_MODE (cogl_fog_mode_get_type ())
GType cogl_fog_mode_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __COGL_TYPES_H__ */

View File

@ -94,6 +94,29 @@ cogl_vertex_buffer_new (guint n_vertices);
guint
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:
* @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.
* "gl_Color::active" or "gl_Color::inactive"
* @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,
* GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT or GL_FLOAT)
* @type: a #CoglAttributeType specifying the data type of each component.
* @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
* directly.
* @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)
*/
void
cogl_vertex_buffer_add (CoglHandle handle,
const char *attribute_name,
guint8 n_components,
GLenum gl_type,
gboolean normalized,
guint16 stride,
const void *pointer);
cogl_vertex_buffer_add (CoglHandle handle,
const char *attribute_name,
guint8 n_components,
CoglAttributeType type,
gboolean normalized,
guint16 stride,
const void *pointer);
/**
* cogl_vertex_buffer_delete:
@ -226,21 +248,37 @@ void
cogl_vertex_buffer_enable (CoglHandle handle,
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:
* @handle: A vertex buffer handle
* @mode: Specifies how the vertices should be interpreted, and should be
* a valid GL primitive type:
* <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)
* @mode: A #CoglVerticesMode specifying how the vertices should be
* interpreted.
* @first: Specifies the index of the first vertex you want to draw with
* @count: Specifies the number of vertices you want to draw.
*
@ -251,52 +289,90 @@ cogl_vertex_buffer_enable (CoglHandle handle,
* drawing.
*/
void
cogl_vertex_buffer_draw (CoglHandle handle,
GLenum mode,
GLint first,
GLsizei count);
cogl_vertex_buffer_draw (CoglHandle handle,
CoglVerticesMode mode,
int first,
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:
* @handle: A vertex buffer handle
* @mode: Specifies how the vertices should be interpreted, and should be
* a valid GL primitive type:
* <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)
* @mode: A #CoglVerticesMode specifying how the vertices should be
* interpreted.
* @indices: A CoglHandle for a set of indices allocated via
* cogl_vertex_buffer_indices_new ()
* @min_index: Specifies the minimum 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.
* @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
* 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
* drawing.
*/
void
cogl_vertex_buffer_draw_elements (CoglHandle handle,
GLenum mode,
GLuint min_index,
GLuint max_index,
GLsizei count,
GLenum indices_type,
const GLvoid *indices);
cogl_vertex_buffer_draw_elements (CoglHandle handle,
CoglVerticesMode mode,
CoglHandle indices,
int min_index,
int max_index,
int indices_offset,
int count);
/**
* cogl_vertex_buffer_ref:
@ -318,6 +394,46 @@ cogl_vertex_buffer_ref (CoglHandle handle);
void
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

125
cogl.h.in
View File

@ -45,6 +45,7 @@
#include <cogl/cogl-types.h>
#include <cogl/cogl-debug.h>
#include <cogl/cogl-deprecated.h>
#include <cogl/cogl-enum-types.h>
G_BEGIN_DECLS
@ -55,22 +56,6 @@ G_BEGIN_DECLS
* 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:
*
@ -187,7 +172,30 @@ void cogl_frustum (float left,
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
* @height: Height of the viewport
* @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
* view scaled according to @aspect along the x-axis. The view is
* 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,
guint height,
void _cogl_setup_viewport (guint width,
guint height,
float fovy,
float aspect,
float z_near,
@ -288,6 +298,14 @@ void cogl_rotate (float angle,
*/
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:
* @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);
/**
* 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:
* @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]);
/**
* cogl_enable_depth_test:
* cogl_set_depth_test_enable:
* @setting: %TRUE to enable depth testing or %FALSE to disable.
*
* 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
* 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.
*
* 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
* 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:
@ -368,9 +413,12 @@ void cogl_disable_fog (void);
* @COGL_BUFFER_BIT_COLOR: Selects the primary color buffer
* @COGL_BUFFER_BIT_DEPTH: Selects the depth 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_DEPTH = 1L<<1,
COGL_BUFFER_BIT_STENCIL = 1L<<2
@ -379,13 +427,14 @@ typedef enum _CoglBufferBit
/**
* cogl_clear:
* @color: Background color to clear to
* @buffers: A mask of @CoglBufferBit<!-- -->'s identifying which auxiliary
* buffers to clear
* @buffers: A mask of #CoglBufferBit<!-- -->'s identifying which auxiliary
* buffers to clear
*
* Clears all the auxiliary buffers identified in the @buffers mask, and if
* 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:
@ -628,7 +677,24 @@ void cogl_push_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:
* @flags: flags controlling what is flushed; currently unused, pass in 0
*
@ -642,6 +708,7 @@ void cogl_pop_draw_buffer (void);
* Since: 1.0
*/
void cogl_flush_gl_state (int flags);
#endif
/* private */
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 = \
-I$(top_srcdir) \
-I$(top_srcdir)/clutter \
@ -9,12 +16,49 @@ INCLUDES = \
-DG_LOG_DOMAIN=\"Cogl-Common\" \
-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
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_LIBADD = -lm $(CLUTTER_LIBS)
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-internal.h \
cogl.c \
@ -39,4 +83,11 @@ libclutter_cogl_common_la_SOURCES = \
cogl-matrix-stack.h \
cogl-material.c \
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) \
glFrustumf((GLfloat)L, (GLfloat)R, (GLfloat)B, \
(GLfloat)T, (GLfloat)N, (GLfloat)F)
#define glOrtho glOrthof
#endif
#include <string.h>
@ -209,30 +212,57 @@ _cogl_current_matrix_frustum (float left,
}
void
_cogl_current_matrix_ortho (float left,
float right,
float bottom,
float top,
float near_val,
float far_val)
_cogl_current_matrix_perspective (float fov_y,
float aspect,
float z_near,
float z_far)
{
_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);
if (current_stack != NULL)
_cogl_matrix_stack_ortho (current_stack,
left, right,
top, bottom,
bottom, top,
near_val,
far_val);
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
/* Nobody is using glOrtho right now anyway, so not bothering */
g_warning ("%s not implemented, need to code cogl_matrix_ortho() if you need"
" this function",
G_STRFUNC);
GE (glOrtho (left, right, bottom, top, near_val, far_val));
#endif
}
}
void
@ -276,6 +306,12 @@ _cogl_get_matrix (CoglMatrixMode mode,
}
}
void
_cogl_set_matrix (const CoglMatrix *matrix)
{
_cogl_current_matrix_load (matrix);
}
void
_cogl_current_matrix_state_init (void)
{
@ -354,85 +390,19 @@ cogl_rotate (float angle, float x, float y, float z)
}
void
_cogl_set_matrix (const CoglMatrix *matrix)
{
_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,
cogl_perspective (float fov_y,
float aspect,
float zNear,
float zFar)
float z_near,
float z_far)
{
float xmax, ymax;
float x, y, c, d;
float fovy_rad_half = (fovy * G_PI) / 360;
CoglMatrix perspective;
GLfloat m[16];
float ymax = z_near * tanf (fov_y * G_PI / 360.0);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
memset (&m[0], 0, sizeof (m));
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_identity ();
/*
* 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
cogl_frustum (-ymax * aspect, /* left */
ymax * aspect, /* right */
-ymax, /* bottom */
ymax, /* top */
z_near,
z_far);
}
void
@ -474,4 +444,65 @@ cogl_frustum (float left,
M(3,2) = 1.0 / d;
M(3,3) = c / d;
#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 },
{ "pango", COGL_DEBUG_PANGO },
{ "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);

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 GQuark \
_cogl_##type_name##_get_type (void) \
_cogl_handle_##type_name##_get_type (void) \
{ \
static GQuark type = 0; \
if (!type) \
@ -99,13 +99,13 @@ _cogl_##type_name##_handle_new (Cogl##TypeName *new_obj) \
obj->klass = &_cogl_##type_name##_class; \
if (!obj->klass->type) \
{ \
obj->klass->type = _cogl_##type_name##_get_type (); \
obj->klass->virt_free = _cogl_##type_name##_free; \
} \
obj->klass->type = _cogl_handle_##type_name##_get_type ();\
obj->klass->virt_free = _cogl_##type_name##_free; \
} \
\
_COGL_HANDLE_DEBUG_NEW (TypeName, obj); \
return (CoglHandle) new_obj; \
} \
_COGL_HANDLE_DEBUG_NEW (TypeName, obj); \
return (CoglHandle) new_obj; \
} \
\
Cogl##TypeName * \
_cogl_##type_name##_pointer_from_handle (CoglHandle handle) \
@ -121,7 +121,8 @@ cogl_is_##type_name (CoglHandle handle) \
if (handle == COGL_INVALID_HANDLE) \
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 \

View File

@ -68,15 +68,20 @@ struct _CoglMaterialLayer
CoglHandle texture; /*!< The texture for this layer, or COGL_INVALID_HANDLE
for an empty layer */
CoglMaterialFilter mag_filter;
CoglMaterialFilter min_filter;
/* Determines how the color of individual texture fragments
* are calculated. */
CoglMaterialLayerCombineFunc texture_combine_rgb_func;
CoglMaterialLayerCombineSrc texture_combine_rgb_src[3];
CoglMaterialLayerCombineOp texture_combine_rgb_op[3];
GLint texture_combine_rgb_func;
GLint texture_combine_rgb_src[3];
GLint texture_combine_rgb_op[3];
CoglMaterialLayerCombineFunc texture_combine_alpha_func;
CoglMaterialLayerCombineSrc texture_combine_alpha_src[3];
CoglMaterialLayerCombineOp texture_combine_alpha_op[3];
GLint texture_combine_alpha_func;
GLint texture_combine_alpha_src[3];
GLint texture_combine_alpha_op[3];
GLfloat texture_combine_constant[4];
/* TODO: Support purely GLSL based material layers */
@ -114,11 +119,104 @@ struct _CoglMaterial
GLfloat alpha_func_reference;
/* Determines how this material is blended with other primitives */
CoglMaterialBlendFactor blend_src_factor;
CoglMaterialBlendFactor blend_dst_factor;
#ifndef HAVE_COGL_GLES
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;
};
/*
* 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 */

View File

@ -35,6 +35,7 @@
#include "cogl-material-private.h"
#include "cogl-texture-private.h"
#include "cogl-blend-string.h"
#include <glib.h>
#include <string.h>
@ -50,6 +51,10 @@
#ifdef HAVE_COGL_GL
#define glActiveTexture ctx->pf_glActiveTexture
#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
static void _cogl_material_free (CoglMaterial *tex);
@ -60,6 +65,12 @@ COGL_HANDLE_DEFINE (MaterialLayer, material_layer);
/* #define DISABLE_MATERIAL_CACHE 1 */
GQuark
_cogl_material_error_quark (void)
{
return g_quark_from_static_string ("cogl-material-error-quark");
}
CoglHandle
cogl_material_new (void)
{
@ -88,8 +99,18 @@ cogl_material_new (void)
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC;
/* Not the same as the GL default, but seems saner... */
material->blend_src_factor = COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA;
material->blend_dst_factor = COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
#ifndef HAVE_COGL_GLES
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->layers = NULL;
@ -408,20 +429,177 @@ cogl_material_set_alpha_test_function (CoglHandle handle,
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
cogl_material_set_blend_factors (CoglHandle handle,
CoglMaterialBlendFactor src_factor,
CoglMaterialBlendFactor dst_factor)
setup_blend_state (CoglBlendStringStatement *statement,
GLenum *blend_equation,
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;
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));
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;
#endif
}
/* 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->index = index_;
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;
/* Choose the same default combine mode as OpenGL:
* MODULATE(PREVIOUS[RGBA],TEXTURE[RGBA]) */
layer->texture_combine_rgb_func = COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE;
layer->texture_combine_rgb_src[0] = COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS;
layer->texture_combine_rgb_src[1] = COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE;
layer->texture_combine_rgb_op[0] = COGL_MATERIAL_LAYER_COMBINE_OP_SRC_COLOR;
layer->texture_combine_rgb_op[1] = COGL_MATERIAL_LAYER_COMBINE_OP_SRC_COLOR;
layer->texture_combine_alpha_func =
COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE;
layer->texture_combine_alpha_src[0] =
COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS;
layer->texture_combine_alpha_src[1] =
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;
layer->texture_combine_rgb_func = GL_MODULATE;
layer->texture_combine_rgb_src[0] = GL_PREVIOUS;
layer->texture_combine_rgb_src[1] = GL_TEXTURE;
layer->texture_combine_rgb_op[0] = GL_SRC_COLOR;
layer->texture_combine_rgb_op[1] = GL_SRC_COLOR;
layer->texture_combine_alpha_func = GL_MODULATE;
layer->texture_combine_alpha_src[0] = GL_PREVIOUS;
layer->texture_combine_alpha_src[1] = GL_TEXTURE;
layer->texture_combine_alpha_op[0] = GL_SRC_ALPHA;
layer->texture_combine_alpha_op[1] = GL_SRC_ALPHA;
cogl_matrix_init_identity (&layer->matrix);
@ -498,7 +673,8 @@ cogl_material_set_layer (CoglHandle material_handle,
int n_layers;
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);
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. */
}
cogl_handle_ref (texture_handle);
if (texture_handle)
cogl_handle_ref (texture_handle);
if (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;
}
void
cogl_material_set_layer_combine_function (
CoglHandle handle,
gint layer_index,
CoglMaterialLayerCombineChannels channels,
CoglMaterialLayerCombineFunc func)
static void
setup_texture_combine_state (CoglBlendStringStatement *statement,
GLint *texture_combine_func,
GLint *texture_combine_src,
GLint *texture_combine_op)
{
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;
CoglMaterialLayer *layer;
gboolean set_alpha_func = FALSE;
gboolean set_rgb_func = FALSE;
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);
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));
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_alpha_func = set_rgb_func = TRUE;
else if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB)
set_rgb_func = TRUE;
else if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA)
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;
constant = layer->texture_combine_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);
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
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
* will be replaced. */
gulong
cogl_material_get_cogl_enable_flags (CoglHandle material_handle)
_cogl_material_get_cogl_enable_flags (CoglHandle material_handle)
{
CoglMaterial *material;
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
* 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)
* by the caller.
*/
@ -748,7 +985,7 @@ cogl_material_layer_get_texture (CoglHandle layer_handle)
}
gulong
cogl_material_layer_get_flags (CoglHandle layer_handle)
_cogl_material_layer_get_flags (CoglHandle layer_handle)
{
CoglMaterialLayer *layer;
@ -760,25 +997,34 @@ cogl_material_layer_get_flags (CoglHandle layer_handle)
}
static guint
get_n_args_for_combine_func (CoglMaterialLayerCombineFunc func)
get_n_args_for_combine_func (GLint func)
{
switch (func)
{
case COGL_MATERIAL_LAYER_COMBINE_FUNC_REPLACE:
case GL_REPLACE:
return 1;
case COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE:
case COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD:
case COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD_SIGNED:
case COGL_MATERIAL_LAYER_COMBINE_FUNC_SUBTRACT:
case COGL_MATERIAL_LAYER_COMBINE_FUNC_DOT3_RGB:
case COGL_MATERIAL_LAYER_COMBINE_FUNC_DOT3_RGBA:
case GL_MODULATE:
case GL_ADD:
case GL_ADD_SIGNED:
case GL_SUBTRACT:
case GL_DOT3_RGB:
case GL_DOT3_RGBA:
return 2;
case COGL_MATERIAL_LAYER_COMBINE_FUNC_INTERPOLATE:
case GL_INTERPOLATE:
return 3;
}
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
_cogl_material_layer_flush_gl_sampler_state (CoglMaterialLayer *layer,
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,
layer->texture_combine_alpha_op[2]));
}
GE (glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
layer->texture_combine_constant));
}
#ifndef DISABLE_MATERIAL_CACHE
@ -976,6 +1225,13 @@ _cogl_material_flush_layers_gl_state (CoglMaterial *material,
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
if it is different from gl_layer_info->gl_texture to avoid
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
&& 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
cogl_material_flush_gl_state (CoglHandle handle, ...)
_cogl_material_flush_gl_state (CoglHandle handle, ...)
{
CoglMaterial *material;
va_list ap;
@ -1204,3 +1492,44 @@ cogl_set_source_texture (CoglHandle texture_handle)
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;
}
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
_cogl_matrix_stack_get (CoglMatrixStack *stack,
CoglMatrix *matrix)
@ -280,25 +333,6 @@ _cogl_matrix_stack_set (CoglMatrixStack *stack,
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_flush_to_gl (CoglMatrixStack *stack,
GLenum gl_mode)

View File

@ -51,10 +51,6 @@ void _cogl_matrix_stack_rotate (CoglMatrixStack *stack,
float z);
void _cogl_matrix_stack_multiply (CoglMatrixStack *stack,
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,
float left,
float right,
@ -62,6 +58,22 @@ void _cogl_matrix_stack_frustum (CoglMatrixStack *stack,
float top,
float z_near,
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,
GLenum gl_mode);

View File

@ -151,21 +151,6 @@ cogl_matrix_invert (CoglMatrix *matrix)
}
#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
cogl_matrix_frustum (CoglMatrix *matrix,
float left,
@ -208,6 +193,62 @@ cogl_matrix_frustum (CoglMatrix *matrix,
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
cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array)
{
@ -220,3 +261,19 @@ cogl_matrix_get_array (const CoglMatrix *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-context.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 <gmodule.h>
@ -39,16 +40,8 @@
#ifdef HAVE_COGL_GL
#define glDrawRangeElements ctx->pf_glDrawRangeElements
#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
/* these are defined in the particular backend */
@ -63,7 +56,6 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
gint batch_len,
GLfloat *vertex_pointer)
{
int needed_indices;
gsize stride;
int i;
gulong enable_flags = 0;
@ -72,35 +64,6 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
_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:
* Our vertex data is arranged as follows:
* 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 = ~disable_mask;
cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_FALLBACK_MASK,
batch_start->fallback_mask,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
disable_mask,
/* Redundant when dealing with unsliced
* textures but does no harm... */
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
batch_start->layer0_override_texture,
NULL);
_cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_FALLBACK_MASK,
batch_start->fallback_mask,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
disable_mask,
/* Redundant when dealing with unsliced
* textures but does no harm... */
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
batch_start->layer0_override_texture,
NULL);
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
* 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)
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));
_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:
* 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 == 2 ? 0xff : 0x00,
0xff);
cogl_material_flush_gl_state (outline, NULL);
_cogl_material_flush_gl_state (outline, NULL);
_cogl_current_matrix_state_flush ();
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
* 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. */
flags = cogl_material_layer_get_flags (layer);
flags = _cogl_material_layer_get_flags (layer);
if (flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX
&& _cogl_texture_span_has_waste (texture, 0, 0))
{
@ -1041,13 +1024,13 @@ _cogl_texture_sliced_polygon (CoglTextureVertex *vertices,
v += stride;
}
cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
(guint32)~1, /* disable all except the
_cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
(guint32)~1, /* disable all except the
first layer */
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
gl_handle,
NULL);
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
gl_handle,
NULL);
_cogl_current_matrix_state_flush ();
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);
}
cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_FALLBACK_MASK,
fallback_mask,
NULL);
_cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_FALLBACK_MASK,
fallback_mask,
NULL);
_cogl_current_matrix_state_flush ();
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
@ -1175,7 +1158,6 @@ cogl_polygon (CoglTextureVertex *vertices,
{
CoglHandle layer = (CoglHandle)tmp->data;
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))
{
@ -1203,7 +1185,8 @@ cogl_polygon (CoglTextureVertex *vertices,
use_sliced_polygon_fallback = TRUE;
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;
if (!warning_seen)
@ -1217,11 +1200,14 @@ cogl_polygon (CoglTextureVertex *vertices,
}
#ifdef HAVE_COGL_GL
/* Temporarily change the wrapping mode on all of the slices to use
* a transparent 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);
{
CoglTexture *tex = _cogl_texture_pointer_from_handle (tex_handle);
/* Temporarily change the wrapping mode on all of the slices to use
* a transparent 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
break;
}
@ -1254,7 +1240,7 @@ cogl_polygon (CoglTextureVertex *vertices,
/* Prepare GL state */
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)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;

View File

@ -103,159 +103,6 @@ cogl_handle_get_type (void)
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
*/

View File

@ -99,9 +99,9 @@ typedef struct _CoglVertexBufferAttrib
union _u
{
const void *pointer;
gsize vbo_offset;
size_t vbo_offset;
} u;
gsize span_bytes;
size_t span_bytes;
guint16 stride;
guint8 n_components;
guint8 texture_unit;
@ -129,25 +129,41 @@ typedef struct _CoglVertexBufferVBO
{
CoglVertexBufferVBOFlags flags;
/* Note: this is a pointer to handle fallbacks, and normally holds
* a GLuint value */
gpointer vbo_name; /*!< The name of the corresponding buffer object */
gsize vbo_bytes; /*!< The lengh of the allocated buffer object in bytes */
/* 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; /*!< The name of the corresponding buffer object */
size_t vbo_bytes; /*!< The lengh of the allocated buffer object in bytes */
GList *attributes;
} 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
{
CoglHandleObject _parent;
guint n_vertices; /*!< The number of vertices in the buffer */
GList *submitted_vbos; /* The VBOs currently submitted to the GPU */
int n_vertices; /*!< The number of vertices in the buffer */
GList *submitted_vbos; /* The VBOs currently submitted to the GPU */
/* Note: new_attributes is normally NULL and only valid while
* modifying a buffer. */
GList *new_attributes; /*!< attributes pending submission */
GList *new_attributes; /*!< attributes pending submission */
} 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 */

View File

@ -136,6 +136,7 @@
#include "cogl-handle.h"
#include "cogl-vertex-buffer-private.h"
#include "cogl-texture-private.h"
#include "cogl-material-private.h"
#define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \
(VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1)))
@ -200,8 +201,10 @@
#endif /* HAVE_COGL_GL */
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 (VertexBufferIndices, vertex_buffer_indices);
CoglHandle
cogl_vertex_buffer_new (guint n_vertices)
@ -411,13 +414,13 @@ get_gl_type_size (CoglVertexBufferAttribFlags flags)
}
void
cogl_vertex_buffer_add (CoglHandle handle,
const char *attribute_name,
guint8 n_components,
GLenum gl_type,
gboolean normalized,
guint16 stride,
const void *pointer)
cogl_vertex_buffer_add (CoglHandle handle,
const char *attribute_name,
guint8 n_components,
CoglAttributeType type,
gboolean normalized,
guint16 stride,
const void *pointer)
{
CoglVertexBuffer *buffer;
GQuark name_quark = g_quark_from_string (attribute_name);
@ -485,7 +488,7 @@ cogl_vertex_buffer_add (CoglHandle handle,
attribute->u.pointer = pointer;
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;
/* 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_FALLBACK_MASK,
fallback_mask,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
disable_mask,
NULL);
_cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_FALLBACK_MASK,
fallback_mask,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
disable_mask,
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)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
@ -1716,23 +1719,21 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
}
void
cogl_vertex_buffer_draw (CoglHandle handle,
GLenum mode,
GLint first,
GLsizei count)
cogl_vertex_buffer_draw (CoglHandle handle,
CoglVerticesMode mode,
int first,
int count)
{
CoglVertexBuffer *buffer;
if (!cogl_is_vertex_buffer (handle))
return;
cogl_clip_ensure ();
buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
enable_state_for_drawing_buffer (buffer);
cogl_clip_ensure ();
_cogl_current_matrix_state_flush ();
enable_state_for_drawing_buffer (buffer);
/* FIXME: flush cogl cache */
GE (glDrawArrays (mode, first, count));
@ -1740,35 +1741,127 @@ cogl_vertex_buffer_draw (CoglHandle handle,
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
cogl_vertex_buffer_draw_elements (CoglHandle handle,
GLenum mode,
GLuint min_index,
GLuint max_index,
GLsizei count,
GLenum indices_type,
const GLvoid *indices)
_cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *indices)
{
gboolean fallback =
(cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
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;
gboolean fallback =
(cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
size_t byte_offset;
CoglVertexBufferIndices *indices = NULL;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_vertex_buffer (handle))
return;
cogl_clip_ensure ();
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);
_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 */
GE (glDrawRangeElements (mode, min_index, max_index,
count, indices_type, indices));
count, indices->type, (void *)byte_offset));
disable_state_for_drawing_buffer (buffer);
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0));
}
static void
@ -1778,8 +1871,92 @@ _cogl_vertex_buffer_free (CoglVertexBuffer *buffer)
for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next)
cogl_vertex_buffer_vbo_free (tmp->data, TRUE);
g_list_free (buffer->submitted_vbos);
for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next)
cogl_vertex_buffer_attribute_free (tmp->data);
g_list_free (buffer->new_attributes);
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-util.h"
#include "cogl-context.h"
#include "cogl-material-private.h"
#if defined (HAVE_COGL_GLES2) || defined (HAVE_COGL_GLES)
#include "cogl-gles2-wrapper.h"
@ -213,30 +214,39 @@ cogl_get_enable ()
}
void
cogl_enable_depth_test (gboolean setting)
cogl_set_depth_test_enabled (gboolean setting)
{
if (setting)
{
glEnable (GL_DEPTH_TEST);
glEnable (GL_ALPHA_TEST);
glDepthFunc (GL_LEQUAL);
glAlphaFunc (GL_GREATER, 0.1);
}
else
{
glDisable (GL_DEPTH_TEST);
glDisable (GL_ALPHA_TEST);
}
glDisable (GL_DEPTH_TEST);
}
gboolean
cogl_get_depth_test_enabled (void)
{
return glIsEnabled (GL_DEPTH_TEST) == GL_TRUE ? TRUE : FALSE;
}
void
cogl_enable_backface_culling (gboolean setting)
cogl_set_backface_culling_enabled (gboolean setting)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
ctx->enable_backface_culling = setting;
}
gboolean
cogl_get_backface_culling_enabled (void)
{
_COGL_GET_CONTEXT (ctx, FALSE);
return ctx->enable_backface_culling;
}
void
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_material_flush_gl_state (ctx->stencil_material, NULL);
_cogl_material_flush_gl_state (ctx->stencil_material, NULL);
if (first)
{
@ -465,12 +475,12 @@ cogl_viewport (guint width,
}
void
cogl_setup_viewport (guint width,
guint height,
float fovy,
float aspect,
float z_near,
float z_far)
_cogl_setup_viewport (guint width,
guint height,
float fovy,
float aspect,
float z_near,
float z_far)
{
float z_camera;
CoglMatrix projection_matrix;
@ -478,7 +488,7 @@ cogl_setup_viewport (guint width,
GE( glViewport (0, 0, width, height) );
/* 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);
@ -532,7 +542,7 @@ cogl_setup_viewport (guint width,
}
CoglFeatureFlags
cogl_get_features ()
cogl_get_features (void)
{
_COGL_GET_CONTEXT (ctx, 0);
@ -653,9 +663,11 @@ cogl_disable_fog (void)
glDisable (GL_FOG);
}
#if 0
void
cogl_flush_gl_state (int flags)
{
_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()"
# 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"
# Extra options to supply to gtkdoc-mkdb.
@ -70,12 +70,14 @@ HTML_IMAGES=
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
# 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
# These files must be listed here *and* in content_files
# 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.
# 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
# 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"?>
<!DOCTYPE book 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">
<!ENTITY version "@VERSION@">
]>
<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-color.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-primitives.xml"/>
<xi:include href="xml/cogl-vertex-buffer.xml"/>

View File

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

View File

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

View File

@ -35,11 +35,6 @@ cogl_sources = \
cogl-context.c \
$(NULL)
coglincludedir = $(includedir)/clutter-@CLUTTER_API_VERSION@/cogl
coglinclude_HEADERS = \
$(cogl_headers) \
$(top_builddir)/clutter/cogl/cogl.h
INCLUDES = \
-I$(top_srcdir)/clutter/cogl \
-I$(top_srcdir)/clutter/cogl/common \
@ -50,12 +45,12 @@ INCLUDES = \
-DG_LOG_DOMAIN=\"Cogl-GL\" \
-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_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_la_SOURCES = \
libclutter_cogl_gl_la_CPPFLAGS = $(CLUTTER_CFLAGS) $(COGL_DEBUG_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS)
libclutter_cogl_gl_la_LIBADD = -lm $(CLUTTER_LIBS) $(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_gl_la_SOURCES = \
$(top_builddir)/clutter/cogl/cogl.h \
$(cogl_headers) \
$(cogl_priv_headers) \

View File

@ -37,7 +37,7 @@
static CoglContext *_context = NULL;
static gboolean gl_is_indirect = FALSE;
gboolean
static gboolean
cogl_create_context ()
{
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->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,
sizeof (CoglTextureGLVertex));
@ -136,6 +135,9 @@ cogl_create_context ()
_context->pf_glActiveTexture = NULL;
_context->pf_glClientActiveTexture = NULL;
_context->pf_glBlendFuncSeparate = NULL;
_context->pf_glBlendEquationSeparate = NULL;
/* Initialise the clip stack */
_cogl_clip_stack_state_init ();
@ -146,8 +148,7 @@ cogl_create_context ()
_context->default_gl_texture_2d_tex =
cogl_texture_new_from_data (1, /* width */
1, /* height */
-1, /* max waste */
COGL_TEXTURE_NONE, /* flags */
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
/* internal format */
COGL_PIXEL_FORMAT_RGBA_8888,
@ -156,8 +157,7 @@ cogl_create_context ()
_context->default_gl_texture_rect_tex =
cogl_texture_new_from_data (1, /* width */
1, /* height */
-1, /* max waste */
COGL_TEXTURE_NONE, /* flags */
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
/* internal format */
COGL_PIXEL_FORMAT_RGBA_8888,
@ -165,16 +165,20 @@ cogl_create_context ()
default_texture_data);
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 =
cogl_material_get_cogl_enable_flags (_context->source_material);
_cogl_material_get_cogl_enable_flags (_context->source_material);
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;
}
void
cogl_destroy_context ()
_cogl_destroy_context ()
{
if (_context == NULL)
return;
@ -199,13 +203,16 @@ cogl_destroy_context ()
if (_context->logged_vertices)
g_array_free (_context->logged_vertices, TRUE);
if (_context->static_indices)
g_array_free (_context->static_indices, TRUE);
if (_context->polygon_vertices)
g_array_free (_context->polygon_vertices, TRUE);
if (_context->current_layers)
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);
}

View File

@ -78,7 +78,6 @@ typedef struct
* can batch things together. */
GArray *journal;
GArray *logged_vertices;
GArray *static_indices;
GArray *polygon_vertices;
/* Some simple caching, to minimize state changes... */
@ -102,6 +101,12 @@ typedef struct
floatVec2 path_nodes_max;
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 */
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;
COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT;
@ -115,6 +120,7 @@ typedef struct
COGL_PFNGLDELETEFRAMEBUFFERSEXTPROC pf_glDeleteFramebuffersEXT;
COGL_PFNGLBLITFRAMEBUFFEREXTPROC pf_glBlitFramebufferEXT;
COGL_PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC pf_glRenderbufferStorageMultisampleEXT;
COGL_PFNGLGENERATEMIPMAPEXTPROC pf_glGenerateMipmapEXT;
COGL_PFNGLCREATEPROGRAMOBJECTARBPROC pf_glCreateProgramObjectARB;
COGL_PFNGLCREATESHADEROBJECTARBPROC pf_glCreateShaderObjectARB;
@ -164,6 +170,11 @@ typedef struct
COGL_PFNGLACTIVETEXTUREPROC pf_glActiveTexture;
COGL_PFNGLCLIENTACTIVETEXTUREPROC pf_glClientActiveTexture;
COGL_PFNGLBLENDEQUATIONPROC pf_glBlendEquation;
COGL_PFNGLBLENDCOLORPROC pf_glBlendColor;
COGL_PFNGLBLENDFUNCSEPARATEPROC pf_glBlendFuncSeparate;
COGL_PFNGLBLENDEQUATIONSEPARATEPROC pf_glBlendEquationSeparate;
} CoglContext;
CoglContext *

View File

@ -773,6 +773,10 @@ typedef void
GLsizei width,
GLsizei height);
typedef void
(APIENTRYP COGL_PFNGLGENERATEMIPMAPEXTPROC)
(GLenum target);
typedef GLhandleARB
(APIENTRYP COGL_PFNGLCREATEPROGRAMOBJECTARBPROC)
(void);
@ -1020,6 +1024,29 @@ typedef void
(APIENTRYP COGL_PFNGLCLIENTACTIVETEXTUREPROC)
(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
#endif

View File

@ -29,6 +29,7 @@
#include "cogl-internal.h"
#include "cogl-context.h"
#include "cogl-clip-stack.h"
#include "cogl-material-private.h"
#include <string.h>
#include <gmodule.h>
@ -78,13 +79,13 @@ _cogl_path_stroke_nodes ()
_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_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
(guint32)~0, /* disable all texture layers */
NULL);
_cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
(guint32)~0, /* disable all texture layers */
NULL);
_cogl_current_matrix_state_flush ();
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);
/* 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 |=
cogl_material_get_cogl_enable_flags (ctx->source_material);
_cogl_material_get_cogl_enable_flags (ctx->source_material);
cogl_enable (enable_flags);
_cogl_path_get_bounds (nodes_min, nodes_max,

View File

@ -108,22 +108,23 @@ cogl_shader_compile (CoglHandle handle)
glCompileShaderARB (shader->gl_handle);
}
void
cogl_shader_get_info_log (CoglHandle handle,
size_t size,
char *buffer)
gchar *
cogl_shader_get_info_log (CoglHandle handle)
{
CoglShader *shader;
char buffer[512];
int len;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
_COGL_GET_CONTEXT (ctx, NULL);
if (!cogl_is_shader (handle))
return;
return NULL;
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';
return g_strdup (buffer);
}
CoglShaderType

View File

@ -30,6 +30,7 @@
typedef struct _CoglTexture CoglTexture;
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
typedef struct _CoglSpanIter CoglSpanIter;
typedef struct _CoglTexturePixel CoglTexturePixel;
struct _CoglTexSliceSpan
{
@ -55,6 +56,18 @@ struct _CoglSpanIter
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
{
CoglHandleObject _parent;
@ -68,11 +81,17 @@ struct _CoglTexture
GArray *slice_y_spans;
GArray *slice_gl_handles;
gint max_waste;
CoglTextureFilter min_filter;
CoglTextureFilter mag_filter;
GLenum min_filter;
GLenum mag_filter;
gboolean is_foreign;
GLint wrap_mode;
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
@ -93,6 +112,14 @@ void
_cogl_texture_set_wrap_mode_parameter (CoglTexture *tex,
GLenum wrap_mode);
void
_cogl_texture_set_filters (CoglHandle handle,
GLenum min_filter,
GLenum mag_filter);
void
_cogl_texture_ensure_mipmaps (CoglHandle handle);
gboolean
_cogl_texture_span_has_waste (CoglTexture *tex,
gint x_span_index,

View File

@ -49,6 +49,7 @@
#define glDrawRangeElements ctx->pf_glDrawRangeElements
#define glActiveTexture ctx->pf_glActiveTexture
#define glClientActiveTexture ctx->pf_glClientActiveTexture
#define glGenerateMipmap ctx->pf_glGenerateMipmapEXT
#else
@ -247,11 +248,12 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
/* Iterate horizontal slices */
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);
/* Pick the gl texture object handle */
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
y * tex->slice_x_spans->len + x);
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, slice_num);
/* Setup gl alignment to match rowstride and top-left corner */
prep_for_gl_pixels_upload (tex->bitmap.rowstride,
@ -259,6 +261,17 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
y_span->start,
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 */
GE( glBindTexture (tex->gl_target, gl_handle) );
@ -343,6 +356,8 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
if (waste_buf)
g_free (waste_buf);
tex->mipmaps_dirty = TRUE;
return TRUE;
}
@ -494,6 +509,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
_cogl_span_iter_next (&x_iter),
source_x += inter_w )
{
gint slice_num;
/* Discard slices out of the subregion early */
if (!x_iter.intersects)
{
@ -516,10 +533,10 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
local_y = (y_iter.intersect_start -
y_iter.pos);
slice_num = y_iter.index * tex->slice_x_spans->len + x_iter.index;
/* Pick slice GL handle */
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
y_iter.index * tex->slice_x_spans->len +
x_iter.index);
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, slice_num);
/* Setup gl alignment to match rowstride and top-left corner */
prep_for_gl_pixels_upload (source_bmp->rowstride,
@ -527,6 +544,17 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
source_y,
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 */
GE( glBindTexture (tex->gl_target, gl_handle) );
@ -640,14 +668,16 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
if (waste_buf)
g_free (waste_buf);
tex->mipmaps_dirty = TRUE;
return TRUE;
}
static gint
_cogl_rect_slices_for_size (gint size_to_fill,
gint max_span_size,
gint max_waste,
GArray *out_spans)
_cogl_rect_slices_for_size (gint size_to_fill,
gint max_span_size,
gint max_waste,
GArray *out_spans)
{
gint n_spans = 0;
CoglTexSliceSpan span;
@ -679,10 +709,10 @@ _cogl_rect_slices_for_size (gint size_to_fill,
}
static gint
_cogl_pot_slices_for_size (gint size_to_fill,
gint max_span_size,
gint max_waste,
GArray *out_spans)
_cogl_pot_slices_for_size (gint size_to_fill,
gint max_span_size,
gint max_waste,
GArray *out_spans)
{
gint n_spans = 0;
CoglTexSliceSpan span;
@ -693,7 +723,8 @@ _cogl_pot_slices_for_size (gint size_to_fill,
span.waste = 0;
/* Fix invalid max_waste */
if (max_waste < 0) max_waste = 0;
if (max_waste < 0)
max_waste = 0;
while (TRUE)
{
@ -826,10 +857,10 @@ _cogl_texture_slices_create (CoglTexture *tex)
/* Check if size supported else bail out */
if (!_cogl_texture_size_supported (tex->gl_target,
tex->gl_format,
tex->gl_type,
max_width,
max_height))
tex->gl_format,
tex->gl_type,
max_width,
max_height))
{
return FALSE;
}
@ -912,6 +943,14 @@ _cogl_texture_slices_create (CoglTexture *tex)
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 */
tex->wrap_mode = GL_FALSE;
@ -940,14 +979,6 @@ _cogl_texture_slices_create (CoglTexture *tex)
/* Setup texture parameters */
GE( glBindTexture (tex->gl_target,
gl_handles[y * n_x_slices + x]) );
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MAG_FILTER,
tex->mag_filter) );
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_MIN_FILTER,
tex->min_filter) );
if (tex->auto_mipmap)
GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP,
GL_TRUE) );
/* Use a transparent border color so that we can leave the
color buffer alone when using texture co-ordinates
@ -984,6 +1015,9 @@ _cogl_texture_slices_free (CoglTexture *tex)
g_array_free (tex->slice_gl_handles, TRUE);
}
if (tex->first_pixels != NULL)
g_free (tex->first_pixels);
}
gboolean
@ -1199,11 +1233,10 @@ _cogl_texture_free (CoglTexture *tex)
}
CoglHandle
cogl_texture_new_with_size (guint width,
guint height,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat internal_format)
cogl_texture_new_with_size (guint width,
guint height,
CoglTextureFlags flags,
CoglPixelFormat internal_format)
{
CoglTexture *tex;
gint bpp;
@ -1221,7 +1254,8 @@ cogl_texture_new_with_size (guint width,
tex = (CoglTexture*) g_malloc (sizeof (CoglTexture));
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.height = height;
@ -1234,9 +1268,14 @@ cogl_texture_new_with_size (guint width,
tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL;
tex->max_waste = max_waste;
tex->min_filter = COGL_TEXTURE_FILTER_NEAREST;
tex->mag_filter = COGL_TEXTURE_FILTER_NEAREST;
if (flags & COGL_TEXTURE_NO_SLICING)
tex->max_waste = -1;
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 */
tex->bitmap.format =
@ -1258,7 +1297,6 @@ cogl_texture_new_with_size (guint width,
CoglHandle
cogl_texture_new_from_data (guint width,
guint height,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat format,
CoglPixelFormat internal_format,
@ -1282,7 +1320,8 @@ cogl_texture_new_from_data (guint width,
tex = (CoglTexture*) g_malloc (sizeof (CoglTexture));
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.height = height;
@ -1295,9 +1334,14 @@ cogl_texture_new_from_data (guint width,
tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL;
tex->max_waste = max_waste;
tex->min_filter = COGL_TEXTURE_FILTER_NEAREST;
tex->mag_filter = COGL_TEXTURE_FILTER_NEAREST;
if (flags & COGL_TEXTURE_NO_SLICING)
tex->max_waste = -1;
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
* error flag but still return texture handle (this
@ -1328,10 +1372,9 @@ cogl_texture_new_from_data (guint width,
}
CoglHandle
cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat internal_format)
cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
CoglTextureFlags flags,
CoglPixelFormat internal_format)
{
CoglTexture *tex;
CoglBitmap *bmp = (CoglBitmap *)bmp_handle;
@ -1342,7 +1385,8 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
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_owner = FALSE;
@ -1351,9 +1395,14 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL;
tex->max_waste = max_waste;
tex->min_filter = COGL_TEXTURE_FILTER_NEAREST;
tex->mag_filter = COGL_TEXTURE_FILTER_NEAREST;
if (flags & COGL_TEXTURE_NO_SLICING)
tex->max_waste = -1;
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
* error flag but still return texture handle if the
@ -1388,13 +1437,12 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
CoglHandle
cogl_texture_new_from_file (const gchar *filename,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat internal_format,
GError **error)
{
CoglHandle bmp;
CoglHandle handle;
CoglHandle bmp;
CoglHandle 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)
return COGL_INVALID_HANDLE;
handle = cogl_texture_new_from_bitmap (bmp,
max_waste,
flags,
internal_format);
handle = cogl_texture_new_from_bitmap (bmp, flags, internal_format);
cogl_handle_unref (bmp);
return handle;
@ -1433,8 +1478,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
GLint gl_int_format = 0;
GLint gl_width = 0;
GLint gl_height = 0;
GLint gl_min_filter;
GLint gl_mag_filter;
GLint gl_gen_mipmap;
guint bpp;
CoglTexture *tex;
@ -1482,14 +1525,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
GL_TEXTURE_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,
GL_GENERATE_MIPMAP,
&gl_gen_mipmap) );
@ -1508,18 +1543,16 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
return COGL_INVALID_HANDLE;
/* Try and match to a cogl format */
if (!_cogl_pixel_format_from_gl_internal (gl_int_format,
&format))
{
return COGL_INVALID_HANDLE;
}
if (!_cogl_pixel_format_from_gl_internal (gl_int_format, &format))
return COGL_INVALID_HANDLE;
/* Create new texture */
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
tex = (CoglTexture *) g_malloc (sizeof (CoglTexture));
/* Setup bitmap info */
tex->is_foreign = TRUE;
tex->auto_mipmap = (gl_gen_mipmap == GL_TRUE) ? TRUE : FALSE;
tex->mipmaps_dirty = TRUE;
bpp = _cogl_get_format_bpp (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_type = GL_UNSIGNED_BYTE;
tex->min_filter = gl_min_filter;
tex->mag_filter = gl_mag_filter;
/* Unknown filter */
tex->min_filter = GL_FALSE;
tex->mag_filter = GL_FALSE;
tex->max_waste = 0;
/* Wrap mode not yet set */
@ -1680,36 +1714,10 @@ cogl_texture_get_gl_texture (CoglHandle handle,
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
cogl_texture_set_filters (CoglHandle handle,
CoglTextureFilter min_filter,
CoglTextureFilter mag_filter)
_cogl_texture_set_filters (CoglHandle handle,
GLenum min_filter,
GLenum mag_filter)
{
CoglTexture *tex;
GLuint gl_handle;
@ -1720,14 +1728,18 @@ cogl_texture_set_filters (CoglHandle 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 */
if (tex->slice_gl_handles == NULL)
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 */
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
cogl_texture_set_region (CoglHandle handle,
gint src_x,

View File

@ -399,6 +399,10 @@ _cogl_features_init (void)
(COGL_PFNGLDELETEFRAMEBUFFERSEXTPROC)
cogl_get_proc_address ("glDeleteFramebuffersEXT");
ctx->pf_glGenerateMipmapEXT =
(COGL_PFNGLGENERATEMIPMAPEXTPROC)
cogl_get_proc_address ("glGenerateMipmapEXT");
if (ctx->pf_glGenRenderbuffersEXT &&
ctx->pf_glBindRenderbufferEXT &&
ctx->pf_glRenderbufferStorageEXT &&
@ -407,7 +411,8 @@ _cogl_features_init (void)
ctx->pf_glFramebufferTexture2DEXT &&
ctx->pf_glFramebufferRenderbufferEXT &&
ctx->pf_glCheckFramebufferStatusEXT &&
ctx->pf_glDeleteFramebuffersEXT)
ctx->pf_glDeleteFramebuffersEXT &&
ctx->pf_glGenerateMipmapEXT)
flags |= COGL_FEATURE_OFFSCREEN;
}
@ -486,6 +491,23 @@ _cogl_features_init (void)
(COGL_PFNGLCLIENTACTIVETEXTUREPROC)
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 */
ctx->feature_flags = flags;
ctx->features_cached = TRUE;

View File

@ -27,12 +27,12 @@ INCLUDES = \
-DG_LOG_DOMAIN=\"Cogl-GLES\" \
-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_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_la_SOURCES = \
libclutter_cogl_gles_la_CPPFLAGS = $(CLUTTER_CFLAGS) $(COGL_DEBUG_CFLAGS) $(CLUTTER_DEBUG_CFLAGS) $(MAINTAINER_CFLAGS)
libclutter_cogl_gles_la_LIBADD = -lm $(CLUTTER_LIBS) $(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_gles_la_SOURCES = \
$(top_builddir)/clutter/cogl/cogl.h \
$(top_builddir)/clutter/cogl/cogl-defines-gles.h \
$(top_builddir)/clutter/cogl/cogl-color.h \
@ -60,7 +60,7 @@ libclutter_cogl_la_SOURCES = \
cogl-shader.c
if USE_GLES2_WRAPPER
libclutter_cogl_la_SOURCES += \
libclutter_cogl_gles_la_SOURCES += \
cogl-gles2-wrapper.c \
cogl-fixed-vertex-shader.h \
cogl-fixed-vertex-shader.c \

View File

@ -39,7 +39,7 @@
static CoglContext *_context = NULL;
static gboolean gl_is_indirect = FALSE;
gboolean
static gboolean
cogl_create_context ()
{
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->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,
sizeof (CoglTextureGLVertex));
@ -107,8 +106,7 @@ cogl_create_context ()
_context->default_gl_texture_2d_tex =
cogl_texture_new_from_data (1, /* width */
1, /* height */
-1, /* max waste */
COGL_TEXTURE_NONE, /* flags */
COGL_TEXTURE_NO_SLICING, /* flags */
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
/* internal format */
COGL_PIXEL_FORMAT_RGBA_8888,
@ -117,8 +115,7 @@ cogl_create_context ()
_context->default_gl_texture_rect_tex =
cogl_texture_new_from_data (1, /* width */
1, /* height */
-1, /* max waste */
COGL_TEXTURE_NONE, /* flags */
COGL_TEXTURE_NO_SLICING, /* flags */
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
/* internal format */
COGL_PIXEL_FORMAT_RGBA_8888,
@ -126,16 +123,20 @@ cogl_create_context ()
default_texture_data);
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 =
cogl_material_get_cogl_enable_flags (_context->source_material);
_cogl_material_get_cogl_enable_flags (_context->source_material);
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;
}
void
cogl_destroy_context ()
_cogl_destroy_context ()
{
if (_context == NULL)
return;
@ -160,13 +161,16 @@ cogl_destroy_context ()
if (_context->logged_vertices)
g_array_free (_context->logged_vertices, TRUE);
if (_context->static_indices)
g_array_free (_context->static_indices, TRUE);
if (_context->polygon_vertices)
g_array_free (_context->polygon_vertices, TRUE);
if (_context->current_layers)
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);
}

View File

@ -80,7 +80,6 @@ typedef struct
* can batch things together. */
GArray *journal;
GArray *logged_vertices;
GArray *static_indices;
GArray *polygon_vertices;
/* Some simple caching, to minimize state changes... */
@ -104,6 +103,12 @@ typedef struct
floatVec2 path_nodes_max;
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
CoglGles2Wrapper gles2;
@ -111,7 +116,6 @@ typedef struct
supported */
GLint viewport_store[4];
#endif
} CoglContext;
CoglContext *

View File

@ -89,13 +89,13 @@ cogl_gles2_wrapper_create_shader (GLenum type, const char *source)
if (!status)
{
char log[1024];
char shader_log[1024];
GLint len;
glGetShaderInfoLog (shader, sizeof (log) - 1, &len, log);
log[len] = '\0';
glGetShaderInfoLog (shader, sizeof (shader_log) - 1, &len, shader_log);
shader_log[len] = '\0';
g_critical ("%s", log);
g_critical ("%s", shader_log);
glDeleteShader (shader);
@ -538,9 +538,9 @@ cogl_gles2_wrapper_get_program (const CoglGles2WrapperSettings *settings)
CoglShader *shader
= _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;
else if (shader->type == CGL_FRAGMENT_SHADER)
else if (shader->type == COGL_SHADER_TYPE_FRAGMENT)
custom_fragment_shader = TRUE;
}
}
@ -581,13 +581,13 @@ cogl_gles2_wrapper_get_program (const CoglGles2WrapperSettings *settings)
if (!status)
{
char log[1024];
char shader_log[1024];
GLint len;
glGetProgramInfoLog (program->program, sizeof (log) - 1, &len, log);
log[len] = '\0';
glGetProgramInfoLog (program->program, sizeof (shader_log) - 1, &len, shader_log);
shader_log[len] = '\0';
g_critical ("%s", log);
g_critical ("%s", shader_log);
glDeleteProgram (program->program);
g_slice_free (CoglGles2WrapperProgram, program);
@ -1300,13 +1300,20 @@ cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture,
}
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
GL_MODULATE. The shader is hard-coded to modulate the texture so
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
cogl_wrap_glClientActiveTexture (GLenum texture)
{

View File

@ -259,6 +259,7 @@ struct _CoglGles2WrapperShader
#define GL_TEXTURE_ENV 0x2300
#define GL_TEXTURE_ENV_MODE 0x2200
#define GL_TEXTURE_ENV_COLOR 0x2201
#define GL_MODULATE 0x2100
#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,
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_glActiveTexture (GLenum texture);
@ -384,6 +386,7 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program);
#define glColorPointer cogl_wrap_glColorPointer
#define glNormalPointer cogl_wrap_glNormalPointer
#define glTexEnvi cogl_wrap_glTexEnvi
#define glTexEnvfv cogl_wrap_glTexEnvfv
#define glActiveTexture cogl_wrap_glActiveTexture
#define glClientActiveTexture cogl_wrap_glClientActiveTexture
#define glEnableClientState cogl_wrap_glEnableClientState

View File

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

View File

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

View File

@ -30,6 +30,7 @@
typedef struct _CoglTexture CoglTexture;
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
typedef struct _CoglSpanIter CoglSpanIter;
typedef struct _CoglTexturePixel CoglTexturePixel;
struct _CoglTexSliceSpan
{
@ -55,6 +56,18 @@ struct _CoglSpanIter
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
{
CoglHandleObject _parent;
@ -68,11 +81,17 @@ struct _CoglTexture
GArray *slice_y_spans;
GArray *slice_gl_handles;
gint max_waste;
CoglTextureFilter min_filter;
CoglTextureFilter mag_filter;
GLenum min_filter;
GLenum mag_filter;
gboolean is_foreign;
GLint wrap_mode;
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
@ -93,6 +112,14 @@ void
_cogl_texture_set_wrap_mode_parameter (CoglTexture *tex,
GLenum wrap_mode);
void
_cogl_texture_set_filters (CoglHandle handle,
GLenum min_filter,
GLenum mag_filter);
void
_cogl_texture_ensure_mipmaps (CoglHandle handle);
gboolean
_cogl_texture_span_has_waste (CoglTexture *tex,
gint x_span_index,

View File

@ -225,11 +225,12 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
/* Iterate horizontal slices */
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);
/* Pick the gl texture object handle */
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
y * tex->slice_x_spans->len + x);
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, slice_num);
/* FIXME: might optimize by not copying to intermediate slice
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.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 */
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
tex->gl_intformat) );
@ -338,9 +349,6 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
waste_buf) );
}
if (tex->auto_mipmap)
cogl_wrap_glGenerateMipmap (tex->gl_target);
/* Free temp bitmap */
g_free (slice_bmp.data);
}
@ -349,6 +357,8 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
if (waste_buf)
g_free (waste_buf);
tex->mipmaps_dirty = TRUE;
return TRUE;
}
@ -442,6 +452,7 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
gint bpp;
GLint viewport[4];
CoglBitmap alpha_bmp;
CoglHandle prev_source;
_COGL_GET_CONTEXT (ctx, FALSE);
@ -477,31 +488,21 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
if (ctx->texture_download_material == COGL_INVALID_HANDLE)
{
ctx->texture_download_material = cogl_material_new ();
cogl_material_set_layer_combine_function (
ctx->texture_download_material,
0, /* layer */
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);
cogl_material_set_blend (ctx->texture_download_material,
"RGBA = ADD (SRC_COLOR, 0)",
NULL);
}
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_combine_arg_op (
ctx->texture_download_material,
0, /* layer */
0, /* arg */
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_COLOR);
cogl_material_flush_gl_state (ctx->texture_download_material, NULL);
cogl_material_set_layer_combine (ctx->texture_download_material,
0, /* layer */
"RGBA = REPLACE (TEXTURE)",
NULL);
_cogl_texture_draw_and_read (tex, target_bmp, viewport);
/* Check whether texture has alpha and framebuffer not */
@ -534,13 +535,11 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
alpha_bmp.height);
/* Draw alpha values into RGB channels */
cogl_material_set_layer_combine_arg_op (
ctx->texture_download_material,
0, /* layer */
0, /* arg */
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_ALPHA);
cogl_material_flush_gl_state (ctx->texture_download_material, NULL);
cogl_material_set_layer_combine (ctx->texture_download_material,
0, /* layer */
"RGBA = REPLACE (TEXTURE[A])",
NULL);
_cogl_texture_draw_and_read (tex, &alpha_bmp, viewport);
/* 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_current_matrix_pop ();
/* restore the original material */
cogl_set_source (prev_source);
cogl_handle_unref (prev_source);
return TRUE;
}
@ -631,6 +634,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
_cogl_span_iter_next (&x_iter),
source_x += inter_w )
{
gint slice_num;
/* Discard slices out of the subregion early */
if (!x_iter.intersects)
{
@ -653,10 +658,10 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
local_y = (y_iter.intersect_start -
y_iter.pos);
slice_num = y_iter.index * tex->slice_x_spans->len + x_iter.index;
/* Pick slice GL handle */
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
y_iter.index * tex->slice_x_spans->len +
x_iter.index);
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, slice_num);
/* FIXME: might optimize by not copying to intermediate slice
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.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 */
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
tex->gl_intformat) );
@ -794,9 +808,6 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
waste_buf) );
}
if (tex->auto_mipmap)
cogl_wrap_glGenerateMipmap (tex->gl_target);
/* Free temp bitmap */
g_free (slice_bmp.data);
}
@ -805,6 +816,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
if (waste_buf)
g_free (waste_buf);
tex->mipmaps_dirty = TRUE;
return TRUE;
}
@ -858,7 +871,8 @@ _cogl_pot_slices_for_size (gint size_to_fill,
span.waste = 0;
/* Fix invalid max_waste */
if (max_waste < 0) max_waste = 0;
if (max_waste < 0)
max_waste = 0;
while (TRUE)
{
@ -866,7 +880,9 @@ _cogl_pot_slices_for_size (gint size_to_fill,
if (size_to_fill > span.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;
size_to_fill -= span.size;
n_spans++;
@ -875,7 +891,9 @@ _cogl_pot_slices_for_size (gint size_to_fill,
{
/* Yes and waste is small enough */
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;
}
else
@ -971,10 +989,10 @@ _cogl_texture_slices_create (CoglTexture *tex)
/* Check if size supported else bail out */
if (!_cogl_texture_size_supported (tex->gl_target,
tex->gl_format,
tex->gl_type,
max_width,
max_height))
tex->gl_format,
tex->gl_type,
max_width,
max_height))
{
return FALSE;
}
@ -1057,6 +1075,14 @@ _cogl_texture_slices_create (CoglTexture *tex)
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 */
tex->wrap_mode = GL_FALSE;
@ -1087,20 +1113,11 @@ _cogl_texture_slices_create (CoglTexture *tex)
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target,
gl_handles[y * n_x_slices + x],
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,
tex->wrap_mode) );
GE( glTexParameteri (tex->gl_target, GL_TEXTURE_WRAP_T,
tex->wrap_mode) );
if (tex->auto_mipmap)
GE( glTexParameteri (tex->gl_target, GL_GENERATE_MIPMAP,
GL_TRUE) );
/* Pass NULL data to init size and internal format */
GE( glTexImage2D (tex->gl_target, 0, tex->gl_intformat,
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);
}
if (tex->first_pixels != NULL)
g_free (tex->first_pixels);
}
gboolean
@ -1288,11 +1308,10 @@ _cogl_texture_free (CoglTexture *tex)
}
CoglHandle
cogl_texture_new_with_size (guint width,
guint height,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat internal_format)
cogl_texture_new_with_size (guint width,
guint height,
CoglTextureFlags flags,
CoglPixelFormat internal_format)
{
CoglTexture *tex;
gint bpp;
@ -1310,7 +1329,8 @@ cogl_texture_new_with_size (guint width,
tex = (CoglTexture*) g_malloc (sizeof (CoglTexture));
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.height = height;
@ -1323,9 +1343,14 @@ cogl_texture_new_with_size (guint width,
tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL;
tex->max_waste = max_waste;
tex->min_filter = CGL_NEAREST;
tex->mag_filter = CGL_NEAREST;
if (flags & COGL_TEXTURE_NO_SLICING)
tex->max_waste = -1;
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 */
tex->bitmap.format =
@ -1347,7 +1372,6 @@ cogl_texture_new_with_size (guint width,
CoglHandle
cogl_texture_new_from_data (guint width,
guint height,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat format,
CoglPixelFormat internal_format,
@ -1371,7 +1395,8 @@ cogl_texture_new_from_data (guint width,
tex = (CoglTexture*) g_malloc (sizeof (CoglTexture));
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.height = height;
@ -1384,9 +1409,14 @@ cogl_texture_new_from_data (guint width,
tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL;
tex->max_waste = max_waste;
tex->min_filter = CGL_NEAREST;
tex->mag_filter = CGL_NEAREST;
if (flags & COGL_TEXTURE_NO_SLICING)
tex->max_waste = -1;
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
* error flag but still return texture handle (this
@ -1417,10 +1447,9 @@ cogl_texture_new_from_data (guint width,
}
CoglHandle
cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat internal_format)
cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
CoglTextureFlags flags,
CoglPixelFormat internal_format)
{
CoglTexture *tex;
CoglBitmap *bmp = (CoglBitmap *)bmp_handle;
@ -1429,7 +1458,8 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
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_owner = TRUE;
@ -1439,9 +1469,14 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
tex->slice_y_spans = NULL;
tex->slice_gl_handles = NULL;
tex->max_waste = max_waste;
tex->min_filter = CGL_NEAREST;
tex->mag_filter = CGL_NEAREST;
if (flags & COGL_TEXTURE_NO_SLICING)
tex->max_waste = -1;
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
* error flag but still return texture handle if the
@ -1476,7 +1511,6 @@ cogl_texture_new_from_bitmap (CoglHandle bmp_handle,
CoglHandle
cogl_texture_new_from_file (const gchar *filename,
gint max_waste,
CoglTextureFlags flags,
CoglPixelFormat internal_format,
GError **error)
@ -1490,10 +1524,7 @@ cogl_texture_new_from_file (const gchar *filename,
if (bmp == COGL_INVALID_HANDLE)
return COGL_INVALID_HANDLE;
handle = cogl_texture_new_from_bitmap (bmp,
max_waste,
flags,
internal_format);
handle = cogl_texture_new_from_bitmap (bmp, flags, internal_format);
cogl_handle_unref (bmp);
return handle;
@ -1521,8 +1552,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
GLint gl_int_format = 0;
GLint gl_width = 0;
GLint gl_height = 0;
GLint gl_min_filter;
GLint gl_mag_filter;
GLint gl_gen_mipmap;
guint bpp;
CoglTexture *tex;
@ -1569,14 +1598,6 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
gl_height = height + y_pot_waste;
#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,
GL_GENERATE_MIPMAP,
&gl_gen_mipmap) );
@ -1607,6 +1628,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
/* Setup bitmap info */
tex->is_foreign = TRUE;
tex->auto_mipmap = (gl_gen_mipmap == GL_TRUE) ? TRUE : FALSE;
tex->mipmaps_dirty = TRUE;
bpp = _cogl_get_format_bpp (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_type = GL_UNSIGNED_BYTE;
tex->min_filter = gl_min_filter;
tex->mag_filter = gl_mag_filter;
/* Unknown filter */
tex->min_filter = GL_FALSE;
tex->mag_filter = GL_FALSE;
tex->max_waste = 0;
/* Wrap mode not yet set */
@ -1767,36 +1790,10 @@ cogl_texture_get_gl_texture (CoglHandle handle,
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
cogl_texture_set_filters (CoglHandle handle,
CoglTextureFilter min_filter,
CoglTextureFilter mag_filter)
_cogl_texture_set_filters (CoglHandle handle,
GLenum min_filter,
GLenum mag_filter)
{
CoglTexture *tex;
GLuint gl_handle;
@ -1807,14 +1804,18 @@ cogl_texture_set_filters (CoglHandle 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 */
if (tex->slice_gl_handles == NULL)
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 */
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
cogl_texture_set_region (CoglHandle handle,
gint src_x,