mirror of
https://github.com/brl/mutter.git
synced 2024-11-12 17:27:03 -05:00
cogl-vertex-attribute: Use glVertexAttribPointer on GLES2
When the GLES2 wrapper is removed we can't use the fixed function API such as glColorPointer to set the builtin attributes. Instead the GLSL progend now maintains a cache of attribute locations that are queried with glGetAttribLocation. The code that previously maintained a cache of the enabled texture coord arrays has been modified to also cache the enabled vertex attributes under GLES2. The vertex attribute API is now the only place that is using this cache so it has been moved into cogl-vertex-attribute.c
This commit is contained in:
parent
12b3d21aaa
commit
e38e9e0355
@ -172,8 +172,8 @@ _cogl_bitmask_set_range_in_array (CoglBitmask *bitmask,
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_bitmask_clear_bits (CoglBitmask *dst,
|
||||
const CoglBitmask *src)
|
||||
_cogl_bitmask_xor_bits (CoglBitmask *dst,
|
||||
const CoglBitmask *src)
|
||||
{
|
||||
if (_cogl_bitmask_has_array (src))
|
||||
{
|
||||
@ -190,8 +190,8 @@ _cogl_bitmask_clear_bits (CoglBitmask *dst,
|
||||
g_array_set_size (dst_array, src_array->len);
|
||||
|
||||
for (i = 0; i < src_array->len; i++)
|
||||
g_array_index (dst_array, unsigned int, i) &=
|
||||
~g_array_index (src_array, unsigned int, i);
|
||||
g_array_index (dst_array, unsigned int, i) ^=
|
||||
g_array_index (src_array, unsigned int, i);
|
||||
}
|
||||
else if (_cogl_bitmask_has_array (dst))
|
||||
{
|
||||
@ -199,12 +199,12 @@ _cogl_bitmask_clear_bits (CoglBitmask *dst,
|
||||
|
||||
dst_array = (GArray *) *dst;
|
||||
|
||||
g_array_index (dst_array, unsigned int, 0) &=
|
||||
~(GPOINTER_TO_UINT (*src) >> 1);
|
||||
g_array_index (dst_array, unsigned int, 0) ^=
|
||||
(GPOINTER_TO_UINT (*src) >> 1);
|
||||
}
|
||||
else
|
||||
*dst = GUINT_TO_POINTER ((GPOINTER_TO_UINT (*dst) &
|
||||
~GPOINTER_TO_UINT (*src)) | 1);
|
||||
*dst = GUINT_TO_POINTER ((GPOINTER_TO_UINT (*dst) ^
|
||||
GPOINTER_TO_UINT (*src)) | 1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -99,16 +99,16 @@ _cogl_bitmask_set_bits (CoglBitmask *dst,
|
||||
const CoglBitmask *src);
|
||||
|
||||
/*
|
||||
* cogl_bitmask_clear_bits:
|
||||
* cogl_bitmask_xor_bits:
|
||||
* @dst: The bitmask to modify
|
||||
* @src: The bitmask to copy bits from
|
||||
*
|
||||
* This makes sure that all of the bits that are set in @src are
|
||||
* cleared in @dst. Any unset bits in @src are left alone in @dst.
|
||||
* For every bit that is set in src, the corresponding bit in dst is
|
||||
* inverted.
|
||||
*/
|
||||
void
|
||||
_cogl_bitmask_clear_bits (CoglBitmask *dst,
|
||||
const CoglBitmask *src);
|
||||
_cogl_bitmask_xor_bits (CoglBitmask *dst,
|
||||
const CoglBitmask *src);
|
||||
|
||||
typedef void (* CoglBitmaskForeachFunc) (int bit_num, gpointer user_data);
|
||||
|
||||
|
@ -183,9 +183,9 @@ cogl_create_context (void)
|
||||
_context->pipeline1_nodes =
|
||||
g_array_sized_new (FALSE, FALSE, sizeof (CoglHandle), 20);
|
||||
|
||||
_cogl_bitmask_init (&_context->texcoord_arrays_enabled);
|
||||
_cogl_bitmask_init (&_context->arrays_enabled);
|
||||
_cogl_bitmask_init (&_context->temp_bitmask);
|
||||
_cogl_bitmask_init (&_context->texcoord_arrays_to_disable);
|
||||
_cogl_bitmask_init (&_context->arrays_to_change);
|
||||
|
||||
_context->max_texture_units = -1;
|
||||
_context->max_texture_image_units = -1;
|
||||
@ -356,9 +356,9 @@ _cogl_destroy_context (void)
|
||||
if (_context->atlas)
|
||||
_cogl_atlas_free (_context->atlas);
|
||||
|
||||
_cogl_bitmask_destroy (&_context->texcoord_arrays_enabled);
|
||||
_cogl_bitmask_destroy (&_context->arrays_enabled);
|
||||
_cogl_bitmask_destroy (&_context->temp_bitmask);
|
||||
_cogl_bitmask_destroy (&_context->texcoord_arrays_to_disable);
|
||||
_cogl_bitmask_destroy (&_context->arrays_to_change);
|
||||
|
||||
g_slist_free (_context->texture_types);
|
||||
g_slist_free (_context->buffer_types);
|
||||
|
@ -120,12 +120,14 @@ typedef struct
|
||||
GArray *pipeline0_nodes;
|
||||
GArray *pipeline1_nodes;
|
||||
|
||||
/* Bitmask of texture coordinates arrays that are enabled */
|
||||
CoglBitmask texcoord_arrays_enabled;
|
||||
/* Bitmask of attributes enabled. On GLES2 these are the vertex
|
||||
attribute numbers and on regular GL these are only used for the
|
||||
texture coordinate arrays */
|
||||
CoglBitmask arrays_enabled;
|
||||
/* These are temporary bitmasks that are used when disabling
|
||||
texcoord arrays. They are here just to avoid allocating new ones
|
||||
each time */
|
||||
CoglBitmask texcoord_arrays_to_disable;
|
||||
CoglBitmask arrays_to_change;
|
||||
CoglBitmask temp_bitmask;
|
||||
|
||||
gboolean gl_blend_enable_cache;
|
||||
|
@ -115,12 +115,6 @@ _cogl_get_enable (void);
|
||||
void
|
||||
_cogl_flush_face_winding (void);
|
||||
|
||||
/* Disables the texcoord arrays that don't have a corresponding bit
|
||||
set in the mask and sets ctx->texcoord_arrays_enabled to mask. Note
|
||||
that it doesn't enable any extra texcoord arrays */
|
||||
void
|
||||
_cogl_disable_other_texcoord_arrays (const CoglBitmask *mask);
|
||||
|
||||
void
|
||||
_cogl_transform_point (const CoglMatrix *matrix_mv,
|
||||
const CoglMatrix *matrix_p,
|
||||
|
@ -37,6 +37,11 @@
|
||||
#include "cogl-context.h"
|
||||
#include "cogl-texture-private.h"
|
||||
|
||||
/* This is needed to set the color attribute on GLES2 */
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
#include "cogl-pipeline-progend-glsl-private.h"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -477,6 +482,8 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* On GLES2 we'll flush the color later */
|
||||
#ifndef HAVE_COGL_GLES2
|
||||
if (!skip_gl_color)
|
||||
{
|
||||
if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) ||
|
||||
@ -492,6 +499,7 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
|
||||
cogl_color_get_alpha_byte (&authority->color)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pipelines_difference & COGL_PIPELINE_STATE_BLEND)
|
||||
{
|
||||
@ -1091,7 +1099,6 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
||||
* 2) then foreach layer:
|
||||
* determine gl_target/gl_texture
|
||||
* bind texture
|
||||
* flush user matrix
|
||||
*
|
||||
* Note: After _cogl_pipeline_flush_common_gl_state you can expect
|
||||
* all state of the layers corresponding texture unit to be
|
||||
@ -1232,6 +1239,27 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
||||
|
||||
done:
|
||||
|
||||
/* We can't assume the color will be retained between flushes on
|
||||
GLES2 because the generic attribute values are not stored as part
|
||||
of the program object so they could be overridden by any
|
||||
attribute changes in another program */
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
if (!skip_gl_color)
|
||||
{
|
||||
int attribute;
|
||||
CoglPipeline *authority =
|
||||
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR);
|
||||
|
||||
attribute = _cogl_pipeline_progend_glsl_get_color_attribute (pipeline);
|
||||
if (attribute != -1)
|
||||
GE (glVertexAttrib4f (attribute,
|
||||
cogl_color_get_red_float (&authority->color),
|
||||
cogl_color_get_green_float (&authority->color),
|
||||
cogl_color_get_blue_float (&authority->color),
|
||||
cogl_color_get_alpha_float (&authority->color)));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Handle the fact that OpenGL associates texture filter and wrap
|
||||
* modes with the texture objects not the texture units... */
|
||||
foreach_texture_unit_update_filter_and_wrap_modes ();
|
||||
|
@ -29,8 +29,26 @@
|
||||
#define __COGL_PIPELINE_PROGEND_GLSL_PRIVATE_H
|
||||
|
||||
#include "cogl-pipeline-private.h"
|
||||
#include "cogl-vertex-attribute-private.h"
|
||||
|
||||
extern const CoglPipelineProgend _cogl_pipeline_glsl_progend;
|
||||
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
||||
int
|
||||
_cogl_pipeline_progend_glsl_get_position_attribute (CoglPipeline *pipeline);
|
||||
|
||||
int
|
||||
_cogl_pipeline_progend_glsl_get_color_attribute (CoglPipeline *pipeline);
|
||||
|
||||
int
|
||||
_cogl_pipeline_progend_glsl_get_normal_attribute (CoglPipeline *pipeline);
|
||||
|
||||
int
|
||||
_cogl_pipeline_progend_glsl_get_tex_coord_attribute (CoglPipeline *pipeline,
|
||||
int unit);
|
||||
|
||||
#endif /* HAVE_COGL_GLES2 */
|
||||
|
||||
#endif /* __COGL_PIPELINE_PROGEND_GLSL_PRIVATE_H */
|
||||
|
||||
|
@ -94,6 +94,18 @@ typedef struct
|
||||
|
||||
gboolean dirty_point_size;
|
||||
GLint point_size_uniform;
|
||||
|
||||
/* Under GLES2 we can't use the builtin functions to set attribute
|
||||
pointers such as the vertex position. Instead the vertex
|
||||
attribute code needs to query the attribute numbers from the
|
||||
progend backend */
|
||||
int position_attribute_location;
|
||||
int color_attribute_location;
|
||||
int normal_attribute_location;
|
||||
int tex_coord0_attribute_location;
|
||||
/* We only allocate this array if more than one tex coord attribute
|
||||
is requested because most pipelines will only use one layer */
|
||||
GArray *tex_coord_attribute_locations;
|
||||
#endif
|
||||
|
||||
/* We need to track the last pipeline that the program was used with
|
||||
@ -125,6 +137,124 @@ get_glsl_priv (CoglPipeline *pipeline)
|
||||
return cogl_object_get_user_data (COGL_OBJECT (pipeline), &glsl_priv_key);
|
||||
}
|
||||
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
||||
#define ATTRIBUTE_LOCATION_UNKNOWN -2
|
||||
|
||||
/* Under GLES2 the vertex attribute API needs to query the attribute
|
||||
numbers because it can't used the fixed function API to set the
|
||||
builtin attributes. We cache the attributes here because the
|
||||
progend knows when the program is changed so it can clear the
|
||||
cache. This should always be called after the pipeline is flushed
|
||||
so they can assert that the gl program is valid */
|
||||
|
||||
int
|
||||
_cogl_pipeline_progend_glsl_get_position_attribute (CoglPipeline *pipeline)
|
||||
{
|
||||
CoglPipelineProgendPrivate *priv = get_glsl_priv (pipeline);
|
||||
|
||||
g_return_val_if_fail (priv != NULL, -1);
|
||||
g_return_val_if_fail (priv->program != 0, -1);
|
||||
|
||||
if (priv->position_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN)
|
||||
GE_RET( priv->position_attribute_location,
|
||||
glGetAttribLocation (priv->program, "cogl_position_in") );
|
||||
|
||||
return priv->position_attribute_location;
|
||||
}
|
||||
|
||||
int
|
||||
_cogl_pipeline_progend_glsl_get_color_attribute (CoglPipeline *pipeline)
|
||||
{
|
||||
CoglPipelineProgendPrivate *priv = get_glsl_priv (pipeline);
|
||||
|
||||
g_return_val_if_fail (priv != NULL, -1);
|
||||
g_return_val_if_fail (priv->program != 0, -1);
|
||||
|
||||
if (priv->color_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN)
|
||||
GE_RET( priv->color_attribute_location,
|
||||
glGetAttribLocation (priv->program, "cogl_color_in") );
|
||||
|
||||
return priv->color_attribute_location;
|
||||
}
|
||||
|
||||
int
|
||||
_cogl_pipeline_progend_glsl_get_normal_attribute (CoglPipeline *pipeline)
|
||||
{
|
||||
CoglPipelineProgendPrivate *priv = get_glsl_priv (pipeline);
|
||||
|
||||
g_return_val_if_fail (priv != NULL, -1);
|
||||
g_return_val_if_fail (priv->program != 0, -1);
|
||||
|
||||
if (priv->normal_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN)
|
||||
GE_RET( priv->normal_attribute_location,
|
||||
glGetAttribLocation (priv->program, "cogl_normal_in") );
|
||||
|
||||
return priv->normal_attribute_location;
|
||||
}
|
||||
|
||||
int
|
||||
_cogl_pipeline_progend_glsl_get_tex_coord_attribute (CoglPipeline *pipeline,
|
||||
int unit)
|
||||
{
|
||||
CoglPipelineProgendPrivate *priv = get_glsl_priv (pipeline);
|
||||
|
||||
g_return_val_if_fail (priv != NULL, -1);
|
||||
g_return_val_if_fail (priv->program != 0, -1);
|
||||
|
||||
if (unit == 0)
|
||||
{
|
||||
if (priv->tex_coord0_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN)
|
||||
GE_RET( priv->tex_coord0_attribute_location,
|
||||
glGetAttribLocation (priv->program, "cogl_tex_coord0_in") );
|
||||
|
||||
return priv->tex_coord0_attribute_location;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *name = g_strdup_printf ("cogl_tex_coord%i_in", unit);
|
||||
int *locations;
|
||||
|
||||
if (priv->tex_coord_attribute_locations == NULL)
|
||||
priv->tex_coord_attribute_locations = g_array_new (FALSE, FALSE,
|
||||
sizeof (int));
|
||||
if (priv->tex_coord_attribute_locations->len <= unit - 1)
|
||||
{
|
||||
int i = priv->tex_coord_attribute_locations->len;
|
||||
g_array_set_size (priv->tex_coord_attribute_locations, unit);
|
||||
for (; i < unit; i++)
|
||||
g_array_index (priv->tex_coord_attribute_locations, int, i) =
|
||||
ATTRIBUTE_LOCATION_UNKNOWN;
|
||||
}
|
||||
|
||||
locations = &g_array_index (priv->tex_coord_attribute_locations, int, 0);
|
||||
|
||||
if (locations[unit - 1] == ATTRIBUTE_LOCATION_UNKNOWN)
|
||||
GE_RET( locations[unit - 1],
|
||||
glGetAttribLocation (priv->program, name) );
|
||||
|
||||
g_free (name);
|
||||
|
||||
return locations[unit - 1];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clear_attribute_cache (CoglPipelineProgendPrivate *priv)
|
||||
{
|
||||
priv->position_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN;
|
||||
priv->color_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN;
|
||||
priv->normal_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN;
|
||||
priv->tex_coord0_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN;
|
||||
if (priv->tex_coord_attribute_locations)
|
||||
{
|
||||
g_array_free (priv->tex_coord_attribute_locations, TRUE);
|
||||
priv->tex_coord_attribute_locations = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_COGL_GLES2 */
|
||||
|
||||
static void
|
||||
destroy_glsl_priv (void *user_data)
|
||||
{
|
||||
@ -132,6 +262,10 @@ destroy_glsl_priv (void *user_data)
|
||||
|
||||
if (--priv->ref_count == 0)
|
||||
{
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
clear_attribute_cache (priv);
|
||||
#endif
|
||||
|
||||
if (priv->program)
|
||||
delete_program (priv->program);
|
||||
|
||||
@ -360,6 +494,9 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
|
||||
priv->n_tex_coord_attribs = 0;
|
||||
priv->unit_state = g_new (UnitState,
|
||||
cogl_pipeline_get_n_layers (pipeline));
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
priv->tex_coord_attribute_locations = NULL;
|
||||
#endif
|
||||
set_glsl_priv (authority, priv);
|
||||
}
|
||||
|
||||
@ -475,6 +612,8 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
if (program_changed)
|
||||
{
|
||||
clear_attribute_cache (priv);
|
||||
|
||||
GE_RET( priv->alpha_test_reference_uniform,
|
||||
glGetUniformLocation (gl_program,
|
||||
"_cogl_alpha_test_ref") );
|
||||
|
@ -76,5 +76,8 @@ _cogl_draw_indexed_vertex_attributes_array (CoglVerticesMode mode,
|
||||
CoglIndices *indices,
|
||||
CoglVertexAttribute **attributes);
|
||||
|
||||
void
|
||||
_cogl_vertex_attribute_disable_cached_arrays (void);
|
||||
|
||||
#endif /* __COGL_VERTEX_ATTRIBUTE_PRIVATE_H */
|
||||
|
||||
|
@ -40,6 +40,9 @@
|
||||
#include "cogl-texture-private.h"
|
||||
#include "cogl-framebuffer-private.h"
|
||||
#include "cogl-indices-private.h"
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
#include "cogl-pipeline-progend-glsl-private.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -423,6 +426,54 @@ validated:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_enabled_cb (int bit_num, void *user_data)
|
||||
{
|
||||
const CoglBitmask *new_values = user_data;
|
||||
gboolean enabled = _cogl_bitmask_get (new_values, bit_num);
|
||||
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
||||
if (enabled)
|
||||
GE( glEnableVertexAttribArray (bit_num) );
|
||||
else
|
||||
GE( glDisableVertexAttribArray (bit_num) );
|
||||
|
||||
#else /* HAVE_COGL_GLES2 */
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
GE( glClientActiveTexture (GL_TEXTURE0 + bit_num) );
|
||||
|
||||
if (enabled)
|
||||
GE( glEnableClientState (GL_TEXTURE_COORD_ARRAY) );
|
||||
else
|
||||
GE( glDisableClientState (GL_TEXTURE_COORD_ARRAY) );
|
||||
|
||||
#endif /* HAVE_COGL_GLES2 */
|
||||
}
|
||||
|
||||
static void
|
||||
set_enabled_arrays (CoglBitmask *value_cache,
|
||||
const CoglBitmask *new_values)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* Get the list of bits that are different */
|
||||
_cogl_bitmask_clear_all (&ctx->arrays_to_change);
|
||||
_cogl_bitmask_set_bits (&ctx->arrays_to_change, value_cache);
|
||||
_cogl_bitmask_xor_bits (&ctx->arrays_to_change, new_values);
|
||||
|
||||
/* Iterate over each bit to change */
|
||||
_cogl_bitmask_foreach (&ctx->arrays_to_change,
|
||||
toggle_enabled_cb,
|
||||
(void *) new_values);
|
||||
|
||||
/* Store the new values */
|
||||
_cogl_bitmask_clear_all (value_cache);
|
||||
_cogl_bitmask_set_bits (value_cache, new_values);
|
||||
}
|
||||
|
||||
static CoglHandle
|
||||
enable_gl_state (CoglVertexAttribute **attributes,
|
||||
ValidateLayerState *state)
|
||||
@ -441,89 +492,31 @@ enable_gl_state (CoglVertexAttribute **attributes,
|
||||
|
||||
source = cogl_get_source ();
|
||||
|
||||
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
|
||||
|
||||
/* Iterate the attributes to work out whether blending needs to be
|
||||
enabled and how many texture coords there are. We need to do this
|
||||
before flushing the pipeline. */
|
||||
for (i = 0; attributes[i]; i++)
|
||||
{
|
||||
CoglVertexAttribute *attribute = attributes[i];
|
||||
CoglVertexArray *vertex_array;
|
||||
CoglBuffer *buffer;
|
||||
void *base;
|
||||
|
||||
vertex_array = cogl_vertex_attribute_get_array (attribute);
|
||||
buffer = COGL_BUFFER (vertex_array);
|
||||
base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_VERTEX_ARRAY);
|
||||
|
||||
switch (attribute->name_id)
|
||||
{
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
|
||||
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
|
||||
/* GE (glEnableClientState (GL_COLOR_ARRAY)); */
|
||||
GE (glColorPointer (attribute->n_components,
|
||||
attribute->type,
|
||||
attribute->stride,
|
||||
base + attribute->offset));
|
||||
|
||||
if (!_cogl_pipeline_get_real_blend_enabled (source))
|
||||
{
|
||||
CoglPipelineBlendEnable blend_enable =
|
||||
COGL_PIPELINE_BLEND_ENABLE_ENABLED;
|
||||
copy = cogl_pipeline_copy (source);
|
||||
_cogl_pipeline_set_blend_enabled (copy, blend_enable);
|
||||
source = copy;
|
||||
}
|
||||
skip_gl_color = TRUE;
|
||||
break;
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
|
||||
/* FIXME: go through cogl cache to enable normal array */
|
||||
GE (glEnableClientState (GL_NORMAL_ARRAY));
|
||||
GE (glNormalPointer (attribute->type,
|
||||
attribute->stride,
|
||||
base + attribute->offset));
|
||||
break;
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
|
||||
GE (glClientActiveTexture (GL_TEXTURE0 +
|
||||
attribute->texture_unit));
|
||||
GE (glEnableClientState (GL_TEXTURE_COORD_ARRAY));
|
||||
GE (glTexCoordPointer (attribute->n_components,
|
||||
attribute->type,
|
||||
attribute->stride,
|
||||
base + attribute->offset));
|
||||
_cogl_bitmask_set (&ctx->temp_bitmask,
|
||||
attribute->texture_unit, TRUE);
|
||||
n_tex_coord_attribs++;
|
||||
break;
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
|
||||
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
|
||||
/* GE (glEnableClientState (GL_VERTEX_ARRAY)); */
|
||||
GE (glVertexPointer (attribute->n_components,
|
||||
attribute->type,
|
||||
attribute->stride,
|
||||
base + attribute->offset));
|
||||
break;
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
|
||||
switch (attributes[i]->name_id)
|
||||
{
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
|
||||
if (!_cogl_pipeline_get_real_blend_enabled (source))
|
||||
{
|
||||
#ifdef MAY_HAVE_PROGRAMABLE_GL
|
||||
/* FIXME: go through cogl cache to enable generic array */
|
||||
GE (glEnableVertexAttribArray (generic_index++));
|
||||
GE (glVertexAttribPointer (generic_index,
|
||||
attribute->n_components,
|
||||
attribute->type,
|
||||
attribute->normalized,
|
||||
attribute->stride,
|
||||
base + attribute->offset));
|
||||
#endif
|
||||
CoglPipelineBlendEnable blend_enable =
|
||||
COGL_PIPELINE_BLEND_ENABLE_ENABLED;
|
||||
copy = cogl_pipeline_copy (source);
|
||||
_cogl_pipeline_set_blend_enabled (copy, blend_enable);
|
||||
source = copy;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_warning ("Unrecognised attribute type 0x%08x", attribute->type);
|
||||
}
|
||||
skip_gl_color = TRUE;
|
||||
break;
|
||||
|
||||
_cogl_buffer_unbind (buffer);
|
||||
}
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
|
||||
n_tex_coord_attribs++;
|
||||
break;
|
||||
|
||||
/* Disable any tex coord arrays that we didn't use */
|
||||
_cogl_disable_other_texcoord_arrays (&ctx->temp_bitmask);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (state->options.flags))
|
||||
{
|
||||
@ -585,12 +578,180 @@ enable_gl_state (CoglVertexAttribute **attributes,
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
|
||||
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
|
||||
|
||||
/* Bind the attribute pointers. We need to do this after the
|
||||
pipeline is flushed because on GLES2 that is the only point when
|
||||
we can determine the attribute locations */
|
||||
|
||||
for (i = 0; attributes[i]; i++)
|
||||
{
|
||||
CoglVertexAttribute *attribute = attributes[i];
|
||||
CoglVertexArray *vertex_array;
|
||||
CoglBuffer *buffer;
|
||||
void *base;
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
int attrib_location;
|
||||
#endif
|
||||
|
||||
vertex_array = cogl_vertex_attribute_get_array (attribute);
|
||||
buffer = COGL_BUFFER (vertex_array);
|
||||
base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_VERTEX_ARRAY);
|
||||
|
||||
switch (attribute->name_id)
|
||||
{
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
||||
attrib_location =
|
||||
_cogl_pipeline_progend_glsl_get_color_attribute (source);
|
||||
if (attrib_location != -1)
|
||||
{
|
||||
GE( glVertexAttribPointer (attrib_location,
|
||||
attribute->n_components,
|
||||
attribute->type,
|
||||
TRUE, /* normalize */
|
||||
attribute->stride,
|
||||
base + attribute->offset) );
|
||||
|
||||
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
|
||||
/* GE (glEnableClientState (GL_COLOR_ARRAY)); */
|
||||
GE (glColorPointer (attribute->n_components,
|
||||
attribute->type,
|
||||
attribute->stride,
|
||||
base + attribute->offset));
|
||||
|
||||
#endif
|
||||
|
||||
break;
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
||||
attrib_location =
|
||||
_cogl_pipeline_progend_glsl_get_normal_attribute (source);
|
||||
if (attrib_location != -1)
|
||||
{
|
||||
GE( glVertexAttribPointer (attrib_location,
|
||||
attribute->n_components,
|
||||
attribute->type,
|
||||
TRUE, /* normalize */
|
||||
attribute->stride,
|
||||
base + attribute->offset) );
|
||||
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* FIXME: go through cogl cache to enable normal array */
|
||||
GE (glEnableClientState (GL_NORMAL_ARRAY));
|
||||
GE (glNormalPointer (attribute->type,
|
||||
attribute->stride,
|
||||
base + attribute->offset));
|
||||
|
||||
#endif
|
||||
|
||||
break;
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
||||
attrib_location = _cogl_pipeline_progend_glsl_get_tex_coord_attribute
|
||||
(source, attribute->texture_unit);
|
||||
if (attrib_location != -1)
|
||||
{
|
||||
GE( glVertexAttribPointer (attrib_location,
|
||||
attribute->n_components,
|
||||
attribute->type,
|
||||
FALSE, /* normalize */
|
||||
attribute->stride,
|
||||
base + attribute->offset) );
|
||||
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
|
||||
}
|
||||
#else
|
||||
|
||||
GE (glClientActiveTexture (GL_TEXTURE0 +
|
||||
attribute->texture_unit));
|
||||
GE (glTexCoordPointer (attribute->n_components,
|
||||
attribute->type,
|
||||
attribute->stride,
|
||||
base + attribute->offset));
|
||||
_cogl_bitmask_set (&ctx->temp_bitmask,
|
||||
attribute->texture_unit, TRUE);
|
||||
|
||||
#endif
|
||||
break;
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
||||
attrib_location =
|
||||
_cogl_pipeline_progend_glsl_get_position_attribute (source);
|
||||
if (attrib_location != -1)
|
||||
{
|
||||
GE( glVertexAttribPointer (attrib_location,
|
||||
attribute->n_components,
|
||||
attribute->type,
|
||||
FALSE, /* normalize */
|
||||
attribute->stride,
|
||||
base + attribute->offset) );
|
||||
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
|
||||
/* GE (glEnableClientState (GL_VERTEX_ARRAY)); */
|
||||
GE (glVertexPointer (attribute->n_components,
|
||||
attribute->type,
|
||||
attribute->stride,
|
||||
base + attribute->offset));
|
||||
|
||||
#endif
|
||||
break;
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
|
||||
{
|
||||
#ifdef MAY_HAVE_PROGRAMABLE_GL
|
||||
/* FIXME: go through cogl cache to enable generic array. */
|
||||
/* FIXME: this is going to end up just using the builtins
|
||||
on GLES 2 */
|
||||
GE (glEnableVertexAttribArray (generic_index++));
|
||||
GE (glVertexAttribPointer (generic_index,
|
||||
attribute->n_components,
|
||||
attribute->type,
|
||||
attribute->normalized,
|
||||
attribute->stride,
|
||||
base + attribute->offset));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_warning ("Unrecognised attribute type 0x%08x", attribute->type);
|
||||
}
|
||||
|
||||
_cogl_buffer_unbind (buffer);
|
||||
}
|
||||
|
||||
/* Flush the state of the attribute arrays */
|
||||
set_enabled_arrays (&ctx->arrays_enabled, &ctx->temp_bitmask);
|
||||
|
||||
_cogl_enable (enable_flags);
|
||||
_cogl_flush_face_winding ();
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_vertex_attribute_disable_cached_arrays (void)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
|
||||
set_enabled_arrays (&ctx->arrays_enabled, &ctx->temp_bitmask);
|
||||
}
|
||||
|
||||
/* FIXME: we shouldn't be disabling state after drawing we should
|
||||
* just disable the things not needed after enabling state. */
|
||||
static void
|
||||
@ -618,7 +779,9 @@ disable_gl_state (CoglVertexAttribute **attributes,
|
||||
break;
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
|
||||
/* FIXME: go through cogl cache to enable normal array */
|
||||
#ifndef HAVE_COGL_GLES2
|
||||
GE (glDisableClientState (GL_NORMAL_ARRAY));
|
||||
#endif
|
||||
break;
|
||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
|
||||
/* The enabled state of the texture coord arrays is
|
||||
|
36
cogl/cogl.c
36
cogl/cogl.c
@ -45,6 +45,7 @@
|
||||
#include "cogl-bitmap-private.h"
|
||||
#include "cogl-texture-private.h"
|
||||
#include "cogl-texture-driver.h"
|
||||
#include "cogl-vertex-attribute-private.h"
|
||||
|
||||
#if defined (HAVE_COGL_GLES2) || defined (HAVE_COGL_GLES)
|
||||
#include "cogl-gles2-wrapper.h"
|
||||
@ -702,36 +703,6 @@ cogl_read_pixels (int x,
|
||||
_cogl_get_format_bpp (format) * width);
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_disable_other_texcoord_arrays_cb (int texcoord_array_num, gpointer data)
|
||||
{
|
||||
CoglContext *ctx = data;
|
||||
|
||||
GE (glClientActiveTexture (GL_TEXTURE0 + texcoord_array_num));
|
||||
GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_disable_other_texcoord_arrays (const CoglBitmask *mask)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* Set texcoord_arrays_to_disable to only contain the arrays we want
|
||||
to disable */
|
||||
_cogl_bitmask_clear_all (&ctx->texcoord_arrays_to_disable);
|
||||
_cogl_bitmask_set_bits (&ctx->texcoord_arrays_to_disable,
|
||||
&ctx->texcoord_arrays_enabled);
|
||||
_cogl_bitmask_clear_bits (&ctx->texcoord_arrays_to_disable, mask);
|
||||
|
||||
_cogl_bitmask_foreach (&ctx->texcoord_arrays_to_disable,
|
||||
_cogl_disable_other_texcoord_arrays_cb, ctx);
|
||||
|
||||
/* Update the mask of arrays that are enabled */
|
||||
_cogl_bitmask_clear_bits (&ctx->texcoord_arrays_enabled,
|
||||
&ctx->texcoord_arrays_to_disable);
|
||||
_cogl_bitmask_set_bits (&ctx->texcoord_arrays_enabled, mask);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_begin_gl (void)
|
||||
{
|
||||
@ -791,9 +762,8 @@ cogl_begin_gl (void)
|
||||
_cogl_enable (enable_flags);
|
||||
_cogl_flush_face_winding ();
|
||||
|
||||
/* Disable all client texture coordinate arrays */
|
||||
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
|
||||
_cogl_disable_other_texcoord_arrays (&ctx->temp_bitmask);
|
||||
/* Disable any cached vertex arrays */
|
||||
_cogl_vertex_attribute_disable_cached_arrays ();
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user