Merge branch 'cogl-material'
Conflicts: clutter/cogl/gl/cogl-texture.c clutter/cogl/gles/cogl-primitives.c * cogl-material: clutter-{clone-,}texture weren't updating their material opacity. Updates GLES1 support for CoglMaterial Normalizes gl vs gles code in preperation for synching material changes Removes cogl_blend_func and cogl_alpha_func Fully integrates CoglMaterial throughout the rest of Cogl [cogl-material] Restore the GL_TEXTURE_ENV_MODE after material_rectangle [cogl-material] Make the user_tex_coords parameter of _rectangle const [test-cogl-material] Remove return value from material_rectangle_paint Add cogl-material.h and cogl-matrix.h to libclutterinclude_HEADERS [cogl-material] improvements for cogl_material_rectangle [cogl-material] Adds a cogl_material_set_color function [cogl-material] Some improvements for how we sync CoglMaterial state with OpenGL [cogl-material] Converts clutter-texture/clutter-clone-texture to the material API [doc] Hooks up cogl-material reference documentation Updates previous GLES multi-texturing code to use CoglMaterial Adds a CoglMaterial abstraction, which includes support for multi-texturing [doc] Hooks up cogl-matrix reference documentation Adds CoglMatrix utility code [tests] Adds an interactive unit test for multi-texturing [multi-texturing] This adds a new cogl_multi_texture API for GL,GLES1 + GLES2
This commit is contained in:
commit
323eaf3fb3
837
cogl-material.h
Normal file
837
cogl-material.h
Normal file
@ -0,0 +1,837 @@
|
||||
#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cogl/cogl.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __COGL_MATERIAL_H__
|
||||
#define __COGL_MATERIAL_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#include <cogl/cogl-types.h>
|
||||
#include <cogl/cogl-matrix.h>
|
||||
|
||||
/**
|
||||
* SECTION:cogl-material
|
||||
* @short_description: Fuctions for creating and manipulating materials
|
||||
*
|
||||
* COGL allows creating and manipulating materials used to fill in
|
||||
* geometry. Materials may simply be lighting attributes (such as an
|
||||
* ambient and diffuse colour) or might represent one or more textures
|
||||
* blended together.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* cogl_material_new:
|
||||
*
|
||||
* Allocates and initializes a blank white material
|
||||
*
|
||||
* Returns: a handle to the new material
|
||||
*/
|
||||
CoglHandle cogl_material_new (void);
|
||||
|
||||
/**
|
||||
* cogl_material_ref:
|
||||
* @handle: a @CoglHandle.
|
||||
*
|
||||
* Increment the reference count for a cogl material.
|
||||
*
|
||||
* Returns: the @handle.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
CoglHandle cogl_material_ref (CoglHandle handle);
|
||||
|
||||
/**
|
||||
* cogl_material_unref:
|
||||
* @handle: a @CoglHandle.
|
||||
*
|
||||
* Decrement the reference count for a cogl material.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_unref (CoglHandle handle);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* cogl_material_set_color:
|
||||
* @material: A CoglMaterial object
|
||||
* @color: The components of the color
|
||||
*
|
||||
* This is the basic color of the material, used when no lighting is enabled.
|
||||
*
|
||||
* The default value is (1.0, 1.0, 1.0, 1.0)
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_color (CoglHandle material, const CoglColor *color);
|
||||
|
||||
/**
|
||||
* cogl_material_set_color:
|
||||
* @material: A CoglMaterial object
|
||||
* @red: The red component
|
||||
* @green: The green component
|
||||
* @blue: The blue component
|
||||
* @alpha: The alpha component
|
||||
*
|
||||
* This is the basic color of the material, used when no lighting is enabled.
|
||||
*
|
||||
* The default value is (1.0, 1.0, 1.0, 1.0)
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_color4ub (CoglHandle handle,
|
||||
guint8 red,
|
||||
guint8 green,
|
||||
guint8 blue,
|
||||
guint8 alpha);
|
||||
|
||||
/**
|
||||
* cogl_material_get_color:
|
||||
* @material: A CoglMaterial object
|
||||
* @color: The location to store the color
|
||||
*
|
||||
* This retrieves the current material color.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_get_color (CoglHandle handle, CoglColor *color);
|
||||
|
||||
/**
|
||||
* cogl_material_set_ambient:
|
||||
* @material: A CoglMaterial object
|
||||
* @ambient: The components of the desired ambient color
|
||||
*
|
||||
* Exposing the standard OpenGL lighting model; this function sets
|
||||
* the material's ambient color. The ambient color affects the overall
|
||||
* color of the object. Since the diffuse color will be intense when
|
||||
* the light hits the surface directly, the ambient will most aparent
|
||||
* where the light hits at a slant.
|
||||
*
|
||||
* The default value is (0.2, 0.2, 0.2, 1.0)
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_ambient (CoglHandle material,
|
||||
const CoglColor *ambient);
|
||||
|
||||
/**
|
||||
* cogl_material_get_ambient:
|
||||
* @material: A CoglMaterial object
|
||||
* @ambient: The location to store the ambient color
|
||||
*
|
||||
* This retrieves the materials current ambient color.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_get_ambient (CoglHandle handle, CoglColor *ambient);
|
||||
|
||||
/**
|
||||
* cogl_material_set_diffuse:
|
||||
* @material: A CoglMaterial object
|
||||
* @diffuse: The components of the desired diffuse color
|
||||
*
|
||||
* Exposing the standard OpenGL lighting model; this function sets
|
||||
* the material's diffuse color. The diffuse color is most intense
|
||||
* where the light hits the surface directly; perpendicular to the
|
||||
* surface.
|
||||
*
|
||||
* The default value is (0.8, 0.8, 0.8, 1.0)
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_diffuse (CoglHandle material,
|
||||
const CoglColor *diffuse);
|
||||
|
||||
/**
|
||||
* cogl_material_get_diffuse:
|
||||
* @material: A CoglMaterial object
|
||||
* @diffuse: The location to store the diffuse color
|
||||
*
|
||||
* This retrieves the materials current diffuse color.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_get_diffuse (CoglHandle handle, CoglColor *diffuse);
|
||||
|
||||
/**
|
||||
* cogl_material_set_ambient_and_diffuse:
|
||||
* @material: A CoglMaterial object
|
||||
* @color: The components of the desired ambient and diffuse colors
|
||||
*
|
||||
* This is a convenience for setting the diffuse and ambient color
|
||||
* of the material at the same time.
|
||||
*
|
||||
* The default ambient color is (0.2, 0.2, 0.2, 1.0)
|
||||
* The default diffuse color is (0.8, 0.8, 0.8, 1.0)
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_ambient_and_diffuse (CoglHandle material,
|
||||
const CoglColor *color);
|
||||
|
||||
/**
|
||||
* cogl_material_set_specular:
|
||||
* @material: A CoglMaterial object
|
||||
* @specular: The components of the desired specular color
|
||||
*
|
||||
* Exposing the standard OpenGL lighting model; this function sets
|
||||
* the material's specular color. The intensity of the specular color
|
||||
* depends on the viewport position, and is brightest along the lines
|
||||
* of reflection.
|
||||
*
|
||||
* The default value is (0.0, 0.0, 0.0, 1.0)
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_specular (CoglHandle material,
|
||||
const CoglColor *specular);
|
||||
|
||||
/**
|
||||
* cogl_material_get_specular:
|
||||
* @material: A CoglMaterial object
|
||||
* @specular: The location to store the specular color
|
||||
*
|
||||
* This retrieves the materials current specular color.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_get_specular (CoglHandle handle, CoglColor *specular);
|
||||
|
||||
/**
|
||||
* cogl_material_set_shininess:
|
||||
* @material: A CoglMaterial object
|
||||
* shininess: The desired shininess; range: [0.0, 1.0]
|
||||
*
|
||||
* This function sets the materials shininess which determines how
|
||||
* specular highlights are calculated. A higher shininess will produce
|
||||
* smaller brigher highlights.
|
||||
*
|
||||
* The default value is 0.0
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_shininess (CoglHandle material,
|
||||
float shininess);
|
||||
/**
|
||||
* cogl_material_get_shininess:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* This retrieves the materials current emission color.
|
||||
*
|
||||
* Return value: The materials current shininess value
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
float cogl_material_get_shininess (CoglHandle handle);
|
||||
|
||||
/**
|
||||
* cogl_material_set_emission:
|
||||
* @material: A CoglMaterial object
|
||||
* @emission: The components of the desired emissive color
|
||||
*
|
||||
* Exposing the standard OpenGL lighting model; this function sets
|
||||
* the material's emissive color. It will look like the surface is
|
||||
* a light source emitting this color.
|
||||
*
|
||||
* The default value is (0.0, 0.0, 0.0, 1.0)
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_emission (CoglHandle material,
|
||||
const CoglColor *emission);
|
||||
|
||||
/**
|
||||
* cogl_material_get_emission:
|
||||
* @material: A CoglMaterial object
|
||||
* @emission: The location to store the emission color
|
||||
*
|
||||
* This retrieves the materials current emission color.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_get_emission (CoglHandle handle, CoglColor *emission);
|
||||
|
||||
/**
|
||||
* CoglMaterialAlphaFunc:
|
||||
* @COGL_MATERIAL_ALPHA_FUNC_NEVER: Never let the fragment through.
|
||||
* @COGL_MATERIAL_ALPHA_FUNC_LESS: Let the fragment through if the incoming
|
||||
* alpha value is less than the reference alpha
|
||||
* value.
|
||||
* @COGL_MATERIAL_ALPHA_FUNC_EQUAL: Let the fragment through if the incoming
|
||||
* alpha value equals the reference alpha
|
||||
* value.
|
||||
* @COGL_MATERIAL_ALPHA_FUNC_LEQUAL: Let the fragment through if the incoming
|
||||
* alpha value is less than or equal to the
|
||||
* reference alpha value.
|
||||
* @COGL_MATERIAL_ALPHA_FUNC_GREATER: Let the fragment through if the incoming
|
||||
* alpha value is greater than the reference
|
||||
* alpha value.
|
||||
* @COGL_MATERIAL_ALPHA_FUNC_NOTEQUAL: Let the fragment through if the incoming
|
||||
* alpha value does not equal the reference
|
||||
* alpha value.
|
||||
* @COGL_MATERIAL_ALPHA_FUNC_GEQUAL: Let the fragment through if the incoming
|
||||
* alpha value is greater than or equal to the
|
||||
* reference alpha value.
|
||||
* @COGL_MATERIAL_ALPHA_FUNC_ALWAYS: Always let the fragment through.
|
||||
*
|
||||
* Alpha testing happens before blending primitives with the framebuffer and
|
||||
* gives an opportunity to discard fragments based on a comparison with the
|
||||
* incoming alpha value and a reference alpha value. The #CoglMaterialAlphaFunc
|
||||
* determines how the comparison is done.
|
||||
*/
|
||||
typedef enum _CoglMaterialAlphaFunc
|
||||
{
|
||||
COGL_MATERIAL_ALPHA_FUNC_NEVER = GL_NEVER,
|
||||
COGL_MATERIAL_ALPHA_FUNC_LESS = GL_LESS,
|
||||
COGL_MATERIAL_ALPHA_FUNC_EQUAL = GL_EQUAL,
|
||||
COGL_MATERIAL_ALPHA_FUNC_LEQUAL = GL_LEQUAL,
|
||||
COGL_MATERIAL_ALPHA_FUNC_GREATER = GL_GREATER,
|
||||
COGL_MATERIAL_ALPHA_FUNC_NOTEQUAL = GL_NOTEQUAL,
|
||||
COGL_MATERIAL_ALPHA_FUNC_GEQUAL = GL_GEQUAL,
|
||||
COGL_MATERIAL_ALPHA_FUNC_ALWAYS = GL_ALWAYS
|
||||
} CoglMaterialAlphaFunc;
|
||||
|
||||
/**
|
||||
* cogl_material_set_alpha_test_function:
|
||||
* @material: A CoglMaterial object
|
||||
* @alpha_func: A @CoglMaterialAlphaFunc constant
|
||||
* @alpha_reference: A reference point that the chosen alpha function uses
|
||||
* to compare incoming fragments to.
|
||||
*
|
||||
* Before a primitive is blended with the framebuffer, it goes through an
|
||||
* alpha test stage which lets you discard fragments based on the current
|
||||
* alpha value. This function lets you change the function used to evaluate
|
||||
* the alpha channel, and thus determine which fragments are discarded
|
||||
* and which continue on to the blending stage.
|
||||
*
|
||||
* The default is COGL_MATERIAL_ALPHA_FUNC_ALWAYS
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_alpha_test_function (CoglHandle material,
|
||||
CoglMaterialAlphaFunc alpha_func,
|
||||
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)
|
||||
*
|
||||
* 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>
|
||||
* <programlisting>
|
||||
* R = Rs*Sr + Rd*Dr
|
||||
* G = Gs*Sg + Gd*Dg
|
||||
* B = Bs*Sb + Bd*Db
|
||||
* A = As*Sa + Ad*Da
|
||||
* </programlisting>
|
||||
*
|
||||
* All factors have a range [0, 1]
|
||||
*
|
||||
* The factors are selected with the following constants:
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* cogl_material_set_blend_factors:
|
||||
* @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.
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* (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
|
||||
*/
|
||||
void cogl_material_set_blend_factors (CoglHandle material,
|
||||
CoglMaterialBlendFactor src_factor,
|
||||
CoglMaterialBlendFactor dst_factor);
|
||||
|
||||
/**
|
||||
* cogl_material_set_layer:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* In addition to the standard OpenGL lighting model a Cogl material may have
|
||||
* one or more layers comprised of textures that can be blended together in
|
||||
* order, with a number of different texture combine modes. This function
|
||||
* defines a new texture layer.
|
||||
*
|
||||
* The index values of multiple layers do not have to be consecutive; it is
|
||||
* only their relative order that is important.
|
||||
*
|
||||
* XXX: In the future, we may define other types of material layers, such
|
||||
* as purely GLSL based layers.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_layer (CoglHandle material,
|
||||
gint layer_index,
|
||||
CoglHandle texture);
|
||||
|
||||
/**
|
||||
* cogl_material_add_texture:
|
||||
* @material: A CoglMaterial object
|
||||
* @layer_index: Specifies the layer you want to remove
|
||||
*
|
||||
* This function removes a layer from your 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)) +
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* <programlisting>
|
||||
* (Rs*Rp, Gs*Gp, Bs*Bp, As*Ap)
|
||||
* </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 = GL_REPLACE,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE = GL_MODULATE,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD = GL_ADD,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_ADD_SIGNED = GL_ADD_SIGNED,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_INTERPOLATE = GL_INTERPOLATE,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_SUBTRACT = GL_SUBTRACT,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_DOT3_RGB = GL_DOT3_RGB,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_DOT3_RGBA = GL_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:
|
||||
* <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);
|
||||
* </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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
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 = GL_CONSTANT,
|
||||
COGL_MATERIAL_LAYER_COMBINE_SRC_PRIMARY_COLOR = GL_PRIMARY_COLOR,
|
||||
COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS = GL_PREVIOUS
|
||||
} CoglMaterialLayerCombineSrc;
|
||||
|
||||
/**
|
||||
* cogl_material_set_layer_combine_arg_src:
|
||||
* @material: A CoglMaterial object
|
||||
* @layer_index:
|
||||
* @argument:
|
||||
* @channels:
|
||||
* @src:
|
||||
*
|
||||
*/
|
||||
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:
|
||||
*
|
||||
*/
|
||||
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
|
||||
|
||||
/**
|
||||
* cogl_material_set_layer_matrix:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* This function lets you set a matrix that can be used to e.g. translate
|
||||
* and rotate a single layer of a material used to fill your geometry.
|
||||
*/
|
||||
void cogl_material_set_layer_matrix (CoglHandle material,
|
||||
gint layer_index,
|
||||
CoglMatrix *matrix);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
const GList *cogl_material_get_layers (CoglHandle material_handle);
|
||||
|
||||
/**
|
||||
* CoglMaterialLayerType:
|
||||
* @COGL_MATERIAL_LAYER_TYPE_TEXTURE: The layer represents a CoglTexture
|
||||
*/
|
||||
typedef enum _CoglMaterialLayerType
|
||||
{
|
||||
COGL_MATERIAL_LAYER_TYPE_TEXTURE
|
||||
} CoglMaterialLayerType;
|
||||
|
||||
/**
|
||||
* cogl_material_layer_get_type:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* cogl_material_layer_get_texture:
|
||||
* @layer_handle: A CoglMaterial layer object
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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 CoglMaterial layer object
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Normally you shouldn't need to use this function directly, but if you
|
||||
* are developing a custom primitive using raw OpenGL that works with
|
||||
* CoglMaterials, then you may want to use this function.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_flush_gl_state (CoglHandle material,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
/**
|
||||
* cogl_set_source:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* This function sets the source material that will be used to fill
|
||||
* subsequent geometry emitted via the cogl API.
|
||||
*
|
||||
* Note: in the future we may add the ability to set a front facing
|
||||
* material, and a back facing material, in which case this function
|
||||
* will set both to the same.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
/* XXX: This doesn't really belong to the cogl-material API, it should
|
||||
* move to cogl.h */
|
||||
void cogl_set_source (CoglHandle material);
|
||||
|
||||
/**
|
||||
* cogl_set_source_texture:
|
||||
* @texture_handle: The Cogl texture you want as your source
|
||||
*
|
||||
* This is a convenience function for creating a material with the first
|
||||
* layer set to #texture_handle and setting that material as the source with
|
||||
* cogl_set_source.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_set_source_texture (CoglHandle texture_handle);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_MATERIAL_H__ */
|
||||
|
146
cogl-matrix.h
Normal file
146
cogl-matrix.h
Normal file
@ -0,0 +1,146 @@
|
||||
#ifndef __COGL_MATRIX_H
|
||||
#define __COGL_MATRIX_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:cogl-matrix
|
||||
* @short_description: Fuctions for initializing and manipulating 4x4
|
||||
* matrices.
|
||||
*
|
||||
* Matrices are used in Cogl to describe affine model-view transforms and
|
||||
* texture transforms, and projective transforms. This exposes a utility API
|
||||
* that can be used for direct manipulation of these matrices.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* CoglMatrix:
|
||||
*
|
||||
* A CoglMatrix holds a 4x4 transform matrix. This is a single precision,
|
||||
* column-major matrix which means it is compatible with what OpenGL expects.
|
||||
*
|
||||
* A CoglMatix can represent transforms such as, rotations, scaling,
|
||||
* translation, sheering, and linear projections. You can combine these
|
||||
* transforms by multiplying multiple matrices in the order you want them
|
||||
* applied.
|
||||
*
|
||||
* The transformation of a vertex (x, y, z, w) by a CoglMatrix is given by:
|
||||
* <programlisting>
|
||||
* x_new = xx * x + xy * y + xz * z + xw * w
|
||||
* y_new = yx * x + yy * y + yz * z + yw * w
|
||||
* z_new = zx * x + zy * y + zz * z + zw * w
|
||||
* w_new = wx * x + wy * y + wz * z + ww * w
|
||||
* </programlisting>
|
||||
* Where w is normally 1
|
||||
*/
|
||||
typedef struct _CoglMatrix {
|
||||
/* column 0 */
|
||||
float xx;
|
||||
float yx;
|
||||
float zx;
|
||||
float wx;
|
||||
|
||||
/* column 1 */
|
||||
float xy;
|
||||
float yy;
|
||||
float zy;
|
||||
float wy;
|
||||
|
||||
/* column 2 */
|
||||
float xz;
|
||||
float yz;
|
||||
float zz;
|
||||
float wz;
|
||||
|
||||
/* column 3 */
|
||||
float xw;
|
||||
float yw;
|
||||
float zw;
|
||||
float ww;
|
||||
|
||||
/*< private >*/
|
||||
|
||||
/* Note: we may want to extend this later with private flags
|
||||
* and a cache of the inverse transform matrix. */
|
||||
} CoglMatrix;
|
||||
|
||||
/**
|
||||
* cogl_matrix_init_identity:
|
||||
* @matrix: A 4x4 transformation matrix
|
||||
*
|
||||
* Resets matrix to the identity matrix:
|
||||
* <programlisting>
|
||||
* .xx=1; .xy=0; .xz=0; .xw=0;
|
||||
* .yx=0; .yy=1; .yz=0; .yw=0;
|
||||
* .zx=0; .zy=0; .zz=1; .zw=0;
|
||||
* .wx=0; .wy=0; .wz=0; .ww=1;
|
||||
* </programlisting>
|
||||
*/
|
||||
void cogl_matrix_init_identity (CoglMatrix *matrix);
|
||||
|
||||
/**
|
||||
* cogl_matrix_multiply:
|
||||
* @result: The address of a 4x4 matrix to store the result in
|
||||
* @a: A 4x4 transformation matrix
|
||||
* @b: A 4x4 transformation matrix
|
||||
*
|
||||
* This function multiples the two supplied matricies together and stores
|
||||
* the result in #result
|
||||
*/
|
||||
void cogl_matrix_multiply (CoglMatrix *result,
|
||||
const CoglMatrix *a,
|
||||
const CoglMatrix *b);
|
||||
|
||||
/**
|
||||
* cogl_matrix_rotate:
|
||||
* @matrix: A 4x4 transformation matrix
|
||||
* @angle: The angle you want to rotate in degrees
|
||||
* @x: X component of your rotation vector
|
||||
* @y: Y component of your rotation vector
|
||||
* @z: Z component of your rotation vector
|
||||
*
|
||||
* This function multiples your matrix with a rotation matrix that applies
|
||||
* a rotation of #angle degrees around the specified 3D vector.
|
||||
*/
|
||||
void cogl_matrix_rotate (CoglMatrix *matrix,
|
||||
float angle,
|
||||
float x,
|
||||
float y,
|
||||
float z);
|
||||
|
||||
/* cogl_matrix_translate:
|
||||
* @matrix: A 4x4 transformation matrix
|
||||
* @x: The X translation you want to apply
|
||||
* @y: The Y translation you want to apply
|
||||
* @z: The Z translation you want to apply
|
||||
*
|
||||
* This function multiples your matrix with a transform matrix that translates
|
||||
* along the X, Y and Z axis.
|
||||
*/
|
||||
void cogl_matrix_translate (CoglMatrix *matrix,
|
||||
float x,
|
||||
float y,
|
||||
float z);
|
||||
|
||||
/**
|
||||
* cogl_matrix_scale:
|
||||
* @matrix: A 4x4 transformation matrix
|
||||
* @sx: The X scale factor
|
||||
* @sy: The Y scale factor
|
||||
* @sz: The Z scale factor
|
||||
*
|
||||
* This function multiples your matrix with a transform matrix that scales
|
||||
* along the X, Y and Z axis.
|
||||
*/
|
||||
void cogl_matrix_scale (CoglMatrix *matrix,
|
||||
float sx,
|
||||
float sy,
|
||||
float sz);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_MATRIX_H */
|
||||
|
@ -57,8 +57,7 @@ G_BEGIN_DECLS
|
||||
* @width: Width of the rectangle
|
||||
* @height: Height of the rectangle
|
||||
*
|
||||
* Fills a rectangle at the given coordinates with the current
|
||||
* drawing color in a highly optimizied fashion.
|
||||
* Fills a rectangle at the given coordinates with the current source material
|
||||
**/
|
||||
void cogl_rectangle (float x,
|
||||
float y,
|
||||
|
158
cogl-texture.h
158
cogl-texture.h
@ -359,68 +359,15 @@ CoglHandle cogl_texture_ref (CoglHandle handle);
|
||||
*/
|
||||
void cogl_texture_unref (CoglHandle handle);
|
||||
|
||||
/**
|
||||
* cogl_texture_rectangle:
|
||||
* @handle: a @CoglHandle.
|
||||
* @x1: x coordinate upper left on screen.
|
||||
* @y1: y coordinate upper left on screen.
|
||||
* @x2: x coordinate lower right on screen.
|
||||
* @y2: y coordinate lower right on screen.
|
||||
* @tx1: x part of texture coordinate to use for upper left pixel
|
||||
* @ty1: y part of texture coordinate to use for upper left pixel
|
||||
* @tx2: x part of texture coordinate to use for lower right pixel
|
||||
* @ty2: y part of texture coordinate to use for left pixel
|
||||
*
|
||||
* Draw a rectangle from a texture to the display, to draw the entire
|
||||
* texture pass in @tx1=0.0 @ty1=0.0 @tx2=1.0 @ty2=1.0.
|
||||
*/
|
||||
void cogl_texture_rectangle (CoglHandle handle,
|
||||
float x1,
|
||||
float y1,
|
||||
float x2,
|
||||
float y2,
|
||||
float tx1,
|
||||
float ty1,
|
||||
float tx2,
|
||||
float ty2);
|
||||
|
||||
/**
|
||||
* cogl_texture_polygon:
|
||||
* @handle: A CoglHandle for a texture
|
||||
* @n_vertices: The length of the vertices array
|
||||
* @vertices: An array of #CoglTextureVertex structs
|
||||
* @use_color: %TRUE if the color member of #CoglTextureVertex should be used
|
||||
*
|
||||
* Draws a polygon from a texture with the given model and texture
|
||||
* coordinates. This can be used to draw arbitrary shapes textured
|
||||
* with a COGL texture. If @use_color is %TRUE then the current COGL
|
||||
* color will be changed for each vertex using the value specified in
|
||||
* the color member of #CoglTextureVertex. This can be used for
|
||||
* example to make the texture fade out by setting the alpha value of
|
||||
* the color.
|
||||
*
|
||||
* All of the texture coordinates must be in the range [0,1] and
|
||||
* repeating the texture is not supported.
|
||||
*
|
||||
* Because of the way this function is implemented it will currently
|
||||
* only work if either the texture is not sliced or the backend is not
|
||||
* OpenGL ES and the minifying and magnifying functions are both set
|
||||
* to CGL_NEAREST.
|
||||
*/
|
||||
void cogl_texture_polygon (CoglHandle handle,
|
||||
guint n_vertices,
|
||||
CoglTextureVertex *vertices,
|
||||
gboolean use_color);
|
||||
|
||||
/**
|
||||
* cogl_bitmap_new_from_file:
|
||||
* @filename: the file to load.
|
||||
* @error: a #GError or %NULL.
|
||||
*
|
||||
* Load an image file from disk. This function can be safely called from
|
||||
* Load an image file from disk. This function can be safely called from
|
||||
* within a thread.
|
||||
*
|
||||
* Returns: A #CoglBitmap to the new loaded image data, or %NULL if loading
|
||||
* Returns: A #CoglBitmap to the new loaded image data, or %NULL if loading
|
||||
* the image failed.
|
||||
*
|
||||
* Since: 1.0
|
||||
@ -452,27 +399,110 @@ gboolean cogl_bitmap_get_size_from_file (const gchar *filename,
|
||||
void cogl_bitmap_free (CoglBitmap *bmp);
|
||||
|
||||
/**
|
||||
* cogl_texture_multiple_rectangles:
|
||||
* @handle: a @CoglHandle.
|
||||
* cogl_rectangle_with_texture_coords:
|
||||
* @x1: x coordinate upper left on screen.
|
||||
* @y1: y coordinate upper left on screen.
|
||||
* @x2: x coordinate lower right on screen.
|
||||
* @y2: y coordinate lower right on screen.
|
||||
* @tx1: x part of texture coordinate to use for upper left pixel
|
||||
* @ty1: y part of texture coordinate to use for upper left pixel
|
||||
* @tx2: x part of texture coordinate to use for lower right pixel
|
||||
* @ty2: y part of texture coordinate to use for left pixel
|
||||
*
|
||||
* Draw a rectangle using the current material and supply texture coordinates
|
||||
* to be used for the first texture layer of the material. To draw the entire
|
||||
* texture pass in @tx1=0.0 @ty1=0.0 @tx2=1.0 @ty2=1.0.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_rectangle_with_texture_coords (float x1,
|
||||
float y1,
|
||||
float x2,
|
||||
float y2,
|
||||
float tx1,
|
||||
float ty1,
|
||||
float tx2,
|
||||
float ty2);
|
||||
|
||||
/**
|
||||
* cogl_rectangle_with_multitexture_coords:
|
||||
* @x1: x coordinate upper left on screen.
|
||||
* @y1: y coordinate upper left on screen.
|
||||
* @x2: x coordinate lower right on screen.
|
||||
* @y2: y coordinate lower right on screen.
|
||||
* @tex_coords: An array containing groups of 4 float values:
|
||||
* [tx1, ty1, tx2, ty2] that are interpreted as two texture coordinates; one
|
||||
* for the upper left texel, and one for the lower right texel. Each value
|
||||
* should be between 0.0 and 1.0, where the coordinate (0.0, 0.0) represents
|
||||
* the top left of the texture, and (1.0, 1.0) the bottom right.
|
||||
* @tex_coords_len: The length of the tex_coords array. (e.g. for one layer
|
||||
* and one group of texture coordinates, this would be 4)
|
||||
*
|
||||
* This function draws a rectangle using the current source material to
|
||||
* texture or fill with. As a material may contain multiple texture layers
|
||||
* this interface lets you supply texture coordinates for each layer of the
|
||||
* material.
|
||||
*
|
||||
* The first pair of coordinates are for the first layer (with the smallest
|
||||
* layer index) and if you supply less texture coordinates than there are
|
||||
* layers in the current source material then default texture coordinates
|
||||
* (0.0, 0.0, 1.0, 1.0) are generated.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_rectangle_with_multitexture_coords (float x1,
|
||||
float y1,
|
||||
float x2,
|
||||
float y2,
|
||||
const float *tex_coords,
|
||||
gint tex_coords_len);
|
||||
|
||||
/**
|
||||
* cogl_rectangles_with_texture_coords:
|
||||
* @verts: an array of vertices
|
||||
* @n_rects: number of rectangles to draw
|
||||
*
|
||||
* Draws a series of rectangles in the same way that
|
||||
* cogl_texture_rectangle() does. In some situations it can give a
|
||||
* cogl_rectangle_with_texture_coords() does. In some situations it can give a
|
||||
* significant performance boost to use this function rather than
|
||||
* calling cogl_texture_rectangle() separately for each rectangle.
|
||||
* calling cogl_rectangle_with_texture_coords() separately for each rectangle.
|
||||
*
|
||||
* @verts should point to an array of #float<!-- -->s with
|
||||
* @n_rects * 8 elements. Each group of 8 values corresponds to the
|
||||
* parameters x1, y1, x2, y2, tx1, ty1, tx2 and ty2 and have the same
|
||||
* meaning as in cogl_texture_rectangle().
|
||||
* meaning as in cogl_rectangle_with_texture_coords().
|
||||
*
|
||||
* Since: 0.8.6
|
||||
*/
|
||||
void cogl_texture_multiple_rectangles
|
||||
(CoglHandle handle,
|
||||
const float *verts,
|
||||
guint n_rects);
|
||||
void cogl_rectangles_with_texture_coords (const float *verts,
|
||||
guint n_rects);
|
||||
|
||||
/**
|
||||
* cogl_polygon:
|
||||
* @vertices: An array of #CoglTextureVertex structs
|
||||
* @n_vertices: The length of the vertices array
|
||||
* @use_color: %TRUE if the color member of #CoglTextureVertex should be used
|
||||
*
|
||||
* Draws a convex polygon using the current source material to fill / texture
|
||||
* with according to the texture coordinates passed.
|
||||
*
|
||||
* If @use_color is %TRUE then the color will be changed for each vertex using
|
||||
* the value specified in the color member of #CoglTextureVertex. This can be
|
||||
* used for example to make the texture fade out by setting the alpha value of
|
||||
* the color.
|
||||
*
|
||||
* All of the texture coordinates must be in the range [0,1] and repeating the
|
||||
* texture is not supported.
|
||||
*
|
||||
* Because of the way this function is implemented it will currently only work
|
||||
* if either the texture is not sliced or the backend is not OpenGL ES and the
|
||||
* minifying and magnifying functions are both set to CGL_NEAREST.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_polygon (CoglTextureVertex *vertices,
|
||||
guint n_vertices,
|
||||
gboolean use_color);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
16
cogl.h.in
16
cogl.h.in
@ -32,10 +32,13 @@
|
||||
|
||||
#include <cogl/cogl-defines-@CLUTTER_COGL@.h>
|
||||
|
||||
#include <cogl/cogl-vertex-buffer.h>
|
||||
#include <cogl/cogl-matrix.h>
|
||||
#include <cogl/cogl-vertex-buffer.h>
|
||||
#include <cogl/cogl-fixed.h>
|
||||
#include <cogl/cogl-color.h>
|
||||
#include <cogl/cogl-offscreen.h>
|
||||
#include <cogl/cogl-material.h>
|
||||
#include <cogl/cogl-path.h>
|
||||
#include <cogl/cogl-shader.h>
|
||||
#include <cogl/cogl-texture.h>
|
||||
@ -402,19 +405,6 @@ void cogl_enable_depth_test (gboolean setting);
|
||||
*/
|
||||
void cogl_enable_backface_culling (gboolean setting);
|
||||
|
||||
/**
|
||||
* cogl_alpha_func:
|
||||
* @func: the comparison function to use, one of CGL_NEVER, CGL_LESS,
|
||||
* CGL_EQUAL, CGL_LEQUAL, CGL_GREATER, CGL_NOTEQUAL, CGL_GEQUAL and GL_ALWAYS.
|
||||
* @ref: reference value.
|
||||
*
|
||||
* Changes the alpha test to use the specified function specified in @func,
|
||||
* comparing with the value in @ref. The default function is CGL_ALWAYS the
|
||||
* initial reference value is 1.0.
|
||||
*/
|
||||
void cogl_alpha_func (COGLenum func,
|
||||
float ref);
|
||||
|
||||
/**
|
||||
* cogl_fog_set:
|
||||
* @fog_color: The color of the fog
|
||||
|
@ -31,5 +31,7 @@ libclutter_cogl_common_la_SOURCES = \
|
||||
cogl-clip-stack.c \
|
||||
cogl-fixed.c \
|
||||
cogl-color.c \
|
||||
cogl-vertex-buffer-private.h \
|
||||
cogl-vertex-buffer.c
|
||||
cogl-vertex-buffer-private.h \
|
||||
cogl-vertex-buffer.c \
|
||||
cogl-matrix.c \
|
||||
cogl-material.c
|
||||
|
@ -57,6 +57,12 @@
|
||||
|
||||
#define COGL_HANDLE_DEFINE(TypeName, type_name, handle_array) \
|
||||
\
|
||||
static CoglHandle * \
|
||||
_cogl_##type_name##_handle_from_pointer (Cogl##TypeName *obj) \
|
||||
{ \
|
||||
return (CoglHandle)obj; \
|
||||
} \
|
||||
\
|
||||
static gint \
|
||||
_cogl_##type_name##_handle_find (CoglHandle handle) \
|
||||
{ \
|
||||
|
99
common/cogl-material-private.h
Normal file
99
common/cogl-material-private.h
Normal file
@ -0,0 +1,99 @@
|
||||
#ifndef __COGL_MATERIAL_PRIVATE_H
|
||||
#define __COGL_MATERIAL_PRIVATE_H
|
||||
|
||||
#include "cogl-material.h"
|
||||
#include "cogl-matrix.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
typedef struct _CoglMaterial CoglMaterial;
|
||||
typedef struct _CoglMaterialLayer CoglMaterialLayer;
|
||||
|
||||
/* XXX: I don't think gtk-doc supports having private enums so these aren't
|
||||
* bundled in with CoglMaterialLayerFlags */
|
||||
typedef enum _CoglMaterialLayerPrivFlags
|
||||
{
|
||||
/* Ref: CoglMaterialLayerFlags
|
||||
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
|
||||
*/
|
||||
COGL_MATERIAL_LAYER_FLAG_DIRTY = 1L<<1,
|
||||
COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE = 1L<<2
|
||||
} CoglMaterialLayerPrivFlags;
|
||||
|
||||
/* For tracking the state of a layer that's been flushed to OpenGL */
|
||||
typedef struct _CoglLayerInfo
|
||||
{
|
||||
CoglHandle handle;
|
||||
gulong flags;
|
||||
GLenum gl_target;
|
||||
GLuint gl_texture;
|
||||
gboolean fallback;
|
||||
gboolean disabled;
|
||||
gboolean layer0_overridden;
|
||||
} CoglLayerInfo;
|
||||
|
||||
struct _CoglMaterialLayer
|
||||
{
|
||||
guint ref_count;
|
||||
guint index; /*!< lowest index is blended first then others
|
||||
on top */
|
||||
gulong flags;
|
||||
CoglHandle texture; /*!< The texture for this layer, or COGL_INVALID_HANDLE
|
||||
for an empty layer */
|
||||
|
||||
/* 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];
|
||||
|
||||
CoglMaterialLayerCombineFunc texture_combine_alpha_func;
|
||||
CoglMaterialLayerCombineSrc texture_combine_alpha_src[3];
|
||||
CoglMaterialLayerCombineOp texture_combine_alpha_op[3];
|
||||
|
||||
/* TODO: Support purely GLSL based material layers */
|
||||
|
||||
CoglMatrix matrix;
|
||||
};
|
||||
|
||||
typedef enum _CoglMaterialFlags
|
||||
{
|
||||
COGL_MATERIAL_FLAG_ENABLE_BLEND = 1L<<0,
|
||||
COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING = 1L<<1,
|
||||
COGL_MATERIAL_FLAG_DIRTY = 1L<<2,
|
||||
COGL_MATERIAL_FLAG_LAYERS_DIRTY = 1L<<3,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_COLOR = 1L<<4,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL = 1L<<5,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC = 1L<<6,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC = 1L<<7
|
||||
} CoglMaterialFlags;
|
||||
|
||||
struct _CoglMaterial
|
||||
{
|
||||
guint ref_count;
|
||||
|
||||
gulong flags;
|
||||
|
||||
/* If no lighting is enabled; this is the basic material color */
|
||||
GLfloat unlit[4];
|
||||
|
||||
/* Standard OpenGL lighting model attributes */
|
||||
GLfloat ambient[4];
|
||||
GLfloat diffuse[4];
|
||||
GLfloat specular[4];
|
||||
GLfloat emission[4];
|
||||
GLfloat shininess;
|
||||
|
||||
/* Determines what fragments are discarded based on their alpha */
|
||||
CoglMaterialAlphaFunc alpha_func;
|
||||
GLfloat alpha_func_reference;
|
||||
|
||||
/* Determines how this material is blended with other primitives */
|
||||
CoglMaterialBlendFactor blend_src_factor;
|
||||
CoglMaterialBlendFactor blend_dst_factor;
|
||||
|
||||
GList *layers;
|
||||
};
|
||||
|
||||
#endif /* __COGL_MATERIAL_PRIVATE_H */
|
||||
|
1152
common/cogl-material.c
Normal file
1152
common/cogl-material.c
Normal file
File diff suppressed because it is too large
Load Diff
138
common/cogl-matrix.c
Normal file
138
common/cogl-matrix.c
Normal file
@ -0,0 +1,138 @@
|
||||
#include <cogl-matrix.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <math.h>
|
||||
|
||||
void
|
||||
cogl_matrix_init_identity (CoglMatrix *matrix)
|
||||
{
|
||||
matrix->xx = 1; matrix->xy = 0; matrix->xz = 0; matrix->xw = 0;
|
||||
matrix->yx = 0; matrix->yy = 1; matrix->yz = 0; matrix->yw = 0;
|
||||
matrix->zx = 0; matrix->zy = 0; matrix->zz = 1; matrix->zw = 0;
|
||||
matrix->wx = 0; matrix->wy = 0; matrix->wz = 0; matrix->ww = 1;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_matrix_multiply (CoglMatrix *result,
|
||||
const CoglMatrix *a,
|
||||
const CoglMatrix *b)
|
||||
{
|
||||
CoglMatrix r;
|
||||
|
||||
/* row 0 */
|
||||
r.xx = a->xx * b->xx + a->xy * b->yx + a->xz * b->zx + a->xw * b->wx;
|
||||
r.xy = a->xx * b->xy + a->xy * b->yy + a->xz * b->zy + a->xw * b->wy;
|
||||
r.xz = a->xx * b->xz + a->xy * b->yz + a->xz * b->zz + a->xw * b->wz;
|
||||
r.xw = a->xx * b->xw + a->xy * b->yw + a->xz * b->zw + a->xw * b->ww;
|
||||
|
||||
/* row 1 */
|
||||
r.yx = a->yx * b->xx + a->yy * b->yx + a->yz * b->zx + a->yw * b->wx;
|
||||
r.yy = a->yx * b->xy + a->yy * b->yy + a->yz * b->zy + a->yw * b->wy;
|
||||
r.yz = a->yx * b->xz + a->yy * b->yz + a->yz * b->zz + a->yw * b->wz;
|
||||
r.yw = a->yx * b->xw + a->yy * b->yw + a->yz * b->zw + a->yw * b->ww;
|
||||
|
||||
/* row 2 */
|
||||
r.zx = a->zx * b->xx + a->zy * b->yx + a->zz * b->zx + a->zw * b->wx;
|
||||
r.zy = a->zx * b->xy + a->zy * b->yy + a->zz * b->zy + a->zw * b->wy;
|
||||
r.zz = a->zx * b->xz + a->zy * b->yz + a->zz * b->zz + a->zw * b->wz;
|
||||
r.zw = a->zx * b->xw + a->zy * b->yw + a->zz * b->zw + a->zw * b->ww;
|
||||
|
||||
/* row 3 */
|
||||
r.wx = a->wx * b->xx + a->wy * b->yx + a->wz * b->zx + a->ww * b->wx;
|
||||
r.wy = a->wx * b->xy + a->wy * b->yy + a->wz * b->zy + a->ww * b->wy;
|
||||
r.wz = a->wx * b->xz + a->wy * b->yz + a->wz * b->zz + a->ww * b->wz;
|
||||
r.ww = a->wx * b->xw + a->wy * b->yw + a->wz * b->zw + a->ww * b->ww;
|
||||
|
||||
/* The idea was that having this unrolled; it might be easier for the
|
||||
* compiler to vectorize, but that's probably not true. Mesa does it
|
||||
* using a single for (i=0; i<4; i++) approach, may that's better...
|
||||
*/
|
||||
|
||||
*result = r;
|
||||
}
|
||||
|
||||
/**
|
||||
* cogl_3dmatrix_rotate:
|
||||
* matrix: A 3D Affine transformation matrix
|
||||
* angle: The angle in degrees you want to rotate by
|
||||
* x: The X component of your rotation vector
|
||||
* y: The Y component of your rotation vector
|
||||
* z: The Z component of your rotation vector
|
||||
*
|
||||
* The matrix is multiplied with a rotation matrix representing a rotation
|
||||
* of angle degress around the vector (x,y,z)
|
||||
*/
|
||||
void
|
||||
cogl_matrix_rotate (CoglMatrix *matrix,
|
||||
float angle,
|
||||
float x,
|
||||
float y,
|
||||
float z)
|
||||
{
|
||||
CoglMatrix rotation;
|
||||
CoglMatrix result;
|
||||
angle *= G_PI / 180.0f;
|
||||
float c = cosf (angle);
|
||||
float s = sinf (angle);
|
||||
|
||||
rotation.xx = x * x * (1.0f - c) + c;
|
||||
rotation.yx = y * x * (1.0f - c) + z * s;
|
||||
rotation.zx = x * z * (1.0f - c) - y * s;
|
||||
rotation.wx = 0.0f;
|
||||
|
||||
rotation.xy = x * y * (1.0f - c) - z * s;
|
||||
rotation.yy = y * y * (1.0f - c) + c;
|
||||
rotation.zy = y * z * (1.0f - c) + x * s;
|
||||
rotation.wy = 0.0f;
|
||||
|
||||
rotation.xz = x * z * (1.0f - c) + y * s;
|
||||
rotation.yz = y * z * (1.0f - c) - x * s;
|
||||
rotation.zz = z * z * (1.0f - c) + c;
|
||||
rotation.wz = 0.0f;
|
||||
|
||||
rotation.xw = 0.0f;
|
||||
rotation.yw = 0.0f;
|
||||
rotation.zw = 0.0f;
|
||||
rotation.ww = 1.0f;
|
||||
|
||||
cogl_matrix_multiply (&result, matrix, &rotation);
|
||||
*matrix = result;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_matrix_translate (CoglMatrix *matrix,
|
||||
float x,
|
||||
float y,
|
||||
float z)
|
||||
{
|
||||
matrix->xw = matrix->xx * x + matrix->xy * y + matrix->xz * z + matrix->xw;
|
||||
matrix->yw = matrix->yx * x + matrix->yy * y + matrix->yz * z + matrix->yw;
|
||||
matrix->zw = matrix->zx * x + matrix->zy * y + matrix->zz * z + matrix->zw;
|
||||
matrix->ww = matrix->wx * x + matrix->wy * y + matrix->wz * z + matrix->ww;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_matrix_scale (CoglMatrix *matrix,
|
||||
float sx,
|
||||
float sy,
|
||||
float sz)
|
||||
{
|
||||
matrix->xx *= sx; matrix->xy *= sy; matrix->xz *= sz;
|
||||
matrix->yx *= sx; matrix->yy *= sy; matrix->yz *= sz;
|
||||
matrix->zx *= sx; matrix->zy *= sy; matrix->zz *= sz;
|
||||
matrix->wx *= sx; matrix->wy *= sy; matrix->wz *= sz;
|
||||
}
|
||||
|
||||
#if 0
|
||||
gboolean
|
||||
cogl_matrix_invert (CoglMatrix *matrix)
|
||||
{
|
||||
/* TODO */
|
||||
/* Note: It might be nice to also use the flag based tricks that mesa does
|
||||
* to alow it to track the type of transformations a matrix represents
|
||||
* so it can use various assumptions to optimise the inversion.
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -43,19 +43,18 @@ void _cogl_path_add_node (gboolean new_sub_path,
|
||||
float y);
|
||||
void _cogl_path_fill_nodes ();
|
||||
void _cogl_path_stroke_nodes ();
|
||||
void _cogl_rectangle (float x,
|
||||
float y,
|
||||
float width,
|
||||
float height);
|
||||
|
||||
void
|
||||
cogl_rectangle (float x,
|
||||
float y,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
cogl_clip_ensure ();
|
||||
|
||||
_cogl_rectangle (x, y, width, height);
|
||||
cogl_rectangle_with_multitexture_coords (x, y,
|
||||
x+width,
|
||||
y+height,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -134,6 +134,7 @@
|
||||
#include "cogl-context.h"
|
||||
#include "cogl-handle.h"
|
||||
#include "cogl-vertex-buffer-private.h"
|
||||
#include "cogl-texture-private.h"
|
||||
|
||||
#define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \
|
||||
(VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1)))
|
||||
@ -1416,12 +1417,15 @@ get_gl_type_from_attribute_flags (CoglVertexBufferAttribFlags flags)
|
||||
static void
|
||||
enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
|
||||
{
|
||||
GList *tmp;
|
||||
GLenum gl_type;
|
||||
GLuint generic_index = 0;
|
||||
gulong enable_flags = COGL_ENABLE_BLEND;
|
||||
/* FIXME: I don't think it's appropriate to force enable
|
||||
* GL_BLEND here. */
|
||||
GList *tmp;
|
||||
GLenum gl_type;
|
||||
GLuint generic_index = 0;
|
||||
gulong enable_flags = 0;
|
||||
guint max_texcoord_attrib_unit = 0;
|
||||
const GList *layers;
|
||||
guint32 fallback_mask = 0;
|
||||
guint32 disable_mask = ~0;
|
||||
int i;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -1460,17 +1464,16 @@ enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
|
||||
(const GLvoid *)attribute->u.vbo_offset));
|
||||
break;
|
||||
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY:
|
||||
/* FIXME: set the active texture unit */
|
||||
/* NB: Cogl currently manages unit 0 */
|
||||
enable_flags |= (COGL_ENABLE_TEXCOORD_ARRAY
|
||||
| COGL_ENABLE_TEXTURE_2D);
|
||||
/* FIXME: I don't think it's appropriate to force enable
|
||||
* GL_TEXTURE_2D here. */
|
||||
/* GE (glEnableClientState (GL_VERTEX_ARRAY)); */
|
||||
GE (glClientActiveTexture (GL_TEXTURE0 +
|
||||
attribute->texture_unit));
|
||||
GE (glEnableClientState (GL_TEXTURE_COORD_ARRAY));
|
||||
GE (glTexCoordPointer (attribute->n_components,
|
||||
gl_type,
|
||||
attribute->stride,
|
||||
(const GLvoid *)attribute->u.vbo_offset));
|
||||
if (attribute->texture_unit > max_texcoord_attrib_unit)
|
||||
max_texcoord_attrib_unit = attribute->texture_unit;
|
||||
disable_mask &= ~(1 << attribute->texture_unit);
|
||||
break;
|
||||
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY:
|
||||
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
|
||||
@ -1505,8 +1508,51 @@ enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
|
||||
}
|
||||
}
|
||||
|
||||
cogl_enable (enable_flags);
|
||||
layers = cogl_material_get_layers (ctx->source_material);
|
||||
for (tmp = (GList *)layers, i = 0;
|
||||
tmp != NULL && i <= max_texcoord_attrib_unit;
|
||||
tmp = tmp->next, i++)
|
||||
{
|
||||
CoglHandle layer = (CoglHandle)tmp->data;
|
||||
CoglHandle tex_handle = cogl_material_layer_get_texture (layer);
|
||||
CoglTexture *texture =
|
||||
_cogl_texture_pointer_from_handle (tex_handle);
|
||||
|
||||
if (cogl_texture_is_sliced (tex_handle)
|
||||
|| _cogl_texture_span_has_waste (texture, 0, 0))
|
||||
{
|
||||
g_warning ("Disabling layer %d of the current source material, "
|
||||
"because texturing with the vertex buffer API is not "
|
||||
"currently supported using sliced textures, or textures "
|
||||
"with waste\n", i);
|
||||
|
||||
/* XXX: maybe we can add a mechanism for users to forcibly use
|
||||
* textures with waste where it would be their responsability to use
|
||||
* texture coords in the range [0,1] such that sampling outside isn't
|
||||
* required. We can then use a texture matrix (or a modification of
|
||||
* the users own matrix) to map 1 to the edge of the texture data.
|
||||
*
|
||||
* Potentially, given the same guarantee as above we could also
|
||||
* support a single sliced layer too. We would have to redraw the
|
||||
* vertices once for each layer, each time with a fiddled texture
|
||||
* matrix.
|
||||
*/
|
||||
fallback_mask |= (1 << i);
|
||||
}
|
||||
else if (!(disable_mask & (1 << i)))
|
||||
fallback_mask |= (1 << i);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
cogl_enable (enable_flags);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1550,9 +1596,9 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
GE (glDisableClientState (GL_NORMAL_ARRAY));
|
||||
break;
|
||||
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY:
|
||||
/* FIXME: set the active texture unit */
|
||||
/* NB: Cogl currently manages unit 0 */
|
||||
/* GE (glDisableClientState (GL_VERTEX_ARRAY)); */
|
||||
GE (glClientActiveTexture (GL_TEXTURE0 +
|
||||
attribute->texture_unit));
|
||||
GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
|
||||
break;
|
||||
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY:
|
||||
/* GE (glDisableClientState (GL_VERTEX_ARRAY)); */
|
||||
|
@ -55,7 +55,9 @@
|
||||
<xi:include href="xml/cogl.xml"/>
|
||||
<xi:include href="xml/cogl-primitives.xml"/>
|
||||
<xi:include href="xml/cogl-util.xml"/>
|
||||
<xi:include href="xml/cogl-matrix.xml"/>
|
||||
<xi:include href="xml/cogl-texture.xml"/>
|
||||
<xi:include href="xml/cogl-material.xml"/>
|
||||
<xi:include href="xml/cogl-shaders.xml"/>
|
||||
<xi:include href="xml/cogl-offscreen.xml"/>
|
||||
<xi:include href="xml/cogl-fixed.xml"/>
|
||||
|
@ -310,3 +310,52 @@ cogl_vertex_buffer_draw
|
||||
cogl_vertex_buffer_draw_range_elements
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>cogl-matrix</FILE>
|
||||
<TITLE>Matrices</TITLE>
|
||||
CoglMatrix
|
||||
cogl_matrix_init_identity
|
||||
cogl_matrix_multiply
|
||||
cogl_matrix_rotate
|
||||
cogl_matrix_translate
|
||||
cogl_matrix_scale
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>cogl-material</FILE>
|
||||
<TITLE>Materials</TITLE>
|
||||
cogl_material_new
|
||||
cogl_material_ref
|
||||
cogl_material_unref
|
||||
cogl_material_set_diffuse
|
||||
cogl_material_set_ambient
|
||||
cogl_material_set_ambient_and_diffuse
|
||||
cogl_material_set_specular
|
||||
cogl_material_set_shininess
|
||||
cogl_material_set_emission
|
||||
cogl_set_source
|
||||
CoglMaterialAlphaFunc
|
||||
cogl_material_set_alpha_test_function
|
||||
CoglMaterialBlendFactor
|
||||
cogl_material_set_blend_factors
|
||||
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_matrix
|
||||
cogl_material_get_cogl_enable_flags
|
||||
cogl_material_flush_gl_material_state
|
||||
cogl_material_flush_gl_alpha_func
|
||||
cogl_material_flush_gl_blend_func
|
||||
cogl_material_get_layers
|
||||
CoglMaterialLayerType
|
||||
cogl_material_layer_get_type
|
||||
cogl_material_layer_get_texture
|
||||
cogl_material_layer_flush_gl_sampler_state
|
||||
</SECTION>
|
||||
|
||||
|
@ -10,7 +10,9 @@ libclutterinclude_HEADERS = \
|
||||
$(top_builddir)/clutter/cogl/cogl-shader.h \
|
||||
$(top_builddir)/clutter/cogl/cogl-texture.h \
|
||||
$(top_builddir)/clutter/cogl/cogl-types.h \
|
||||
$(top_builddir)/clutter/cogl/cogl-vertex-buffer.h
|
||||
$(top_builddir)/clutter/cogl/cogl-vertex-buffer.h \
|
||||
$(top_builddir)/clutter/cogl/cogl-material.h \
|
||||
$(top_builddir)/clutter/cogl/cogl-matrix.h
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "cogl-internal.h"
|
||||
#include "cogl-util.h"
|
||||
#include "cogl-context.h"
|
||||
#include "cogl-texture-private.h"
|
||||
#include "cogl-material-private.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -39,6 +41,9 @@ static CoglContext *_context = NULL;
|
||||
gboolean
|
||||
cogl_create_context ()
|
||||
{
|
||||
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
|
||||
gulong enable_flags = 0;
|
||||
|
||||
if (_context != NULL)
|
||||
return FALSE;
|
||||
|
||||
@ -52,27 +57,40 @@ cogl_create_context ()
|
||||
_context->enable_flags = 0;
|
||||
_context->color_alpha = 255;
|
||||
|
||||
_context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
|
||||
_context->last_path = 0;
|
||||
_context->material_handles = NULL;
|
||||
_context->material_layer_handles = NULL;
|
||||
_context->default_material = cogl_material_new ();
|
||||
_context->source_material = NULL;
|
||||
|
||||
_context->texture_handles = NULL;
|
||||
_context->texture_vertices = g_array_new (FALSE, FALSE,
|
||||
_context->default_gl_texture_2d_tex = COGL_INVALID_HANDLE;
|
||||
_context->default_gl_texture_rect_tex = COGL_INVALID_HANDLE;
|
||||
|
||||
_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));
|
||||
_context->texture_indices = g_array_new (FALSE, FALSE,
|
||||
sizeof (GLushort));
|
||||
|
||||
_context->current_material = NULL;
|
||||
_context->current_material_flags = 0;
|
||||
_context->current_layers = g_array_new (FALSE, FALSE,
|
||||
sizeof (CoglLayerInfo));
|
||||
_context->n_texcoord_arrays_enabled = 0;
|
||||
|
||||
_context->fbo_handles = NULL;
|
||||
_context->draw_buffer = COGL_WINDOW_BUFFER;
|
||||
|
||||
_context->blend_src_factor = CGL_SRC_ALPHA;
|
||||
_context->blend_dst_factor = CGL_ONE_MINUS_SRC_ALPHA;
|
||||
|
||||
_context->shader_handles = NULL;
|
||||
|
||||
_context->program_handles = NULL;
|
||||
|
||||
_context->vertex_buffer_handles = NULL;
|
||||
|
||||
_context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
|
||||
_context->last_path = 0;
|
||||
_context->stencil_material = cogl_material_new ();
|
||||
|
||||
_context->pf_glGenRenderbuffersEXT = NULL;
|
||||
_context->pf_glBindRenderbufferEXT = NULL;
|
||||
_context->pf_glRenderbufferStorageEXT = NULL;
|
||||
@ -118,15 +136,37 @@ cogl_create_context ()
|
||||
|
||||
_context->pf_glDrawRangeElements = NULL;
|
||||
|
||||
/* Init OpenGL state */
|
||||
GE( glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) );
|
||||
GE( glColorMask (TRUE, TRUE, TRUE, FALSE) );
|
||||
GE( glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) );
|
||||
cogl_enable (0);
|
||||
|
||||
/* Initialise the clip stack */
|
||||
_cogl_clip_stack_state_init ();
|
||||
|
||||
/* Create default textures used for fall backs */
|
||||
_context->default_gl_texture_2d_tex =
|
||||
cogl_texture_new_from_data (1, /* width */
|
||||
1, /* height */
|
||||
-1, /* max waste */
|
||||
FALSE, /* auto mipmap */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
|
||||
/* internal format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
0, /* auto calc row stride */
|
||||
&default_texture_data);
|
||||
_context->default_gl_texture_rect_tex =
|
||||
cogl_texture_new_from_data (1, /* width */
|
||||
1, /* height */
|
||||
-1, /* max waste */
|
||||
FALSE, /* auto mipmap */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
|
||||
/* internal format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
0, /* auto calc row stride */
|
||||
&default_texture_data);
|
||||
|
||||
cogl_set_source (_context->default_material);
|
||||
cogl_material_flush_gl_state (_context->source_material, NULL);
|
||||
enable_flags =
|
||||
cogl_material_get_cogl_enable_flags (_context->source_material);
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -150,10 +190,25 @@ cogl_destroy_context ()
|
||||
if (_context->program_handles)
|
||||
g_array_free (_context->program_handles, TRUE);
|
||||
|
||||
if (_context->texture_vertices)
|
||||
g_array_free (_context->texture_vertices, TRUE);
|
||||
if (_context->texture_indices)
|
||||
g_array_free (_context->texture_indices, TRUE);
|
||||
if (_context->default_gl_texture_2d_tex)
|
||||
cogl_texture_unref (_context->default_gl_texture_2d_tex);
|
||||
if (_context->default_gl_texture_rect_tex)
|
||||
cogl_texture_unref (_context->default_gl_texture_rect_tex);
|
||||
|
||||
if (_context->default_material)
|
||||
cogl_material_unref (_context->default_material);
|
||||
|
||||
if (_context->journal)
|
||||
g_array_free (_context->journal, TRUE);
|
||||
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);
|
||||
|
||||
g_free (_context);
|
||||
}
|
||||
|
@ -45,32 +45,37 @@ typedef struct
|
||||
/* Enable cache */
|
||||
gulong enable_flags;
|
||||
guint8 color_alpha;
|
||||
COGLenum blend_src_factor;
|
||||
COGLenum blend_dst_factor;
|
||||
|
||||
gboolean enable_backface_culling;
|
||||
|
||||
/* Primitives */
|
||||
floatVec2 path_start;
|
||||
floatVec2 path_pen;
|
||||
GArray *path_nodes;
|
||||
guint last_path;
|
||||
floatVec2 path_nodes_min;
|
||||
floatVec2 path_nodes_max;
|
||||
|
||||
/* Cache of inverse projection matrix */
|
||||
GLfloat inverse_projection[16];
|
||||
|
||||
/* Textures */
|
||||
GArray *texture_handles;
|
||||
GArray *texture_vertices;
|
||||
GArray *texture_indices;
|
||||
/* The gl texture number that the above vertices apply to. This to
|
||||
detect when a different slice is encountered so that the vertices
|
||||
can be flushed */
|
||||
GLuint texture_current;
|
||||
GLenum texture_target;
|
||||
GLenum texture_wrap_mode;
|
||||
GArray *texture_handles;
|
||||
CoglHandle default_gl_texture_2d_tex;
|
||||
CoglHandle default_gl_texture_rect_tex;
|
||||
|
||||
/* Materials */
|
||||
GArray *material_handles;
|
||||
GArray *material_layer_handles;
|
||||
CoglHandle default_material;
|
||||
CoglHandle source_material;
|
||||
|
||||
/* Batching geometry... */
|
||||
/* We journal the texture rectangles we want to submit to OpenGL so
|
||||
* we have an oppertunity to optimise the final order so that we
|
||||
* can batch things together. */
|
||||
GArray *journal;
|
||||
GArray *logged_vertices;
|
||||
GArray *static_indices;
|
||||
GArray *polygon_vertices;
|
||||
|
||||
/* Some simple caching, to minimize state changes... */
|
||||
CoglHandle current_material;
|
||||
gulong current_material_flags;
|
||||
GArray *current_layers;
|
||||
guint n_texcoord_arrays_enabled;
|
||||
|
||||
/* Framebuffer objects */
|
||||
GArray *fbo_handles;
|
||||
@ -88,6 +93,15 @@ typedef struct
|
||||
/* Vertex buffers */
|
||||
GArray *vertex_buffer_handles;
|
||||
|
||||
/* Primitives */
|
||||
floatVec2 path_start;
|
||||
floatVec2 path_pen;
|
||||
GArray *path_nodes;
|
||||
guint last_path;
|
||||
floatVec2 path_nodes_min;
|
||||
floatVec2 path_nodes_max;
|
||||
CoglHandle stencil_material;
|
||||
|
||||
/* Relying on glext.h to define these */
|
||||
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;
|
||||
COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT;
|
||||
|
@ -309,6 +309,7 @@ typedef GLuint COGLuint;
|
||||
#define CGL_MAX_TEXTURE_STACK_DEPTH GL_MAX_TEXTURE_STACK_DEPTH
|
||||
#define CGL_MAX_VIEWPORT_DIMS GL_MAX_VIEWPORT_DIMS
|
||||
#define CGL_MAX_CLIENT_ATTRIB_STACK_DEPTH GL_MAX_CLIENT_ATTRIB_STACK_DEPTH
|
||||
#define CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS GL_MAX_TEXTURE_UNITS
|
||||
#define CGL_ATTRIB_STACK_DEPTH GL_ATTRIB_STACK_DEPTH
|
||||
#define CGL_CLIENT_ATTRIB_STACK_DEPTH GL_CLIENT_ATTRIB_STACK_DEPTH
|
||||
#define CGL_COLOR_CLEAR_VALUE GL_COLOR_CLEAR_VALUE
|
||||
|
@ -51,13 +51,10 @@ const char *_cogl_error_string(GLenum errorCode);
|
||||
#endif /* COGL_DEBUG */
|
||||
|
||||
#define COGL_ENABLE_BLEND (1<<1)
|
||||
#define COGL_ENABLE_TEXTURE_2D (1<<2)
|
||||
#define COGL_ENABLE_ALPHA_TEST (1<<3)
|
||||
#define COGL_ENABLE_TEXTURE_RECT (1<<4)
|
||||
#define COGL_ENABLE_VERTEX_ARRAY (1<<5)
|
||||
#define COGL_ENABLE_TEXCOORD_ARRAY (1<<6)
|
||||
#define COGL_ENABLE_COLOR_ARRAY (1<<7)
|
||||
#define COGL_ENABLE_BACKFACE_CULLING (1<<8)
|
||||
#define COGL_ENABLE_ALPHA_TEST (1<<2)
|
||||
#define COGL_ENABLE_VERTEX_ARRAY (1<<3)
|
||||
#define COGL_ENABLE_COLOR_ARRAY (1<<4)
|
||||
#define COGL_ENABLE_BACKFACE_CULLING (1<<5)
|
||||
|
||||
gint
|
||||
_cogl_get_format_bpp (CoglPixelFormat format);
|
||||
|
@ -38,31 +38,17 @@
|
||||
|
||||
#define _COGL_MAX_BEZ_RECURSE_DEPTH 16
|
||||
|
||||
void
|
||||
_cogl_rectangle (float x,
|
||||
float y,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
cogl_enable (ctx->color_alpha < 255
|
||||
? COGL_ENABLE_BLEND : 0);
|
||||
|
||||
GE( glRectf (x, y, x + width, y + height) );
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_path_add_node (gboolean new_sub_path,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
CoglPathNode new_node;
|
||||
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
new_node.x = (x);
|
||||
new_node.y = (y);
|
||||
new_node.x = x;
|
||||
new_node.y = y;
|
||||
new_node.path_size = 0;
|
||||
|
||||
if (new_sub_path || ctx->path_nodes->len == 0)
|
||||
@ -89,13 +75,18 @@ _cogl_path_add_node (gboolean new_sub_path,
|
||||
void
|
||||
_cogl_path_stroke_nodes ()
|
||||
{
|
||||
guint path_start = 0;
|
||||
guint path_start = 0;
|
||||
gulong enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
cogl_enable (COGL_ENABLE_VERTEX_ARRAY
|
||||
| (ctx->color_alpha < 255
|
||||
? COGL_ENABLE_BLEND : 0));
|
||||
|
||||
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);
|
||||
|
||||
while (path_start < ctx->path_nodes->len)
|
||||
{
|
||||
@ -106,7 +97,7 @@ _cogl_path_stroke_nodes ()
|
||||
(guchar *) path
|
||||
+ G_STRUCT_OFFSET (CoglPathNode, x)) );
|
||||
GE( glDrawArrays (GL_LINE_STRIP, 0, path->path_size) );
|
||||
|
||||
|
||||
path_start += path->path_size;
|
||||
}
|
||||
}
|
||||
@ -132,12 +123,22 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
CoglPathNode *path,
|
||||
gboolean merge)
|
||||
{
|
||||
guint path_start = 0;
|
||||
guint sub_path_num = 0;
|
||||
float bounds_x;
|
||||
float bounds_y;
|
||||
float bounds_w;
|
||||
float bounds_h;
|
||||
guint path_start = 0;
|
||||
guint sub_path_num = 0;
|
||||
float bounds_x;
|
||||
float bounds_y;
|
||||
float bounds_w;
|
||||
float bounds_h;
|
||||
gulong enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
|
||||
_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);
|
||||
|
||||
enable_flags |=
|
||||
cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
_cogl_path_get_bounds (nodes_min, nodes_max,
|
||||
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
|
||||
@ -159,11 +160,9 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
|
||||
GE( glColorMask (FALSE, FALSE, FALSE, FALSE) );
|
||||
GE( glDepthMask (FALSE) );
|
||||
|
||||
|
||||
while (path_start < path_size)
|
||||
{
|
||||
cogl_enable (COGL_ENABLE_VERTEX_ARRAY);
|
||||
|
||||
GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
|
||||
(guchar *) path
|
||||
+ G_STRUCT_OFFSET (CoglPathNode, x)) );
|
||||
@ -201,17 +200,17 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
GE( glRecti (-1, 1, 1, -1) );
|
||||
GE( glRecti (-1, 1, 1, -1) );
|
||||
cogl_rectangle (-1.0, -1.0, 2, 2);
|
||||
cogl_rectangle (-1.0, -1.0, 2, 2);
|
||||
GE( glPopMatrix () );
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glPopMatrix () );
|
||||
}
|
||||
|
||||
|
||||
GE( glStencilMask (~(GLuint) 0) );
|
||||
GE( glDepthMask (TRUE) );
|
||||
GE( glColorMask (TRUE, TRUE, TRUE, TRUE) );
|
||||
|
||||
|
||||
GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
|
||||
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
|
||||
}
|
||||
@ -226,6 +225,9 @@ _cogl_path_fill_nodes ()
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
_cogl_path_get_bounds (ctx->path_nodes_min, ctx->path_nodes_max,
|
||||
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
|
||||
|
||||
_cogl_add_path_to_stencil_buffer (ctx->path_nodes_min,
|
||||
ctx->path_nodes_max,
|
||||
ctx->path_nodes->len,
|
||||
@ -233,9 +235,6 @@ _cogl_path_fill_nodes ()
|
||||
CoglPathNode, 0),
|
||||
ctx->clip.stencil_used);
|
||||
|
||||
_cogl_path_get_bounds (ctx->path_nodes_min, ctx->path_nodes_max,
|
||||
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
|
||||
|
||||
cogl_rectangle (bounds_x, bounds_y, bounds_w, bounds_h);
|
||||
|
||||
/* The stencil buffer now contains garbage so the clip area needs to
|
||||
|
@ -28,9 +28,9 @@
|
||||
|
||||
#include "cogl-bitmap.h"
|
||||
|
||||
typedef struct _CoglTexture CoglTexture;
|
||||
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
||||
typedef struct _CoglSpanIter CoglSpanIter;
|
||||
typedef struct _CoglTexture CoglTexture;
|
||||
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
||||
typedef struct _CoglSpanIter CoglSpanIter;
|
||||
|
||||
struct _CoglTexSliceSpan
|
||||
{
|
||||
@ -59,7 +59,23 @@ struct _CoglTexture
|
||||
gboolean auto_mipmap;
|
||||
};
|
||||
|
||||
/* To improve batching of geometry when submitting vertices to OpenGL we
|
||||
* log the texture rectangles we want to draw to a journal, so when we
|
||||
* later flush the journal we aim to batch data, and gl draw calls. */
|
||||
typedef struct _CoglJournalEntry
|
||||
{
|
||||
CoglHandle material;
|
||||
gint n_layers;
|
||||
guint32 fallback_mask;
|
||||
GLuint layer0_override_texture;
|
||||
} CoglJournalEntry;
|
||||
|
||||
CoglTexture*
|
||||
_cogl_texture_pointer_from_handle (CoglHandle handle);
|
||||
|
||||
gboolean
|
||||
_cogl_texture_span_has_waste (CoglTexture *tex,
|
||||
gint x_span_index,
|
||||
gint y_span_index);
|
||||
|
||||
#endif /* __COGL_TEXTURE_H */
|
||||
|
1276
gl/cogl-texture.c
1276
gl/cogl-texture.c
File diff suppressed because it is too large
Load Diff
294
gl/cogl.c
294
gl/cogl.c
@ -171,6 +171,10 @@ cogl_check_extension (const gchar *name, const gchar *ext)
|
||||
void
|
||||
cogl_paint_init (const CoglColor *color)
|
||||
{
|
||||
#if COGL_DEBUG
|
||||
fprintf(stderr, "\n ============== Paint Start ================ \n");
|
||||
#endif
|
||||
|
||||
GE( glClearColor (cogl_color_get_red_float (color),
|
||||
cogl_color_get_green_float (color),
|
||||
cogl_color_get_blue_float (color),
|
||||
@ -180,16 +184,16 @@ cogl_paint_init (const CoglColor *color)
|
||||
glDisable (GL_LIGHTING);
|
||||
glDisable (GL_FOG);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Disable the depth test for now as has some strange side effects,
|
||||
* mainly on x/y axis rotation with multiple layers at same depth
|
||||
* (eg rotating text on a bg has very strange effect). Seems no clean
|
||||
* 100% effective way to fix without other odd issues.. So for now
|
||||
* mainly on x/y axis rotation with multiple layers at same depth
|
||||
* (eg rotating text on a bg has very strange effect). Seems no clean
|
||||
* 100% effective way to fix without other odd issues.. So for now
|
||||
* move to application to handle and add cogl_enable_depth_test()
|
||||
* as for custom actors (i.e groups) to enable if need be.
|
||||
*
|
||||
* glEnable (GL_DEPTH_TEST);
|
||||
* glEnable (GL_ALPHA_TEST)
|
||||
* glEnable (GL_DEPTH_TEST);
|
||||
* glEnable (GL_ALPHA_TEST)
|
||||
* glDepthFunc (GL_LEQUAL);
|
||||
* glAlphaFunc (GL_GREATER, 0.1);
|
||||
*/
|
||||
@ -199,33 +203,31 @@ cogl_paint_init (const CoglColor *color)
|
||||
void
|
||||
cogl_push_matrix (void)
|
||||
{
|
||||
glPushMatrix();
|
||||
GE( glPushMatrix() );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_pop_matrix (void)
|
||||
{
|
||||
glPopMatrix();
|
||||
GE( glPopMatrix() );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_scale (float x, float y)
|
||||
{
|
||||
glScalef ((float)(x),
|
||||
(float)(y),
|
||||
1.0);
|
||||
GE( glScalef (x, y, 1.0) );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_translate (float x, float y, float z)
|
||||
{
|
||||
glTranslatef (x, y, z);
|
||||
GE( glTranslatef (x, y, z) );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_rotate (float angle, float x, float y, float z)
|
||||
{
|
||||
glRotatef (angle, x, y, z);
|
||||
GE( glRotatef (angle, x, y, z) );
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
@ -251,7 +253,7 @@ cogl_toggle_flag (CoglContext *ctx,
|
||||
GE( glDisable (gl_flag) );
|
||||
ctx->enable_flags &= ~flag;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -278,7 +280,7 @@ cogl_toggle_client_flag (CoglContext *ctx,
|
||||
GE( glDisableClientState (gl_flag) );
|
||||
ctx->enable_flags &= ~flag;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -289,33 +291,19 @@ cogl_enable (gulong flags)
|
||||
* hope of lessening number GL traffic.
|
||||
*/
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_BLEND,
|
||||
GL_BLEND);
|
||||
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_TEXTURE_2D,
|
||||
GL_TEXTURE_2D);
|
||||
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_BACKFACE_CULLING,
|
||||
GL_CULL_FACE);
|
||||
|
||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_TEXTURE_RECT,
|
||||
GL_TEXTURE_RECTANGLE_ARB);
|
||||
#endif
|
||||
|
||||
cogl_toggle_client_flag (ctx, flags,
|
||||
COGL_ENABLE_VERTEX_ARRAY,
|
||||
GL_VERTEX_ARRAY);
|
||||
|
||||
cogl_toggle_client_flag (ctx, flags,
|
||||
COGL_ENABLE_TEXCOORD_ARRAY,
|
||||
GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
|
||||
cogl_toggle_client_flag (ctx, flags,
|
||||
COGL_ENABLE_COLOR_ARRAY,
|
||||
GL_COLOR_ARRAY);
|
||||
@ -325,25 +313,8 @@ gulong
|
||||
cogl_get_enable ()
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
return ctx->enable_flags;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_blend_func (COGLenum src_factor, COGLenum dst_factor)
|
||||
{
|
||||
/* This function caches the blending setup in the
|
||||
* hope of lessening GL traffic.
|
||||
*/
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (ctx->blend_src_factor != src_factor ||
|
||||
ctx->blend_dst_factor != dst_factor)
|
||||
{
|
||||
glBlendFunc (src_factor, dst_factor);
|
||||
ctx->blend_src_factor = src_factor;
|
||||
ctx->blend_dst_factor = dst_factor;
|
||||
}
|
||||
return ctx->enable_flags;
|
||||
}
|
||||
|
||||
void
|
||||
@ -351,14 +322,14 @@ cogl_enable_depth_test (gboolean setting)
|
||||
{
|
||||
if (setting)
|
||||
{
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glEnable (GL_ALPHA_TEST);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
glAlphaFunc (GL_GREATER, 0.1);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDisable (GL_ALPHA_TEST);
|
||||
}
|
||||
}
|
||||
@ -375,21 +346,19 @@ void
|
||||
cogl_set_source_color (const CoglColor *color)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
glColor4ub (cogl_color_get_red_byte (color),
|
||||
cogl_color_get_green_byte (color),
|
||||
cogl_color_get_blue_byte (color),
|
||||
cogl_color_get_alpha_byte (color));
|
||||
|
||||
/* Store alpha for proper blending enables */
|
||||
ctx->color_alpha = cogl_color_get_alpha_byte (color);
|
||||
|
||||
/* In case cogl_set_source_texture was previously used... */
|
||||
cogl_material_remove_layer (ctx->default_material, 0);
|
||||
|
||||
cogl_material_set_color (ctx->default_material, color);
|
||||
cogl_set_source (ctx->default_material);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_matrix (const GLfloat *matrix, GLfloat *vertex)
|
||||
apply_matrix (const float *matrix, float *vertex)
|
||||
{
|
||||
int x, y;
|
||||
GLfloat vertex_out[4] = { 0 };
|
||||
float vertex_out[4] = { 0 };
|
||||
|
||||
for (y = 0; y < 4; y++)
|
||||
for (x = 0; x < 4; x++)
|
||||
@ -399,7 +368,9 @@ apply_matrix (const GLfloat *matrix, GLfloat *vertex)
|
||||
}
|
||||
|
||||
static void
|
||||
project_vertex (GLfloat *modelview, GLfloat *project, GLfloat *vertex)
|
||||
project_vertex (float *modelview,
|
||||
float *project,
|
||||
float *vertex)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -414,8 +385,8 @@ project_vertex (GLfloat *modelview, GLfloat *project, GLfloat *vertex)
|
||||
|
||||
static void
|
||||
set_clip_plane (GLint plane_num,
|
||||
const GLfloat *vertex_a,
|
||||
const GLfloat *vertex_b)
|
||||
const float *vertex_a,
|
||||
const float *vertex_b)
|
||||
{
|
||||
GLdouble plane[4];
|
||||
GLfloat angle;
|
||||
@ -423,15 +394,15 @@ set_clip_plane (GLint plane_num,
|
||||
|
||||
/* Calculate the angle between the axes and the line crossing the
|
||||
two points */
|
||||
angle = atan2f ((vertex_b[1] - vertex_a[1]),
|
||||
(vertex_b[0] - vertex_a[0])) * 180.0f / G_PI;
|
||||
angle = atan2f (vertex_b[1] - vertex_a[1],
|
||||
vertex_b[0] - vertex_a[0]) * (180.0/G_PI);
|
||||
|
||||
GE( glPushMatrix () );
|
||||
/* Load the identity matrix and multiply by the reverse of the
|
||||
projection matrix so we can specify the plane in screen
|
||||
coordinates */
|
||||
GE( glLoadIdentity () );
|
||||
GE( glMultMatrixf (ctx->inverse_projection) );
|
||||
GE( glMultMatrixf ((GLfloat *) ctx->inverse_projection) );
|
||||
/* Rotate about point a */
|
||||
GE( glTranslatef (vertex_a[0], vertex_a[1], vertex_a[2]) );
|
||||
/* Rotate the plane by the calculated angle so that it will connect
|
||||
@ -439,9 +410,9 @@ set_clip_plane (GLint plane_num,
|
||||
GE( glRotatef (angle, 0.0f, 0.0f, 1.0f) );
|
||||
GE( glTranslatef (-vertex_a[0], -vertex_a[1], -vertex_a[2]) );
|
||||
|
||||
plane[0] = 0.0f;
|
||||
plane[1] = -1.0f;
|
||||
plane[2] = 0.0f;
|
||||
plane[0] = 0;
|
||||
plane[1] = -1.0;
|
||||
plane[2] = 0;
|
||||
plane[3] = vertex_a[1];
|
||||
GE( glClipPlane (plane_num, plane) );
|
||||
|
||||
@ -456,18 +427,11 @@ _cogl_set_clip_planes (float x_offset,
|
||||
{
|
||||
GLfloat modelview[16], projection[16];
|
||||
|
||||
GLfloat vertex_tl[4] = { (x_offset),
|
||||
(y_offset),
|
||||
0.0f, 1.0f };
|
||||
GLfloat vertex_tr[4] = { (x_offset + width),
|
||||
(y_offset),
|
||||
0.0f, 1.0f };
|
||||
GLfloat vertex_bl[4] = { (x_offset),
|
||||
(y_offset + height),
|
||||
0.0f, 1.0f };
|
||||
GLfloat vertex_br[4] = { (x_offset + width),
|
||||
(y_offset + height),
|
||||
0.0f, 1.0f };
|
||||
float vertex_tl[4] = { x_offset, y_offset, 0, 1.0 };
|
||||
float vertex_tr[4] = { x_offset + width, y_offset, 0, 1.0 };
|
||||
float vertex_bl[4] = { x_offset, y_offset + height, 0, 1.0 };
|
||||
float vertex_br[4] = { x_offset + width, y_offset + height,
|
||||
0, 1.0 };
|
||||
|
||||
GE( glGetFloatv (GL_MODELVIEW_MATRIX, modelview) );
|
||||
GE( glGetFloatv (GL_PROJECTION_MATRIX, projection) );
|
||||
@ -485,7 +449,7 @@ _cogl_set_clip_planes (float x_offset,
|
||||
if ((vertex_tl[0] < vertex_tr[0] ? 1 : 0)
|
||||
!= (vertex_bl[1] < vertex_tl[1] ? 1 : 0))
|
||||
{
|
||||
GLfloat temp[4];
|
||||
float temp[4];
|
||||
memcpy (temp, vertex_tl, sizeof (temp));
|
||||
memcpy (vertex_tl, vertex_tr, sizeof (temp));
|
||||
memcpy (vertex_tr, temp, sizeof (temp));
|
||||
@ -512,7 +476,7 @@ _cogl_add_stencil_clip (float x_offset,
|
||||
if (first)
|
||||
{
|
||||
GE( glEnable (GL_STENCIL_TEST) );
|
||||
|
||||
|
||||
/* Initially disallow everything */
|
||||
GE( glClearStencil (0) );
|
||||
GE( glClear (GL_STENCIL_BUFFER_BIT) );
|
||||
@ -545,7 +509,7 @@ _cogl_add_stencil_clip (float x_offset,
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
GE( glRecti (-1, 1, 1, -1) );
|
||||
GE( glRectf (-1, 1, 1, -1) );
|
||||
GE( glPopMatrix () );
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glPopMatrix () );
|
||||
@ -559,14 +523,8 @@ _cogl_add_stencil_clip (float x_offset,
|
||||
void
|
||||
_cogl_set_matrix (const float *matrix)
|
||||
{
|
||||
float float_matrix[16];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
float_matrix[i] = (matrix[i]);
|
||||
|
||||
GE( glLoadIdentity () );
|
||||
GE( glMultMatrixf (float_matrix) );
|
||||
GE( glMultMatrixf (matrix) );
|
||||
}
|
||||
|
||||
void
|
||||
@ -593,13 +551,6 @@ _cogl_disable_clip_planes (void)
|
||||
GE( glDisable (GL_CLIP_PLANE0) );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_alpha_func (COGLenum func,
|
||||
float ref)
|
||||
{
|
||||
GE( glAlphaFunc (func, (ref)) );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_perspective (float fovy,
|
||||
float aspect,
|
||||
@ -637,26 +588,27 @@ cogl_perspective (float fovy,
|
||||
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.0F;
|
||||
M(0,0) = x;
|
||||
M(1,1) = y;
|
||||
M(2,2) = c;
|
||||
M(2,3) = d;
|
||||
M(3,2) = -1.0;
|
||||
|
||||
GE( glMultMatrixf (m) );
|
||||
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
|
||||
/* Calculate and store the inverse of the matrix */
|
||||
memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16);
|
||||
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
|
||||
|
||||
#define m ctx->inverse_projection
|
||||
M(0, 0) = 1.0f / (x);
|
||||
M(1, 1) = 1.0f / (y);
|
||||
M(2, 3) = -1.0f;
|
||||
M(3, 2) = 1.0f / (d);
|
||||
M(3, 3) = (c) / (d);
|
||||
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
|
||||
}
|
||||
|
||||
@ -668,7 +620,7 @@ cogl_frustum (float left,
|
||||
float z_near,
|
||||
float z_far)
|
||||
{
|
||||
GLfloat c, d;
|
||||
float c, d;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -685,24 +637,18 @@ cogl_frustum (float left,
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
|
||||
/* Calculate and store the inverse of the matrix */
|
||||
memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16);
|
||||
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
|
||||
|
||||
c = - (z_far + z_near)
|
||||
/ (z_far - z_near);
|
||||
d = - (2 * (z_far * z_near))
|
||||
/ (z_far - z_near);
|
||||
c = - (z_far + z_near) / (z_far - z_near);
|
||||
d = - (2 * (z_far * z_near)) / (z_far - z_near);
|
||||
|
||||
#define M(row,col) ctx->inverse_projection[col*4+row]
|
||||
M(0,0) = (right - left)
|
||||
/ (2 * z_near);
|
||||
M(0,3) = (right + left)
|
||||
/ (2 * z_near);
|
||||
M(1,1) = (top - bottom)
|
||||
/ (2 * z_near);
|
||||
M(1,3) = (top + bottom)
|
||||
/ (2 * z_near);
|
||||
M(2,3) = -1.0f;
|
||||
M(3,2) = 1.0f / d;
|
||||
M(0,0) = (right - left) / (2 * z_near);
|
||||
M(0,3) = (right + left) / (2 * z_near);
|
||||
M(1,1) = (top - bottom) / (2 * z_near);
|
||||
M(1,3) = (top + bottom) / (2 * z_near);
|
||||
M(2,3) = -1.0;
|
||||
M(3,2) = 1.0 / d;
|
||||
M(3,3) = c / d;
|
||||
#undef M
|
||||
}
|
||||
@ -715,18 +661,22 @@ cogl_viewport (guint width,
|
||||
}
|
||||
|
||||
void
|
||||
cogl_setup_viewport (guint width,
|
||||
guint height,
|
||||
cogl_setup_viewport (guint width,
|
||||
guint height,
|
||||
float fovy,
|
||||
float aspect,
|
||||
float z_near,
|
||||
float z_far)
|
||||
{
|
||||
GLfloat z_camera;
|
||||
GLfloat projection_matrix[16];
|
||||
float z_camera;
|
||||
float projection_matrix[16];
|
||||
|
||||
GE( glViewport (0, 0, width, height) );
|
||||
|
||||
/* For Ortho projection.
|
||||
* glOrthof (0, width << 16, 0, height << 16, -1 << 16, 1 << 16);
|
||||
*/
|
||||
|
||||
cogl_perspective (fovy, aspect, z_near, z_far);
|
||||
|
||||
/*
|
||||
@ -774,9 +724,7 @@ cogl_setup_viewport (guint width,
|
||||
GE( glLoadIdentity () );
|
||||
|
||||
GE( glTranslatef (-0.5f, -0.5f, -z_camera) );
|
||||
GE( glScalef ( 1.0f / width,
|
||||
-1.0f / height,
|
||||
1.0f / width) );
|
||||
GE( glScalef (1.0f / width, -1.0f / height, 1.0f / width) );
|
||||
GE( glTranslatef (0.0f, -1.0 * height, 0.0f) );
|
||||
}
|
||||
|
||||
@ -815,7 +763,7 @@ _cogl_features_init ()
|
||||
GLint num_stencil_bits = 0;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
|
||||
flags = COGL_FEATURE_TEXTURE_READ_PIXELS;
|
||||
|
||||
gl_extensions = (const gchar*) glGetString (GL_EXTENSIONS);
|
||||
@ -827,7 +775,7 @@ _cogl_features_init ()
|
||||
#endif
|
||||
flags |= COGL_FEATURE_TEXTURE_NPOT;
|
||||
}
|
||||
|
||||
|
||||
#ifdef GL_YCBCR_MESA
|
||||
if (cogl_check_extension ("GL_MESA_ycbcr_texture", gl_extensions))
|
||||
{
|
||||
@ -842,47 +790,47 @@ _cogl_features_init ()
|
||||
ctx->pf_glCreateProgramObjectARB =
|
||||
(COGL_PFNGLCREATEPROGRAMOBJECTARBPROC)
|
||||
cogl_get_proc_address ("glCreateProgramObjectARB");
|
||||
|
||||
|
||||
ctx->pf_glCreateShaderObjectARB =
|
||||
(COGL_PFNGLCREATESHADEROBJECTARBPROC)
|
||||
cogl_get_proc_address ("glCreateShaderObjectARB");
|
||||
|
||||
|
||||
ctx->pf_glShaderSourceARB =
|
||||
(COGL_PFNGLSHADERSOURCEARBPROC)
|
||||
cogl_get_proc_address ("glShaderSourceARB");
|
||||
|
||||
|
||||
ctx->pf_glCompileShaderARB =
|
||||
(COGL_PFNGLCOMPILESHADERARBPROC)
|
||||
cogl_get_proc_address ("glCompileShaderARB");
|
||||
|
||||
|
||||
ctx->pf_glAttachObjectARB =
|
||||
(COGL_PFNGLATTACHOBJECTARBPROC)
|
||||
cogl_get_proc_address ("glAttachObjectARB");
|
||||
|
||||
|
||||
ctx->pf_glLinkProgramARB =
|
||||
(COGL_PFNGLLINKPROGRAMARBPROC)
|
||||
cogl_get_proc_address ("glLinkProgramARB");
|
||||
|
||||
|
||||
ctx->pf_glUseProgramObjectARB =
|
||||
(COGL_PFNGLUSEPROGRAMOBJECTARBPROC)
|
||||
cogl_get_proc_address ("glUseProgramObjectARB");
|
||||
|
||||
|
||||
ctx->pf_glGetUniformLocationARB =
|
||||
(COGL_PFNGLGETUNIFORMLOCATIONARBPROC)
|
||||
cogl_get_proc_address ("glGetUniformLocationARB");
|
||||
|
||||
|
||||
ctx->pf_glDeleteObjectARB =
|
||||
(COGL_PFNGLDELETEOBJECTARBPROC)
|
||||
cogl_get_proc_address ("glDeleteObjectARB");
|
||||
|
||||
|
||||
ctx->pf_glGetInfoLogARB =
|
||||
(COGL_PFNGLGETINFOLOGARBPROC)
|
||||
cogl_get_proc_address ("glGetInfoLogARB");
|
||||
|
||||
|
||||
ctx->pf_glGetObjectParameterivARB =
|
||||
(COGL_PFNGLGETOBJECTPARAMETERIVARBPROC)
|
||||
cogl_get_proc_address ("glGetObjectParameterivARB");
|
||||
|
||||
|
||||
ctx->pf_glUniform1fARB =
|
||||
(COGL_PFNGLUNIFORM1FARBPROC)
|
||||
cogl_get_proc_address ("glUniform1fARB");
|
||||
@ -898,7 +846,7 @@ _cogl_features_init ()
|
||||
ctx->pf_glDisableVertexAttribArrayARB =
|
||||
(COGL_PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)
|
||||
cogl_get_proc_address ("glDisableVertexAttribArrayARB");
|
||||
|
||||
|
||||
ctx->pf_glUniform2fARB =
|
||||
(COGL_PFNGLUNIFORM2FARBPROC)
|
||||
cogl_get_proc_address ("glUniform2fARB");
|
||||
@ -962,7 +910,7 @@ _cogl_features_init ()
|
||||
ctx->pf_glUniformMatrix2fvARB =
|
||||
(COGL_PFNGLUNIFORMMATRIX2FVARBPROC)
|
||||
cogl_get_proc_address ("glUniformMatrix2fvARB");
|
||||
|
||||
|
||||
ctx->pf_glUniformMatrix3fvARB =
|
||||
(COGL_PFNGLUNIFORMMATRIX3FVARBPROC)
|
||||
cogl_get_proc_address ("glUniformMatrix3fvARB");
|
||||
@ -1006,50 +954,50 @@ _cogl_features_init ()
|
||||
ctx->pf_glDisableVertexAttribArrayARB)
|
||||
flags |= COGL_FEATURE_SHADERS_GLSL;
|
||||
}
|
||||
|
||||
|
||||
if (cogl_check_extension ("GL_EXT_framebuffer_object", gl_extensions) ||
|
||||
cogl_check_extension ("GL_ARB_framebuffer_object", gl_extensions))
|
||||
{
|
||||
{
|
||||
ctx->pf_glGenRenderbuffersEXT =
|
||||
(COGL_PFNGLGENRENDERBUFFERSEXTPROC)
|
||||
cogl_get_proc_address ("glGenRenderbuffersEXT");
|
||||
|
||||
|
||||
ctx->pf_glDeleteRenderbuffersEXT =
|
||||
(COGL_PFNGLDELETERENDERBUFFERSEXTPROC)
|
||||
cogl_get_proc_address ("glDeleteRenderbuffersEXT");
|
||||
|
||||
|
||||
ctx->pf_glBindRenderbufferEXT =
|
||||
(COGL_PFNGLBINDRENDERBUFFEREXTPROC)
|
||||
cogl_get_proc_address ("glBindRenderbufferEXT");
|
||||
|
||||
|
||||
ctx->pf_glRenderbufferStorageEXT =
|
||||
(COGL_PFNGLRENDERBUFFERSTORAGEEXTPROC)
|
||||
cogl_get_proc_address ("glRenderbufferStorageEXT");
|
||||
|
||||
|
||||
ctx->pf_glGenFramebuffersEXT =
|
||||
(COGL_PFNGLGENFRAMEBUFFERSEXTPROC)
|
||||
cogl_get_proc_address ("glGenFramebuffersEXT");
|
||||
|
||||
|
||||
ctx->pf_glBindFramebufferEXT =
|
||||
(COGL_PFNGLBINDFRAMEBUFFEREXTPROC)
|
||||
cogl_get_proc_address ("glBindFramebufferEXT");
|
||||
|
||||
|
||||
ctx->pf_glFramebufferTexture2DEXT =
|
||||
(COGL_PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
|
||||
cogl_get_proc_address ("glFramebufferTexture2DEXT");
|
||||
|
||||
|
||||
ctx->pf_glFramebufferRenderbufferEXT =
|
||||
(COGL_PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
|
||||
cogl_get_proc_address ("glFramebufferRenderbufferEXT");
|
||||
|
||||
|
||||
ctx->pf_glCheckFramebufferStatusEXT =
|
||||
(COGL_PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
|
||||
cogl_get_proc_address ("glCheckFramebufferStatusEXT");
|
||||
|
||||
|
||||
ctx->pf_glDeleteFramebuffersEXT =
|
||||
(COGL_PFNGLDELETEFRAMEBUFFERSEXTPROC)
|
||||
cogl_get_proc_address ("glDeleteFramebuffersEXT");
|
||||
|
||||
|
||||
if (ctx->pf_glGenRenderbuffersEXT &&
|
||||
ctx->pf_glBindRenderbufferEXT &&
|
||||
ctx->pf_glRenderbufferStorageEXT &&
|
||||
@ -1061,23 +1009,23 @@ _cogl_features_init ()
|
||||
ctx->pf_glDeleteFramebuffersEXT)
|
||||
flags |= COGL_FEATURE_OFFSCREEN;
|
||||
}
|
||||
|
||||
|
||||
if (cogl_check_extension ("GL_EXT_framebuffer_blit", gl_extensions))
|
||||
{
|
||||
ctx->pf_glBlitFramebufferEXT =
|
||||
(COGL_PFNGLBLITFRAMEBUFFEREXTPROC)
|
||||
cogl_get_proc_address ("glBlitFramebufferEXT");
|
||||
|
||||
|
||||
if (ctx->pf_glBlitFramebufferEXT)
|
||||
flags |= COGL_FEATURE_OFFSCREEN_BLIT;
|
||||
}
|
||||
|
||||
|
||||
if (cogl_check_extension ("GL_EXT_framebuffer_multisample", gl_extensions))
|
||||
{
|
||||
ctx->pf_glRenderbufferStorageMultisampleEXT =
|
||||
(COGL_PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
|
||||
cogl_get_proc_address ("glRenderbufferStorageMultisampleEXT");
|
||||
|
||||
|
||||
if (ctx->pf_glRenderbufferStorageMultisampleEXT)
|
||||
flags |= COGL_FEATURE_OFFSCREEN_MULTISAMPLE;
|
||||
}
|
||||
@ -1140,10 +1088,10 @@ CoglFeatureFlags
|
||||
cogl_get_features ()
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
|
||||
if (!ctx->features_cached)
|
||||
_cogl_features_init ();
|
||||
|
||||
|
||||
return ctx->feature_flags;
|
||||
}
|
||||
|
||||
@ -1151,10 +1099,10 @@ gboolean
|
||||
cogl_features_available (CoglFeatureFlags features)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
|
||||
if (!ctx->features_cached)
|
||||
_cogl_features_init ();
|
||||
|
||||
|
||||
return (ctx->feature_flags & features) == features;
|
||||
}
|
||||
|
||||
@ -1205,8 +1153,8 @@ cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha)
|
||||
void
|
||||
cogl_fog_set (const CoglColor *fog_color,
|
||||
float density,
|
||||
float start,
|
||||
float stop)
|
||||
float z_near,
|
||||
float z_far)
|
||||
{
|
||||
GLfloat fogColor[4];
|
||||
|
||||
@ -1222,8 +1170,8 @@ cogl_fog_set (const CoglColor *fog_color,
|
||||
glFogi (GL_FOG_MODE, GL_LINEAR);
|
||||
glHint (GL_FOG_HINT, GL_NICEST);
|
||||
|
||||
glFogf (GL_FOG_DENSITY, (density));
|
||||
glFogf (GL_FOG_START, (start));
|
||||
glFogf (GL_FOG_END, (stop));
|
||||
glFogf (GL_FOG_DENSITY, (GLfloat) density);
|
||||
glFogf (GL_FOG_START, (GLfloat) z_near);
|
||||
glFogf (GL_FOG_END, (GLfloat) z_far);
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,9 @@ libclutterinclude_HEADERS = \
|
||||
$(top_builddir)/clutter/cogl/cogl-shader.h \
|
||||
$(top_builddir)/clutter/cogl/cogl-texture.h \
|
||||
$(top_builddir)/clutter/cogl/cogl-types.h \
|
||||
$(top_builddir)/clutter/cogl/cogl-vertex-buffer.h
|
||||
$(top_builddir)/clutter/cogl/cogl-vertex-buffer.h \
|
||||
$(top_builddir)/clutter/cogl/cogl-material.h \
|
||||
$(top_builddir)/clutter/cogl/cogl-matrix.h
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
|
@ -28,65 +28,108 @@
|
||||
#endif
|
||||
|
||||
#include "cogl.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "cogl-internal.h"
|
||||
#include "cogl-util.h"
|
||||
#include "cogl-context.h"
|
||||
#include "cogl-texture-private.h"
|
||||
#include "cogl-material-private.h"
|
||||
|
||||
#include "cogl-gles2-wrapper.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static CoglContext *_context = NULL;
|
||||
|
||||
gboolean
|
||||
cogl_create_context ()
|
||||
{
|
||||
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
|
||||
gulong enable_flags = 0;
|
||||
|
||||
if (_context != NULL)
|
||||
return FALSE;
|
||||
|
||||
|
||||
/* Allocate context memory */
|
||||
_context = (CoglContext*) g_malloc (sizeof (CoglContext));
|
||||
|
||||
|
||||
/* Init default values */
|
||||
_context->feature_flags = 0;
|
||||
_context->features_cached = FALSE;
|
||||
|
||||
|
||||
_context->enable_flags = 0;
|
||||
_context->color_alpha = 255;
|
||||
|
||||
_context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
|
||||
_context->last_path = 0;
|
||||
|
||||
_context->material_handles = NULL;
|
||||
_context->material_layer_handles = NULL;
|
||||
_context->default_material = cogl_material_new ();
|
||||
_context->source_material = NULL;
|
||||
|
||||
_context->texture_handles = NULL;
|
||||
_context->texture_vertices = g_array_new (FALSE, FALSE,
|
||||
_context->default_gl_texture_2d_tex = COGL_INVALID_HANDLE;
|
||||
_context->default_gl_texture_rect_tex = COGL_INVALID_HANDLE;
|
||||
_context->texture_download_material = COGL_INVALID_HANDLE;
|
||||
|
||||
_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));
|
||||
_context->texture_indices = g_array_new (FALSE, FALSE,
|
||||
sizeof (GLushort));
|
||||
|
||||
_context->current_material = NULL;
|
||||
_context->current_material_flags = 0;
|
||||
_context->current_layers = g_array_new (FALSE, FALSE,
|
||||
sizeof (CoglLayerInfo));
|
||||
_context->n_texcoord_arrays_enabled = 0;
|
||||
|
||||
_context->fbo_handles = NULL;
|
||||
_context->program_handles = NULL;
|
||||
_context->shader_handles = NULL;
|
||||
_context->draw_buffer = COGL_WINDOW_BUFFER;
|
||||
|
||||
_context->shader_handles = NULL;
|
||||
|
||||
_context->program_handles = NULL;
|
||||
|
||||
_context->vertex_buffer_handles = NULL;
|
||||
|
||||
_context->blend_src_factor = CGL_SRC_ALPHA;
|
||||
_context->blend_dst_factor = CGL_ONE_MINUS_SRC_ALPHA;
|
||||
|
||||
_context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
|
||||
_context->last_path = 0;
|
||||
_context->stencil_material = cogl_material_new ();
|
||||
|
||||
/* Init the GLES2 wrapper */
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
cogl_gles2_wrapper_init (&_context->gles2);
|
||||
#endif
|
||||
|
||||
/* Init OpenGL state */
|
||||
GE( cogl_wrap_glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) );
|
||||
GE( glColorMask (TRUE, TRUE, TRUE, FALSE) );
|
||||
GE( glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) );
|
||||
cogl_enable (0);
|
||||
|
||||
/* Initialise the clip stack */
|
||||
_cogl_clip_stack_state_init ();
|
||||
|
||||
|
||||
/* Create default textures used for fall backs */
|
||||
_context->default_gl_texture_2d_tex =
|
||||
cogl_texture_new_from_data (1, /* width */
|
||||
1, /* height */
|
||||
-1, /* max waste */
|
||||
FALSE, /* auto mipmap */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
|
||||
/* internal format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
0, /* auto calc row stride */
|
||||
&default_texture_data);
|
||||
_context->default_gl_texture_rect_tex =
|
||||
cogl_texture_new_from_data (1, /* width */
|
||||
1, /* height */
|
||||
-1, /* max waste */
|
||||
FALSE, /* auto mipmap */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
|
||||
/* internal format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
0, /* auto calc row stride */
|
||||
&default_texture_data);
|
||||
|
||||
cogl_set_source (_context->default_material);
|
||||
cogl_material_flush_gl_state (_context->source_material, NULL);
|
||||
enable_flags =
|
||||
cogl_material_get_cogl_enable_flags (_context->source_material);
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -101,15 +144,6 @@ cogl_destroy_context ()
|
||||
if (_context->path_nodes)
|
||||
g_array_free (_context->path_nodes, TRUE);
|
||||
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
cogl_gles2_wrapper_deinit (&_context->gles2);
|
||||
#endif
|
||||
|
||||
if (_context->texture_vertices)
|
||||
g_array_free (_context->texture_vertices, TRUE);
|
||||
if (_context->texture_indices)
|
||||
g_array_free (_context->texture_indices, TRUE);
|
||||
|
||||
if (_context->texture_handles)
|
||||
g_array_free (_context->texture_handles, TRUE);
|
||||
if (_context->fbo_handles)
|
||||
@ -118,16 +152,36 @@ cogl_destroy_context ()
|
||||
g_array_free (_context->shader_handles, TRUE);
|
||||
if (_context->program_handles)
|
||||
g_array_free (_context->program_handles, TRUE);
|
||||
|
||||
|
||||
if (_context->default_gl_texture_2d_tex)
|
||||
cogl_texture_unref (_context->default_gl_texture_2d_tex);
|
||||
if (_context->default_gl_texture_rect_tex)
|
||||
cogl_texture_unref (_context->default_gl_texture_rect_tex);
|
||||
|
||||
if (_context->default_material)
|
||||
cogl_material_unref (_context->default_material);
|
||||
|
||||
if (_context->journal)
|
||||
g_array_free (_context->journal, TRUE);
|
||||
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);
|
||||
|
||||
g_free (_context);
|
||||
}
|
||||
|
||||
CoglContext *
|
||||
_cogl_context_get_default ()
|
||||
{
|
||||
/* Create if doesn't exists yet */
|
||||
/* Create if doesn't exist yet */
|
||||
if (_context == NULL)
|
||||
cogl_create_context ();
|
||||
|
||||
|
||||
return _context;
|
||||
}
|
||||
|
@ -41,52 +41,69 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
/* Features cache */
|
||||
CoglFeatureFlags feature_flags;
|
||||
gboolean features_cached;
|
||||
|
||||
/* Enable cache */
|
||||
gulong enable_flags;
|
||||
guint8 color_alpha;
|
||||
COGLenum blend_src_factor;
|
||||
COGLenum blend_dst_factor;
|
||||
CoglFeatureFlags feature_flags;
|
||||
gboolean features_cached;
|
||||
|
||||
/* Enable cache */
|
||||
gulong enable_flags;
|
||||
guint8 color_alpha;
|
||||
|
||||
gboolean enable_backface_culling;
|
||||
|
||||
gboolean enable_backface_culling;
|
||||
|
||||
/* Primitives */
|
||||
floatVec2 path_start;
|
||||
floatVec2 path_pen;
|
||||
GArray *path_nodes;
|
||||
guint last_path;
|
||||
floatVec2 path_nodes_min;
|
||||
floatVec2 path_nodes_max;
|
||||
|
||||
/* Cache of inverse projection matrix */
|
||||
float inverse_projection[16];
|
||||
|
||||
/* Materials */
|
||||
GArray *material_handles;
|
||||
GArray *material_layer_handles;
|
||||
CoglHandle default_material;
|
||||
CoglHandle source_material;
|
||||
|
||||
/* Textures */
|
||||
GArray *texture_handles;
|
||||
GArray *texture_vertices;
|
||||
GArray *texture_indices;
|
||||
/* The gl texture number that the above vertices apply to. This to
|
||||
detect when a different slice is encountered so that the vertices
|
||||
can be flushed */
|
||||
GLuint texture_current;
|
||||
GLenum texture_target;
|
||||
GLenum texture_format;
|
||||
GArray *texture_handles;
|
||||
CoglHandle default_gl_texture_2d_tex;
|
||||
CoglHandle default_gl_texture_rect_tex;
|
||||
CoglHandle texture_download_material;
|
||||
|
||||
/* Batching geometry... */
|
||||
/* We journal the texture rectangles we want to submit to OpenGL so
|
||||
* we have an oppertunity to optimise the final order so that we
|
||||
* can batch things together. */
|
||||
GArray *journal;
|
||||
GArray *logged_vertices;
|
||||
GArray *static_indices;
|
||||
GArray *polygon_vertices;
|
||||
|
||||
/* Some simple caching, to minimize state changes... */
|
||||
CoglHandle current_material;
|
||||
gulong current_material_flags;
|
||||
GArray *current_layers;
|
||||
guint n_texcoord_arrays_enabled;
|
||||
|
||||
/* Framebuffer objects */
|
||||
GArray *fbo_handles;
|
||||
CoglBufferTarget draw_buffer;
|
||||
GArray *fbo_handles;
|
||||
CoglBufferTarget draw_buffer;
|
||||
|
||||
/* Shaders */
|
||||
GArray *program_handles;
|
||||
GArray *shader_handles;
|
||||
GArray *shader_handles;
|
||||
|
||||
/* Vertex buffers */
|
||||
GArray *vertex_buffer_handles;
|
||||
/* Programs */
|
||||
GArray *program_handles;
|
||||
|
||||
/* Clip stack */
|
||||
CoglClipStackState clip;
|
||||
CoglClipStackState clip;
|
||||
|
||||
/* Vertex buffers */
|
||||
GArray *vertex_buffer_handles;
|
||||
|
||||
/* Primitives */
|
||||
floatVec2 path_start;
|
||||
floatVec2 path_pen;
|
||||
GArray *path_nodes;
|
||||
guint last_path;
|
||||
floatVec2 path_nodes_min;
|
||||
floatVec2 path_nodes_max;
|
||||
CoglHandle stencil_material;
|
||||
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
CoglGles2Wrapper gles2;
|
||||
@ -95,7 +112,7 @@ typedef struct
|
||||
supported */
|
||||
GLint viewport_store[4];
|
||||
#endif
|
||||
|
||||
|
||||
} CoglContext;
|
||||
|
||||
CoglContext *
|
||||
@ -106,6 +123,6 @@ _cogl_context_get_default ();
|
||||
CoglContext *ctxvar = _cogl_context_get_default (); \
|
||||
if (ctxvar == NULL) return retval;
|
||||
|
||||
#define NO_RETVAL
|
||||
#define NO_RETVAL
|
||||
|
||||
#endif /* __COGL_CONTEXT_H */
|
||||
|
@ -162,7 +162,11 @@ G_BEGIN_DECLS
|
||||
#define CGL_STENCIL_PASS_DEPTH_PASS GL_STENCIL_PASS_DEPTH_PASS
|
||||
#define CGL_STENCIL_REF GL_STENCIL_REF
|
||||
#define CGL_STENCIL_WRITEMASK GL_STENCIL_WRITEMASK
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
#define CGL_MATRIX_MODE 0x0BA0 /* bad style but works for now */
|
||||
#else
|
||||
#define CGL_MATRIX_MODE GL_MATRIX_MODE
|
||||
#endif
|
||||
#define CGL_VIEWPORT GL_VIEWPORT
|
||||
#define CGL_MODELVIEW_STACK_DEPTH GL_MODELVIEW_STACK_DEPTH
|
||||
#define CGL_PROJECTION_STACK_DEPTH GL_PROJECTION_STACK_DEPTH
|
||||
@ -190,7 +194,11 @@ G_BEGIN_DECLS
|
||||
#define CGL_MAX_VIEWPORT_DIMS GL_MAX_VIEWPORT_DIMS
|
||||
#define CGL_MAX_ELEMENTS_VERTICES GL_MAX_ELEMENTS_VERTICES
|
||||
#define CGL_MAX_ELEMENTS_INDICES GL_MAX_ELEMENTS_INDICES
|
||||
#define CGL_MAX_TEXTURE_UNITS GL_MAX_TEXTURE_UNITS
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
#define CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
|
||||
#else
|
||||
#define CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS GL_MAX_TEXTURE_UNITS
|
||||
#endif
|
||||
#define CGL_SUBPIXEL_BITS GL_SUBPIXEL_BITS
|
||||
#define CGL_RED_BITS GL_RED_BITS
|
||||
#define CGL_GREEN_BITS GL_GREEN_BITS
|
||||
@ -315,7 +323,7 @@ G_BEGIN_DECLS
|
||||
|
||||
/* PixelType */
|
||||
/* GL_UNSIGNED_BYTE */
|
||||
#define CGL_UNSIGNED_SHORT_4_4_4_4 GL_UNSIGNED_SHORT_4_4_4_4
|
||||
#define CGL_UNSIGNED_SHORT_4_4_4_4 GL_UNSIGNED_SHORT_4_4_4_4
|
||||
#define CGL_UNSIGNED_SHORT_5_5_5_1 GL_UNSIGNED_SHORT_5_5_5_1
|
||||
#define CGL_UNSIGNED_SHORT_5_6_5 CGL_UNSIGNED_SHORT_5_6_5
|
||||
|
||||
|
@ -206,29 +206,29 @@ cogl_draw_buffer (CoglBufferTarget target, CoglHandle offscreen)
|
||||
from a non-screen buffer */
|
||||
GE( glGetIntegerv (GL_VIEWPORT, ctx->viewport_store) );
|
||||
|
||||
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
|
||||
GE( cogl_wrap_glPushMatrix () );
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
|
||||
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
|
||||
GE( cogl_wrap_glPushMatrix () );
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Override viewport and matrix setup if redirecting
|
||||
from another offscreen buffer */
|
||||
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glLoadIdentity () );
|
||||
|
||||
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glLoadIdentity () );
|
||||
}
|
||||
|
||||
/* Setup new viewport and matrices */
|
||||
GE( glViewport (0, 0, fbo->width, fbo->height) );
|
||||
GE( cogl_wrap_glTranslatef (-1.0, -1.0, 0) );
|
||||
GE( cogl_wrap_glScalef (((float)(2) /
|
||||
GE( glTranslatef (-1.0, -1.0, 0) );
|
||||
GE( glScalef (((float)(2) /
|
||||
(float)(fbo->width)),
|
||||
((float)(2) /
|
||||
(float)(fbo->height)),
|
||||
@ -265,11 +265,11 @@ cogl_draw_buffer (CoglBufferTarget target, CoglHandle offscreen)
|
||||
GE( glViewport (ctx->viewport_store[0], ctx->viewport_store[1],
|
||||
ctx->viewport_store[2], ctx->viewport_store[3]) );
|
||||
|
||||
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
|
||||
GE( cogl_wrap_glPopMatrix () );
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glPopMatrix () );
|
||||
|
||||
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
|
||||
GE( cogl_wrap_glPopMatrix () );
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glPopMatrix () );
|
||||
}
|
||||
|
||||
/* Bind window framebuffer object */
|
||||
|
@ -1,16 +1,20 @@
|
||||
/*** cogl_fixed_fragment_shader_start ***/
|
||||
/*** cogl_fixed_fragment_shader_variables_start ***/
|
||||
|
||||
/* There is no default precision for floats in fragment shaders in
|
||||
GLES 2 so we need to define one */
|
||||
precision mediump float;
|
||||
precision highp float;
|
||||
|
||||
/*** cogl_fixed_fragment_shader_inputs ***/
|
||||
|
||||
/* Inputs from the vertex shader */
|
||||
varying vec4 frag_color;
|
||||
varying vec2 tex_coord;
|
||||
varying float fog_amount;
|
||||
|
||||
/*** cogl_fixed_fragment_shader_texturing_options ***/
|
||||
|
||||
/* Texturing options */
|
||||
uniform sampler2D texture_unit;
|
||||
|
||||
/*** cogl_fixed_fragment_shader_fogging_options ***/
|
||||
|
||||
/* Fogging options */
|
||||
uniform vec4 fog_color;
|
||||
@ -18,28 +22,13 @@ uniform vec4 fog_color;
|
||||
/* Alpha test options */
|
||||
uniform float alpha_test_ref;
|
||||
|
||||
/*** cogl_fixed_fragment_shader_main_declare ***/
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
/*** cogl_fixed_fragment_shader_texture_alpha_only ***/
|
||||
/*** cogl_fixed_fragment_shader_main_start ***/
|
||||
|
||||
/* If the texture only has an alpha channel (eg, with the textures
|
||||
from the pango renderer) then the RGB components will be
|
||||
black. We want to use the RGB from the current color in that
|
||||
case */
|
||||
gl_FragColor = frag_color;
|
||||
gl_FragColor.a *= texture2D (texture_unit, tex_coord).a;
|
||||
|
||||
/*** cogl_fixed_fragment_shader_texture ***/
|
||||
|
||||
/* This pointless extra variable is needed to work around an
|
||||
apparent bug in the PowerVR drivers. Without it the alpha
|
||||
blending seems to stop working */
|
||||
vec4 frag_color_copy = frag_color;
|
||||
gl_FragColor = frag_color_copy * texture2D (texture_unit, tex_coord);
|
||||
|
||||
/*** cogl_fixed_fragment_shader_solid_color ***/
|
||||
gl_FragColor = frag_color;
|
||||
|
||||
/*** cogl_fixed_fragment_shader_fog ***/
|
||||
|
||||
|
@ -1,34 +1,41 @@
|
||||
/*** cogl_fixed_vertex_shader_start ***/
|
||||
/*** cogl_fixed_vertex_shader_per_vertex_attribs ***/
|
||||
|
||||
/* Per vertex attributes */
|
||||
attribute vec4 vertex_attrib;
|
||||
attribute vec4 tex_coord_attrib;
|
||||
attribute vec4 color_attrib;
|
||||
|
||||
/*** cogl_fixed_vertex_shader_transform_matrices ***/
|
||||
|
||||
/* Transformation matrices */
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 mvp_matrix; /* combined modelview and projection matrix */
|
||||
uniform mat4 texture_matrix;
|
||||
|
||||
/*** cogl_fixed_vertex_shader_output_variables ***/
|
||||
|
||||
/* Outputs to the fragment shader */
|
||||
varying vec4 frag_color;
|
||||
varying vec2 tex_coord;
|
||||
varying float fog_amount;
|
||||
|
||||
/*** cogl_fixed_vertex_shader_fogging_options ***/
|
||||
|
||||
/* Fogging options */
|
||||
uniform float fog_density;
|
||||
uniform float fog_start;
|
||||
uniform float fog_end;
|
||||
|
||||
/*** cogl_fixed_vertex_shader_main_start ***/
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
vec4 transformed_tex_coord;
|
||||
|
||||
/* Calculate the transformed position */
|
||||
gl_Position = mvp_matrix * vertex_attrib;
|
||||
|
||||
/* Calculate the transformed texture coordinate */
|
||||
vec4 transformed_tex_coord = texture_matrix * tex_coord_attrib;
|
||||
tex_coord = transformed_tex_coord.st / transformed_tex_coord.q;
|
||||
|
||||
/*** cogl_fixed_vertex_shader_frag_color_start ***/
|
||||
|
||||
/* Pass the interpolated vertex color on to the fragment shader */
|
||||
frag_color = color_attrib;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "cogl-context.h"
|
||||
#include "cogl-shader-private.h"
|
||||
#include "cogl-program.h"
|
||||
#include "cogl-internal.h"
|
||||
|
||||
#define _COGL_GET_GLES2_WRAPPER(wvar, retval) \
|
||||
CoglGles2Wrapper *wvar; \
|
||||
@ -66,9 +67,9 @@
|
||||
while (0)
|
||||
|
||||
#define COGL_GLES2_WRAPPER_VERTEX_ATTRIB 0
|
||||
#define COGL_GLES2_WRAPPER_TEX_COORD_ATTRIB 1
|
||||
#define COGL_GLES2_WRAPPER_COLOR_ATTRIB 2
|
||||
#define COGL_GLES2_WRAPPER_NORMAL_ATTRIB 3
|
||||
#define COGL_GLES2_WRAPPER_COLOR_ATTRIB 1
|
||||
#define COGL_GLES2_WRAPPER_NORMAL_ATTRIB 2
|
||||
|
||||
|
||||
static GLuint
|
||||
cogl_gles2_wrapper_create_shader (GLenum type, const char *source)
|
||||
@ -109,13 +110,19 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
|
||||
memset (wrapper, 0, sizeof (CoglGles2Wrapper));
|
||||
|
||||
/* Initialize the stacks */
|
||||
cogl_wrap_glMatrixMode (GL_TEXTURE);
|
||||
cogl_wrap_glLoadIdentity ();
|
||||
cogl_wrap_glMatrixMode (GL_PROJECTION);
|
||||
cogl_wrap_glLoadIdentity ();
|
||||
cogl_wrap_glMatrixMode (GL_MODELVIEW);
|
||||
cogl_wrap_glLoadIdentity ();
|
||||
|
||||
wrapper->texture_units =
|
||||
g_array_new (FALSE, FALSE, sizeof (CoglGles2WrapperTextureUnit *));
|
||||
|
||||
/* The gl*ActiveTexture wrappers will initialise the texture
|
||||
* stack for the texture unit when it's first activated */
|
||||
cogl_wrap_glActiveTexture (GL_TEXTURE0);
|
||||
cogl_wrap_glClientActiveTexture (GL_TEXTURE0);
|
||||
|
||||
/* Initialize the fogging options */
|
||||
cogl_wrap_glDisable (GL_FOG);
|
||||
cogl_wrap_glFogf (GL_FOG_MODE, GL_LINEAR);
|
||||
@ -137,11 +144,14 @@ cogl_gles2_settings_equal (const CoglGles2WrapperSettings *a,
|
||||
{
|
||||
if (fragment_tests)
|
||||
{
|
||||
if (a->texture_2d_enabled != b->texture_2d_enabled)
|
||||
return FALSE;
|
||||
|
||||
if (a->texture_2d_enabled && a->alpha_only != b->alpha_only)
|
||||
return FALSE;
|
||||
int i;
|
||||
for (i = 0; i < a->n_texture_units; i++)
|
||||
{
|
||||
if (a->texture_units[i].enabled != b->texture_units[i].enabled)
|
||||
return FALSE;
|
||||
if (a->texture_units[i].alpha_only != b->texture_units[i].alpha_only)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (a->alpha_test_enabled != b->alpha_test_enabled)
|
||||
return FALSE;
|
||||
@ -165,6 +175,7 @@ cogl_gles2_get_vertex_shader (const CoglGles2WrapperSettings *settings)
|
||||
GLuint shader_obj;
|
||||
CoglGles2WrapperShader *shader;
|
||||
GSList *node;
|
||||
int i;
|
||||
|
||||
_COGL_GET_GLES2_WRAPPER (w, NULL);
|
||||
|
||||
@ -177,7 +188,47 @@ cogl_gles2_get_vertex_shader (const CoglGles2WrapperSettings *settings)
|
||||
return (CoglGles2WrapperShader *) node->data;
|
||||
|
||||
/* Otherwise create a new shader */
|
||||
shader_source = g_string_new (cogl_fixed_vertex_shader_start);
|
||||
shader_source = g_string_new (cogl_fixed_vertex_shader_per_vertex_attribs);
|
||||
|
||||
for (i = 0; i < settings->n_texture_units; i++)
|
||||
{
|
||||
if (!settings->texture_units[i].enabled)
|
||||
continue;
|
||||
g_string_append_printf (shader_source,
|
||||
"attribute vec4 multi_tex_coord_attrib%d;\n",
|
||||
i);
|
||||
}
|
||||
|
||||
g_string_append (shader_source, cogl_fixed_vertex_shader_transform_matrices);
|
||||
g_string_append_printf (shader_source,
|
||||
"uniform mat4 texture_matrix[%d];\n",
|
||||
settings->n_texture_units);
|
||||
|
||||
g_string_append (shader_source, cogl_fixed_vertex_shader_output_variables);
|
||||
g_string_append_printf (shader_source,
|
||||
"varying vec2 tex_coord[%d];",
|
||||
settings->n_texture_units);
|
||||
|
||||
g_string_append (shader_source, cogl_fixed_vertex_shader_fogging_options);
|
||||
g_string_append (shader_source, cogl_fixed_vertex_shader_main_start);
|
||||
|
||||
for (i = 0; i < settings->n_texture_units; i++)
|
||||
{
|
||||
if (!settings->texture_units[i].enabled)
|
||||
continue;
|
||||
|
||||
g_string_append_printf (shader_source,
|
||||
"transformed_tex_coord = "
|
||||
"texture_matrix[%d] "
|
||||
" * multi_tex_coord_attrib%d;\n",
|
||||
i, i);
|
||||
g_string_append_printf (shader_source,
|
||||
"tex_coord[%d] = transformed_tex_coord.st "
|
||||
" / transformed_tex_coord.q;\n",
|
||||
i);
|
||||
}
|
||||
|
||||
g_string_append (shader_source, cogl_fixed_vertex_shader_frag_color_start);
|
||||
|
||||
if (settings->fog_enabled)
|
||||
{
|
||||
@ -207,10 +258,10 @@ cogl_gles2_get_vertex_shader (const CoglGles2WrapperSettings *settings)
|
||||
shader_source->str);
|
||||
|
||||
g_string_free (shader_source, TRUE);
|
||||
|
||||
|
||||
if (shader_obj == 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
shader = g_slice_new (CoglGles2WrapperShader);
|
||||
shader->shader = shader_obj;
|
||||
shader->settings = *settings;
|
||||
@ -228,6 +279,7 @@ cogl_gles2_get_fragment_shader (const CoglGles2WrapperSettings *settings)
|
||||
GLuint shader_obj;
|
||||
CoglGles2WrapperShader *shader;
|
||||
GSList *node;
|
||||
int i;
|
||||
|
||||
_COGL_GET_GLES2_WRAPPER (w, NULL);
|
||||
|
||||
@ -240,18 +292,61 @@ cogl_gles2_get_fragment_shader (const CoglGles2WrapperSettings *settings)
|
||||
return (CoglGles2WrapperShader *) node->data;
|
||||
|
||||
/* Otherwise create a new shader */
|
||||
shader_source = g_string_new (cogl_fixed_fragment_shader_start);
|
||||
if (settings->texture_2d_enabled)
|
||||
shader_source = g_string_new (cogl_fixed_fragment_shader_variables_start);
|
||||
|
||||
g_string_append (shader_source, cogl_fixed_fragment_shader_inputs);
|
||||
g_string_append_printf (shader_source,
|
||||
"varying vec2 tex_coord[%d];\n",
|
||||
settings->n_texture_units);
|
||||
|
||||
g_string_append (shader_source, cogl_fixed_fragment_shader_texturing_options);
|
||||
g_string_append_printf (shader_source,
|
||||
"uniform sampler2D texture_unit[%d];\n",
|
||||
settings->n_texture_units);
|
||||
|
||||
g_string_append (shader_source, cogl_fixed_fragment_shader_fogging_options);
|
||||
|
||||
g_string_append (shader_source, cogl_fixed_fragment_shader_main_declare);
|
||||
|
||||
g_string_append (shader_source, cogl_fixed_fragment_shader_main_start);
|
||||
|
||||
/* This pointless extra variable is needed to work around an
|
||||
apparent bug in the PowerVR drivers. Without it the alpha
|
||||
blending seems to stop working */
|
||||
/* g_string_append (shader_source, "gl_FragColor = frag_color;\n");
|
||||
*/
|
||||
g_string_append (shader_source,
|
||||
"vec4 frag_color_copy = frag_color;\n");
|
||||
g_string_append (shader_source, "gl_FragColor = frag_color;\n");
|
||||
|
||||
for (i = 0; i < settings->n_texture_units; i++)
|
||||
{
|
||||
if (settings->alpha_only)
|
||||
g_string_append (shader_source,
|
||||
cogl_fixed_fragment_shader_texture_alpha_only);
|
||||
if (settings->texture_units[i].alpha_only)
|
||||
{
|
||||
/* If the texture only has an alpha channel (eg, with the textures
|
||||
from the pango renderer) then the RGB components will be
|
||||
black. We want to use the RGB from the current color in that
|
||||
case */
|
||||
g_string_append_printf (
|
||||
shader_source,
|
||||
"gl_FragColor.a *= "
|
||||
"texture2D (texture_unit[%d], tex_coord[%d]).a;\n",
|
||||
i, i);
|
||||
}
|
||||
else
|
||||
g_string_append (shader_source,
|
||||
cogl_fixed_fragment_shader_texture);
|
||||
{
|
||||
g_string_append_printf (
|
||||
shader_source,
|
||||
"gl_FragColor *= "
|
||||
"texture2D (texture_unit[%d], tex_coord[%d]);\n",
|
||||
i, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
g_string_append (shader_source, cogl_fixed_fragment_shader_solid_color);
|
||||
/* FIXME */
|
||||
g_string_append (shader_source, "gl_FragColor.r = 1.0;\n");
|
||||
g_string_append (shader_source, "gl_FragColor.g = 1.0;\n");
|
||||
if (i == 0)
|
||||
g_string_append (shader_source, "gl_FragColor = frag_color;\n");
|
||||
|
||||
if (settings->fog_enabled)
|
||||
g_string_append (shader_source, cogl_fixed_fragment_shader_fog);
|
||||
@ -294,10 +389,10 @@ cogl_gles2_get_fragment_shader (const CoglGles2WrapperSettings *settings)
|
||||
shader_source->str);
|
||||
|
||||
g_string_free (shader_source, TRUE);
|
||||
|
||||
|
||||
if (shader_obj == 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
shader = g_slice_new (CoglGles2WrapperShader);
|
||||
shader->shader = shader_obj;
|
||||
shader->settings = *settings;
|
||||
@ -308,6 +403,69 @@ cogl_gles2_get_fragment_shader (const CoglGles2WrapperSettings *settings)
|
||||
return shader;
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_gles2_wrapper_get_locations (GLuint program,
|
||||
CoglGles2WrapperSettings *settings,
|
||||
CoglGles2WrapperUniforms *uniforms,
|
||||
CoglGles2WrapperAttributes *attribs)
|
||||
{
|
||||
int i;
|
||||
|
||||
uniforms->mvp_matrix_uniform
|
||||
= glGetUniformLocation (program, "mvp_matrix");
|
||||
uniforms->modelview_matrix_uniform
|
||||
= glGetUniformLocation (program, "modelview_matrix");
|
||||
|
||||
uniforms->texture_matrix_uniforms =
|
||||
g_array_new (FALSE, FALSE, sizeof (GLint));
|
||||
uniforms->texture_sampler_uniforms =
|
||||
g_array_new (FALSE, FALSE, sizeof (GLint));
|
||||
attribs->multi_texture_coords =
|
||||
g_array_new (FALSE, FALSE, sizeof (GLint));
|
||||
for (i = 0; i < settings->n_texture_units; i++)
|
||||
{
|
||||
char *matrix_var_name = g_strdup_printf ("texture_matrix[%d]", i);
|
||||
char *sampler_var_name = g_strdup_printf ("texture_unit[%d]", i);
|
||||
char *tex_coord_var_name =
|
||||
g_strdup_printf ("multi_tex_coord_attrib%d", i);
|
||||
GLint location;
|
||||
|
||||
location = glGetUniformLocation (program, matrix_var_name);
|
||||
g_array_append_val (uniforms->texture_matrix_uniforms, location);
|
||||
location = glGetUniformLocation (program, sampler_var_name);
|
||||
g_array_append_val (uniforms->texture_sampler_uniforms, location);
|
||||
location = glGetAttribLocation (program, tex_coord_var_name);
|
||||
g_array_append_val (attribs->multi_texture_coords, location);
|
||||
|
||||
g_free (tex_coord_var_name);
|
||||
g_free (sampler_var_name);
|
||||
g_free (matrix_var_name);
|
||||
}
|
||||
|
||||
uniforms->fog_density_uniform
|
||||
= glGetUniformLocation (program, "fog_density");
|
||||
uniforms->fog_start_uniform
|
||||
= glGetUniformLocation (program, "fog_start");
|
||||
uniforms->fog_end_uniform
|
||||
= glGetUniformLocation (program, "fog_end");
|
||||
uniforms->fog_color_uniform
|
||||
= glGetUniformLocation (program, "fog_color");
|
||||
|
||||
uniforms->alpha_test_ref_uniform
|
||||
= glGetUniformLocation (program, "alpha_test_ref");
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_gles2_wrapper_bind_attributes (GLuint program)
|
||||
{
|
||||
glBindAttribLocation (program, COGL_GLES2_WRAPPER_VERTEX_ATTRIB,
|
||||
"vertex_attrib");
|
||||
glBindAttribLocation (program, COGL_GLES2_WRAPPER_COLOR_ATTRIB,
|
||||
"color_attrib");
|
||||
glBindAttribLocation (program, COGL_GLES2_WRAPPER_NORMAL_ATTRIB,
|
||||
"normal_attrib");
|
||||
}
|
||||
|
||||
static CoglGles2WrapperProgram *
|
||||
cogl_gles2_wrapper_get_program (const CoglGles2WrapperSettings *settings)
|
||||
{
|
||||
@ -403,61 +561,22 @@ cogl_gles2_wrapper_get_program (const CoglGles2WrapperSettings *settings)
|
||||
}
|
||||
|
||||
program->settings = *settings;
|
||||
|
||||
cogl_gles2_wrapper_get_uniforms (program->program, &program->uniforms);
|
||||
|
||||
cogl_gles2_wrapper_get_locations (program->program,
|
||||
&program->settings,
|
||||
&program->uniforms,
|
||||
&program->attributes);
|
||||
|
||||
/* We haven't tried to get a location for any of the custom uniforms
|
||||
yet */
|
||||
for (i = 0; i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++)
|
||||
program->custom_uniforms[i] = COGL_GLES2_UNBOUND_CUSTOM_UNIFORM;
|
||||
|
||||
|
||||
w->compiled_programs = g_slist_append (w->compiled_programs, program);
|
||||
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_gles2_wrapper_bind_attributes (GLuint program)
|
||||
{
|
||||
glBindAttribLocation (program, COGL_GLES2_WRAPPER_VERTEX_ATTRIB,
|
||||
"vertex_attrib");
|
||||
glBindAttribLocation (program, COGL_GLES2_WRAPPER_TEX_COORD_ATTRIB,
|
||||
"tex_coord_attrib");
|
||||
glBindAttribLocation (program, COGL_GLES2_WRAPPER_COLOR_ATTRIB,
|
||||
"color_attrib");
|
||||
glBindAttribLocation (program, COGL_GLES2_WRAPPER_NORMAL_ATTRIB,
|
||||
"normal_attrib");
|
||||
}
|
||||
|
||||
void
|
||||
cogl_gles2_wrapper_get_uniforms (GLuint program,
|
||||
CoglGles2WrapperUniforms *uniforms)
|
||||
{
|
||||
uniforms->mvp_matrix_uniform
|
||||
= glGetUniformLocation (program, "mvp_matrix");
|
||||
uniforms->modelview_matrix_uniform
|
||||
= glGetUniformLocation (program, "modelview_matrix");
|
||||
uniforms->texture_matrix_uniform
|
||||
= glGetUniformLocation (program, "texture_matrix");
|
||||
uniforms->bound_texture_uniform
|
||||
= glGetUniformLocation (program, "texture_unit");
|
||||
|
||||
uniforms->fog_density_uniform
|
||||
= glGetUniformLocation (program, "fog_density");
|
||||
uniforms->fog_start_uniform
|
||||
= glGetUniformLocation (program, "fog_start");
|
||||
uniforms->fog_end_uniform
|
||||
= glGetUniformLocation (program, "fog_end");
|
||||
uniforms->fog_color_uniform
|
||||
= glGetUniformLocation (program, "fog_color");
|
||||
|
||||
uniforms->alpha_test_ref_uniform
|
||||
= glGetUniformLocation (program, "alpha_test_ref");
|
||||
|
||||
uniforms->texture_unit_uniform
|
||||
= glGetUniformLocation (program, "texture_unit");
|
||||
}
|
||||
|
||||
void
|
||||
cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
|
||||
{
|
||||
@ -493,9 +612,11 @@ cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
|
||||
g_free (wrapper->custom_uniforms[i].v.array);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
cogl_gles2_wrapper_update_matrix (CoglGles2Wrapper *wrapper, GLenum matrix_num)
|
||||
{
|
||||
CoglGles2WrapperTextureUnit *texture_unit;
|
||||
|
||||
switch (matrix_num)
|
||||
{
|
||||
default:
|
||||
@ -509,7 +630,11 @@ cogl_gles2_wrapper_update_matrix (CoglGles2Wrapper *wrapper, GLenum matrix_num)
|
||||
break;
|
||||
|
||||
case GL_TEXTURE:
|
||||
wrapper->dirty_uniforms |= COGL_GLES2_DIRTY_TEXTURE_MATRIX;
|
||||
wrapper->dirty_uniforms |= COGL_GLES2_DIRTY_TEXTURE_MATRICES;
|
||||
texture_unit = g_array_index (wrapper->texture_units,
|
||||
CoglGles2WrapperTextureUnit *,
|
||||
wrapper->active_texture_unit);
|
||||
texture_unit->dirty_matrix = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -542,11 +667,19 @@ cogl_wrap_glPushMatrix ()
|
||||
break;
|
||||
|
||||
case GL_TEXTURE:
|
||||
src = w->texture_stack + w->texture_stack_pos * 16;
|
||||
w->texture_stack_pos = (w->texture_stack_pos + 1)
|
||||
& (COGL_GLES2_TEXTURE_STACK_SIZE - 1);
|
||||
dst = w->texture_stack + w->texture_stack_pos * 16;
|
||||
break;
|
||||
{
|
||||
CoglGles2WrapperTextureUnit *texture_unit;
|
||||
texture_unit = g_array_index (w->texture_units,
|
||||
CoglGles2WrapperTextureUnit *,
|
||||
w->active_texture_unit);
|
||||
src = texture_unit->texture_stack
|
||||
+ texture_unit->texture_stack_pos * 16;
|
||||
texture_unit->texture_stack_pos = (texture_unit->texture_stack_pos + 1)
|
||||
& (COGL_GLES2_TEXTURE_STACK_SIZE - 1);
|
||||
dst = texture_unit->texture_stack
|
||||
+ texture_unit->texture_stack_pos * 16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the old matrix to the new position */
|
||||
@ -556,6 +689,7 @@ cogl_wrap_glPushMatrix ()
|
||||
void
|
||||
cogl_wrap_glPopMatrix ()
|
||||
{
|
||||
CoglGles2WrapperTextureUnit *texture_unit;
|
||||
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
|
||||
|
||||
/* Decrement the stack pointer */
|
||||
@ -573,7 +707,10 @@ cogl_wrap_glPopMatrix ()
|
||||
break;
|
||||
|
||||
case GL_TEXTURE:
|
||||
w->texture_stack_pos = (w->texture_stack_pos - 1)
|
||||
texture_unit = g_array_index (w->texture_units,
|
||||
CoglGles2WrapperTextureUnit *,
|
||||
w->active_texture_unit);
|
||||
texture_unit->texture_stack_pos = (texture_unit->texture_stack_pos - 1)
|
||||
& (COGL_GLES2_TEXTURE_STACK_SIZE - 1);
|
||||
break;
|
||||
}
|
||||
@ -593,6 +730,8 @@ cogl_wrap_glMatrixMode (GLenum mode)
|
||||
static float *
|
||||
cogl_gles2_get_matrix_stack_top (CoglGles2Wrapper *wrapper)
|
||||
{
|
||||
CoglGles2WrapperTextureUnit *texture_unit;
|
||||
|
||||
switch (wrapper->matrix_mode)
|
||||
{
|
||||
default:
|
||||
@ -603,7 +742,12 @@ cogl_gles2_get_matrix_stack_top (CoglGles2Wrapper *wrapper)
|
||||
return wrapper->projection_stack + wrapper->projection_stack_pos * 16;
|
||||
|
||||
case GL_TEXTURE:
|
||||
return wrapper->texture_stack + wrapper->texture_stack_pos * 16;
|
||||
|
||||
texture_unit = g_array_index (wrapper->texture_units,
|
||||
CoglGles2WrapperTextureUnit *,
|
||||
wrapper->active_texture_unit);
|
||||
return texture_unit->texture_stack
|
||||
+ texture_unit->texture_stack_pos * 16;
|
||||
}
|
||||
}
|
||||
|
||||
@ -734,7 +878,7 @@ cogl_wrap_glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
|
||||
float anglef = (angle) * G_PI / 180.0f;
|
||||
float c = cosf (anglef);
|
||||
float s = sinf (anglef);
|
||||
|
||||
|
||||
matrix[0] = xf * xf * (1.0f - c) + c;
|
||||
matrix[1] = yf * xf * (1.0f - c) + zf * s;
|
||||
matrix[2] = xf * zf * (1.0f - c) - yf * s;
|
||||
@ -791,8 +935,22 @@ void
|
||||
cogl_wrap_glTexCoordPointer (GLint size, GLenum type, GLsizei stride,
|
||||
const GLvoid *pointer)
|
||||
{
|
||||
glVertexAttribPointer (COGL_GLES2_WRAPPER_TEX_COORD_ATTRIB, size, type,
|
||||
GL_FALSE, stride, pointer);
|
||||
int active_unit;
|
||||
CoglGles2WrapperTextureUnit *texture_unit;
|
||||
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
|
||||
|
||||
active_unit = w->active_client_texture_unit;
|
||||
|
||||
texture_unit = g_array_index (w->texture_units,
|
||||
CoglGles2WrapperTextureUnit *,
|
||||
active_unit);
|
||||
texture_unit->texture_coords_size = size;
|
||||
texture_unit->texture_coords_type = type;
|
||||
texture_unit->texture_coords_stride = stride;
|
||||
texture_unit->texture_coords_pointer = pointer;
|
||||
|
||||
w->dirty_attribute_pointers
|
||||
|= COGL_GLES2_DIRTY_TEX_COORD_VERTEX_ATTRIB;
|
||||
}
|
||||
|
||||
void
|
||||
@ -926,7 +1084,7 @@ cogl_wrap_prepare_for_draw (void)
|
||||
cogl_gles2_wrapper_mult_matrix (mvp_matrix,
|
||||
w->projection_stack
|
||||
+ w->projection_stack_pos * 16,
|
||||
modelview_matrix);
|
||||
modelview_matrix);
|
||||
|
||||
if (program->uniforms.mvp_matrix_uniform != -1)
|
||||
glUniformMatrix4fv (program->uniforms.mvp_matrix_uniform, 1,
|
||||
@ -935,11 +1093,28 @@ cogl_wrap_prepare_for_draw (void)
|
||||
glUniformMatrix4fv (program->uniforms.modelview_matrix_uniform, 1,
|
||||
GL_FALSE, modelview_matrix);
|
||||
}
|
||||
if ((w->dirty_uniforms & COGL_GLES2_DIRTY_TEXTURE_MATRIX)
|
||||
&& program->uniforms.texture_matrix_uniform != -1)
|
||||
glUniformMatrix4fv (program->uniforms.texture_matrix_uniform, 1,
|
||||
GL_FALSE,
|
||||
w->texture_stack + w->texture_stack_pos * 16);
|
||||
if ((w->dirty_uniforms & COGL_GLES2_DIRTY_TEXTURE_MATRICES))
|
||||
{
|
||||
int i;
|
||||
|
||||
/* TODO - we should probably have a per unit dirty flag too */
|
||||
|
||||
for (i = 0; i < program->uniforms.texture_matrix_uniforms->len; i++)
|
||||
{
|
||||
CoglGles2WrapperTextureUnit *texture_unit;
|
||||
GLint uniform =
|
||||
g_array_index (program->uniforms.texture_matrix_uniforms,
|
||||
GLint, i);
|
||||
|
||||
texture_unit = g_array_index (w->texture_units,
|
||||
CoglGles2WrapperTextureUnit *,
|
||||
i);
|
||||
if (uniform != -1)
|
||||
glUniformMatrix4fv (uniform, 1, GL_FALSE,
|
||||
texture_unit->texture_stack
|
||||
+ texture_unit->texture_stack_pos * 16);
|
||||
}
|
||||
}
|
||||
|
||||
if ((w->dirty_uniforms & COGL_GLES2_DIRTY_FOG_DENSITY)
|
||||
&& program->uniforms.fog_density_uniform != -1)
|
||||
@ -956,9 +1131,22 @@ cogl_wrap_prepare_for_draw (void)
|
||||
glUniform1f (program->uniforms.alpha_test_ref_uniform,
|
||||
w->alpha_test_ref);
|
||||
|
||||
if ((w->dirty_uniforms & COGL_GLES2_DIRTY_TEXTURE_UNIT)
|
||||
&& program->uniforms.texture_unit_uniform != -1)
|
||||
glUniform1i (program->uniforms.texture_unit_uniform, 0);
|
||||
if ((w->dirty_uniforms & COGL_GLES2_DIRTY_TEXTURE_UNITS))
|
||||
{
|
||||
int i;
|
||||
|
||||
/* TODO - we should probably have a per unit dirty flag too */
|
||||
|
||||
for (i = 0; i < program->uniforms.texture_sampler_uniforms->len; i++)
|
||||
{
|
||||
GLint uniform =
|
||||
g_array_index (program->uniforms.texture_sampler_uniforms,
|
||||
GLint, i);
|
||||
|
||||
if (uniform != -1)
|
||||
glUniform1i (uniform, i);
|
||||
}
|
||||
}
|
||||
|
||||
w->dirty_uniforms = 0;
|
||||
}
|
||||
@ -986,10 +1174,70 @@ cogl_wrap_prepare_for_draw (void)
|
||||
&w->custom_uniforms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
w->dirty_custom_uniforms = 0;
|
||||
}
|
||||
|
||||
if (w->dirty_attribute_pointers
|
||||
& COGL_GLES2_DIRTY_TEX_COORD_VERTEX_ATTRIB)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* TODO - coverage test */
|
||||
for (i = 0; i < w->settings.n_texture_units; i++)
|
||||
{
|
||||
GLint tex_coord_var_index;
|
||||
CoglGles2WrapperTextureUnit *texture_unit;
|
||||
|
||||
if (!w->settings.texture_units[i].enabled)
|
||||
continue;
|
||||
|
||||
texture_unit = g_array_index (w->texture_units,
|
||||
CoglGles2WrapperTextureUnit *,
|
||||
w->active_texture_unit);
|
||||
if (!texture_unit->texture_coords_enabled)
|
||||
continue;
|
||||
|
||||
/* TODO - we should probably have a per unit dirty flag too */
|
||||
|
||||
/* TODO - coverage test */
|
||||
tex_coord_var_index =
|
||||
g_array_index (program->attributes.multi_texture_coords,
|
||||
GLint, i);
|
||||
glVertexAttribPointer (tex_coord_var_index,
|
||||
texture_unit->texture_coords_size,
|
||||
texture_unit->texture_coords_type,
|
||||
GL_FALSE,
|
||||
texture_unit->texture_coords_stride,
|
||||
texture_unit->texture_coords_pointer);
|
||||
}
|
||||
}
|
||||
|
||||
if (w->dirty_vertex_attrib_enables)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* TODO - coverage test */
|
||||
|
||||
/* TODO - we should probably have a per unit dirty flag too */
|
||||
|
||||
for (i = 0; i < w->texture_units->len; i++)
|
||||
{
|
||||
CoglGles2WrapperTextureUnit *texture_unit =
|
||||
g_array_index (w->texture_units,
|
||||
CoglGles2WrapperTextureUnit *,
|
||||
w->active_texture_unit);
|
||||
if (texture_unit->texture_coords_enabled)
|
||||
glEnableVertexAttribArray (
|
||||
g_array_index (program->attributes.multi_texture_coords,
|
||||
GLint, i));
|
||||
else
|
||||
glDisableVertexAttribArray (
|
||||
g_array_index (program->attributes.multi_texture_coords,
|
||||
GLint, i));
|
||||
w->dirty_vertex_attrib_enables = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1020,7 +1268,10 @@ cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture,
|
||||
/* We need to keep track of whether the texture is alpha-only
|
||||
because the emulation of GL_MODULATE needs to work differently in
|
||||
that case */
|
||||
_COGL_GLES2_CHANGE_SETTING (w, alpha_only, internal_format == GL_ALPHA);
|
||||
_COGL_GLES2_CHANGE_SETTING (
|
||||
w, texture_units[w->active_texture_unit].alpha_only,
|
||||
internal_format == GL_ALPHA);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -1031,6 +1282,79 @@ cogl_wrap_glTexEnvf (GLenum target, GLenum pname, GLfloat param)
|
||||
nothing needs to be done here. */
|
||||
}
|
||||
|
||||
static void
|
||||
realize_texture_units (CoglGles2Wrapper *w, int texture_unit_index)
|
||||
{
|
||||
/* We save the active texture unit since we may need to temporarily
|
||||
* change this to initialise each new texture unit and we want to
|
||||
* restore the active unit afterwards */
|
||||
int initial_active_unit = w->active_texture_unit;
|
||||
|
||||
if (texture_unit_index >= w->settings.n_texture_units)
|
||||
{
|
||||
int n_new_texture_units =
|
||||
texture_unit_index + 1 - w->settings.n_texture_units;
|
||||
GLint prev_mode;
|
||||
int i;
|
||||
|
||||
w->settings.texture_units =
|
||||
g_realloc (w->settings.texture_units,
|
||||
texture_unit_index + 1
|
||||
* sizeof (CoglGles2WrapperTextureUnitSettings));
|
||||
|
||||
/* We will need to set the matrix mode to GL_TEXTURE to
|
||||
* initialise any new texture units, so we save the current
|
||||
* mode for restoring afterwards */
|
||||
GE( cogl_wrap_glGetIntegerv (CGL_MATRIX_MODE, &prev_mode));
|
||||
|
||||
for (i = 0; i < n_new_texture_units; i++)
|
||||
{
|
||||
CoglGles2WrapperTextureUnit *new_unit;
|
||||
CoglGles2WrapperTextureUnitSettings *new_unit_settings;
|
||||
|
||||
new_unit = g_new0 (CoglGles2WrapperTextureUnit, 1);
|
||||
g_array_append_val (w->texture_units, new_unit);
|
||||
|
||||
w->active_texture_unit = i;
|
||||
GE( cogl_wrap_glMatrixMode (GL_TEXTURE));
|
||||
GE( cogl_wrap_glLoadIdentity ());
|
||||
|
||||
new_unit_settings =
|
||||
&w->settings.texture_units[w->settings.n_texture_units + i];
|
||||
new_unit_settings->enabled = FALSE;
|
||||
new_unit_settings->alpha_only = FALSE;
|
||||
}
|
||||
|
||||
GE( cogl_wrap_glMatrixMode ((GLenum)prev_mode));
|
||||
|
||||
w->settings.n_texture_units = w->texture_units->len;
|
||||
}
|
||||
|
||||
w->active_texture_unit = initial_active_unit;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_wrap_glClientActiveTexture (GLenum texture)
|
||||
{
|
||||
int texture_unit_index = texture - GL_TEXTURE0;
|
||||
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
|
||||
|
||||
w->active_client_texture_unit = texture_unit_index;
|
||||
|
||||
realize_texture_units (w, texture_unit_index);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_wrap_glActiveTexture (GLenum texture)
|
||||
{
|
||||
int texture_unit_index = texture - GL_TEXTURE0;
|
||||
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
|
||||
|
||||
w->active_texture_unit = texture_unit_index;
|
||||
|
||||
realize_texture_units (w, texture_unit_index);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_wrap_glEnable (GLenum cap)
|
||||
{
|
||||
@ -1039,7 +1363,8 @@ cogl_wrap_glEnable (GLenum cap)
|
||||
switch (cap)
|
||||
{
|
||||
case GL_TEXTURE_2D:
|
||||
_COGL_GLES2_CHANGE_SETTING (w, texture_2d_enabled, TRUE);
|
||||
_COGL_GLES2_CHANGE_SETTING (
|
||||
w, texture_units[w->active_texture_unit].enabled, TRUE);
|
||||
break;
|
||||
|
||||
case GL_FOG:
|
||||
@ -1063,7 +1388,8 @@ cogl_wrap_glDisable (GLenum cap)
|
||||
switch (cap)
|
||||
{
|
||||
case GL_TEXTURE_2D:
|
||||
_COGL_GLES2_CHANGE_SETTING (w, texture_2d_enabled, FALSE);
|
||||
_COGL_GLES2_CHANGE_SETTING (
|
||||
w, texture_units[w->active_texture_unit].enabled, FALSE);
|
||||
break;
|
||||
|
||||
case GL_FOG:
|
||||
@ -1082,13 +1408,26 @@ cogl_wrap_glDisable (GLenum cap)
|
||||
void
|
||||
cogl_wrap_glEnableClientState (GLenum array)
|
||||
{
|
||||
CoglGles2WrapperTextureUnit *texture_unit;
|
||||
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
|
||||
|
||||
switch (array)
|
||||
{
|
||||
case GL_VERTEX_ARRAY:
|
||||
glEnableVertexAttribArray (COGL_GLES2_WRAPPER_VERTEX_ATTRIB);
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
glEnableVertexAttribArray (COGL_GLES2_WRAPPER_TEX_COORD_ATTRIB);
|
||||
/* TODO - review if this should be in w->settings? */
|
||||
|
||||
texture_unit = g_array_index (w->texture_units,
|
||||
CoglGles2WrapperTextureUnit *,
|
||||
w->active_texture_unit);
|
||||
if (texture_unit->texture_coords_enabled != 1)
|
||||
{
|
||||
texture_unit->texture_coords_enabled = 1;
|
||||
w->dirty_vertex_attrib_enables
|
||||
|= COGL_GLES2_DIRTY_TEX_COORD_ATTRIB_ENABLES;
|
||||
}
|
||||
break;
|
||||
case GL_COLOR_ARRAY:
|
||||
glEnableVertexAttribArray (COGL_GLES2_WRAPPER_COLOR_ATTRIB);
|
||||
@ -1102,13 +1441,26 @@ cogl_wrap_glEnableClientState (GLenum array)
|
||||
void
|
||||
cogl_wrap_glDisableClientState (GLenum array)
|
||||
{
|
||||
CoglGles2WrapperTextureUnit *texture_unit;
|
||||
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
|
||||
|
||||
switch (array)
|
||||
{
|
||||
case GL_VERTEX_ARRAY:
|
||||
glDisableVertexAttribArray (COGL_GLES2_WRAPPER_VERTEX_ATTRIB);
|
||||
break;
|
||||
case GL_TEXTURE_COORD_ARRAY:
|
||||
glDisableVertexAttribArray (COGL_GLES2_WRAPPER_TEX_COORD_ATTRIB);
|
||||
|
||||
texture_unit = g_array_index (w->texture_units,
|
||||
CoglGles2WrapperTextureUnit *,
|
||||
w->active_texture_unit);
|
||||
/* TODO - review if this should be in w->settings? */
|
||||
if (texture_unit->texture_coords_enabled != 0)
|
||||
{
|
||||
texture_unit->texture_coords_enabled = 0;
|
||||
w->dirty_vertex_attrib_enables
|
||||
|= COGL_GLES2_DIRTY_TEX_COORD_ATTRIB_ENABLES;
|
||||
}
|
||||
break;
|
||||
case GL_COLOR_ARRAY:
|
||||
glDisableVertexAttribArray (COGL_GLES2_WRAPPER_COLOR_ATTRIB);
|
||||
@ -1156,6 +1508,10 @@ cogl_wrap_glGetIntegerv (GLenum pname, GLint *params)
|
||||
*params = 0;
|
||||
break;
|
||||
|
||||
case CGL_MATRIX_MODE:
|
||||
*params = w->matrix_mode;
|
||||
break;
|
||||
|
||||
default:
|
||||
glGetIntegerv (pname, params);
|
||||
break;
|
||||
@ -1195,7 +1551,7 @@ cogl_wrap_glFogf (GLenum pname, GLfloat param)
|
||||
case GL_FOG_MODE:
|
||||
_COGL_GLES2_CHANGE_SETTING (w, fog_mode, param);
|
||||
break;
|
||||
|
||||
|
||||
case GL_FOG_DENSITY:
|
||||
_COGL_GLES2_CHANGE_UNIFORM (w, FOG_DENSITY, fog_density,
|
||||
(param));
|
||||
|
@ -32,11 +32,17 @@ G_BEGIN_DECLS
|
||||
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
||||
typedef struct _CoglGles2Wrapper CoglGles2Wrapper;
|
||||
typedef struct _CoglGles2WrapperUniforms CoglGles2WrapperUniforms;
|
||||
typedef struct _CoglGles2WrapperSettings CoglGles2WrapperSettings;
|
||||
typedef struct _CoglGles2WrapperProgram CoglGles2WrapperProgram;
|
||||
typedef struct _CoglGles2WrapperShader CoglGles2WrapperShader;
|
||||
typedef struct _CoglGles2Wrapper CoglGles2Wrapper;
|
||||
typedef struct _CoglGles2WrapperTextureUnit
|
||||
CoglGles2WrapperTextureUnit;
|
||||
|
||||
typedef struct _CoglGles2WrapperAttributes CoglGles2WrapperAttributes;
|
||||
typedef struct _CoglGles2WrapperUniforms CoglGles2WrapperUniforms;
|
||||
typedef struct _CoglGles2WrapperTextureUnitSettings
|
||||
CoglGles2WrapperTextureUnitSettings;
|
||||
typedef struct _CoglGles2WrapperSettings CoglGles2WrapperSettings;
|
||||
typedef struct _CoglGles2WrapperProgram CoglGles2WrapperProgram;
|
||||
typedef struct _CoglGles2WrapperShader CoglGles2WrapperShader;
|
||||
|
||||
#define COGL_GLES2_NUM_CUSTOM_UNIFORMS 16
|
||||
#define COGL_GLES2_UNBOUND_CUSTOM_UNIFORM -2
|
||||
@ -46,78 +52,129 @@ typedef struct _CoglGles2WrapperShader CoglGles2WrapperShader;
|
||||
#define COGL_GLES2_PROJECTION_STACK_SIZE 2
|
||||
#define COGL_GLES2_TEXTURE_STACK_SIZE 2
|
||||
|
||||
/* Dirty flags for shader uniforms */
|
||||
enum
|
||||
{
|
||||
COGL_GLES2_DIRTY_MVP_MATRIX = 1 << 0,
|
||||
COGL_GLES2_DIRTY_MODELVIEW_MATRIX = 1 << 1,
|
||||
COGL_GLES2_DIRTY_TEXTURE_MATRIX = 1 << 2,
|
||||
COGL_GLES2_DIRTY_TEXTURE_MATRICES = 1 << 2,
|
||||
COGL_GLES2_DIRTY_FOG_DENSITY = 1 << 3,
|
||||
COGL_GLES2_DIRTY_FOG_START = 1 << 4,
|
||||
COGL_GLES2_DIRTY_FOG_END = 1 << 5,
|
||||
COGL_GLES2_DIRTY_FOG_COLOR = 1 << 6,
|
||||
COGL_GLES2_DIRTY_ALPHA_TEST_REF = 1 << 7,
|
||||
COGL_GLES2_DIRTY_TEXTURE_UNIT = 1 << 8,
|
||||
COGL_GLES2_DIRTY_TEXTURE_UNITS = 1 << 8,
|
||||
|
||||
COGL_GLES2_DIRTY_ALL = (1 << 9) - 1
|
||||
};
|
||||
|
||||
/* Dirty flags for shader vertex attribute pointers */
|
||||
enum
|
||||
{
|
||||
COGL_GLES2_DIRTY_TEX_COORD_VERTEX_ATTRIB = 1 << 0
|
||||
};
|
||||
|
||||
/* Dirty flags for shader vertex attributes enabled status */
|
||||
enum
|
||||
{
|
||||
COGL_GLES2_DIRTY_TEX_COORD_ATTRIB_ENABLES = 1 << 0
|
||||
};
|
||||
|
||||
struct _CoglGles2WrapperAttributes
|
||||
{
|
||||
GArray *multi_texture_coords;
|
||||
};
|
||||
|
||||
struct _CoglGles2WrapperUniforms
|
||||
{
|
||||
GLint mvp_matrix_uniform;
|
||||
GLint modelview_matrix_uniform;
|
||||
GLint texture_matrix_uniform;
|
||||
GLint bound_texture_uniform;
|
||||
GLint mvp_matrix_uniform;
|
||||
GLint modelview_matrix_uniform;
|
||||
GArray *texture_matrix_uniforms;
|
||||
|
||||
GLint fog_density_uniform;
|
||||
GLint fog_start_uniform;
|
||||
GLint fog_end_uniform;
|
||||
GLint fog_color_uniform;
|
||||
GArray *texture_sampler_uniforms;
|
||||
|
||||
GLint alpha_test_ref_uniform;
|
||||
GLint fog_density_uniform;
|
||||
GLint fog_start_uniform;
|
||||
GLint fog_end_uniform;
|
||||
GLint fog_color_uniform;
|
||||
|
||||
GLint alpha_test_ref_uniform;
|
||||
|
||||
GLint texture_unit_uniform;
|
||||
};
|
||||
|
||||
struct _CoglGles2WrapperTextureUnitSettings
|
||||
{
|
||||
guint enabled:1;
|
||||
guint alpha_only:1;
|
||||
/* TODO: blending state */
|
||||
};
|
||||
|
||||
/* NB: We get a copy of this for each fragment/vertex
|
||||
* program varient we generate so we try to keep it
|
||||
* fairly lean */
|
||||
struct _CoglGles2WrapperSettings
|
||||
{
|
||||
gboolean texture_2d_enabled;
|
||||
gboolean alpha_only;
|
||||
CoglGles2WrapperTextureUnitSettings *texture_units;
|
||||
guint n_texture_units;
|
||||
|
||||
gboolean alpha_test_enabled;
|
||||
GLint alpha_test_func;
|
||||
|
||||
gboolean fog_enabled;
|
||||
GLint fog_mode;
|
||||
|
||||
/* The current in-use user program */
|
||||
CoglHandle user_program;
|
||||
|
||||
guint alpha_test_enabled:1;
|
||||
guint fog_enabled:1;
|
||||
};
|
||||
|
||||
struct _CoglGles2WrapperTextureUnit
|
||||
{
|
||||
GLfloat texture_stack[COGL_GLES2_TEXTURE_STACK_SIZE * 16];
|
||||
GLuint texture_stack_pos;
|
||||
|
||||
GLenum texture_coords_type;
|
||||
GLint texture_coords_size;
|
||||
GLsizei texture_coords_stride;
|
||||
const void *texture_coords_pointer;
|
||||
|
||||
guint texture_coords_enabled:1;
|
||||
guint dirty_matrix:1; /*!< shader uniform needs updating */
|
||||
};
|
||||
|
||||
struct _CoglGles2Wrapper
|
||||
{
|
||||
GLuint matrix_mode;
|
||||
GLfloat modelview_stack[COGL_GLES2_MODELVIEW_STACK_SIZE * 16];
|
||||
GLuint modelview_stack_pos;
|
||||
GLfloat projection_stack[COGL_GLES2_PROJECTION_STACK_SIZE * 16];
|
||||
GLuint projection_stack_pos;
|
||||
GLfloat texture_stack[COGL_GLES2_TEXTURE_STACK_SIZE * 16];
|
||||
GLuint texture_stack_pos;
|
||||
GLuint matrix_mode;
|
||||
GLfloat modelview_stack[COGL_GLES2_MODELVIEW_STACK_SIZE * 16];
|
||||
GLuint modelview_stack_pos;
|
||||
GLfloat projection_stack[COGL_GLES2_PROJECTION_STACK_SIZE * 16];
|
||||
GLuint projection_stack_pos;
|
||||
GArray *texture_units;
|
||||
guint active_texture_unit;
|
||||
guint active_client_texture_unit;
|
||||
|
||||
/* The combined modelview and projection matrix is only updated at
|
||||
the last minute in glDrawArrays to avoid recalculating it for
|
||||
every change to the modelview matrix */
|
||||
GLboolean mvp_uptodate;
|
||||
GLboolean mvp_uptodate;
|
||||
|
||||
/* The currently bound program */
|
||||
CoglGles2WrapperProgram *current_program;
|
||||
|
||||
/* The current settings */
|
||||
/* The current settings. Effectively these represent anything that
|
||||
* will require a modified fixed function shader */
|
||||
CoglGles2WrapperSettings settings;
|
||||
/* Whether the settings have changed since the last draw */
|
||||
gboolean settings_dirty;
|
||||
/* Uniforms that have changed since the last draw */
|
||||
int dirty_uniforms, dirty_custom_uniforms;
|
||||
|
||||
/* Attribute pointers that have changed since the last draw */
|
||||
int dirty_attribute_pointers;
|
||||
|
||||
/* Vertex attribute pointer enables that have changed since the last draw */
|
||||
int dirty_vertex_attrib_enables;
|
||||
|
||||
/* List of all compiled program combinations */
|
||||
GSList *compiled_programs;
|
||||
|
||||
@ -143,6 +200,10 @@ struct _CoglGles2WrapperProgram
|
||||
/* The settings that were used to generate this combination */
|
||||
CoglGles2WrapperSettings settings;
|
||||
|
||||
/* The attributes for this program that are not bound up-front
|
||||
* with constant indices */
|
||||
CoglGles2WrapperAttributes attributes;
|
||||
|
||||
/* The uniforms for this program */
|
||||
CoglGles2WrapperUniforms uniforms;
|
||||
GLint custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS];
|
||||
@ -232,6 +293,9 @@ void cogl_wrap_glNormalPointer (GLenum type, GLsizei stride,
|
||||
|
||||
void cogl_wrap_glTexEnvf (GLenum target, GLenum pname, GLfloat param);
|
||||
|
||||
void cogl_wrap_glClientActiveTexture (GLenum texture);
|
||||
void cogl_wrap_glActiveTexture (GLenum texture);
|
||||
|
||||
void cogl_wrap_glEnableClientState (GLenum array);
|
||||
void cogl_wrap_glDisableClientState (GLenum array);
|
||||
|
||||
@ -258,12 +322,6 @@ void cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture,
|
||||
/* This function is only available on GLES 2 */
|
||||
#define cogl_wrap_glGenerateMipmap glGenerateMipmap
|
||||
|
||||
void cogl_gles2_wrapper_bind_attributes (GLuint program);
|
||||
void cogl_gles2_wrapper_get_uniforms (GLuint program,
|
||||
CoglGles2WrapperUniforms *uniforms);
|
||||
void cogl_gles2_wrapper_update_matrix (CoglGles2Wrapper *wrapper,
|
||||
GLenum matrix_num);
|
||||
|
||||
void _cogl_gles2_clear_cache_for_program (CoglHandle program);
|
||||
|
||||
#else /* HAVE_COGL_GLES2 */
|
||||
@ -290,6 +348,7 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program);
|
||||
#define cogl_wrap_glColorPointer glColorPointer
|
||||
#define cogl_wrap_glNormalPointer glNormalPointer
|
||||
#define cogl_wrap_glTexEnvf glTexEnvf
|
||||
#define cogl_wrap_glActiveTexture glActiveTexture
|
||||
#define cogl_wrap_glEnableClientState glEnableClientState
|
||||
#define cogl_wrap_glDisableClientState glDisableClientState
|
||||
#define cogl_wrap_glAlphaFunc glAlphaFunc
|
||||
@ -310,6 +369,11 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program);
|
||||
glGenerateMipmap doesn't need to do anything */
|
||||
#define cogl_wrap_glGenerateMipmap(x) ((void) 0)
|
||||
|
||||
/* 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 /* HAVE_COGL_GLES2 */
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -75,13 +75,10 @@ const char *_cogl_error_string(GLenum errorCode);
|
||||
#endif /* COGL_DEBUG */
|
||||
|
||||
#define COGL_ENABLE_BLEND (1<<1)
|
||||
#define COGL_ENABLE_TEXTURE_2D (1<<2)
|
||||
#define COGL_ENABLE_ALPHA_TEST (1<<3)
|
||||
#define COGL_ENABLE_TEXTURE_RECT (1<<4)
|
||||
#define COGL_ENABLE_VERTEX_ARRAY (1<<5)
|
||||
#define COGL_ENABLE_TEXCOORD_ARRAY (1<<6)
|
||||
#define COGL_ENABLE_COLOR_ARRAY (1<<7)
|
||||
#define COGL_ENABLE_BACKFACE_CULLING (1<<8)
|
||||
#define COGL_ENABLE_ALPHA_TEST (1<<2)
|
||||
#define COGL_ENABLE_VERTEX_ARRAY (1<<3)
|
||||
#define COGL_ENABLE_COLOR_ARRAY (1<<4)
|
||||
#define COGL_ENABLE_BACKFACE_CULLING (1<<5)
|
||||
|
||||
gint
|
||||
_cogl_get_format_bpp (CoglPixelFormat format);
|
||||
|
@ -38,30 +38,9 @@
|
||||
|
||||
#define _COGL_MAX_BEZ_RECURSE_DEPTH 16
|
||||
|
||||
void
|
||||
_cogl_rectangle (float x,
|
||||
float y,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
GLfloat rect_verts[8] = {
|
||||
(GLfloat) x, (GLfloat) y,
|
||||
(GLfloat) (x + width), (GLfloat) y,
|
||||
(GLfloat) x, (GLfloat) (y + height),
|
||||
(GLfloat) (x + width), (GLfloat) (y + height)
|
||||
};
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
cogl_enable (COGL_ENABLE_VERTEX_ARRAY
|
||||
| (ctx->color_alpha < 255 ? COGL_ENABLE_BLEND : 0));
|
||||
GE ( cogl_wrap_glVertexPointer (2, GL_FLOAT, 0, rect_verts ) );
|
||||
GE ( cogl_wrap_glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_path_add_node (gboolean new_sub_path,
|
||||
float x,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
CoglPathNode new_node;
|
||||
@ -96,23 +75,28 @@ _cogl_path_add_node (gboolean new_sub_path,
|
||||
void
|
||||
_cogl_path_stroke_nodes ()
|
||||
{
|
||||
guint path_start = 0;
|
||||
guint path_start = 0;
|
||||
gulong enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
cogl_enable (COGL_ENABLE_VERTEX_ARRAY
|
||||
| (ctx->color_alpha < 255
|
||||
? COGL_ENABLE_BLEND : 0));
|
||||
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);
|
||||
|
||||
while (path_start < ctx->path_nodes->len)
|
||||
{
|
||||
CoglPathNode *path = &g_array_index (ctx->path_nodes, CoglPathNode,
|
||||
path_start);
|
||||
|
||||
GE( cogl_wrap_glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
|
||||
(guchar *) path
|
||||
+ G_STRUCT_OFFSET (CoglPathNode, x)) );
|
||||
GE( cogl_wrap_glDrawArrays (GL_LINE_STRIP, 0, path->path_size) );
|
||||
GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
|
||||
(guchar *) path
|
||||
+ G_STRUCT_OFFSET (CoglPathNode, x)) );
|
||||
GE( glDrawArrays (GL_LINE_STRIP, 0, path->path_size) );
|
||||
|
||||
path_start += path->path_size;
|
||||
}
|
||||
@ -145,12 +129,22 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
CoglPathNode *path,
|
||||
gboolean merge)
|
||||
{
|
||||
guint path_start = 0;
|
||||
guint sub_path_num = 0;
|
||||
float bounds_x;
|
||||
float bounds_y;
|
||||
float bounds_w;
|
||||
float bounds_h;
|
||||
guint path_start = 0;
|
||||
guint sub_path_num = 0;
|
||||
float bounds_x;
|
||||
float bounds_y;
|
||||
float bounds_w;
|
||||
float bounds_h;
|
||||
gulong enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
|
||||
_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);
|
||||
|
||||
enable_flags |=
|
||||
cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
_cogl_path_get_bounds (nodes_min, nodes_max,
|
||||
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
|
||||
@ -167,7 +161,7 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
GE( glStencilFunc (GL_LEQUAL, 0x1, 0x3) );
|
||||
}
|
||||
|
||||
GE( cogl_wrap_glEnable (GL_STENCIL_TEST) );
|
||||
GE( glEnable (GL_STENCIL_TEST) );
|
||||
GE( glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT) );
|
||||
|
||||
GE( glColorMask (FALSE, FALSE, FALSE, FALSE) );
|
||||
@ -175,12 +169,10 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
|
||||
while (path_start < path_size)
|
||||
{
|
||||
cogl_enable (COGL_ENABLE_VERTEX_ARRAY);
|
||||
|
||||
GE( cogl_wrap_glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
|
||||
(guchar *) path
|
||||
+ G_STRUCT_OFFSET (CoglPathNode, x)) );
|
||||
GE( cogl_wrap_glDrawArrays (GL_TRIANGLE_FAN, 0, path->path_size) );
|
||||
GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
|
||||
(guchar *) path
|
||||
+ G_STRUCT_OFFSET (CoglPathNode, x)) );
|
||||
GE( glDrawArrays (GL_TRIANGLE_FAN, 0, path->path_size) );
|
||||
|
||||
if (sub_path_num > 0)
|
||||
{
|
||||
@ -209,16 +201,16 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
GE( glStencilOp (GL_DECR, GL_DECR, GL_DECR) );
|
||||
/* Decrement all of the bits twice so that only pixels where the
|
||||
value is 3 will remain */
|
||||
GE( cogl_wrap_glPushMatrix () );
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
|
||||
GE( cogl_wrap_glPushMatrix () );
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
cogl_rectangle (-1.0, -1.0, 2, 2);
|
||||
cogl_rectangle (-1.0, -1.0, 2, 2);
|
||||
GE( cogl_wrap_glPopMatrix () );
|
||||
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
|
||||
GE( cogl_wrap_glPopMatrix () );
|
||||
GE( glPopMatrix () );
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glPopMatrix () );
|
||||
}
|
||||
|
||||
GE( glStencilMask (~(GLuint) 0) );
|
||||
@ -255,7 +247,7 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* clear scanline intersection lists */
|
||||
for (i=0; i < bounds_h; i++)
|
||||
for (i=0; i < bounds_h; i++)
|
||||
scanlines[i]=NULL;
|
||||
|
||||
first_x = prev_x = (path->x);
|
||||
@ -392,8 +384,8 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
|
||||
/* render triangles */
|
||||
cogl_enable (COGL_ENABLE_VERTEX_ARRAY
|
||||
| (ctx->color_alpha < 255 ? COGL_ENABLE_BLEND : 0));
|
||||
GE ( cogl_wrap_glVertexPointer (2, GL_FLOAT, 0, coords ) );
|
||||
GE ( cogl_wrap_glDrawArrays (GL_TRIANGLES, 0, spans * 2 * 3));
|
||||
GE ( glVertexPointer (2, GL_FLOAT, 0, coords ) );
|
||||
GE ( glDrawArrays (GL_TRIANGLES, 0, spans * 2 * 3));
|
||||
g_free (coords);
|
||||
}
|
||||
}
|
||||
@ -444,4 +436,3 @@ _cogl_path_fill_nodes ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,9 +28,9 @@
|
||||
|
||||
#include "cogl-bitmap.h"
|
||||
|
||||
typedef struct _CoglTexture CoglTexture;
|
||||
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
||||
typedef struct _CoglSpanIter CoglSpanIter;
|
||||
typedef struct _CoglTexture CoglTexture;
|
||||
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
||||
typedef struct _CoglSpanIter CoglSpanIter;
|
||||
|
||||
struct _CoglTexSliceSpan
|
||||
{
|
||||
@ -59,7 +59,23 @@ struct _CoglTexture
|
||||
gboolean auto_mipmap;
|
||||
};
|
||||
|
||||
/* To improve batching of geometry when submitting vertices to OpenGL we
|
||||
* log the texture rectangles we want to draw to a journal, so when we
|
||||
* later flush the journal we aim to batch data, and gl draw calls. */
|
||||
typedef struct _CoglJournalEntry
|
||||
{
|
||||
CoglHandle material;
|
||||
gint n_layers;
|
||||
guint32 fallback_mask;
|
||||
GLuint layer0_override_texture;
|
||||
} CoglJournalEntry;
|
||||
|
||||
CoglTexture*
|
||||
_cogl_texture_pointer_from_handle (CoglHandle handle);
|
||||
|
||||
gboolean
|
||||
_cogl_texture_span_has_waste (CoglTexture *tex,
|
||||
gint x_span_index,
|
||||
gint y_span_index);
|
||||
|
||||
#endif /* __COGL_TEXTURE_H */
|
||||
|
2092
gles/cogl-texture.c
2092
gles/cogl-texture.c
File diff suppressed because it is too large
Load Diff
343
gles/cogl.c
343
gles/cogl.c
@ -73,14 +73,13 @@ _cogl_error_string(GLenum errorCode)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
CoglFuncPtr
|
||||
cogl_get_proc_address (const gchar* name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gboolean
|
||||
cogl_check_extension (const gchar *name, const gchar *ext)
|
||||
{
|
||||
return FALSE;
|
||||
@ -93,45 +92,59 @@ cogl_paint_init (const CoglColor *color)
|
||||
fprintf(stderr, "\n ============== Paint Start ================ \n");
|
||||
#endif
|
||||
|
||||
glClearColor (cogl_color_get_red (color),
|
||||
cogl_color_get_green (color),
|
||||
cogl_color_get_blue (color),
|
||||
0);
|
||||
GE( glClearColor (cogl_color_get_red_float (color),
|
||||
cogl_color_get_green_float (color),
|
||||
cogl_color_get_blue_float (color),
|
||||
0.0) );
|
||||
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
cogl_wrap_glDisable (GL_LIGHTING);
|
||||
cogl_wrap_glDisable (GL_FOG);
|
||||
glDisable (GL_LIGHTING);
|
||||
glDisable (GL_FOG);
|
||||
|
||||
/*
|
||||
* Disable the depth test for now as has some strange side effects,
|
||||
* mainly on x/y axis rotation with multiple layers at same depth
|
||||
* (eg rotating text on a bg has very strange effect). Seems no clean
|
||||
* 100% effective way to fix without other odd issues.. So for now
|
||||
* move to application to handle and add cogl_enable_depth_test()
|
||||
* as for custom actors (i.e groups) to enable if need be.
|
||||
*
|
||||
* glEnable (GL_DEPTH_TEST);
|
||||
* glEnable (GL_ALPHA_TEST)
|
||||
* glDepthFunc (GL_LEQUAL);
|
||||
* glAlphaFunc (GL_GREATER, 0.1);
|
||||
*/
|
||||
}
|
||||
|
||||
/* FIXME: inline most of these */
|
||||
void
|
||||
cogl_push_matrix (void)
|
||||
{
|
||||
GE( cogl_wrap_glPushMatrix() );
|
||||
GE( glPushMatrix() );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_pop_matrix (void)
|
||||
{
|
||||
GE( cogl_wrap_glPopMatrix() );
|
||||
GE( glPopMatrix() );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_scale (float x, float y)
|
||||
{
|
||||
GE( cogl_wrap_glScalef (x, y, 1.0) );
|
||||
GE( glScalef (x, y, 1.0) );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_translate (float x, float y, float z)
|
||||
{
|
||||
GE( cogl_wrap_glTranslatef (x, y, z) );
|
||||
GE( glTranslatef (x, y, z) );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_rotate (float angle, float x, float y, float z)
|
||||
{
|
||||
GE( cogl_wrap_glRotatef (angle, x, y, z) );
|
||||
GE( glRotatef (angle, x, y, z) );
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
@ -147,17 +160,17 @@ cogl_toggle_flag (CoglContext *ctx,
|
||||
{
|
||||
if (!(ctx->enable_flags & flag))
|
||||
{
|
||||
GE( cogl_wrap_glEnable (gl_flag) );
|
||||
GE( glEnable (gl_flag) );
|
||||
ctx->enable_flags |= flag;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (ctx->enable_flags & flag)
|
||||
{
|
||||
GE( cogl_wrap_glDisable (gl_flag) );
|
||||
GE( glDisable (gl_flag) );
|
||||
ctx->enable_flags &= ~flag;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -174,17 +187,17 @@ cogl_toggle_client_flag (CoglContext *ctx,
|
||||
{
|
||||
if (!(ctx->enable_flags & flag))
|
||||
{
|
||||
GE( cogl_wrap_glEnableClientState (gl_flag) );
|
||||
GE( glEnableClientState (gl_flag) );
|
||||
ctx->enable_flags |= flag;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (ctx->enable_flags & flag)
|
||||
{
|
||||
GE( cogl_wrap_glDisableClientState (gl_flag) );
|
||||
GE( glDisableClientState (gl_flag) );
|
||||
ctx->enable_flags &= ~flag;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -195,14 +208,10 @@ cogl_enable (gulong flags)
|
||||
* hope of lessening number GL traffic.
|
||||
*/
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_BLEND,
|
||||
GL_BLEND);
|
||||
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_TEXTURE_2D,
|
||||
GL_TEXTURE_2D);
|
||||
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_BACKFACE_CULLING,
|
||||
@ -211,10 +220,6 @@ cogl_enable (gulong flags)
|
||||
cogl_toggle_client_flag (ctx, flags,
|
||||
COGL_ENABLE_VERTEX_ARRAY,
|
||||
GL_VERTEX_ARRAY);
|
||||
|
||||
cogl_toggle_client_flag (ctx, flags,
|
||||
COGL_ENABLE_TEXCOORD_ARRAY,
|
||||
GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
cogl_toggle_client_flag (ctx, flags,
|
||||
COGL_ENABLE_COLOR_ARRAY,
|
||||
@ -225,25 +230,8 @@ gulong
|
||||
cogl_get_enable ()
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
return ctx->enable_flags;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_blend_func (COGLenum src_factor, COGLenum dst_factor)
|
||||
{
|
||||
/* This function caches the blending setup in the
|
||||
* hope of lessening GL traffic.
|
||||
*/
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (ctx->blend_src_factor != src_factor ||
|
||||
ctx->blend_dst_factor != dst_factor)
|
||||
{
|
||||
glBlendFunc (src_factor, dst_factor);
|
||||
ctx->blend_src_factor = src_factor;
|
||||
ctx->blend_dst_factor = dst_factor;
|
||||
}
|
||||
return ctx->enable_flags;
|
||||
}
|
||||
|
||||
void
|
||||
@ -251,15 +239,15 @@ cogl_enable_depth_test (gboolean setting)
|
||||
{
|
||||
if (setting)
|
||||
{
|
||||
cogl_wrap_glEnable (GL_DEPTH_TEST);
|
||||
cogl_wrap_glEnable (GL_ALPHA_TEST);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glEnable (GL_ALPHA_TEST);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
cogl_wrap_glAlphaFunc (GL_GREATER, 0.1);
|
||||
glAlphaFunc (GL_GREATER, 0.1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cogl_wrap_glDisable (GL_DEPTH_TEST);
|
||||
cogl_wrap_glDisable (GL_ALPHA_TEST);
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDisable (GL_ALPHA_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,35 +263,12 @@ void
|
||||
cogl_set_source_color (const CoglColor *color)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
#if 0 /*HAVE_GLES_COLOR4UB*/
|
||||
|
||||
/* NOTE: seems SDK_OGLES-1.1_LINUX_PCEMULATION_2.02.22.0756 has this call
|
||||
* but is broken - see #857. Therefor disabling.
|
||||
*/
|
||||
/* In case cogl_set_source_texture was previously used... */
|
||||
cogl_material_remove_layer (ctx->default_material, 0);
|
||||
|
||||
/*
|
||||
* GLES 1.1 does actually have this function, it's in the header file but
|
||||
* missing in the reference manual (and SDK):
|
||||
*
|
||||
* http://www.khronos.org/egl/headers/1_1/gl.h
|
||||
*/
|
||||
GE( glColor4ub (color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
color->alpha) );
|
||||
|
||||
|
||||
#else
|
||||
/* conversion can cause issues with picking on some gles implementations */
|
||||
GE( cogl_wrap_glColor4f (cogl_color_get_red (color),
|
||||
cogl_color_get_green (color),
|
||||
cogl_color_get_blue (color),
|
||||
cogl_color_get_alpha (color)) );
|
||||
#endif
|
||||
|
||||
/* Store alpha for proper blending enables */
|
||||
ctx->color_alpha = cogl_color_get_alpha_byte (color);
|
||||
cogl_material_set_color (ctx->default_material, color);
|
||||
cogl_set_source (ctx->default_material);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -314,7 +279,7 @@ apply_matrix (const float *matrix, float *vertex)
|
||||
|
||||
for (y = 0; y < 4; y++)
|
||||
for (x = 0; x < 4; x++)
|
||||
vertex_out[y] += (vertex[x] * matrix[y + x * 4]);
|
||||
vertex_out[y] += vertex[x] * matrix[y + x * 4];
|
||||
|
||||
memcpy (vertex, vertex_out, sizeof (vertex_out));
|
||||
}
|
||||
@ -332,7 +297,7 @@ project_vertex (float *modelview,
|
||||
apply_matrix (project, vertex);
|
||||
/* Convert from homogenized coordinates */
|
||||
for (i = 0; i < 4; i++)
|
||||
vertex[i] = (vertex[i] / vertex[3]);
|
||||
vertex[i] /= vertex[3];
|
||||
}
|
||||
|
||||
static void
|
||||
@ -349,26 +314,26 @@ set_clip_plane (GLint plane_num,
|
||||
angle = atan2f (vertex_b[1] - vertex_a[1],
|
||||
vertex_b[0] - vertex_a[0]) * (180.0/G_PI);
|
||||
|
||||
GE( cogl_wrap_glPushMatrix () );
|
||||
GE( glPushMatrix () );
|
||||
/* Load the identity matrix and multiply by the reverse of the
|
||||
projection matrix so we can specify the plane in screen
|
||||
coordinates */
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( cogl_wrap_glMultMatrixf ((GLfloat *) ctx->inverse_projection) );
|
||||
GE( glLoadIdentity () );
|
||||
GE( glMultMatrixf ((GLfloat *) ctx->inverse_projection) );
|
||||
/* Rotate about point a */
|
||||
GE( cogl_wrap_glTranslatef (vertex_a[0], vertex_a[1], vertex_a[2]) );
|
||||
GE( glTranslatef (vertex_a[0], vertex_a[1], vertex_a[2]) );
|
||||
/* Rotate the plane by the calculated angle so that it will connect
|
||||
the two points */
|
||||
GE( cogl_wrap_glRotatef (angle, 0.0f, 0.0f, 1.0f) );
|
||||
GE( cogl_wrap_glTranslatef (-vertex_a[0], -vertex_a[1], -vertex_a[2]) );
|
||||
GE( glRotatef (angle, 0.0f, 0.0f, 1.0f) );
|
||||
GE( glTranslatef (-vertex_a[0], -vertex_a[1], -vertex_a[2]) );
|
||||
|
||||
plane[0] = 0;
|
||||
plane[1] = -1.0;
|
||||
plane[2] = 0;
|
||||
plane[3] = vertex_a[1];
|
||||
GE( cogl_wrap_glClipPlanef (plane_num, plane) );
|
||||
GE( glClipPlanef (plane_num, plane) );
|
||||
|
||||
GE( cogl_wrap_glPopMatrix () );
|
||||
GE( glPopMatrix () );
|
||||
}
|
||||
|
||||
void
|
||||
@ -383,21 +348,21 @@ _cogl_set_clip_planes (float x_offset,
|
||||
float vertex_tr[4] = { x_offset + width, y_offset, 0, 1.0 };
|
||||
float vertex_bl[4] = { x_offset, y_offset + height, 0, 1.0 };
|
||||
float vertex_br[4] = { x_offset + width, y_offset + height,
|
||||
0, 1.0 };
|
||||
0, 1.0 };
|
||||
|
||||
GE( cogl_wrap_glGetFloatv (GL_MODELVIEW_MATRIX, modelview) );
|
||||
GE( cogl_wrap_glGetFloatv (GL_PROJECTION_MATRIX, projection) );
|
||||
GE( glGetFloatv (GL_MODELVIEW_MATRIX, modelview) );
|
||||
GE( glGetFloatv (GL_PROJECTION_MATRIX, projection) );
|
||||
|
||||
project_vertex (modelview, projection, vertex_tl);
|
||||
project_vertex (modelview, projection, vertex_tr);
|
||||
project_vertex (modelview, projection, vertex_bl);
|
||||
project_vertex (modelview, projection, vertex_br);
|
||||
|
||||
/* If the order of the top and bottom lines is different from
|
||||
the order of the left and right lines then the clip rect must
|
||||
have been transformed so that the back is visible. We
|
||||
therefore need to swap one pair of vertices otherwise all of
|
||||
the planes will be the wrong way around */
|
||||
/* If the order of the top and bottom lines is different from the
|
||||
order of the left and right lines then the clip rect must have
|
||||
been transformed so that the back is visible. We therefore need
|
||||
to swap one pair of vertices otherwise all of the planes will be
|
||||
the wrong way around */
|
||||
if ((vertex_tl[0] < vertex_tr[0] ? 1 : 0)
|
||||
!= (vertex_bl[1] < vertex_tl[1] ? 1 : 0))
|
||||
{
|
||||
@ -425,10 +390,12 @@ _cogl_add_stencil_clip (float x_offset,
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
cogl_material_flush_gl_state (ctx->stencil_material);
|
||||
|
||||
if (first)
|
||||
{
|
||||
GE( cogl_wrap_glEnable (GL_STENCIL_TEST) );
|
||||
|
||||
GE( glEnable (GL_STENCIL_TEST) );
|
||||
|
||||
/* Initially disallow everything */
|
||||
GE( glClearStencil (0) );
|
||||
GE( glClear (GL_STENCIL_BUFFER_BIT) );
|
||||
@ -451,15 +418,15 @@ _cogl_add_stencil_clip (float x_offset,
|
||||
only pixels where both the original stencil buffer and the
|
||||
rectangle are set will be valid */
|
||||
GE( glStencilOp (GL_DECR, GL_DECR, GL_DECR) );
|
||||
GE( cogl_wrap_glPushMatrix () );
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
|
||||
GE( cogl_wrap_glPushMatrix () );
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
cogl_rectangle (-1.0, -1.0, 2, 2);
|
||||
GE( cogl_wrap_glPopMatrix () );
|
||||
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
|
||||
GE( cogl_wrap_glPopMatrix () );
|
||||
GE( glPopMatrix () );
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glPopMatrix () );
|
||||
}
|
||||
|
||||
/* Restore the stencil mode */
|
||||
@ -470,44 +437,34 @@ _cogl_add_stencil_clip (float x_offset,
|
||||
void
|
||||
_cogl_set_matrix (const float *matrix)
|
||||
{
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( cogl_wrap_glMultMatrixf (matrix) );
|
||||
GE( glLoadIdentity () );
|
||||
GE( glMultMatrixf (matrix) );
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_disable_stencil_buffer (void)
|
||||
{
|
||||
GE( cogl_wrap_glDisable (GL_STENCIL_TEST) );
|
||||
GE( glDisable (GL_STENCIL_TEST) );
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_enable_clip_planes (void)
|
||||
{
|
||||
GE( cogl_wrap_glEnable (GL_CLIP_PLANE0) );
|
||||
GE( cogl_wrap_glEnable (GL_CLIP_PLANE1) );
|
||||
GE( cogl_wrap_glEnable (GL_CLIP_PLANE2) );
|
||||
GE( cogl_wrap_glEnable (GL_CLIP_PLANE3) );
|
||||
GE( glEnable (GL_CLIP_PLANE0) );
|
||||
GE( glEnable (GL_CLIP_PLANE1) );
|
||||
GE( glEnable (GL_CLIP_PLANE2) );
|
||||
GE( glEnable (GL_CLIP_PLANE3) );
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_disable_clip_planes (void)
|
||||
{
|
||||
GE( cogl_wrap_glDisable (GL_CLIP_PLANE3) );
|
||||
GE( cogl_wrap_glDisable (GL_CLIP_PLANE2) );
|
||||
GE( cogl_wrap_glDisable (GL_CLIP_PLANE1) );
|
||||
GE( cogl_wrap_glDisable (GL_CLIP_PLANE0) );
|
||||
GE( glDisable (GL_CLIP_PLANE3) );
|
||||
GE( glDisable (GL_CLIP_PLANE2) );
|
||||
GE( glDisable (GL_CLIP_PLANE1) );
|
||||
GE( glDisable (GL_CLIP_PLANE0) );
|
||||
}
|
||||
|
||||
void
|
||||
cogl_alpha_func (COGLenum func,
|
||||
float ref)
|
||||
{
|
||||
GE( cogl_wrap_glAlphaFunc (func, (ref)) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixed point implementation of the perspective function
|
||||
*/
|
||||
void
|
||||
cogl_perspective (float fovy,
|
||||
float aspect,
|
||||
@ -519,21 +476,21 @@ cogl_perspective (float fovy,
|
||||
float fovy_rad_half = (fovy * G_PI) / 360;
|
||||
|
||||
GLfloat m[16];
|
||||
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
memset (&m[0], 0, sizeof (m));
|
||||
|
||||
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glLoadIdentity () );
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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 can are loosing significant
|
||||
* 2) When working with small numbers, we are loosing significant
|
||||
* precision
|
||||
*/
|
||||
ymax = (zNear * (sinf (fovy_rad_half) / cosf (fovy_rad_half)));
|
||||
@ -551,9 +508,9 @@ cogl_perspective (float fovy,
|
||||
M(2,3) = d;
|
||||
M(3,2) = -1.0;
|
||||
|
||||
GE( cogl_wrap_glMultMatrixf (m) );
|
||||
GE( glMultMatrixf (m) );
|
||||
|
||||
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
|
||||
/* Calculate and store the inverse of the matrix */
|
||||
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
|
||||
@ -581,30 +538,33 @@ cogl_frustum (float left,
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glLoadIdentity () );
|
||||
|
||||
GE( cogl_wrap_glFrustumf (left, right,
|
||||
bottom, top,
|
||||
z_near, z_far) );
|
||||
GE( glFrustumf (left,
|
||||
right,
|
||||
bottom,
|
||||
top,
|
||||
z_near,
|
||||
z_far) );
|
||||
|
||||
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
|
||||
/* Calculate and store the inverse of the matrix */
|
||||
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
|
||||
|
||||
c = -(z_far + z_near / z_far - z_near);
|
||||
d = -(2 * (z_far * z_near) / z_far - z_near);
|
||||
c = - (z_far + z_near) / (z_far - z_near);
|
||||
d = - (2 * (z_far * z_near)) / (z_far - z_near);
|
||||
|
||||
#define M(row,col) ctx->inverse_projection[col*4+row]
|
||||
M(0,0) = (right - left / 2 * z_near);
|
||||
M(0,3) = (right + left / 2 * z_near);
|
||||
M(1,1) = (top - bottom / 2 * z_near);
|
||||
M(1,3) = (top + bottom / 2 * z_near);
|
||||
M(0,0) = (right - left) / (2 * z_near);
|
||||
M(0,3) = (right + left) / (2 * z_near);
|
||||
M(1,1) = (top - bottom) / (2 * z_near);
|
||||
M(1,3) = (top + bottom) / (2 * z_near);
|
||||
M(2,3) = -1.0;
|
||||
M(3,2) = (1.0 / d);
|
||||
M(3,3) = (c / d);
|
||||
#undef M
|
||||
M(3,2) = 1.0 / d;
|
||||
M(3,3) = c / d;
|
||||
#undef M
|
||||
}
|
||||
|
||||
void
|
||||
@ -615,26 +575,24 @@ cogl_viewport (guint width,
|
||||
}
|
||||
|
||||
void
|
||||
cogl_setup_viewport (guint w,
|
||||
guint h,
|
||||
cogl_setup_viewport (guint width,
|
||||
guint height,
|
||||
float fovy,
|
||||
float aspect,
|
||||
float z_near,
|
||||
float z_far)
|
||||
{
|
||||
gint width = (gint) w;
|
||||
gint height = (gint) h;
|
||||
float z_camera;
|
||||
float projection_matrix[16];
|
||||
|
||||
|
||||
GE( glViewport (0, 0, width, height) );
|
||||
|
||||
/* For Ortho projection.
|
||||
* cogl_wrap_glOrthof (0, width << 16, 0, height << 16, -1 << 16, 1 << 16);
|
||||
* glOrthof (0, width << 16, 0, height << 16, -1 << 16, 1 << 16);
|
||||
*/
|
||||
|
||||
cogl_perspective (fovy, aspect, z_near, z_far);
|
||||
|
||||
|
||||
/*
|
||||
* camera distance from screen
|
||||
*
|
||||
@ -644,15 +602,13 @@ cogl_setup_viewport (guint w,
|
||||
cogl_get_projection_matrix (projection_matrix);
|
||||
z_camera = 0.5 * projection_matrix[0];
|
||||
|
||||
GE( cogl_wrap_glLoadIdentity () );
|
||||
GE( glLoadIdentity () );
|
||||
|
||||
GE( cogl_wrap_glTranslatef (-0.5f, -0.5f, -z_camera) );
|
||||
GE( glTranslatef (-0.5f, -0.5f, -z_camera) );
|
||||
|
||||
GE( cogl_wrap_glScalef ( 1.0 / width,
|
||||
-1.0 / height,
|
||||
1.0 / width) );
|
||||
GE( glScalef (1.0f / width, -1.0f / height, 1.0f / width) );
|
||||
|
||||
GE( cogl_wrap_glTranslatef (0, -1.0 * height, 0) );
|
||||
GE( glTranslatef (0.0f, -1.0 * height, 0.0f) );
|
||||
}
|
||||
|
||||
static void
|
||||
@ -664,12 +620,12 @@ _cogl_features_init ()
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
GE( cogl_wrap_glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) );
|
||||
GE( glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) );
|
||||
/* We need at least three stencil bits to combine clips */
|
||||
if (num_stencil_bits > 2)
|
||||
flags |= COGL_FEATURE_STENCIL_BUFFER;
|
||||
|
||||
GE( cogl_wrap_glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) );
|
||||
GE( glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) );
|
||||
if (max_clip_planes >= 4)
|
||||
flags |= COGL_FEATURE_FOUR_CLIP_PLANES;
|
||||
|
||||
@ -677,6 +633,7 @@ _cogl_features_init ()
|
||||
flags |= COGL_FEATURE_SHADERS_GLSL | COGL_FEATURE_OFFSCREEN;
|
||||
#endif
|
||||
|
||||
/* Cache features */
|
||||
ctx->feature_flags = flags;
|
||||
ctx->features_cached = TRUE;
|
||||
}
|
||||
@ -685,10 +642,10 @@ CoglFeatureFlags
|
||||
cogl_get_features ()
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
|
||||
if (!ctx->features_cached)
|
||||
_cogl_features_init ();
|
||||
|
||||
|
||||
return ctx->feature_flags;
|
||||
}
|
||||
|
||||
@ -696,23 +653,23 @@ gboolean
|
||||
cogl_features_available (CoglFeatureFlags features)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
|
||||
if (!ctx->features_cached)
|
||||
_cogl_features_init ();
|
||||
|
||||
|
||||
return (ctx->feature_flags & features) == features;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_get_modelview_matrix (float m[16])
|
||||
{
|
||||
cogl_wrap_glGetFloatv (GL_MODELVIEW_MATRIX, m);
|
||||
glGetFloatv (GL_MODELVIEW_MATRIX, m);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_get_projection_matrix (float m[16])
|
||||
{
|
||||
cogl_wrap_glGetFloatv (GL_PROJECTION_MATRIX, m);
|
||||
glGetFloatv (GL_PROJECTION_MATRIX, m);
|
||||
}
|
||||
|
||||
void
|
||||
@ -721,7 +678,7 @@ cogl_get_viewport (float v[4])
|
||||
GLint viewport[4];
|
||||
int i;
|
||||
|
||||
cogl_wrap_glGetIntegerv (GL_VIEWPORT, viewport);
|
||||
glGetIntegerv (GL_VIEWPORT, viewport);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
v[i] = (float)(viewport[i]);
|
||||
@ -730,14 +687,27 @@ cogl_get_viewport (float v[4])
|
||||
void
|
||||
cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha)
|
||||
{
|
||||
GLint value;
|
||||
if (red)
|
||||
GE( cogl_wrap_glGetIntegerv(GL_RED_BITS, red) );
|
||||
{
|
||||
GE( glGetIntegerv(GL_RED_BITS, &value) );
|
||||
*red = value;
|
||||
}
|
||||
if (green)
|
||||
GE( cogl_wrap_glGetIntegerv(GL_GREEN_BITS, green) );
|
||||
{
|
||||
GE( glGetIntegerv(GL_GREEN_BITS, &value) );
|
||||
*green = value;
|
||||
}
|
||||
if (blue)
|
||||
GE( cogl_wrap_glGetIntegerv(GL_BLUE_BITS, blue) );
|
||||
{
|
||||
GE( glGetIntegerv(GL_BLUE_BITS, &value) );
|
||||
*blue = value;
|
||||
}
|
||||
if (alpha)
|
||||
GE( cogl_wrap_glGetIntegerv(GL_ALPHA_BITS, alpha ) );
|
||||
{
|
||||
GE( glGetIntegerv(GL_ALPHA_BITS, &value ) );
|
||||
*alpha = value;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -748,19 +718,20 @@ cogl_fog_set (const CoglColor *fog_color,
|
||||
{
|
||||
GLfloat fogColor[4];
|
||||
|
||||
fogColor[0] = cogl_color_get_red (fog_color);
|
||||
fogColor[1] = cogl_color_get_green (fog_color);
|
||||
fogColor[2] = cogl_color_get_blue (fog_color);
|
||||
fogColor[3] = cogl_color_get_alpha (fog_color);
|
||||
fogColor[0] = cogl_color_get_red_float (fog_color);
|
||||
fogColor[1] = cogl_color_get_green_float (fog_color);
|
||||
fogColor[2] = cogl_color_get_blue_float (fog_color);
|
||||
fogColor[3] = cogl_color_get_alpha_float (fog_color);
|
||||
|
||||
cogl_wrap_glEnable (GL_FOG);
|
||||
glEnable (GL_FOG);
|
||||
|
||||
cogl_wrap_glFogfv (GL_FOG_COLOR, fogColor);
|
||||
glFogfv (GL_FOG_COLOR, fogColor);
|
||||
|
||||
cogl_wrap_glFogf (GL_FOG_MODE, GL_LINEAR);
|
||||
glFogf (GL_FOG_MODE, GL_LINEAR);
|
||||
glHint (GL_FOG_HINT, GL_NICEST);
|
||||
|
||||
cogl_wrap_glFogf (GL_FOG_DENSITY, (GLfloat) density);
|
||||
cogl_wrap_glFogf (GL_FOG_START, (GLfloat) z_near);
|
||||
cogl_wrap_glFogf (GL_FOG_END, (GLfloat) z_far);
|
||||
glFogf (GL_FOG_DENSITY, (GLfloat) density);
|
||||
glFogf (GL_FOG_START, (GLfloat) z_near);
|
||||
glFogf (GL_FOG_END, (GLfloat) z_far);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user