diff --git a/cogl/cogl-material-private.h b/cogl/cogl-material-private.h index 54b14b8e5..451aaebbe 100644 --- a/cogl/cogl-material-private.h +++ b/cogl/cogl-material-private.h @@ -721,10 +721,6 @@ _cogl_material_layer_get_filters (CoglMaterialLayer *layer, CoglMaterialFilter *min_filter, CoglMaterialFilter *mag_filter); -void -_cogl_material_set_user_program (CoglMaterial *material, - CoglHandle program); - void _cogl_material_texture_storage_change_notify (CoglHandle texture); diff --git a/cogl/cogl-material.c b/cogl/cogl-material.c index 58aa2e13d..f6e5f257a 100644 --- a/cogl/cogl-material.c +++ b/cogl/cogl-material.c @@ -3975,6 +3975,19 @@ cogl_material_set_blend_constant (CoglMaterial *material, #endif } +CoglHandle +cogl_material_get_user_program (CoglMaterial *material) +{ + CoglMaterial *authority; + + g_return_val_if_fail (cogl_is_material (material), COGL_INVALID_HANDLE); + + authority = + _cogl_material_get_authority (material, COGL_MATERIAL_STATE_USER_SHADER); + + return authority->big_state->user_program; +} + /* XXX: for now we don't mind if the program has vertex shaders * attached but if we ever make a similar API public we should only * allow attaching of programs containing fragment shaders. Eventually @@ -3982,8 +3995,8 @@ cogl_material_set_blend_constant (CoglMaterial *material, * processing. */ void -_cogl_material_set_user_program (CoglMaterial *material, - CoglHandle program) +cogl_material_set_user_program (CoglMaterial *material, + CoglHandle program) { CoglMaterialState state = COGL_MATERIAL_STATE_USER_SHADER; CoglMaterial *authority; @@ -5125,8 +5138,11 @@ _cogl_material_apply_legacy_state (CoglMaterial *material) * the cogl_material API instead. */ - if (ctx->current_program) - _cogl_material_set_user_program (material, ctx->current_program); + /* A program explicitly set on the material has higher precedence than + * one associated with the context using cogl_program_use() */ + if (ctx->current_program && + cogl_material_get_user_program (material) == COGL_INVALID_HANDLE) + cogl_material_set_user_program (material, ctx->current_program); if (ctx->legacy_depth_test_enabled) cogl_material_set_depth_test_enabled (material, TRUE); diff --git a/cogl/cogl-material.h b/cogl/cogl-material.h index 989c8cedc..ef5b76a9b 100644 --- a/cogl/cogl-material.h +++ b/cogl/cogl-material.h @@ -636,6 +636,70 @@ cogl_material_set_point_size (CoglHandle material, float cogl_material_get_point_size (CoglHandle material); +/** + * cogl_material_get_user_program: + * @material: a #CoglMaterial object. + * + * Queries what user program has been associated with the given + * @material using cogl_material_set_user_program(). + * + * Return value: The current user program or %COGL_INVALID_HANDLE. + * + * Since: 1.4 + */ +CoglHandle +cogl_material_get_user_program (CoglMaterial *material); + +/** + * cogl_material_set_user_program: + * @material: a #CoglMaterial object. + * @program: A #CoglHandle to a linked CoglProgram + * + * Associates a linked CoglProgram with the given material so that the + * program can take full control of vertex and/or fragment processing. + * + * This is an example of how it can be used to associate an ARBfp + * program with a #CoglMaterial: + * |[ + * CoglHandle shader; + * CoglHandle program; + * CoglMaterial *material; + * + * shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); + * cogl_shader_source (shader, + * "!!ARBfp1.0\n" + * "MOV result.color,fragment.color;\n" + * "END\n"); + * cogl_shader_compile (shader); + * + * program = cogl_create_program (); + * cogl_program_attach_shader (program, shader); + * cogl_program_link (program); + * + * material = cogl_material_new (); + * cogl_material_set_user_program (material, program); + * + * cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); + * cogl_rectangle (0, 0, 100, 100); + * ]| + * + * It is possibly worth keeping in mind that this API is not part of + * the long term design for how we want to expose shaders to Cogl + * developers (We are planning on deprecating the cogl_program and + * cogl_shader APIs in favour of a "snippet" framework) but in the + * meantime we hope this will handle most practical GLSL and ARBfp + * requirements. + * + * Also remember you need to check for either the + * %COGL_FEATURE_SHADERS_GLSL or %COGL_FEATURE_SHADERS_ARBFP before + * using the cogl_program or cogl_shader API. + * + * Since: 1.4 + */ +void +cogl_material_set_user_program (CoglMaterial *material, + CoglHandle program); + /** * cogl_material_set_layer: * @material: A #CoglMaterial object