Ejemplo n.º 1
0
static void
_cogl_pipeline_set_alpha_test_function_reference (CoglPipeline *pipeline,
                                                  float alpha_reference)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE;
  CoglPipeline *authority;
  CoglPipelineAlphaFuncState *alpha_state;

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  authority = _cogl_pipeline_get_authority (pipeline, state);

  alpha_state = &authority->big_state->alpha_state;
  if (alpha_state->alpha_func_reference == alpha_reference)
    return;

  /* - Flush journal primitives referencing the current state.
   * - Make sure the pipeline has no dependants so it may be modified.
   * - If the pipeline isn't currently an authority for the state being
   *   changed, then initialize that state from the current authority.
   */
  _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);

  alpha_state = &pipeline->big_state->alpha_state;
  alpha_state->alpha_func_reference = alpha_reference;

  _cogl_pipeline_update_authority
    (pipeline, authority, state,
     _cogl_pipeline_alpha_func_reference_state_equal);
}
Ejemplo n.º 2
0
void
cogl_pipeline_set_point_size (CoglPipeline *pipeline,
                              float point_size)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_POINT_SIZE;
  CoglPipeline *authority;

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  authority = _cogl_pipeline_get_authority (pipeline, state);

  if (authority->big_state->point_size == point_size)
    return;

  /* - Flush journal primitives referencing the current state.
   * - Make sure the pipeline has no dependants so it may be modified.
   * - If the pipeline isn't currently an authority for the state being
   *   changed, then initialize that state from the current authority.
   */
  _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);

  pipeline->big_state->point_size = point_size;

  _cogl_pipeline_update_authority (pipeline, authority, state,
                                   _cogl_pipeline_point_size_equal);
}
Ejemplo n.º 3
0
void
cogl_set_source (void *material_or_pipeline)
{
  CoglSourceState *top;
  CoglPipeline *pipeline = COGL_PIPELINE (material_or_pipeline);

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
  _COGL_RETURN_IF_FAIL (ctx->source_stack);

  top = ctx->source_stack->data;
  if (top->pipeline == pipeline && top->enable_legacy)
    return;

  if (top->push_count == 1)
    {
      /* NB: top->pipeline may be only thing keeping pipeline
       * alive currently so ref pipeline first... */
      cogl_object_ref (pipeline);
      cogl_object_unref (top->pipeline);
      top->pipeline = pipeline;
      top->enable_legacy = TRUE;
    }
  else
    {
      top->push_count--;
      cogl_push_source (pipeline);
    }
}
Ejemplo n.º 4
0
void
_cogl_pipeline_set_blend_enabled (CoglPipeline *pipeline,
                                  CoglPipelineBlendEnable enable)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_BLEND_ENABLE;
  CoglPipeline *authority;

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
  _COGL_RETURN_IF_FAIL (enable > 1 &&
                        "don't pass TRUE or FALSE to _set_blend_enabled!");

  authority = _cogl_pipeline_get_authority (pipeline, state);

  if (authority->blend_enable == enable)
    return;

  /* - Flush journal primitives referencing the current state.
   * - Make sure the pipeline has no dependants so it may be modified.
   * - If the pipeline isn't currently an authority for the state being
   *   changed, then initialize that state from the current authority.
   */
  _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);

  pipeline->blend_enable = enable;

  _cogl_pipeline_update_authority (pipeline, authority, state,
                                   _cogl_pipeline_blend_enable_equal);

  _cogl_pipeline_update_blend_enable (pipeline, state);
}
Ejemplo n.º 5
0
void
cogl_pipeline_set_color (CoglPipeline    *pipeline,
			 const CoglColor *color)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_COLOR;
  CoglPipeline *authority;

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  authority = _cogl_pipeline_get_authority (pipeline, state);

  if (cogl_color_equal (color, &authority->color))
    return;

  /* - Flush journal primitives referencing the current state.
   * - Make sure the pipeline has no dependants so it may be modified.
   * - If the pipeline isn't currently an authority for the state being
   *   changed, then initialize that state from the current authority.
   */
  _cogl_pipeline_pre_change_notify (pipeline, state, color, FALSE);

  pipeline->color = *color;

  _cogl_pipeline_update_authority (pipeline, authority, state,
                                   _cogl_pipeline_color_equal);

  _cogl_pipeline_update_blend_enable (pipeline, state);
}
Ejemplo n.º 6
0
void
cogl_pipeline_set_color_mask (CoglPipeline *pipeline,
                              CoglColorMask color_mask)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_LOGIC_OPS;
  CoglPipeline *authority;
  CoglPipelineLogicOpsState *logic_ops_state;

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  authority = _cogl_pipeline_get_authority (pipeline, state);

  logic_ops_state = &authority->big_state->logic_ops_state;
  if (logic_ops_state->color_mask == color_mask)
    return;

  /* - Flush journal primitives referencing the current state.
   * - Make sure the pipeline has no dependants so it may be modified.
   * - If the pipeline isn't currently an authority for the state being
   *   changed, then initialize that state from the current authority.
   */
  _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);

  logic_ops_state = &pipeline->big_state->logic_ops_state;
  logic_ops_state->color_mask = color_mask;

  _cogl_pipeline_update_authority (pipeline, authority, state,
                                   _cogl_pipeline_logic_ops_state_equal);
}
Ejemplo n.º 7
0
void
cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline,
                                      CoglWinding front_winding)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
  CoglPipeline *authority;
  CoglPipelineCullFaceState *cull_face_state;

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  authority = _cogl_pipeline_get_authority (pipeline, state);

  cull_face_state = &authority->big_state->cull_face_state;

  if (cull_face_state->front_winding == front_winding)
    return;

  /* - Flush journal primitives referencing the current state.
   * - Make sure the pipeline has no dependants so it may be modified.
   * - If the pipeline isn't currently an authority for the state being
   *   changed, then initialize that state from the current authority.
   */
  _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);

  pipeline->big_state->cull_face_state.front_winding = front_winding;

  _cogl_pipeline_update_authority (pipeline, authority, state,
                                   _cogl_pipeline_cull_face_state_equal);
}
Ejemplo n.º 8
0
/* FIXME: This should take a context pointer for Cogl 2.0 Technically
 * we could make it so we can retrieve a context reference from the
 * pipeline, but this would not by symmetric with cogl_pop_source. */
