Beispiel #1
0
/**
 * clutter_shader_get_cogl_fragment_shader:
 * @shader: a #ClutterShader
 *
 * Retrieves the underlying #CoglHandle for the fragment shader.
 *
 * Return value: A #CoglHandle for the fragment shader, or %NULL
 *
 * Since: 1.0
 */
CoglHandle
clutter_shader_get_cogl_fragment_shader (ClutterShader *shader)
{
  g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL);

  return clutter_shader_get_cogl_shader (shader, CLUTTER_FRAGMENT_SHADER);
}
Beispiel #2
0
/**
 * clutter_shader_get_cogl_vertex_shader:
 * @shader: a #ClutterShader
 *
 * Retrieves the underlying #CoglHandle for the vertex shader.
 *
 * Return value: A #CoglHandle for the vertex shader, or %NULL
 *
 * Since: 1.0
 */
CoglHandle
clutter_shader_get_cogl_vertex_shader (ClutterShader *shader)
{
  g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL);

  return clutter_shader_get_cogl_shader (shader, CLUTTER_VERTEX_SHADER);
}
Beispiel #3
0
/**
 * clutter_shader_get_vertex_source:
 * @shader: a #ClutterShader
 *
 * Query the current GLSL vertex source set on @shader.
 *
 * Return value: the source of the vertex shader for this
 * ClutterShader object or %NULL. The returned string is owned by the
 * shader object and should never be modified or freed
 *
 * Since: 0.6
 */
const gchar *
clutter_shader_get_vertex_source (ClutterShader *shader)
{
  g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL);

  return clutter_shader_get_source (shader, CLUTTER_VERTEX_SHADER);
}
Beispiel #4
0
/**
 * clutter_shader_get_cogl_program:
 * @shader: a #ClutterShader
 *
 * Retrieves the underlying #CoglHandle for the shader program.
 *
 * Return value: A #CoglHandle for the shader program, or %NULL
 *
 * Since: 1.0
 */
CoglHandle
clutter_shader_get_cogl_program (ClutterShader *shader)
{
  g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL);

  return shader->priv->program;
}
Beispiel #5
0
/**
 * clutter_shader_release:
 * @shader: a #ClutterShader
 *
 * Frees up any GL context resources held by the shader.
 *
 * Since: 0.6
 */
void
clutter_shader_release (ClutterShader *shader)
{
  ClutterShaderPrivate *priv;

  g_return_if_fail (CLUTTER_IS_SHADER (shader));

  priv = shader->priv;

  if (!priv->compiled)
    return;

  g_assert (priv->program != COGL_INVALID_HANDLE);

  if (priv->vertex_is_glsl && priv->vertex_shader != COGL_INVALID_HANDLE)
    cogl_handle_unref (priv->vertex_shader);

  if (priv->fragment_is_glsl && priv->fragment_shader != COGL_INVALID_HANDLE)
    cogl_handle_unref (priv->fragment_shader);

  if (priv->program != COGL_INVALID_HANDLE)
    cogl_handle_unref (priv->program);

  priv->vertex_shader = COGL_INVALID_HANDLE;
  priv->fragment_shader = COGL_INVALID_HANDLE;
  priv->program = COGL_INVALID_HANDLE;
  priv->compiled = FALSE;

  g_object_notify (G_OBJECT (shader), "compiled");
}
Beispiel #6
0
/**
 * clutter_shader_get_fragment_source:
 * @shader: a #ClutterShader
 *
 * Query the current GLSL fragment source set on @shader.
 *
 * Return value: the source of the fragment shader for this
 * ClutterShader object or %NULL. The returned string is owned by the
 * shader object and should never be modified or freed
 *
 * Since: 0.6
 */
const gchar *
clutter_shader_get_fragment_source (ClutterShader *shader)
{
  g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL);

  return clutter_shader_get_source (shader, CLUTTER_FRAGMENT_SHADER);
}
Beispiel #7
0
/**
 * clutter_shader_get_is_enabled:
 * @shader: a #ClutterShader
 *
 * Checks whether @shader is enabled.
 *
 * Return value: %TRUE if the shader is enabled.
 *
 * Since: 0.6
 */
gboolean
clutter_shader_get_is_enabled (ClutterShader *shader)
{
  g_return_val_if_fail (CLUTTER_IS_SHADER (shader), FALSE);

  return shader->priv->is_enabled;
}
Beispiel #8
0
/**
 * clutter_shader_set_uniform:
 * @shader: a #ClutterShader.
 * @name: name of uniform in GLSL shader program to set.
 * @value: a #ClutterShaderFloat, #ClutterShaderInt or #ClutterShaderMatrix
 *         #GValue.
 *
 * Sets a user configurable variable in the GLSL shader programs attached to
 * a #ClutterShader.
 *
 * Since: 1.0
 */
