diff options
Diffstat (limited to 'cogl/driver/gl/cogl-attribute-gl.c')
-rw-r--r-- | cogl/driver/gl/cogl-attribute-gl.c | 272 |
1 files changed, 186 insertions, 86 deletions
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); |