Esempio n. 1
0
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);
        }
      }
}
Esempio n. 2
0
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 ();
    }
}
Esempio n. 3
0
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;
    }
}