/** * 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); }
/** * 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); }
/** * 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); }
/** * 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; }
/** * 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"); }
/** * 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); }
/** * 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; }
/** * 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 (); }
/** * 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]); }
/** * 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); }
/** * 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; }
/** * 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; }
/** * 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"); } }