mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 13:24:09 +00:00
attribute: Adds support for constant CoglAttributes
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 Reviewed-by: Neil Roberts <neil@linux.intel.com> (cherry picked from commit 6507216f8030e84dcf2e63b8ecfe906ac47f2ca7)
This commit is contained in:
parent
56ae6f9afa
commit
6e379fb54e
@ -32,6 +32,7 @@
|
||||
#include "cogl-attribute.h"
|
||||
#include "cogl-framebuffer.h"
|
||||
#include "cogl-pipeline-private.h"
|
||||
#include "cogl-boxed-value.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -55,14 +56,25 @@ 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;
|
||||
};
|
||||
|
||||
|
@ -158,6 +158,48 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CoglBool
|
||||
validate_n_components (const CoglAttributeNameState *name_state,
|
||||
int n_components)
|
||||
{
|
||||
switch (name_state->name_id)
|
||||
{
|
||||
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
|
||||
if (G_UNLIKELY (n_components == 1))
|
||||
{
|
||||
g_critical ("glVertexPointer doesn't allow 1 component vertex "
|
||||
"positions so we currently only support \"cogl_vertex\" "
|
||||
"attributes where n_components == 2, 3 or 4");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
|
||||
if (G_UNLIKELY (n_components != 3 && n_components != 4))
|
||||
{
|
||||
g_critical ("glColorPointer expects 3 or 4 component colors so we "
|
||||
"currently only support \"cogl_color\" attributes where "
|
||||
"n_components == 3 or 4");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
|
||||
break;
|
||||
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
|
||||
if (G_UNLIKELY (n_components != 3))
|
||||
{
|
||||
g_critical ("glNormalPointer expects 3 component normals so we "
|
||||
"currently only support \"cogl_normal\" attributes "
|
||||
"where n_components == 3");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CoglAttribute *
|
||||
cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
|
||||
const char *name,
|
||||
@ -167,9 +209,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,50 +224,21 @@ 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)
|
||||
{
|
||||
switch (attribute->name_state->name_id)
|
||||
{
|
||||
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
|
||||
if (G_UNLIKELY (n_components == 1))
|
||||
{
|
||||
g_critical ("glVertexPointer doesn't allow 1 component vertex "
|
||||
"positions so we currently only support \"cogl_vertex\" "
|
||||
"attributes where n_components == 2, 3 or 4");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
|
||||
if (G_UNLIKELY (n_components != 3 && n_components != 4))
|
||||
{
|
||||
g_critical ("glColorPointer expects 3 or 4 component colors so we "
|
||||
"currently only support \"cogl_color\" attributes where "
|
||||
"n_components == 3 or 4");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
|
||||
break;
|
||||
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
|
||||
if (G_UNLIKELY (n_components != 3))
|
||||
{
|
||||
g_critical ("glNormalPointer expects 3 component normals so we "
|
||||
"currently only support \"cogl_normal\" attributes "
|
||||
"where n_components == 3");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
}
|
||||
attribute->normalized = attribute->name_state->normalized_default;
|
||||
if (!validate_n_components (attribute->name_state, n_components))
|
||||
return NULL;
|
||||
attribute->normalized =
|
||||
attribute->name_state->normalized_default;
|
||||
}
|
||||
else
|
||||
attribute->normalized = FALSE;
|
||||
@ -236,6 +250,206 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CoglAttribute *
|
||||
_cogl_attribute_new_const (CoglContext *context,
|
||||
const char *name,
|
||||
int n_components,
|
||||
int n_columns,
|
||||
CoglBool transpose,
|
||||
const 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;
|
||||
}
|
||||
|
||||
if (!validate_n_components (attribute->name_state, n_components))
|
||||
goto error;
|
||||
|
||||
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,
|
||||
const 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,
|
||||
const 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,
|
||||
const 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,
|
||||
const float *matrix2x2,
|
||||
CoglBool transpose)
|
||||
{
|
||||
return _cogl_attribute_new_const (context,
|
||||
name,
|
||||
2, /* n_components */
|
||||
2, /* 2 column vector */
|
||||
FALSE, /* no transpose */
|
||||
matrix2x2);
|
||||
}
|
||||
|
||||
CoglAttribute *
|
||||
cogl_attribute_new_const_3x3fv (CoglContext *context,
|
||||
const char *name,
|
||||
const float *matrix3x3,
|
||||
CoglBool transpose)
|
||||
{
|
||||
return _cogl_attribute_new_const (context,
|
||||
name,
|
||||
3, /* n_components */
|
||||
3, /* 3 column vector */
|
||||
FALSE, /* no transpose */
|
||||
matrix3x3);
|
||||
}
|
||||
|
||||
CoglAttribute *
|
||||
cogl_attribute_new_const_4x4fv (CoglContext *context,
|
||||
const char *name,
|
||||
const float *matrix4x4,
|
||||
CoglBool transpose)
|
||||
{
|
||||
return _cogl_attribute_new_const (context,
|
||||
name,
|
||||
4, /* n_components */
|
||||
4, /* 4 column vector */
|
||||
FALSE, /* no transpose */
|
||||
matrix4x4);
|
||||
}
|
||||
|
||||
CoglBool
|
||||
cogl_attribute_get_normalized (CoglAttribute *attribute)
|
||||
{
|
||||
@ -272,8 +486,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 +496,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);
|
||||
}
|
||||
|
@ -141,6 +141,317 @@ cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
|
||||
int components,
|
||||
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:
|
||||
*
|
||||
* [|
|
||||
* attribute 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:
|
||||
*
|
||||
* [|
|
||||
* attribute 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:
|
||||
*
|
||||
* [|
|
||||
* attribute 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:
|
||||
*
|
||||
* [|
|
||||
* attribute 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:
|
||||
*
|
||||
* [|
|
||||
* attribute vec2 name;
|
||||
* |]
|
||||
*
|
||||
* Returns: A newly allocated #CoglAttribute representing the given
|
||||
* constant vector.
|
||||
*/
|
||||
CoglAttribute *
|
||||
cogl_attribute_new_const_2fv (CoglContext *context,
|
||||
const char *name,
|
||||
const 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:
|
||||
*
|
||||
* [|
|
||||
* attribute 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,
|
||||
const 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:
|
||||
*
|
||||
* [|
|
||||
* attribute 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,
|
||||
const 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:
|
||||
*
|
||||
* [|
|
||||
* attribute 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,
|
||||
const 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:
|
||||
*
|
||||
* [|
|
||||
* attribute 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,
|
||||
const 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:
|
||||
*
|
||||
* [|
|
||||
* attribute 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,
|
||||
const float *matrix4x4,
|
||||
CoglBool transpose);
|
||||
|
||||
/**
|
||||
* cogl_attribute_set_normalized:
|
||||
* @attribute: A #CoglAttribute
|
||||
|
@ -152,29 +152,187 @@ 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)
|
||||
@ -305,88 +463,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
|
||||
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
|
||||
setup_generic_attribute (ctx, pipeline, attribute, base);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
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);
|
||||
attribute_buffer = cogl_attribute_get_buffer (attribute);
|
||||
buffer = COGL_BUFFER (attribute_buffer);
|
||||
base = _cogl_buffer_gl_bind (buffer,
|
||||
COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER);
|
||||
|
||||
_cogl_bitmask_set (&ctx->enable_texcoord_attributes_tmp,
|
||||
unit, TRUE);
|
||||
GE (ctx, glClientActiveTexture (GL_TEXTURE0 + 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
|
||||
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_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_buffered_attribute (ctx, pipeline, attribute, base);
|
||||
|
||||
_cogl_buffer_gl_unbind (buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
|
||||
setup_generic_const_attribute (ctx, pipeline, attribute);
|
||||
else
|
||||
setup_legacy_const_attribute (ctx, pipeline, attribute);
|
||||
}
|
||||
|
||||
_cogl_buffer_gl_unbind (buffer);
|
||||
}
|
||||
|
||||
apply_attribute_enable_updates (ctx, pipeline);
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user