diff --git a/cogl-material.h b/cogl-material.h index 43c603559..2ad878551 100644 --- a/cogl-material.h +++ b/cogl-material.h @@ -152,20 +152,6 @@ void cogl_material_set_shininess (CoglHandle material, void cogl_material_set_emission (CoglHandle material, const CoglColor *emission); -/** - * cogl_set_source: - * @material: A CoglMaterial object - * - * This function sets the source material that will be used to fill - * subsequent geometry emitted via the cogl API. - * - * XXX: This doesn't really belong to the cogl-material API, it should - * move to cogl.h - * - * Since 1.0 - */ -void cogl_set_source (CoglHandle material); - /** * CoglMaterialAlphaFunc: * @COGL_MATERIAL_ALPHA_FUNC_NEVER: Never let the fragment through. @@ -586,34 +572,10 @@ void cogl_material_set_layer_matrix (CoglHandle material, * Note: This API is hopfully just a stop-gap solution. Ideally * cogl_enable will be replaced. */ +/* TODO: find a nicer solution! */ gulong cogl_material_get_cogl_enable_flags (CoglHandle handle); -/** - * cogl_material_flush_gl_material_state: - * @material: A CoglMaterial object - * - * This commits the glMaterial state to the OpenGL driver. Normally you - * shouldn't need to use this function directly, since Cogl will do this - * internally, but if you are developing custom primitives directly with - * OpenGL you may want to use this. - */ -void cogl_material_flush_gl_material_state (CoglHandle material_handle); - -/** - * cogl_material_flush_gl_alpha_func: - * @material: A CoglMaterial object - * - */ -void cogl_material_flush_gl_alpha_func (CoglHandle material_handle); - -/** - * cogl_material_flush_gl_blend_func: - * @material: A CoglMaterial object - * - */ -void cogl_material_flush_gl_blend_func (CoglHandle material_handle); - /** * cogl_material_get_layers: * @material: A CoglMaterial object @@ -691,6 +653,38 @@ CoglHandle cogl_material_layer_get_texture (CoglHandle layer_handle); */ void cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle); +/** + * cogl_set_source: + * @material: A CoglMaterial object + * + * This function sets the source material that will be used to fill + * subsequent geometry emitted via the cogl API. + * + * Note: in the future we may add the ability to set a front facing + * material, and a back facing material, in which case this function + * will set both to the same. + * + * Since 1.0 + */ +/* XXX: This doesn't really belong to the cogl-material API, it should + * move to cogl.h */ +void cogl_set_source (CoglHandle material); + +/** + * cogl_flush_material_gl_state: + * + * This function commits all the state of the source CoglMaterial - not + * including the per-layer state - to the OpenGL[ES] driver. + * + * Normally you shouldn't need to use this function directly, but if you + * are developing a custom primitive using raw OpenGL that works with + * CoglMaterials, then you may want to use this function. + * + * Since 1.0 + */ +/* XXX: This should be moved with cogl_set_source to cogl.h */ +void cogl_flush_material_gl_state (void); + G_END_DECLS #endif /* __COGL_MATERIAL_H__ */ diff --git a/common/cogl-material.c b/common/cogl-material.c index 7d98d3de1..2e9f5a353 100644 --- a/common/cogl-material.c +++ b/common/cogl-material.c @@ -79,7 +79,8 @@ cogl_material_set_ambient (CoglHandle handle, ambient[1] = cogl_color_get_green_float (ambient_color); ambient[2] = cogl_color_get_blue_float (ambient_color); ambient[3] = cogl_color_get_alpha_float (ambient_color); - /* material->ambient = *ambient_color; */ + + material->flags |= COGL_MATERIAL_FLAG_DIRTY; } void @@ -98,7 +99,8 @@ cogl_material_set_diffuse (CoglHandle handle, diffuse[1] = cogl_color_get_green_float (diffuse_color); diffuse[2] = cogl_color_get_blue_float (diffuse_color); diffuse[3] = cogl_color_get_alpha_float (diffuse_color); - /* material->diffuse = *diffuse_color; */ + + material->flags |= COGL_MATERIAL_FLAG_DIRTY; } void @@ -125,7 +127,8 @@ cogl_material_set_specular (CoglHandle handle, specular[1] = cogl_color_get_green_float (specular_color); specular[2] = cogl_color_get_blue_float (specular_color); specular[3] = cogl_color_get_alpha_float (specular_color); - /* material->specular = *specular_color; */ + + material->flags |= COGL_MATERIAL_FLAG_DIRTY; } void @@ -143,6 +146,8 @@ cogl_material_set_shininess (CoglHandle handle, material = _cogl_material_pointer_from_handle (handle); material->shininess = (GLfloat)shininess * 128.0; + + material->flags |= COGL_MATERIAL_FLAG_DIRTY; } void @@ -161,22 +166,8 @@ cogl_material_set_emission (CoglHandle handle, emission[1] = cogl_color_get_green_float (emission_color); emission[2] = cogl_color_get_blue_float (emission_color); emission[3] = cogl_color_get_alpha_float (emission_color); - /* material->emission = *emission_color; */ -} -/* TODO: Should go in cogl.c */ -void -cogl_set_source (CoglHandle material_handle) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_is_material (material_handle)); - - if (ctx->source_material) - cogl_material_unref (ctx->source_material); - - cogl_material_ref (material_handle); - ctx->source_material = material_handle; + material->flags |= COGL_MATERIAL_FLAG_DIRTY; } void @@ -191,6 +182,8 @@ cogl_material_set_alpha_test_function (CoglHandle handle, material = _cogl_material_pointer_from_handle (handle); material->alpha_func = alpha_func; material->alpha_func_reference = (GLfloat)alpha_reference; + + material->flags |= COGL_MATERIAL_FLAG_DIRTY; } void @@ -205,6 +198,8 @@ cogl_material_set_blend_factors (CoglHandle handle, material = _cogl_material_pointer_from_handle (handle); material->blend_src_factor = src_factor; material->blend_dst_factor = dst_factor; + + material->flags |= COGL_MATERIAL_FLAG_DIRTY; } /* Asserts that a layer corresponding to the given index exists. If no @@ -492,44 +487,6 @@ cogl_material_get_cogl_enable_flags (CoglHandle material_handle) return enable_flags; } -void -cogl_material_flush_gl_material_state (CoglHandle material_handle) -{ - CoglMaterial *material; - - g_return_if_fail (cogl_is_material (material_handle)); - - material = _cogl_material_pointer_from_handle (material_handle); - - GE (glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient)); - GE (glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse)); - GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, material->specular)); - GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, material->emission)); - GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &material->shininess)); -} - -void -cogl_material_flush_gl_alpha_func (CoglHandle material_handle) -{ - CoglMaterial *material; - - g_return_if_fail (cogl_is_material (material_handle)); - - material = _cogl_material_pointer_from_handle (material_handle); - - /* NB: Currently the Cogl defines are compatible with the GL ones: */ - GE (glAlphaFunc (material->alpha_func, material->alpha_func_reference)); -} - -void -cogl_material_flush_gl_blend_func (CoglHandle material_handle) -{ - CoglMaterial *material; - - g_return_if_fail (cogl_is_material (material_handle)); - GE (glBlendFunc (material->blend_src_factor, material->blend_dst_factor)); -} - /* It's a bit out of the ordinary to return a const GList *, but it's * probably sensible to try and avoid list manipulation for every * primitive emitted in a scene, every frame. @@ -678,3 +635,50 @@ cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle) } } +/* TODO: Should go in cogl.c, but that implies duplication which is also + * not ideal. */ +void +cogl_set_source (CoglHandle material_handle) +{ + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + g_return_if_fail (cogl_is_material (material_handle)); + + if (ctx->source_material == material_handle) + return; + + if (ctx->source_material) + cogl_material_unref (ctx->source_material); + + cogl_material_ref (material_handle); + ctx->source_material = material_handle; +} +/* TODO: add cogl_set_front_source (), and cogl_set_back_source () */ + +void +cogl_flush_material_gl_state (void) +{ + CoglMaterial *material; + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + material = _cogl_material_pointer_from_handle (ctx->source_material); + + if (ctx->source_material == ctx->current_material + && !(material->flags & COGL_MATERIAL_FLAG_DIRTY)) + return; + + /* FIXME - we only need to set these if lighting is enabled... */ + GE (glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient)); + GE (glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse)); + GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, material->specular)); + GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, material->emission)); + GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &material->shininess)); + + /* NB: Currently the Cogl defines are compatible with the GL ones: */ + GE (glAlphaFunc (material->alpha_func, material->alpha_func_reference)); + + GE (glBlendFunc (material->blend_src_factor, material->blend_dst_factor)); + + ctx->current_material = ctx->source_material; +} + diff --git a/gl/cogl-context.c b/gl/cogl-context.c index 9283ad69d..f74df873a 100644 --- a/gl/cogl-context.c +++ b/gl/cogl-context.c @@ -62,6 +62,7 @@ cogl_create_context () _context->material_handles = NULL; _context->material_layer_handles = NULL; _context->source_material = NULL; + _context->current_material = NULL; _context->fbo_handles = NULL; _context->draw_buffer = COGL_WINDOW_BUFFER; diff --git a/gl/cogl-context.h b/gl/cogl-context.h index 3eb00e1b7..e54489d3c 100644 --- a/gl/cogl-context.h +++ b/gl/cogl-context.h @@ -70,6 +70,7 @@ typedef struct GArray *material_handles; GArray *material_layer_handles; CoglHandle source_material; + CoglHandle current_material; /* Framebuffer objects */ GArray *fbo_handles; diff --git a/gl/cogl-texture.c b/gl/cogl-texture.c index 54e6c5688..ab84c9543 100644 --- a/gl/cogl-texture.c +++ b/gl/cogl-texture.c @@ -2531,9 +2531,8 @@ cogl_material_rectangle (CoglFixed x1, GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords)); /* Setup the remaining GL state according to this material... */ - cogl_material_flush_gl_material_state (material); - cogl_material_flush_gl_alpha_func (material); - cogl_material_flush_gl_blend_func (material); + cogl_flush_material_gl_state (); + /* FIXME: This api is a bit yukky, ideally it will be removed if we * re-work the cogl_enable mechanism */ enable_flags |= cogl_material_get_cogl_enable_flags (material);