void
clutter_shader_set_uniform (ClutterShader *shader,
                            const gchar   *name,
                            const GValue  *value)
{
  ClutterShaderPrivate *priv;
  GLint                 location = 0;
  gsize                 size;

  g_return_if_fail (CLUTTER_IS_SHADER (shader));
  g_return_if_fail (name != NULL);
  g_return_if_fail (value != NULL);
  g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value) ||
                    CLUTTER_VALUE_HOLDS_SHADER_INT (value) ||
                    CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value) ||
                    G_VALUE_HOLDS_FLOAT (value) ||
                    G_VALUE_HOLDS_INT (value));

  priv = shader->priv;
  g_return_if_fail (priv->program != COGL_INVALID_HANDLE);

  location = cogl_program_get_uniform_location (priv->program, name);

  if (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value))
    {
      const GLfloat *floats;

      floats = clutter_value_get_shader_float (value, &size);
      cogl_program_uniform_float (location, size, 1, floats);
    }
  else if (CLUTTER_VALUE_HOLDS_SHADER_INT (value))
    {
      const int *ints;

      ints = clutter_value_get_shader_int (value, &size);
      cogl_program_uniform_int (location, size, 1, ints);
    }
  else if (CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value))
    {
      const GLfloat *matrix;

      matrix = clutter_value_get_shader_matrix (value, &size);
      cogl_program_uniform_matrix (location, size, 1, FALSE, matrix);
    }
  else if (G_VALUE_HOLDS_FLOAT (value))
    {
      GLfloat float_val = g_value_get_float (value);

      cogl_program_uniform_float (location, 1, 1, &float_val);
    }
  else if (G_VALUE_HOLDS_INT (value))
    {
      int int_val = g_value_get_int (value);

      cogl_program_uniform_int (location, 1, 1, &int_val);
    }
  else
    g_assert_not_reached ();
}
Beispiel #9
0
/**
 * clutter_shader_release:
 * @shader: a #ClutterShader
 *
 * Frees up any GL context resources held by the shader.
 *
 * Since: 0.6
 *
 * Deprecated: 1.8: Use #ClutterShaderEffect instead.
 */
void
clutter_shader_release (ClutterShader *shader)
{
  g_return_if_fail (CLUTTER_IS_SHADER (shader));

  clutter_shader_release_internal (shader);

  g_object_notify_by_pspec (G_OBJECT (shader), obj_props[PROP_COMPILED]);
}
Beispiel #10
0
/**
 * clutter_shader_set_vertex_source:
 * @shader: a #ClutterShader
 * @data: GLSL source code.
 * @length: length of source buffer (currently ignored)
 *
 * Sets the GLSL source code to be used by a #ClutterShader for the vertex
 * program.
 *
 * Since: 0.6
 */
void
clutter_shader_set_vertex_source (ClutterShader      *shader,
                                  const gchar        *data,
                                  gssize              length)
{
  g_return_if_fail (CLUTTER_IS_SHADER (shader));
  g_return_if_fail (data != NULL);

  clutter_shader_set_source (shader, CLUTTER_VERTEX_SHADER, data, length);
}
Beispiel #11
0
/**
 * clutter_shader_set_fragment_source:
 * @shader: a #ClutterShader
 * @data: GLSL source code.
 * @length: length of source buffer (currently ignored)
 *
 * Sets the GLSL source code to be used by a #ClutterShader for the fragment
 * program.
 *
 * Since: 0.6
 */
void
clutter_shader_set_fragment_source (ClutterShader      *shader,
                                    const gchar        *data,
                                    gssize              length)
{
  g_return_if_fail (CLUTTER_IS_SHADER (shader));
  g_return_if_fail (data != NULL);

  clutter_shader_set_source (shader, CLUTTER_FRAGMENT_SHADER, data, length);
}
/**
 * clutter_actor_set_shader:
 * @self: a #ClutterActor
 * @shader: (allow-none): a #ClutterShader or %NULL to unset the shader.
 *
 * Sets the #ClutterShader to be used when rendering @self.
 *
 * If @shader is %NULL this function will unset any currently set shader
 * for the actor.
 *
 * <note>Any #ClutterEffect applied to @self will take the precedence
 * over the #ClutterShader set using this function.</note>
 *
 * Return value: %TRUE if the shader was successfully applied
 *   or removed
 *
 * Since: 0.6
 *
 * Deprecated: 1.8: Use #ClutterShaderEffect and
 *   clutter_actor_add_effect() instead.
 */