void
cogl_push_source (void *material_or_pipeline)
{
  CoglPipeline *pipeline = COGL_PIPELINE (material_or_pipeline);

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  _cogl_push_source (pipeline, TRUE);
}
Ejemplo n.º 9
0
CoglPipelineBlendEnable
_cogl_pipeline_get_blend_enabled (CoglPipeline *pipeline)
{
  CoglPipeline *authority;

  _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE);

  authority =
    _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND_ENABLE);
  return authority->blend_enable;
}
Ejemplo n.º 10
0
void
cogl_path_fill (CoglPath *path,
                CoglFramebuffer *framebuffer,
                CoglPipeline *pipeline)
{
  _COGL_RETURN_IF_FAIL (cogl_is_path (path));
  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (framebuffer));
  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  _cogl_path_fill_nodes (path, framebuffer, pipeline, 0 /* flags */);
}
Ejemplo n.º 11
0
/* XXX: deprecated */
void
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
                              CoglPipeline *pipeline,
                              CoglPath *path)
{
  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (framebuffer));
  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
  _COGL_RETURN_IF_FAIL (cogl_is_path (path));

  _cogl_path_stroke_nodes (path, framebuffer, pipeline);
}
Ejemplo n.º 12
0
void
cogl_pipeline_get_depth_state (CoglPipeline *pipeline,
                               CoglDepthState *state)
{
  CoglPipeline *authority;

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  authority =
    _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH);
  *state = authority->big_state->depth_state;
}
Ejemplo n.º 13
0
CoglPipelineAlphaFunc
cogl_pipeline_get_alpha_test_function (CoglPipeline *pipeline)
{
  CoglPipeline *authority;

  _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0);

  authority =
    _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_ALPHA_FUNC);

  return authority->big_state->alpha_state.alpha_func;
}
Ejemplo n.º 14
0
float
cogl_pipeline_get_point_size (CoglPipeline *pipeline)
{
  CoglPipeline *authority;

  _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE);

  authority =
    _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE);

  return authority->big_state->point_size;
}
Ejemplo n.º 15
0
CoglColorMask
cogl_pipeline_get_color_mask (CoglPipeline *pipeline)
{
  CoglPipeline *authority;

  _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0);

  authority =
    _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LOGIC_OPS);

  return authority->big_state->logic_ops_state.color_mask;
}
Ejemplo n.º 16
0
float
cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline)
{
  CoglPipeline *authority;

  _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0.0f);

  authority =
    _cogl_pipeline_get_authority (pipeline,
                                  COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE);

  return authority->big_state->alpha_state.alpha_func_reference;
}
Ejemplo n.º 17
0
CoglWinding
cogl_pipeline_get_front_face_winding (CoglPipeline *pipeline)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
  CoglPipeline *authority;

  _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline),
                            COGL_PIPELINE_CULL_FACE_MODE_NONE);

  authority = _cogl_pipeline_get_authority (pipeline, state);

  return authority->big_state->cull_face_state.front_winding;
}
Ejemplo n.º 18
0
CoglPipelineCullFaceMode
cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
  CoglPipeline *authority;

  _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline),
                            COGL_PIPELINE_CULL_FACE_MODE_NONE);

  authority = _cogl_pipeline_get_authority (pipeline, state);

  return authority->big_state->cull_face_state.mode;
}
Ejemplo n.º 19
0
void
cogl_pipeline_get_color (CoglPipeline *pipeline,
                         CoglColor    *color)
{
  CoglPipeline *authority;

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  authority =
    _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR);

  *color = authority->color;
}
Ejemplo n.º 20
0
void
cogl_pipeline_add_snippet (CoglPipeline *pipeline,
                           CoglSnippet *snippet)
{
  g_return_if_fail (cogl_is_pipeline (pipeline));
  g_return_if_fail (cogl_is_snippet (snippet));
  g_return_if_fail (snippet->hook < COGL_SNIPPET_FIRST_LAYER_HOOK);

  if (snippet->hook < COGL_SNIPPET_FIRST_PIPELINE_FRAGMENT_HOOK)
    _cogl_pipeline_add_vertex_snippet (pipeline, snippet);
  else
    _cogl_pipeline_add_fragment_snippet (pipeline, snippet);
}
Ejemplo n.º 21
0
void
cogl_path_stroke (CoglPath *path,
                  CoglFramebuffer *framebuffer,
                  CoglPipeline *pipeline)
{
  CoglPathData *data;
  CoglPipeline *copy = NULL;
  unsigned int path_start;
  int path_num = 0;
  CoglPathNode *node;

  _COGL_RETURN_IF_FAIL (cogl_is_path (path));
  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (framebuffer));
  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  data = path->data;

  if (data->path_nodes->len == 0)
    return;

  if (cogl_pipeline_get_n_layers (pipeline) != 0)
    {
      copy = cogl_pipeline_copy (pipeline);
      _cogl_pipeline_prune_to_n_layers (copy, 0);
      pipeline = copy;
    }

  _cogl_path_build_stroke_attribute_buffer (path);

  for (path_start = 0;
       path_start < data->path_nodes->len;
       path_start += node->path_size)
    {
      CoglPrimitive *primitive;

      node = &g_array_index (data->path_nodes, CoglPathNode, path_start);

      primitive =
        cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_LINE_STRIP,
                                            node->path_size,
                                            &data->stroke_attributes[path_num],
                                            1);
      cogl_primitive_draw (primitive, framebuffer, pipeline);
      cogl_object_unref (primitive);

      path_num++;
    }

  if (copy)
    cogl_object_unref (copy);
}
Ejemplo n.º 22
0
CoglBool
cogl_pipeline_set_depth_state (CoglPipeline *pipeline,
                               const CoglDepthState *depth_state,
                               CoglError **error)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH;
  CoglPipeline *authority;
  CoglDepthState *orig_state;

  _COGL_GET_CONTEXT (ctx, FALSE);

  _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE);
  _COGL_RETURN_VAL_IF_FAIL (depth_state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);

  authority = _cogl_pipeline_get_authority (pipeline, state);

  orig_state = &authority->big_state->depth_state;
  if (orig_state->test_enabled == depth_state->test_enabled &&
      orig_state->write_enabled == depth_state->write_enabled &&
      orig_state->test_function == depth_state->test_function &&
      orig_state->range_near == depth_state->range_near &&
      orig_state->range_far == depth_state->range_far)
    return TRUE;

  if (ctx->driver == COGL_DRIVER_GLES1 &&
      (depth_state->range_near != 0 ||
       depth_state->range_far != 1))
    {
      _cogl_set_error (error,
                       COGL_SYSTEM_ERROR,
                       COGL_SYSTEM_ERROR_UNSUPPORTED,
                       "glDepthRange not available on GLES 1");
      return FALSE;
    }

  /* - Flush journal primitives referencing the current state.
   * - Make sure the pipeline has no dependants so it may be modified.
   * - If the pipeline isn't currently an authority for the state being
   *   changed, then initialize that state from the current authority.
   */
  _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);

  pipeline->big_state->depth_state = *depth_state;

  _cogl_pipeline_update_authority (pipeline, authority, state,
                                   _cogl_pipeline_depth_state_equal);

  return TRUE;
}
Ejemplo n.º 23
0
/**
 * clutter_deform_effect_set_back_material:
 * @effect: a #ClutterDeformEffect
 * @material: (allow-none): a handle to a Cogl material
 *
 * Sets the material that should be used when drawing the back face
 * of the actor during a deformation
 *
 * The #ClutterDeformEffect will take a reference on the material's
 * handle
 *
 * Since: 1.4
 */
