static inline void clutter_shader_effect_add_uniform (ClutterShaderEffect *effect, const gchar *name, const GValue *value) { ClutterShaderEffectPrivate *priv = effect->priv; ShaderUniform *uniform; if (priv->uniforms == NULL) { priv->uniforms = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, shader_uniform_free); } uniform = g_hash_table_lookup (priv->uniforms, name); if (uniform == NULL) { uniform = shader_uniform_new (name, value); g_hash_table_insert (priv->uniforms, uniform->name, uniform); } else shader_uniform_update (uniform, value); if (priv->is_compiled) { uniform->location = cogl_program_get_uniform_location (priv->program, uniform->name); } }
/** * 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 (); }
static VALUE rb_cogl_program_get_uniform_location (VALUE self, VALUE uniform_name) { CoglHandle program = rb_cogl_program_get_handle (self); COGLint location; location = cogl_program_get_uniform_location (program, StringValuePtr (uniform_name)); return INT2NUM (location); }
static gboolean st_scroll_view_fade_pre_paint (ClutterEffect *effect) { StScrollViewFade *self = ST_SCROLL_VIEW_FADE (effect); ClutterEffectClass *parent_class; if (self->shader == COGL_INVALID_HANDLE) return FALSE; if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) return FALSE; if (self->actor == NULL) return FALSE; if (self->program == COGL_INVALID_HANDLE) self->program = cogl_create_program (); if (!self->is_attached) { g_assert (self->shader != COGL_INVALID_HANDLE); g_assert (self->program != COGL_INVALID_HANDLE); cogl_program_attach_shader (self->program, self->shader); cogl_program_link (self->program); cogl_handle_unref (self->shader); self->is_attached = TRUE; self->tex_uniform = cogl_program_get_uniform_location (self->program, "tex"); self->height_uniform = cogl_program_get_uniform_location (self->program, "height"); self->width_uniform = cogl_program_get_uniform_location (self->program, "width"); self->scrollbar_width_uniform = cogl_program_get_uniform_location (self->program, "scrollbar_width"); self->scrollbar_height_uniform = cogl_program_get_uniform_location (self->program, "scrollbar_height"); self->rtl_uniform = cogl_program_get_uniform_location (self->program, "rtl"); self->offset_top_uniform = cogl_program_get_uniform_location (self->program, "offset_top"); self->offset_bottom_uniform = cogl_program_get_uniform_location (self->program, "offset_bottom"); } parent_class = CLUTTER_EFFECT_CLASS (st_scroll_view_fade_parent_class); return parent_class->pre_paint (effect); }
static void clutter_gst_i420_glsl_init (ClutterGstVideoSink *sink) { ClutterGstVideoSinkPrivate *priv = sink->priv; GLint location; clutter_gst_video_sink_set_glsl_shader (sink, yv12_to_rgba_shader); cogl_program_use (priv->program); location = cogl_program_get_uniform_location (priv->program, "ytex"); cogl_program_uniform_1i (location, 0); location = cogl_program_get_uniform_location (priv->program, "vtex"); cogl_program_uniform_1i (location, 1); location = cogl_program_get_uniform_location (priv->program, "utex"); cogl_program_uniform_1i (location, 2); cogl_program_use (COGL_INVALID_HANDLE); _renderer_connect_signals (sink, clutter_gst_yv12_glsl_paint, clutter_gst_yv12_glsl_post_paint); }
/** * mash_light_get_uniform_location: * @light: The #MashLight which is generating the shader * @program: The program passed in from mash_light_update_uniforms(). * @uniform_name: The name of a uniform * * This is a convenience intended to be used within * mash_light_update_uniforms() to help query uniform locations. It * should not generally need to be called by an application unless it * is implementing its own lighting algorithms. * * This is a wrapper around cogl_program_get_uniform_location() which * appends an actor specific string to the uniform name. This is * useful when uniforms have been declared like ‘position$’ within * mash_light_append_shader(). */ int mash_light_get_uniform_location (MashLight *light, CoglHandle program, const char *uniform_name) { MashLightPrivate *priv; char *unique_name; int location; g_return_val_if_fail (MASH_IS_LIGHT (light), -1); priv = light->priv; /* Append this light's unique identifier to the uniform name */ unique_name = g_strconcat (uniform_name, priv->unique_str, NULL); location = cogl_program_get_uniform_location (program, unique_name); g_free (unique_name); return location; }
static void set_shader_num (int new_no) { CoglHandle shader; CoglHandle program; int image_width = cogl_texture_get_width (redhand); int image_height = cogl_texture_get_height (redhand); float param0[4]; int uniform_no; g_print ("setting shaders[%i] named '%s'\n", new_no, shaders[new_no].name); shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); cogl_shader_source (shader, shaders[new_no].source); cogl_shader_compile (shader); program = cogl_create_program (); cogl_program_attach_shader (program, shader); cogl_handle_unref (shader); cogl_program_link (program); param0[0] = 1.0f/image_width; /* texel x step delta */ param0[1] = 1.0f/image_height; /* texel y step delta */ param0[2] = 0.4; /* brightness */ param0[3] = -1.9; /* contrast */ uniform_no = cogl_program_get_uniform_location (program, "program.local[0]"); cogl_program_set_uniform_float (program, uniform_no, 4, 1, param0); cogl_material_set_user_program (material, program); cogl_handle_unref (program); shader_no = new_no; }
static void clutter_shader_effect_update_uniforms (ClutterShaderEffect *effect) { ClutterShaderEffectPrivate *priv = effect->priv; GHashTableIter iter; gpointer key, value; gsize size; if (priv->program == COGL_INVALID_HANDLE) return; if (priv->uniforms == NULL) return; key = value = NULL; g_hash_table_iter_init (&iter, priv->uniforms); while (g_hash_table_iter_next (&iter, &key, &value)) { ShaderUniform *uniform = value; if (uniform->location == -1) uniform->location = cogl_program_get_uniform_location (priv->program, uniform->name); if (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (&uniform->value)) { const GLfloat *floats; floats = clutter_value_get_shader_float (&uniform->value, &size); cogl_program_set_uniform_float (priv->program, uniform->location, size, 1, floats); } else if (CLUTTER_VALUE_HOLDS_SHADER_INT (&uniform->value)) { const GLint *ints; ints = clutter_value_get_shader_int (&uniform->value, &size); cogl_program_set_uniform_int (priv->program, uniform->location, size, 1, ints); } else if (CLUTTER_VALUE_HOLDS_SHADER_MATRIX (&uniform->value)) { const GLfloat *matrix; matrix = clutter_value_get_shader_matrix (&uniform->value, &size); cogl_program_set_uniform_matrix (priv->program, uniform->location, size, 1, FALSE, matrix); } else if (G_VALUE_HOLDS_FLOAT (&uniform->value)) { const GLfloat float_val = g_value_get_float (&uniform->value); cogl_program_set_uniform_float (priv->program, uniform->location, 1, 1, &float_val); } else if (G_VALUE_HOLDS_DOUBLE (&uniform->value)) { const GLfloat float_val = (GLfloat) g_value_get_double (&uniform->value); cogl_program_set_uniform_float (priv->program, uniform->location, 1, 1, &float_val); } else if (G_VALUE_HOLDS_INT (&uniform->value)) { const GLint int_val = g_value_get_int (&uniform->value); cogl_program_set_uniform_int (priv->program, uniform->location, 1, 1, &int_val); } else g_warning ("Invalid uniform of type '%s' for name '%s'", g_type_name (G_VALUE_TYPE (&uniform->value)), uniform->name); } }
static gboolean clutter_colorize_effect_pre_paint (ClutterEffect *effect) { ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect); ClutterEffectClass *parent_class; if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) return FALSE; self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); if (self->actor == NULL) return FALSE; if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) { /* if we don't have support for GLSL shaders then we * forcibly disable the ActorMeta */ g_warning ("Unable to use the ShaderEffect: the graphics hardware " "or the current GL driver does not implement support " "for the GLSL shading language."); clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE); return FALSE; } if (self->shader == COGL_INVALID_HANDLE) { self->shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); cogl_shader_source (self->shader, colorize_glsl_shader); self->is_compiled = FALSE; self->tex_uniform = -1; self->tint_uniform = -1; } if (self->program == COGL_INVALID_HANDLE) self->program = cogl_create_program (); if (!self->is_compiled) { g_assert (self->shader != COGL_INVALID_HANDLE); g_assert (self->program != COGL_INVALID_HANDLE); cogl_shader_compile (self->shader); if (!cogl_shader_is_compiled (self->shader)) { gchar *log_buf = cogl_shader_get_info_log (self->shader); g_warning (G_STRLOC ": Unable to compile the colorize shader: %s", log_buf); g_free (log_buf); cogl_handle_unref (self->shader); cogl_handle_unref (self->program); self->shader = COGL_INVALID_HANDLE; self->program = COGL_INVALID_HANDLE; } else { cogl_program_attach_shader (self->program, self->shader); cogl_program_link (self->program); cogl_handle_unref (self->shader); self->is_compiled = TRUE; self->tex_uniform = cogl_program_get_uniform_location (self->program, "tex"); self->tint_uniform = cogl_program_get_uniform_location (self->program, "tint"); } } parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class); return parent_class->pre_paint (effect); }
static void rc_set_shader(CoglHandle material, const RendererClutterShaderInfo *shaderInfo) { CoglHandle shader; CoglHandle program; gint uniform_no; shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); cogl_shader_source (shader, "vec3 checker(vec2 texc, vec3 color0, vec3 color1) \n" "{ \n" " if (mod(floor(texc.x) + floor(texc.y), 2.0) == 0.0) \n" " return color0; \n" " else \n" " return color1; \n" "} \n" " \n" "uniform sampler2D tex; \n" "uniform sampler3D clut; \n" "uniform float scale; \n" "uniform float offset; \n" "uniform float checkersize; \n" "uniform vec3 color0; \n" "uniform vec3 color1; \n" " \n" "void main(void) \n" "{ \n" " vec3 bg = checker(gl_FragCoord.xy / checkersize, color0, color1); \n" " vec4 img4 = texture2D(tex, gl_TexCoord[0].xy); \n" " vec3 img3 = img4.bgr; \n" " img3 = img3 * scale + offset; \n" " img3 = texture3D(clut, img3).rgb; \n" " \n" " gl_FragColor = vec4(img3 * img4.a + bg * (1.0 - img4.a), 1.0); \n" "} \n" ); cogl_shader_compile(shader); gchar *err = cogl_shader_get_info_log(shader); DEBUG_3("%s\n",err); g_free(err); program = cogl_create_program (); cogl_program_attach_shader (program, shader); cogl_handle_unref (shader); cogl_program_link (program); uniform_no = cogl_program_get_uniform_location (program, "tex"); cogl_program_set_uniform_1i (program, uniform_no, 0); uniform_no = cogl_program_get_uniform_location (program, "clut"); cogl_program_set_uniform_1i (program, uniform_no, 1); uniform_no = cogl_program_get_uniform_location (program, "scale"); cogl_program_set_uniform_1f (program, uniform_no, (double) (CLUT_SIZE - 1) / CLUT_SIZE); uniform_no = cogl_program_get_uniform_location (program, "offset"); cogl_program_set_uniform_1f (program, uniform_no, 1.0 / (2 * CLUT_SIZE)); uniform_no = cogl_program_get_uniform_location (program, "checkersize"); cogl_program_set_uniform_1f (program, uniform_no, shaderInfo->checkersize); uniform_no = cogl_program_get_uniform_location (program, "color0"); cogl_program_set_uniform_float (program, uniform_no, 3, 1, shaderInfo->checkercolor0); uniform_no = cogl_program_get_uniform_location (program, "color1"); cogl_program_set_uniform_float (program, uniform_no, 3, 1, shaderInfo->checkercolor1); cogl_material_set_user_program (material, program); cogl_handle_unref (program); }
static gboolean cd_icc_effect_pre_paint (ClutterEffect *effect) { CdIccEffect *self = CD_ICC_EFFECT (effect); ClutterEffectClass *parent_class; ClutterActorBox allocation; gfloat width, height; if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) return FALSE; self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); if (self->actor == NULL) return FALSE; if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) { /* if we don't have support for GLSL shaders then we * forcibly disable the ActorMeta */ g_warning ("Unable to use the ShaderEffect: the graphics hardware " "or the current GL driver does not implement support " "for the GLSL shading language."); clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE); return FALSE; } clutter_actor_get_allocation_box (self->actor, &allocation); clutter_actor_box_get_size (&allocation, &width, &height); if (self->shader == COGL_INVALID_HANDLE) { self->shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); cogl_shader_source (self->shader, glsl_shader); self->is_compiled = FALSE; self->main_texture_uniform = -1; self->indirect_texture_uniform = -1; self->color_data1_uniform = -1; self->color_data2_uniform = -1; } if (self->program == COGL_INVALID_HANDLE) self->program = cogl_create_program (); if (!self->is_compiled) { g_assert (self->shader != COGL_INVALID_HANDLE); g_assert (self->program != COGL_INVALID_HANDLE); cogl_shader_compile (self->shader); if (!cogl_shader_is_compiled (self->shader)) { gchar *log_buf = cogl_shader_get_info_log (self->shader); g_warning (G_STRLOC ": Unable to compile the icc shader: %s", log_buf); g_free (log_buf); cogl_handle_unref (self->shader); cogl_handle_unref (self->program); self->shader = COGL_INVALID_HANDLE; self->program = COGL_INVALID_HANDLE; } else { cogl_program_attach_shader (self->program, self->shader); cogl_program_link (self->program); cogl_handle_unref (self->shader); self->is_compiled = TRUE; self->main_texture_uniform = cogl_program_get_uniform_location (self->program, "main_texture"); self->indirect_texture_uniform = cogl_program_get_uniform_location (self->program, "indirect_texture"); self->color_data1_uniform = cogl_program_get_uniform_location (self->program, "color_data1"); self->color_data2_uniform = cogl_program_get_uniform_location (self->program, "color_data2"); } } parent_class = CLUTTER_EFFECT_CLASS (cd_icc_effect_parent_class); return parent_class->pre_paint (effect); }