gboolean
clutter_actor_set_shader (ClutterActor  *self,
                          ClutterShader *shader)
{
  ShaderData *shader_data;

  g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
  g_return_val_if_fail (shader == NULL || CLUTTER_IS_SHADER (shader), FALSE);

  if (shader != NULL)
    g_object_ref (shader);
  else
    {
      /* if shader passed in is NULL we destroy the shader */
      g_object_set_data (G_OBJECT (self), "-clutter-actor-shader-data", NULL);
      return TRUE;
    }

  shader_data = g_object_get_data (G_OBJECT (self), "-clutter-actor-shader-data");
  if (shader_data == NULL)
    {
      shader_data = g_slice_new (ShaderData);
      shader_data->actor = self;
      shader_data->shader = NULL;
      shader_data->value_hash =
        g_hash_table_new_full (g_str_hash, g_str_equal,
                               g_free,
                               shader_value_free);

      g_object_set_data_full (G_OBJECT (self), "-clutter-actor-shader-data",
                              shader_data,
                              destroy_shader_data);
    }

  if (shader_data->shader != NULL)
    g_object_unref (shader_data->shader);

  shader_data->shader = shader;

  clutter_actor_queue_redraw (self);

  return TRUE;
}
Beispiel #13
0
/**
 * clutter_shader_compile:
 * @shader: a #ClutterShader
 * @error: return location for a #GError, or %NULL
 *
 * Compiles and links GLSL sources set for vertex and fragment shaders for
 * a #ClutterShader. If the compilation fails and a #GError return location is
 * provided the error will contain the errors from the compiler, if any.
 *
 * Return value: returns TRUE if the shader was succesfully compiled.
 *
 * Since: 0.8
 */
gboolean
clutter_shader_compile (ClutterShader  *shader,
                        GError        **error)
{
  ClutterShaderPrivate *priv;

  g_return_val_if_fail (CLUTTER_IS_SHADER (shader), FALSE);

  priv = shader->priv;

  if (priv->compiled)
    return priv->compiled;

  if ((priv->vertex_source != COGL_INVALID_HANDLE && !priv->vertex_is_glsl) ||
      (priv->fragment_source != COGL_INVALID_HANDLE && !priv->fragment_is_glsl))
    {
      /* XXX: Could remove this check, since we only advertise support for GLSL
       * shaders anyways. */
      g_set_error (error, CLUTTER_SHADER_ERROR,
                   CLUTTER_SHADER_ERROR_NO_ASM,
                   "ASM shaders not supported");
      priv->compiled = FALSE;
      return priv->compiled;
    }

  if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
    {
      g_set_error (error, CLUTTER_SHADER_ERROR,
                   CLUTTER_SHADER_ERROR_NO_GLSL,
                   "GLSL shaders not supported");
      priv->compiled = FALSE;
      return priv->compiled;
    }

  priv->compiled = bind_glsl_shader (shader, error);
  g_object_notify (G_OBJECT (shader), "compiled");

  return priv->compiled;
}
Beispiel #14
0
/**
 * clutter_shader_set_is_enabled:
 * @shader: a #ClutterShader
 * @enabled: The new state of the shader.
 *
 * Enables a shader. This function will attempt to compile and link
 * the shader, if it isn't already.
 *
 * When @enabled is %FALSE the default state of the GL pipeline will be
 * used instead.
 *
 * Since: 0.6
 */
void
clutter_shader_set_is_enabled (ClutterShader *shader,
                               gboolean       enabled)
{
  ClutterShaderPrivate *priv;

  g_return_if_fail (CLUTTER_IS_SHADER (shader));

  priv = shader->priv;

  if (priv->is_enabled != enabled)
    {
      GError *error = NULL;
      gboolean res;

      res = clutter_shader_compile (shader, &error);
      if (!res)
        {
          g_warning ("Unable to bind the shader: %s",
                     error ? error->message : "unknown error");
          if (error)
            g_error_free (error);

          return;
        }

      priv->is_enabled = enabled;

      if (priv->is_enabled)
        cogl_program_use (priv->program);
      else
        cogl_program_use (COGL_INVALID_HANDLE);

      g_object_notify (G_OBJECT (shader), "enabled");
    }
}