static void translate_sources (CoglPipeline *pipeline, int n_sources, CoglPipelineCombineSource *source_in, GLenum *source_out) { int i; /* The texture source numbers specified in the layer combine are the layer numbers so we need to map these to unit indices */ for (i = 0; i < n_sources; i++) switch (source_in[i]) { case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: source_out[i] = GL_TEXTURE; break; case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: source_out[i] = GL_CONSTANT; break; case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: source_out[i] = GL_PRIMARY_COLOR; break; case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS: source_out[i] = GL_PREVIOUS; break; default: { int layer_num = source_in[i] - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; CoglPipelineGetLayerFlags flags = COGL_PIPELINE_GET_LAYER_NO_CREATE; CoglPipelineLayer *layer = _cogl_pipeline_get_layer_with_flags (pipeline, layer_num, flags); if (layer == NULL) { static CoglBool warning_seen = FALSE; if (!warning_seen) { g_warning ("The application is trying to use a texture " "combine with a layer number that does not exist"); warning_seen = TRUE; } source_out[i] = GL_PREVIOUS; } else source_out[i] = (_cogl_pipeline_layer_get_unit_index (layer) + GL_TEXTURE0); } } }
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; const CoglPipelineGetLayerFlags flags = COGL_PIPELINE_GET_LAYER_NO_CREATE; CoglPipelineLayer *layer = _cogl_pipeline_get_layer_with_flags (pipeline, layer_number, flags); if (layer) { 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 (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE)) 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 (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE)) 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; const CoglPipelineGetLayerFlags flags = COGL_PIPELINE_GET_LAYER_NO_CREATE; CoglPipelineLayer *layer = _cogl_pipeline_get_layer_with_flags (pipeline, layer_number, flags); if (layer) { 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 (); } } }
/* Note: we are trying to avoid duplicating strings during codegen * which is why we have the slightly awkward * CoglPipelineFragendARBfpArg mechanism. */ static void setup_arg (CoglPipeline *pipeline, CoglPipelineLayer *layer, CoglBlendStringChannelMask mask, int arg_index, CoglPipelineCombineSource src, GLint op, CoglPipelineFragendARBfpArg *arg) { CoglPipelineShaderState *shader_state = get_shader_state (pipeline); static const char *tmp_name[3] = { "tmp0", "tmp1", "tmp2" }; switch (src) { case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE; arg->name = "texel%d"; arg->texture_unit = _cogl_pipeline_layer_get_unit_index (layer); setup_texture_source (shader_state, arg->texture_unit, _cogl_pipeline_layer_get_texture_type (layer)); break; case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: { int unit_index = _cogl_pipeline_layer_get_unit_index (layer); UnitState *unit_state = &shader_state->unit_state[unit_index]; unit_state->constant_id = shader_state->next_constant_id++; unit_state->has_combine_constant = TRUE; unit_state->dirty_combine_constant = TRUE; arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_CONSTANT; arg->name = "program.local[%d]"; arg->constant_id = unit_state->constant_id; break; } case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; arg->name = "fragment.color.primary"; break; case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS: arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; if (_cogl_pipeline_layer_get_unit_index (layer) == 0) arg->name = "fragment.color.primary"; else arg->name = "output"; break; default: /* Sample the texture attached to a specific layer */ { int layer_num = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; CoglPipelineGetLayerFlags flags = COGL_PIPELINE_GET_LAYER_NO_CREATE; CoglPipelineLayer *other_layer = _cogl_pipeline_get_layer_with_flags (pipeline, layer_num, flags); if (other_layer == NULL) { static CoglBool warning_seen = FALSE; if (!warning_seen) { g_warning ("The application is trying to use a texture " "combine with a layer number that does not exist"); warning_seen = TRUE; } arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; arg->name = "output"; } else { CoglTextureType texture_type; arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE; arg->name = "texture[%d]"; arg->texture_unit = _cogl_pipeline_layer_get_unit_index (other_layer); texture_type = _cogl_pipeline_layer_get_texture_type (other_layer); setup_texture_source (shader_state, arg->texture_unit, texture_type); } } break; } arg->swizzle = ""; switch (op) { case COGL_PIPELINE_COMBINE_OP_SRC_COLOR: break; case COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR: g_string_append_printf (shader_state->source, "SUB tmp%d, one, ", arg_index); append_arg (shader_state->source, arg); g_string_append_printf (shader_state->source, ";\n"); arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; arg->name = tmp_name[arg_index]; arg->swizzle = ""; break; case COGL_PIPELINE_COMBINE_OP_SRC_ALPHA: /* avoid a swizzle if we know RGB are going to be masked * in the end anyway */ if (mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) arg->swizzle = ".a"; break; case COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA: g_string_append_printf (shader_state->source, "SUB tmp%d, one, ", arg_index); append_arg (shader_state->source, arg); /* avoid a swizzle if we know RGB are going to be masked * in the end anyway */ if (mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) g_string_append_printf (shader_state->source, ".a;\n"); else g_string_append_printf (shader_state->source, ";\n"); arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; arg->name = tmp_name[arg_index]; break; default: g_error ("Unknown texture combine operator %d", op); break; } }