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:
Neil Roberts 2010-12-03 17:46:16 +00:00
parent 1515a8d73a
commit 4514d49dda
11 changed files with 455 additions and 138 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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 ();

View File

@ -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 */

View File

@ -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") );

View File

@ -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 */

View File

@ -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

View File

@ -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