void
clutter_deform_effect_set_back_material (ClutterDeformEffect *effect,
                                         CoglHandle           material)
{
  ClutterDeformEffectPrivate *priv;
  CoglPipeline *pipeline = COGL_PIPELINE (material);

  g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
  g_return_if_fail (pipeline == NULL || cogl_is_pipeline (pipeline));

  priv = effect->priv;

  clutter_deform_effect_free_back_pipeline (effect);

  priv->back_pipeline = material;
  if (priv->back_pipeline != NULL)
    cogl_object_ref (priv->back_pipeline);

  clutter_deform_effect_invalidate (effect);
}
Ejemplo n.º 24
0
void
cogl_pipeline_set_blend_constant (CoglPipeline *pipeline,
                                  const CoglColor *constant_color)
{
  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_BLEND_CONSTANT))
    return;

#if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
  {
    CoglPipelineState state = COGL_PIPELINE_STATE_BLEND;
    CoglPipeline *authority;
    CoglPipelineBlendState *blend_state;

    authority = _cogl_pipeline_get_authority (pipeline, state);

    blend_state = &authority->big_state->blend_state;
    if (cogl_color_equal (constant_color, &blend_state->blend_constant))
      return;

    /* - Flush journal primitives referencing the current state.
     * - Make sure the pipeline has no dependants so it may be modified.
     * - If the pipeline isn't currently an authority for the state being
     *   changed, then initialize that state from the current authority.
     */
    _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);

    blend_state = &pipeline->big_state->blend_state;
    blend_state->blend_constant = *constant_color;

    _cogl_pipeline_update_authority (pipeline, authority, state,
                                     _cogl_pipeline_blend_state_equal);

    _cogl_pipeline_update_blend_enable (pipeline, state);
  }
