summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bragg <robert@linux.intel.com>2012-08-06 21:19:27 +0100
committerRobert Bragg <robert@linux.intel.com>2012-09-26 13:32:11 +0100
commit63cc8c7107393fe5e4ef56260b95eef001ff093b (patch)
treec6c4d336abaeaf8b41460e591f180dd8c8ac4310
parent9f774b2b0848353b655cc44e59d3886aec658fcc (diff)
downloadcogl-wip/glsl-unified.tar.gz
attribute: Adds support for constant CoglAttributeswip/glsl-unified
This makes it possible to create vertex attributes that efficiently represent constant values without duplicating the constant for every vertex. This adds the following new constructors for constant attributes: cogl_attribute_new_const_1f cogl_attribute_new_const_2fv cogl_attribute_new_const_3fv cogl_attribute_new_const_4fv cogl_attribute_new_const_2f cogl_attribute_new_const_3f cogl_attribute_new_const_4f cogl_attribute_new_const_2x2fv cogl_attribute_new_const_3x3fv cogl_attribute_new_const_4x4fv
-rw-r--r--cogl/cogl-attribute-private.h24
-rw-r--r--cogl/cogl-attribute.c245
-rw-r--r--cogl/cogl-attribute.h325
-rw-r--r--cogl/driver/gl/cogl-attribute-gl.c272
-rw-r--r--cogl/gl-prototypes/cogl-fixed-functions.h8
5 files changed, 763 insertions, 111 deletions
diff --git a/cogl/cogl-attribute-private.h b/cogl/cogl-attribute-private.h
index b4adaa87..943934fe 100644
--- a/cogl/cogl-attribute-private.h
+++ b/cogl/cogl-attribute-private.h
@@ -32,6 +32,7 @@
#include "cogl-attribute.h"
#include "cogl-framebuffer.h"
#include "cogl-pipeline-private.h"
+#include "cogl-boxed-value.h"
typedef enum
{
@@ -48,21 +49,32 @@ typedef struct _CoglAttributeNameState
CoglAttributeNameID name_id;
int name_index;
CoglBool normalized_default;
- int texture_unit;
+ int layer_number;
} CoglAttributeNameState;
struct _CoglAttribute
{
CoglObject _parent;
- CoglAttributeBuffer *attribute_buffer;
const CoglAttributeNameState *name_state;
- size_t stride;
- size_t offset;
- int n_components;
- CoglAttributeType type;
CoglBool normalized;
+ CoglBool is_buffered;
+
+ union {
+ struct {
+ CoglAttributeBuffer *attribute_buffer;
+ size_t stride;
+ size_t offset;
+ int n_components;
+ CoglAttributeType type;
+ } buffered;
+ struct {
+ CoglContext *context;
+ CoglBoxedValue boxed;
+ } constant;
+ } d;
+
int immutable_ref;
};
diff --git a/cogl/cogl-attribute.c b/cogl/cogl-attribute.c
index 6e40f542..ae1805f2 100644
--- a/cogl/cogl-attribute.c
+++ b/cogl/cogl-attribute.c
@@ -64,12 +64,12 @@ validate_cogl_attribute_name (const char *name,
char **real_attribute_name,
CoglAttributeNameID *name_id,
CoglBool *normalized,
- int *texture_unit)
+ int *layer_number)
{
name = name + 5; /* skip "cogl_" */
*normalized = FALSE;
- *texture_unit = 0;
+ *layer_number = 0;
if (strcmp (name, "position_in") == 0)
*name_id = COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY;
@@ -86,7 +86,7 @@ validate_cogl_attribute_name (const char *name,
else if (strncmp (name, "tex_coord", strlen ("tex_coord")) == 0)
{
char *endptr;
- *texture_unit = strtoul (name + 9, &endptr, 10);
+ *layer_number = strtoul (name + 9, &endptr, 10);
if (strcmp (endptr, "_in") != 0)
{
g_warning ("Texture coordinate attributes should either be named "
@@ -126,14 +126,14 @@ _cogl_attribute_register_attribute_name (CoglContext *context,
&name_state->name,
&name_state->name_id,
&name_state->normalized_default,
- &name_state->texture_unit))
+ &name_state->layer_number))
goto error;
}
else
{
name_state->name_id = COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY;
name_state->normalized_default = FALSE;
- name_state->texture_unit = 0;
+ name_state->layer_number = 0;
}
if (name_state->name == NULL)
@@ -167,9 +167,10 @@ cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
CoglAttributeType type)
{
CoglAttribute *attribute = g_slice_new (CoglAttribute);
+ CoglBuffer *buffer = COGL_BUFFER (attribute_buffer);
+ CoglContext *ctx = buffer->context;
- /* FIXME: retrieve the context from the buffer */
- _COGL_GET_CONTEXT (ctx, NULL);
+ attribute->is_buffered = TRUE;
attribute->name_state =
g_hash_table_lookup (ctx->attribute_name_states_hash, name);
@@ -181,11 +182,13 @@ cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
goto error;
attribute->name_state = name_state;
}
- attribute->attribute_buffer = cogl_object_ref (attribute_buffer);
- attribute->stride = stride;
- attribute->offset = offset;
- attribute->n_components = n_components;
- attribute->type = type;
+
+ attribute->d.buffered.attribute_buffer = cogl_object_ref (attribute_buffer);
+ attribute->d.buffered.stride = stride;
+ attribute->d.buffered.offset = offset;
+ attribute->d.buffered.n_components = n_components;
+ attribute->d.buffered.type = type;
+
attribute->immutable_ref = 0;
if (attribute->name_state->name_id != COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY)
@@ -224,7 +227,8 @@ cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
default:
g_warn_if_reached ();
}
- attribute->normalized = attribute->name_state->normalized_default;
+ attribute->normalized =
+ attribute->name_state->normalized_default;
}
else
attribute->normalized = FALSE;
@@ -236,6 +240,203 @@ error:
return NULL;
}
+static CoglAttribute *
+_cogl_attribute_new_const (CoglContext *context,
+ const char *name,
+ int n_components,
+ int n_columns,
+ CoglBool transpose,
+ float *value)
+{
+ CoglAttribute *attribute = g_slice_new (CoglAttribute);
+
+ attribute->name_state =
+ g_hash_table_lookup (context->attribute_name_states_hash, name);
+ if (!attribute->name_state)
+ {
+ CoglAttributeNameState *name_state =
+ _cogl_attribute_register_attribute_name (context, name);
+ if (!name_state)
+ goto error;
+ attribute->name_state = name_state;
+ }
+
+ attribute->is_buffered = FALSE;
+ attribute->normalized = FALSE;
+
+ attribute->d.constant.context = cogl_object_ref (context);
+
+ attribute->d.constant.boxed.v.array = NULL;
+
+ if (n_columns == 1)
+ {
+ _cogl_boxed_value_set_float (&attribute->d.constant.boxed,
+ n_components,
+ 1,
+ value);
+ }
+ else
+ {
+ /* FIXME: Up until GL[ES] 3 only square matrices were supported
+ * and we don't currently expose non-square matrices in Cogl.
+ */
+ _COGL_RETURN_VAL_IF_FAIL (n_columns == n_components, NULL);
+ _cogl_boxed_value_set_matrix (&attribute->d.constant.boxed,
+ n_columns,
+ 1,
+ transpose,
+ value);
+ }
+
+ return _cogl_attribute_object_new (attribute);
+
+error:
+ _cogl_attribute_free (attribute);
+ return NULL;
+}
+
+CoglAttribute *
+cogl_attribute_new_const_1f (CoglContext *context,
+ const char *name,
+ float value)
+{
+ return _cogl_attribute_new_const (context,
+ name,
+ 1, /* n_components */
+ 1, /* 1 column vector */
+ FALSE, /* no transpose */
+ &value);
+}
+
+CoglAttribute *
+cogl_attribute_new_const_2fv (CoglContext *context,
+ const char *name,
+ float *value)
+{
+ return _cogl_attribute_new_const (context,
+ name,
+ 2, /* n_components */
+ 1, /* 1 column vector */
+ FALSE, /* no transpose */
+ value);
+}
+
+CoglAttribute *
+cogl_attribute_new_const_3fv (CoglContext *context,
+ const char *name,
+ float *value)
+{
+ return _cogl_attribute_new_const (context,
+ name,
+ 3, /* n_components */
+ 1, /* 1 column vector */
+ FALSE, /* no transpose */
+ value);
+}
+
+CoglAttribute *
+cogl_attribute_new_const_4fv (CoglContext *context,
+ const char *name,
+ float *value)
+{
+ return _cogl_attribute_new_const (context,
+ name,
+ 4, /* n_components */
+ 1, /* 1 column vector */
+ FALSE, /* no transpose */
+ value);
+}
+
+CoglAttribute *
+cogl_attribute_new_const_2f (CoglContext *context,
+ const char *name,
+ float component0,
+ float component1)
+{
+ float vec2[2] = { component0, component1 };
+ return _cogl_attribute_new_const (context,
+ name,
+ 2, /* n_components */
+ 1, /* 1 column vector */
+ FALSE, /* no transpose */
+ vec2);
+}
+
+CoglAttribute *
+cogl_attribute_new_const_3f (CoglContext *context,
+ const char *name,
+ float component0,
+ float component1,
+ float component2)
+{
+ float vec3[3] = { component0, component1, component2 };
+ return _cogl_attribute_new_const (context,
+ name,
+ 3, /* n_components */
+ 1, /* 1 column vector */
+ FALSE, /* no transpose */
+ vec3);
+}
+
+CoglAttribute *
+cogl_attribute_new_const_4f (CoglContext *context,
+ const char *name,
+ float component0,
+ float component1,
+ float component2,
+ float component3)
+{
+ float vec4[4] = { component0, component1, component2, component3 };
+ return _cogl_attribute_new_const (context,
+ name,
+ 4, /* n_components */
+ 1, /* 1 column vector */
+ FALSE, /* no transpose */
+ vec4);
+}
+
+CoglAttribute *
+cogl_attribute_new_const_2x2fv (CoglContext *context,
+ const char *name,
+ float *matrix2x2,
+ CoglBool transpose)
+{
+ return _cogl_attribute_new_const (context,
+ name,
+ 2, /* n_components */
+ 2, /* 1 column vector */
+ FALSE, /* no transpose */
+ matrix2x2);
+}
+
+CoglAttribute *
+cogl_attribute_new_const_3x3fv (CoglContext *context,
+ const char *name,
+ float *matrix3x3,
+ CoglBool transpose)
+{
+ return _cogl_attribute_new_const (context,
+ name,
+ 3, /* n_components */
+ 3, /* 1 column vector */
+ FALSE, /* no transpose */
+ matrix3x3);
+}
+
+CoglAttribute *
+cogl_attribute_new_const_4x4fv (CoglContext *context,
+ const char *name,
+ float *matrix4x4,
+ CoglBool transpose)
+{
+ return _cogl_attribute_new_const (context,
+ name,
+ 4, /* n_components */
+ 4, /* 1 column vector */
+ FALSE, /* no transpose */
+ matrix4x4);
+}
+
CoglBool
cogl_attribute_get_normalized (CoglAttribute *attribute)
{
@@ -272,8 +473,9 @@ CoglAttributeBuffer *
cogl_attribute_get_buffer (CoglAttribute *attribute)
{
_COGL_RETURN_VAL_IF_FAIL (cogl_is_attribute (attribute), NULL);
+ _COGL_RETURN_VAL_IF_FAIL (attribute->is_buffered, NULL);
- return attribute->attribute_buffer;
+ return attribute->d.buffered.attribute_buffer;
}
void
@@ -281,40 +483,45 @@ cogl_attribute_set_buffer (CoglAttribute *attribute,
CoglAttributeBuffer *attribute_buffer)
{
_COGL_RETURN_IF_FAIL (cogl_is_attribute (attribute));
+ _COGL_RETURN_IF_FAIL (attribute->is_buffered);
if (G_UNLIKELY (attribute->immutable_ref))
warn_about_midscene_changes ();
cogl_object_ref (attribute_buffer);
- cogl_object_unref (attribute->attribute_buffer);
- attribute->attribute_buffer = attribute_buffer;
+ cogl_object_unref (attribute->d.buffered.attribute_buffer);
+ attribute->d.buffered.attribute_buffer = attribute_buffer;
}
CoglAttribute *
_cogl_attribute_immutable_ref (CoglAttribute *attribute)
{
+ CoglBuffer *buffer = COGL_BUFFER (attribute->d.buffered.attribute_buffer);
+
_COGL_RETURN_VAL_IF_FAIL (cogl_is_attribute (attribute), NULL);
attribute->immutable_ref++;
- _cogl_buffer_immutable_ref (COGL_BUFFER (attribute->attribute_buffer));
+ _cogl_buffer_immutable_ref (buffer);
return attribute;
}
void
_cogl_attribute_immutable_unref (CoglAttribute *attribute)
{
+ CoglBuffer *buffer = COGL_BUFFER (attribute->d.buffered.attribute_buffer);
+
_COGL_RETURN_IF_FAIL (cogl_is_attribute (attribute));
_COGL_RETURN_IF_FAIL (attribute->immutable_ref > 0);
attribute->immutable_ref--;
- _cogl_buffer_immutable_unref (COGL_BUFFER (attribute->attribute_buffer));
+ _cogl_buffer_immutable_unref (buffer);
}
static void
_cogl_attribute_free (CoglAttribute *attribute)
{
- cogl_object_unref (attribute->attribute_buffer);
+ cogl_object_unref (attribute->d.buffered.attribute_buffer);
g_slice_free (CoglAttribute, attribute);
}
diff --git a/cogl/cogl-attribute.h b/cogl/cogl-attribute.h
index 60ffaba2..577f138b 100644
--- a/cogl/cogl-attribute.h
+++ b/cogl/cogl-attribute.h
@@ -142,6 +142,317 @@ cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
CoglAttributeType type);
/**
+ * cogl_attribute_new_const_1f:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @value: The constant value for the attribute
+ *
+ * Creates a new, single component, attribute whose value remains
+ * constant across all the vertices of a primitive without needing to
+ * duplicate the value for each vertex.
+ *
+ * The constant @value is a single precision floating point scalar
+ * which should have a corresponding declaration in GLSL code like:
+ *
+ * [|
+ * varying float name;
+ * |]
+ *
+ * Returns: A newly allocated #CoglAttribute representing the given
+ * constant @value.
+ */
+CoglAttribute *
+cogl_attribute_new_const_1f (CoglContext *context,
+ const char *name,
+ float value);
+
+/**
+ * cogl_attribute_new_const_2f:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @constant0: The first component of a 2 component vector
+ * @constant1: The second component of a 2 component vector
+ *
+ * Creates a new, 2 component, attribute whose value remains
+ * constant across all the vertices of a primitive without needing to
+ * duplicate the value for each vertex.
+ *
+ * The constants (@component0, @component1) represent a 2 component
+ * float vector which should have a corresponding declaration in GLSL
+ * code like:
+ *
+ * [|
+ * varying vec2 name;
+ * |]
+ *
+ * Returns: A newly allocated #CoglAttribute representing the given
+ * constant vector.
+ */
+CoglAttribute *
+cogl_attribute_new_const_2f (CoglContext *context,
+ const char *name,
+ float component0,
+ float component1);
+
+/**
+ * cogl_attribute_new_const_3f:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @constant0: The first component of a 3 component vector
+ * @constant1: The second component of a 3 component vector
+ * @constant2: The third component of a 3 component vector
+ *
+ * Creates a new, 3 component, attribute whose value remains
+ * constant across all the vertices of a primitive without needing to
+ * duplicate the value for each vertex.
+ *
+ * The constants (@component0, @component1, @component2) represent a 3
+ * component float vector which should have a corresponding
+ * declaration in GLSL code like:
+ *
+ * [|
+ * varying vec3 name;
+ * |]
+ *
+ * unless the built in name "cogl_normal_in" is being used where no
+ * explicit GLSL declaration need be made.
+ *
+ * Returns: A newly allocated #CoglAttribute representing the given
+ * constant vector.
+ */
+CoglAttribute *
+cogl_attribute_new_const_3f (CoglContext *context,
+ const char *name,
+ float component0,
+ float component1,
+ float component2);
+
+/**
+ * cogl_attribute_new_const_4f:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @constant0: The first component of a 4 component vector
+ * @constant1: The second component of a 4 component vector
+ * @constant2: The third component of a 4 component vector
+ * @constant3: The fourth component of a 4 component vector
+ *
+ * Creates a new, 4 component, attribute whose value remains
+ * constant across all the vertices of a primitive without needing to
+ * duplicate the value for each vertex.
+ *
+ * The constants (@component0, @component1, @component2, @constant3)
+ * represent a 4 component float vector which should have a
+ * corresponding declaration in GLSL code like:
+ *
+ * [|
+ * varying vec4 name;
+ * |]
+ *
+ * unless one of the built in names "cogl_color_in",
+ * "cogl_tex_coord0_in or "cogl_tex_coord1_in" etc is being used where
+ * no explicit GLSL declaration need be made.
+ *
+ * Returns: A newly allocated #CoglAttribute representing the given
+ * constant vector.
+ */
+CoglAttribute *
+cogl_attribute_new_const_4f (CoglContext *context,
+ const char *name,
+ float component0,
+ float component1,
+ float component2,
+ float component3);
+
+/**
+ * cogl_attribute_new_const_2fv:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @value: A pointer to a 2 component float vector
+ *
+ * Creates a new, 2 component, attribute whose value remains
+ * constant across all the vertices of a primitive without needing to
+ * duplicate the value for each vertex.
+ *
+ * The constants (value[0], value[1]) represent a 2 component float
+ * vector which should have a corresponding declaration in GLSL code
+ * like:
+ *
+ * [|
+ * varying vec2 name;
+ * |]
+ *
+ * Returns: A newly allocated #CoglAttribute representing the given
+ * constant vector.
+ */
+CoglAttribute *
+cogl_attribute_new_const_2fv (CoglContext *context,
+ const char *name,
+ float *value);
+
+/**
+ * cogl_attribute_new_const_3fv:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @value: A pointer to a 3 component float vector
+ *
+ * Creates a new, 3 component, attribute whose value remains
+ * constant across all the vertices of a primitive without needing to
+ * duplicate the value for each vertex.
+ *
+ * The constants (value[0], value[1], value[2]) represent a 3
+ * component float vector which should have a corresponding
+ * declaration in GLSL code like:
+ *
+ * [|
+ * varying vec3 name;
+ * |]
+ *
+ * unless the built in name "cogl_normal_in" is being used where no
+ * explicit GLSL declaration need be made.
+ *
+ * Returns: A newly allocated #CoglAttribute representing the given
+ * constant vector.
+ */
+CoglAttribute *
+cogl_attribute_new_const_3fv (CoglContext *context,
+ const char *name,
+ float *value);
+
+/**
+ * cogl_attribute_new_const_4fv:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @value: A pointer to a 4 component float vector
+ *
+ * Creates a new, 4 component, attribute whose value remains
+ * constant across all the vertices of a primitive without needing to
+ * duplicate the value for each vertex.
+ *
+ * The constants (value[0], value[1], value[2], value[3]) represent a
+ * 4 component float vector which should have a corresponding
+ * declaration in GLSL code like:
+ *
+ * [|
+ * varying vec4 name;
+ * |]
+ *
+ * unless one of the built in names "cogl_color_in",
+ * "cogl_tex_coord0_in or "cogl_tex_coord1_in" etc is being used where
+ * no explicit GLSL declaration need be made.
+ *
+ * Returns: A newly allocated #CoglAttribute representing the given
+ * constant vector.
+ */
+CoglAttribute *
+cogl_attribute_new_const_4fv (CoglContext *context,
+ const char *name,
+ float *value);
+
+/**
+ * cogl_attribute_new_const_2x2fv:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @matrix2x2: A pointer to a 2 by 2 matrix
+ * @transpose: Whether the matrix should be transposed on upload or
+ * not
+ *
+ * Creates a new matrix attribute whose value remains constant
+ * across all the vertices of a primitive without needing to duplicate
+ * the value for each vertex.
+ *
+ * @matrix2x2 represent a square 2 by 2 matrix specified in
+ * column-major order (each pair of consecutive numbers represents a
+ * column) which should have a corresponding declaration in GLSL code
+ * like:
+ *
+ * [|
+ * varying mat2 name;
+ * |]
+ *
+ * If @transpose is %TRUE then all matrix components are rotated
+ * around the diagonal of the matrix such that the first column
+ * becomes the first row and the second column becomes the second row.
+ *
+ * Returns: A newly allocated #CoglAttribute representing the given
+ * constant matrix.
+ */
+CoglAttribute *
+cogl_attribute_new_const_2x2fv (CoglContext *context,
+ const char *name,
+ float *matrix2x2,
+ CoglBool transpose);
+
+/**
+ * cogl_attribute_new_const_3x3fv:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @matrix3x3: A pointer to a 3 by 3 matrix
+ * @transpose: Whether the matrix should be transposed on upload or
+ * not
+ *
+ * Creates a new matrix attribute whose value remains constant
+ * across all the vertices of a primitive without needing to duplicate
+ * the value for each vertex.
+ *
+ * @matrix3x3 represent a square 3 by 3 matrix specified in
+ * column-major order (each triple of consecutive numbers represents a
+ * column) which should have a corresponding declaration in GLSL code
+ * like:
+ *
+ * [|
+ * varying mat3 name;
+ * |]
+ *
+ * If @transpose is %TRUE then all matrix components are rotated
+ * around the diagonal of the matrix such that the first column
+ * becomes the first row and the second column becomes the second row
+ * etc.
+ *
+ * Returns: A newly allocated #CoglAttribute representing the given
+ * constant matrix.
+ */
+CoglAttribute *
+cogl_attribute_new_const_3x3fv (CoglContext *context,
+ const char *name,
+ float *matrix3x3,
+ CoglBool transpose);
+
+/**
+ * cogl_attribute_new_const_4x4fv:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @matrix4x4: A pointer to a 4 by 4 matrix
+ * @transpose: Whether the matrix should be transposed on upload or
+ * not
+ *
+ * Creates a new matrix attribute whose value remains constant
+ * across all the vertices of a primitive without needing to duplicate
+ * the value for each vertex.
+ *
+ * @matrix4x4 represent a square 4 by 4 matrix specified in
+ * column-major order (each 4-tuple of consecutive numbers represents a
+ * column) which should have a corresponding declaration in GLSL code
+ * like:
+ *
+ * [|
+ * varying mat4 name;
+ * |]
+ *
+ * If @transpose is %TRUE then all matrix components are rotated
+ * around the diagonal of the matrix such that the first column
+ * becomes the first row and the second column becomes the second row
+ * etc.
+ *
+ * Returns: A newly allocated #CoglAttribute representing the given
+ * constant matrix.
+ */
+CoglAttribute *
+cogl_attribute_new_const_4x4fv (CoglContext *context,
+ const char *name,
+ float *matrix4x4,
+ CoglBool transpose);
+
+/**
* cogl_attribute_set_normalized:
* @attribute: A #CoglAttribute
* @normalized: The new value for the normalized property.
@@ -204,6 +515,20 @@ cogl_attribute_set_buffer (CoglAttribute *attribute,
CoglAttributeBuffer *attribute_buffer);
/**
+ * cogl_attribute_new_constf:
+ * @context: A #CoglContext
+ * @name: The name of the attribute (used to reference it from GLSL)
+ * @value: A single component float value
+ *
+ * Stability: unstable
+ * Since: 2.0
+ */
+CoglAttribute *
+cogl_attribute_new_const1f (CoglContext *context,
+ const char *name,
+ float value);
+
+/**
* cogl_is_attribute:
* @object: A #CoglObject
*
diff --git a/cogl/driver/gl/cogl-attribute-gl.c b/cogl/driver/gl/cogl-attribute-gl.c
index 0c21d129..9c4da9b8 100644
--- a/cogl/driver/gl/cogl-attribute-gl.c
+++ b/cogl/driver/gl/cogl-attribute-gl.c
@@ -152,30 +152,188 @@ foreach_changed_bit_and_save (CoglContext *context,
#ifdef COGL_PIPELINE_PROGEND_GLSL
static void
-setup_generic_attribute (CoglContext *context,
- CoglPipeline *pipeline,
- CoglAttribute *attribute,
- uint8_t *base)
+setup_generic_buffered_attribute (CoglContext *context,
+ CoglPipeline *pipeline,
+ CoglAttribute *attribute,
+ uint8_t *base)
{
int name_index = attribute->name_state->name_index;
int attrib_location =
_cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index);
- if (attrib_location != -1)
+
+ if (attrib_location == -1)
+ return;
+
+ GE( context, glVertexAttribPointer (attrib_location,
+ attribute->d.buffered.n_components,
+ attribute->d.buffered.type,
+ attribute->normalized,
+ attribute->d.buffered.stride,
+ base + attribute->d.buffered.offset) );
+ _cogl_bitmask_set (&context->enable_custom_attributes_tmp,
+ attrib_location, TRUE);
+}
+
+static void
+setup_generic_const_attribute (CoglContext *context,
+ CoglPipeline *pipeline,
+ CoglAttribute *attribute)
+{
+ int name_index = attribute->name_state->name_index;
+ int attrib_location =
+ _cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index);
+ int columns;
+ int i;
+
+ if (attrib_location == -1)
+ return;
+
+ if (attribute->d.constant.boxed.type == COGL_BOXED_MATRIX)
+ columns = attribute->d.constant.boxed.size;
+ else
+ columns = 1;
+
+ /* Note: it's ok to access a COGL_BOXED_FLOAT as a matrix with only
+ * one column... */
+
+ switch (attribute->d.constant.boxed.size)
{
- GE( context, glVertexAttribPointer (attrib_location,
- attribute->n_components,
- attribute->type,
- attribute->normalized,
- attribute->stride,
- base + attribute->offset) );
- _cogl_bitmask_set (&context->enable_custom_attributes_tmp,
- attrib_location, TRUE);
+ case 1:
+ GE( context, glVertexAttrib1fv (attrib_location,
+ attribute->d.constant.boxed.v.matrix));
+ break;
+ case 2:
+ for (i = 0; i < columns; i++)
+ GE( context, glVertexAttrib2fv (attrib_location + i,
+ attribute->d.constant.boxed.v.matrix));
+ break;
+ case 3:
+ for (i = 0; i < columns; i++)
+ GE( context, glVertexAttrib3fv (attrib_location + i,
+ attribute->d.constant.boxed.v.matrix));
+ break;
+ case 4:
+ for (i = 0; i < columns; i++)
+ GE( context, glVertexAttrib4fv (attrib_location + i,
+ attribute->d.constant.boxed.v.matrix));
+ break;
+ default:
+ g_warn_if_reached ();
}
}
#endif /* COGL_PIPELINE_PROGEND_GLSL */
static void
+setup_legacy_buffered_attribute (CoglContext *ctx,
+ CoglPipeline *pipeline,
+ CoglAttribute *attribute,
+ uint8_t *base)
+{
+ switch (attribute->name_state->name_id)
+ {
+ case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
+ _cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp,
+ COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY, TRUE);
+ GE (ctx, glColorPointer (attribute->d.buffered.n_components,
+ attribute->d.buffered.type,
+ attribute->d.buffered.stride,
+ base + attribute->d.buffered.offset));
+ break;
+ case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
+ _cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp,
+ COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY, TRUE);
+ GE (ctx, glNormalPointer (attribute->d.buffered.type,
+ attribute->d.buffered.stride,
+ base + attribute->d.buffered.offset));
+ break;
+ case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
+ {
+ int layer_number = attribute->name_state->layer_number;
+ CoglPipelineLayer *layer =
+ _cogl_pipeline_get_layer (pipeline, layer_number);
+ int unit = _cogl_pipeline_layer_get_unit_index (layer);
+
+ _cogl_bitmask_set (&ctx->enable_texcoord_attributes_tmp, unit, TRUE);
+
+ GE (ctx, glClientActiveTexture (GL_TEXTURE0 + unit));
+ GE (ctx, glTexCoordPointer (attribute->d.buffered.n_components,
+ attribute->d.buffered.type,
+ attribute->d.buffered.stride,
+ base + attribute->d.buffered.offset));
+ break;
+ }
+ case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
+ _cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp,
+ COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY, TRUE);
+ GE (ctx, glVertexPointer (attribute->d.buffered.n_components,
+ attribute->d.buffered.type,
+ attribute->d.buffered.stride,
+ base + attribute->d.buffered.offset));
+ break;
+ case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
+#ifdef COGL_PIPELINE_PROGEND_GLSL
+ if (ctx->driver != COGL_DRIVER_GLES1)
+ setup_generic_buffered_attribute (ctx, pipeline, attribute, base);
+#endif
+ break;
+ default:
+ g_warn_if_reached ();
+ }
+}
+
+static void
+setup_legacy_const_attribute (CoglContext *ctx,
+ CoglPipeline *pipeline,
+ CoglAttribute *attribute)
+{
+#ifdef COGL_PIPELINE_PROGEND_GLSL
+ if (attribute->name_state->name_id == COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY)
+ {
+ if (ctx->driver != COGL_DRIVER_GLES1)
+ setup_generic_const_attribute (ctx, pipeline, attribute);
+ }
+ else
+#endif
+ {
+ float vector[4] = { 0, 0, 0, 1 };
+ float *boxed = attribute->d.constant.boxed.v.float_value;
+ int n_components = attribute->d.constant.boxed.size;
+ int i;
+
+ for (i = 0; i < n_components; i++)
+ vector[i] = boxed[i];
+
+ switch (attribute->name_state->name_id)
+ {
+ case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
+ GE (ctx, glColor4f (vector[0], vector[1], vector[2], vector[3]));
+ break;
+ case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
+ GE (ctx, glNormal3f (vector[0], vector[1], vector[2]));
+ break;
+ case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
+ {
+ int layer_number = attribute->name_state->layer_number;
+ CoglPipelineLayer *layer =
+ _cogl_pipeline_get_layer (pipeline, layer_number);
+ int unit = _cogl_pipeline_layer_get_unit_index (layer);
+
+ GE (ctx, glClientActiveTexture (GL_TEXTURE0 + unit));
+
+ GE (ctx, glMultiTexCoord4f (vector[0], vector[1], vector[2], vector[3]));
+ break;
+ }
+ case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
+ GE (ctx, glVertex4f (vector[0], vector[1], vector[2], vector[3]));
+ break;
+ default:
+ g_warn_if_reached ();
+ }
+ }
+}
+
+static void
apply_attribute_enable_updates (CoglContext *context,
CoglPipeline *pipeline)
{
@@ -311,85 +469,27 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
CoglBuffer *buffer;
uint8_t *base;
- attribute_buffer = cogl_attribute_get_buffer (attribute);
- buffer = COGL_BUFFER (attribute_buffer);
- base = _cogl_buffer_gl_bind (buffer, COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER);
-
- switch (attribute->name_state->name_id)
+ if (attribute->is_buffered)
{
- case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
-#ifdef COGL_PIPELINE_PROGEND_GLSL
- if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
- setup_generic_attribute (ctx, pipeline, attribute, base);
- else
-#endif
- {
- _cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp,
- COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY, TRUE);
- GE (ctx, glColorPointer (attribute->n_components,
- attribute->type,
- attribute->stride,
- base + attribute->offset));
- }
- break;
- case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
-#ifdef COGL_PIPELINE_PROGEND_GLSL
- if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
- setup_generic_attribute (ctx, pipeline, attribute, base);
- else
-#endif
- {
- _cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp,
- COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY, TRUE);
- GE (ctx, glNormalPointer (attribute->type,
- attribute->stride,
- base + attribute->offset));
- }
- break;
- case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
-#ifdef COGL_PIPELINE_PROGEND_GLSL
+ attribute_buffer = cogl_attribute_get_buffer (attribute);
+ buffer = COGL_BUFFER (attribute_buffer);
+ base = _cogl_buffer_gl_bind (buffer,
+ COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER);
+
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
- setup_generic_attribute (ctx, pipeline, attribute, base);
+ setup_generic_buffered_attribute (ctx, pipeline, attribute, base);
else
-#endif
- {
- _cogl_bitmask_set (&ctx->enable_texcoord_attributes_tmp,
- attribute->name_state->texture_unit, TRUE);
- GE (ctx,
- glClientActiveTexture (GL_TEXTURE0 +
- attribute->name_state->texture_unit));
- GE (ctx, glTexCoordPointer (attribute->n_components,
- attribute->type,
- attribute->stride,
- base + attribute->offset));
- }
- break;
- case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
-#ifdef COGL_PIPELINE_PROGEND_GLSL
+ setup_legacy_buffered_attribute (ctx, pipeline, attribute, base);
+
+ _cogl_buffer_gl_unbind (buffer);
+ }
+ else
+ {
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
- setup_generic_attribute (ctx, pipeline, attribute, base);
+ setup_generic_const_attribute (ctx, pipeline, attribute);
else
-#endif
- {
- _cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp,
- COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY, TRUE);
- GE (ctx, glVertexPointer (attribute->n_components,
- attribute->type,
- attribute->stride,
- base + attribute->offset));
- }
- break;
- case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
-#ifdef COGL_PIPELINE_PROGEND_GLSL
- if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
- setup_generic_attribute (ctx, pipeline, attribute, base);
-#endif
- break;
- default:
- g_warning ("Unrecognised attribute type 0x%08x", attribute->type);
+ setup_legacy_const_attribute (ctx, pipeline, attribute);
}
-
- _cogl_buffer_gl_unbind (buffer);
}
apply_attribute_enable_updates (ctx, pipeline);
diff --git a/cogl/gl-prototypes/cogl-fixed-functions.h b/cogl/gl-prototypes/cogl-fixed-functions.h
index 6ac3c92a..7e5ab8e8 100644
--- a/cogl/gl-prototypes/cogl-fixed-functions.h
+++ b/cogl/gl-prototypes/cogl-fixed-functions.h
@@ -72,6 +72,8 @@ COGL_EXT_FUNCTION (void, glTexEnvfv,
(GLenum target, GLenum pname, const GLfloat *params))
COGL_EXT_FUNCTION (void, glColor4ub,
(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha))
+COGL_EXT_FUNCTION (void, glColor4f,
+ (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha))
COGL_EXT_FUNCTION (void, glColorPointer,
(GLint size,
GLenum type,
@@ -85,8 +87,12 @@ COGL_EXT_FUNCTION (void, glLoadIdentity,
(void))
COGL_EXT_FUNCTION (void, glMatrixMode,
(GLenum mode))
+COGL_EXT_FUNCTION (void, glNormal3f,
+ (GLfloat x, GLfloat y, GLfloat z))
COGL_EXT_FUNCTION (void, glNormalPointer,
(GLenum type, GLsizei stride, const GLvoid *pointer))
+COGL_EXT_FUNCTION (void, glMultiTexCoord4f,
+ (GLfloat s, GLfloat t, GLfloat r, GLfloat q))
COGL_EXT_FUNCTION (void, glTexCoordPointer,
(GLint size,
GLenum type,
@@ -96,6 +102,8 @@ COGL_EXT_FUNCTION (void, glTexEnvi,
(GLenum target,
GLenum pname,
GLint param))
+COGL_EXT_FUNCTION (void, glVertex4f,
+ (GLfloat x, GLfloat y, GLfloat z, GLfloat w))
COGL_EXT_FUNCTION (void, glVertexPointer,
(GLint size,
GLenum type,