#endif
}
Ejemplo n.º 25
0
/* This internal version of cogl_push_source is the same except it
   never applies the legacy state. Some parts of Cogl use this
   internally to set a temporary pipeline with a known state */
void
_cogl_push_source (CoglPipeline *pipeline, CoglBool enable_legacy)
{
  CoglSourceState *top;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  if (ctx->source_stack)
    {
      top = ctx->source_stack->data;
      if (top->pipeline == pipeline && top->enable_legacy == enable_legacy)
        {
          top->push_count++;
          return;
        }
      else
        _push_source_real (pipeline, enable_legacy);
    }
  else
    _push_source_real (pipeline, enable_legacy);
}
Ejemplo n.º 26
0
static CoglBoxedValue *
_cogl_pipeline_override_uniform (CoglPipeline *pipeline,
                                 int location)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_UNIFORMS;
  CoglPipelineUniformsState *uniforms_state;
  int override_index;

  _COGL_GET_CONTEXT (ctx, NULL);

  g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL);
  g_return_val_if_fail (location >= 0, NULL);
  g_return_val_if_fail (location < ctx->n_uniform_names, NULL);

  /* - Flush journal primitives referencing the current state.
   * - Make sure the pipeline has no dependants so it may be modified.
   * - If the pipeline isn't currently an authority for the state being
   *   changed, then initialize that state from the current authority.
   */
  _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);

  uniforms_state = &pipeline->big_state->uniforms_state;

  /* Count the number of bits that are set below this location. That
     should give us the position where our new value should lie */
  override_index = _cogl_bitmask_popcount_upto (&uniforms_state->override_mask,
                                                location);

  _cogl_bitmask_set (&uniforms_state->changed_mask, location, TRUE);

  /* If this pipeline already has an override for this value then we
     can just use it directly */
  if (_cogl_bitmask_get (&uniforms_state->override_mask, location))
    return uniforms_state->override_values + override_index;

  /* We need to create a new override value in the right position
     within the array. This is pretty inefficient but the hope is that
     it will be much more common to modify an existing uniform rather
     than modify a new one so it is more important to optimise the
     former case. */

  if (uniforms_state->override_values == NULL)
    {
      g_assert (override_index == 0);
      uniforms_state->override_values = g_new (CoglBoxedValue, 1);
    }
  else
    {
      /* We need to grow the array and copy in the old values */
      CoglBoxedValue *old_values = uniforms_state->override_values;
      int old_size = _cogl_bitmask_popcount (&uniforms_state->override_mask);

      uniforms_state->override_values = g_new (CoglBoxedValue, old_size + 1);

      /* Copy in the old values leaving a gap for the new value */
      memcpy (uniforms_state->override_values,
              old_values,
              sizeof (CoglBoxedValue) * override_index);
      memcpy (uniforms_state->override_values + override_index + 1,
              old_values + override_index,
              sizeof (CoglBoxedValue) * (old_size - override_index));

      g_free (old_values);
    }

  _cogl_boxed_value_init (uniforms_state->override_values + override_index);

  _cogl_bitmask_set (&uniforms_state->override_mask, location, TRUE);

  return uniforms_state->override_values + override_index;
}
Ejemplo n.º 27
0
CoglBool
cogl_pipeline_set_blend (CoglPipeline *pipeline,
                         const char *blend_description,
                         CoglError **error)
{
  CoglPipelineState state = COGL_PIPELINE_STATE_BLEND;
  CoglPipeline *authority;
  CoglBlendStringStatement statements[2];
  CoglBlendStringStatement *rgb;
  CoglBlendStringStatement *a;
  int count;
  CoglPipelineBlendState *blend_state;

  _COGL_GET_CONTEXT (ctx, FALSE);

  _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE);

  count =
    _cogl_blend_string_compile (blend_description,
                                COGL_BLEND_STRING_CONTEXT_BLENDING,
                                statements,
                                error);
  if (!count)
    return FALSE;

  if (count == 1)
    rgb = a = statements;
  else
    {
      rgb = &statements[0];
      a = &statements[1];
    }

  authority =
    _cogl_pipeline_get_authority (pipeline, state);

  /* - Flush journal primitives referencing the current state.
   * - Make sure the pipeline has no dependants so it may be modified.
   * - If the pipeline isn't currently an authority for the state being
   *   changed, then initialize that state from the current authority.
   */
  _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);

  blend_state = &pipeline->big_state->blend_state;
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES2)
  if (ctx->driver != COGL_DRIVER_GLES1)
    {
      setup_blend_state (rgb,
                         &blend_state->blend_equation_rgb,
                         &blend_state->blend_src_factor_rgb,
                         &blend_state->blend_dst_factor_rgb);
      setup_blend_state (a,
                         &blend_state->blend_equation_alpha,
                         &blend_state->blend_src_factor_alpha,
                         &blend_state->blend_dst_factor_alpha);
    }
  else
#endif
    {
      setup_blend_state (rgb,
                         NULL,
                         &blend_state->blend_src_factor_rgb,
                         &blend_state->blend_dst_factor_rgb);
    }

  /* If we are the current authority see if we can revert to one of our
   * ancestors being the authority */
  if (pipeline == authority &&
      _cogl_pipeline_get_parent (authority) != NULL)
    {
      CoglPipeline *parent = _cogl_pipeline_get_parent (authority);
      CoglPipeline *old_authority =
        _cogl_pipeline_get_authority (parent, state);

      if (_cogl_pipeline_blend_state_equal (authority, old_authority))
        pipeline->differences &= ~state;
    }

  /* If we weren't previously the authority on this state then we need
   * to extended our differences mask and so it's possible that some
   * of our ancestry will now become redundant, so we aim to reparent
   * ourselves if that's true... */
  if (pipeline != authority)
    {
      pipeline->differences |= state;
      _cogl_pipeline_prune_redundant_ancestry (pipeline);
    }

  _cogl_pipeline_update_blend_enable (pipeline, state);

  return TRUE;
}
Ejemplo n.º 28
0
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
// If text or lines are blurry when integrating ImGui in your engine:
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplGtk3Cogl_RenderDrawData(ImDrawData* draw_data)
{
    // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
    ImGuiIO& io = ImGui::GetIO();
    int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
    int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
    if (fb_width == 0 || fb_height == 0)
        return;
    draw_data->ScaleClipRects(io.DisplayFramebufferScale);

    cogl_framebuffer_orthographic(g_Framebuffer, 0, 0,
                                  io.DisplaySize.x, io.DisplaySize.y,
                                  -1, 1);

    CoglContext *context = cogl_framebuffer_get_context(g_Framebuffer);
    for (int n = 0; n < draw_data->CmdListsCount; n++)
    {
        const ImDrawList* cmd_list = draw_data->CmdLists[n];
        int idx_buffer_offset = 0;

        CoglAttributeBuffer *vertices =
            cogl_attribute_buffer_new(context,
                                      cmd_list->VtxBuffer.Size * sizeof(ImDrawVert),
                                      cmd_list->VtxBuffer.Data);

#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
        CoglAttribute *attrs[3] = {
            cogl_attribute_new(vertices, "cogl_position_in",
                               sizeof(ImDrawVert), OFFSETOF(ImDrawVert, pos),
                               2, COGL_ATTRIBUTE_TYPE_FLOAT),
            cogl_attribute_new(vertices, "cogl_tex_coord0_in",
                               sizeof(ImDrawVert), OFFSETOF(ImDrawVert, uv),
                               2, COGL_ATTRIBUTE_TYPE_FLOAT),
            cogl_attribute_new(vertices, "cogl_color_in",
                               sizeof(ImDrawVert), OFFSETOF(ImDrawVert, col),
                               4, COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE)
        };
#undef OFFSETOF

        CoglPrimitive *primitive =
            cogl_primitive_new_with_attributes(COGL_VERTICES_MODE_TRIANGLES,
                                               cmd_list->VtxBuffer.Size,
                                               attrs, 3);

        CoglIndices *indices = cogl_indices_new(context,
                                                sizeof(ImDrawIdx) == 2 ?
                                                COGL_INDICES_TYPE_UNSIGNED_SHORT :
                                                COGL_INDICES_TYPE_UNSIGNED_INT,
                                                cmd_list->IdxBuffer.Data,
                                                cmd_list->IdxBuffer.Size);

        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
        {
            const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];

            cogl_indices_set_offset(indices, sizeof(ImDrawIdx) * idx_buffer_offset);
            cogl_primitive_set_indices(primitive, indices, pcmd->ElemCount);

            if (pcmd->UserCallback)
            {
                pcmd->UserCallback(cmd_list, pcmd);
            }
            else
            {
                bool has_texture = pcmd->TextureId != NULL;
                CoglPipeline *pipeline =
                    has_texture ?
                    (cogl_is_pipeline(pcmd->TextureId) ?
                     (CoglPipeline *) pcmd->TextureId : g_ImagePipeline) :
                    g_ColorPipeline;

                if (has_texture && pipeline == g_ImagePipeline) {
                    cogl_pipeline_set_layer_texture(g_ImagePipeline, 0,
                                                    COGL_TEXTURE(pcmd->TextureId));
                }

                cogl_framebuffer_push_scissor_clip(g_Framebuffer,
                                                   pcmd->ClipRect.x,
                                                   pcmd->ClipRect.y,
                                                   pcmd->ClipRect.z - pcmd->ClipRect.x,
                                                   pcmd->ClipRect.w - pcmd->ClipRect.y);
                cogl_primitive_draw(primitive, g_Framebuffer, pipeline);
                cogl_framebuffer_pop_clip(g_Framebuffer);
            }
            idx_buffer_offset += pcmd->ElemCount;
        }

        for (int i = 0; i < 3; i++)
            cogl_object_unref(attrs[i]);
        cogl_object_unref(primitive);
        cogl_object_unref(vertices);
        cogl_object_unref(indices);
    }
}