mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 12:02:04 +00:00
material: route fogging state through CoglMaterial
Previously cogl_set_fog would cause a flush of the Cogl journal and would directly bang the GL state machine to setup fogging. As part of the ongoing effort to track most state in CoglMaterial to support renderlists this now adds an indirection so that cogl_set_fog now just updates ctx->legacy_fog_state. The fogging state then gets enabled as a legacy override similar to how the old depth testing API is handled.
This commit is contained in:
parent
279e68d8d9
commit
9b9e764dc1
@ -84,7 +84,6 @@ cogl_create_context (void)
|
||||
_cogl_material_init_default_layers ();
|
||||
|
||||
_context->enable_flags = 0;
|
||||
_context->fog_enabled = FALSE;
|
||||
|
||||
_context->enable_backface_culling = FALSE;
|
||||
_context->flushed_front_winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE;
|
||||
@ -105,6 +104,8 @@ cogl_create_context (void)
|
||||
_context->active_texture_unit = 1;
|
||||
GE (glActiveTexture (GL_TEXTURE1));
|
||||
|
||||
_context->legacy_fog_state.enabled = FALSE;
|
||||
|
||||
_context->simple_material = cogl_material_new ();
|
||||
_context->source_material = NULL;
|
||||
_context->arbfp_source_buffer = g_string_new ("");
|
||||
|
@ -56,7 +56,6 @@ typedef struct
|
||||
|
||||
/* Enable cache */
|
||||
unsigned long enable_flags;
|
||||
gboolean fog_enabled;
|
||||
|
||||
gboolean enable_backface_culling;
|
||||
CoglFrontWinding flushed_front_winding;
|
||||
@ -73,6 +72,8 @@ typedef struct
|
||||
GArray *texture_units;
|
||||
int active_texture_unit;
|
||||
|
||||
CoglMaterialFogState legacy_fog_state;
|
||||
|
||||
/* Materials */
|
||||
CoglMaterial *simple_material;
|
||||
CoglMaterial *source_material;
|
||||
|
@ -250,7 +250,7 @@ _cogl_material_backend_arbfp_start (CoglMaterial *material,
|
||||
return FALSE;
|
||||
|
||||
/* TODO: support fog */
|
||||
if (ctx->fog_enabled)
|
||||
if (ctx->legacy_fog_state.enabled)
|
||||
return FALSE;
|
||||
|
||||
/* Note: we allocate ARBfp private state for both the given material
|
||||
|
@ -186,6 +186,54 @@ static gboolean
|
||||
_cogl_material_backend_fixed_end (CoglMaterial *material,
|
||||
unsigned long materials_difference)
|
||||
{
|
||||
if (materials_difference & COGL_MATERIAL_STATE_FOG)
|
||||
{
|
||||
CoglMaterial *authority =
|
||||
_cogl_material_get_authority (material, COGL_MATERIAL_STATE_FOG);
|
||||
CoglMaterialFogState *fog_state = &authority->big_state->fog_state;
|
||||
|
||||
if (fog_state->enabled)
|
||||
{
|
||||
GLfloat fogColor[4];
|
||||
GLenum gl_mode = GL_LINEAR;
|
||||
|
||||
fogColor[0] = cogl_color_get_red_float (&fog_state->color);
|
||||
fogColor[1] = cogl_color_get_green_float (&fog_state->color);
|
||||
fogColor[2] = cogl_color_get_blue_float (&fog_state->color);
|
||||
fogColor[3] = cogl_color_get_alpha_float (&fog_state->color);
|
||||
|
||||
GE (glEnable (GL_FOG));
|
||||
|
||||
GE (glFogfv (GL_FOG_COLOR, fogColor));
|
||||
|
||||
#if HAVE_COGL_GLES
|
||||
switch (fog_state->mode)
|
||||
{
|
||||
case COGL_FOG_MODE_LINEAR:
|
||||
gl_mode = GL_LINEAR;
|
||||
break;
|
||||
case COGL_FOG_MODE_EXPONENTIAL:
|
||||
gl_mode = GL_EXP;
|
||||
break;
|
||||
case COGL_FOG_MODE_EXPONENTIAL_SQUARED:
|
||||
gl_mode = GL_EXP2;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* TODO: support other modes for GLES2 */
|
||||
|
||||
/* NB: GLES doesn't have glFogi */
|
||||
GE (glFogf (GL_FOG_MODE, gl_mode));
|
||||
GE (glHint (GL_FOG_HINT, GL_NICEST));
|
||||
|
||||
GE (glFogf (GL_FOG_DENSITY, fog_state->density));
|
||||
GE (glFogf (GL_FOG_START, fog_state->z_near));
|
||||
GE (glFogf (GL_FOG_END, fog_state->z_far));
|
||||
}
|
||||
else
|
||||
GE (glDisable (GL_FOG));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -332,8 +332,9 @@ typedef enum _CoglMaterialState
|
||||
COGL_MATERIAL_STATE_BLEND = 1L<<5,
|
||||
COGL_MATERIAL_STATE_USER_SHADER = 1L<<6,
|
||||
COGL_MATERIAL_STATE_DEPTH = 1L<<7,
|
||||
COGL_MATERIAL_STATE_FOG = 1L<<8,
|
||||
|
||||
COGL_MATERIAL_STATE_REAL_BLEND_ENABLE = 1L<<8,
|
||||
COGL_MATERIAL_STATE_REAL_BLEND_ENABLE = 1L<<9,
|
||||
|
||||
COGL_MATERIAL_STATE_ALL_SPARSE =
|
||||
COGL_MATERIAL_STATE_COLOR |
|
||||
@ -343,7 +344,8 @@ typedef enum _CoglMaterialState
|
||||
COGL_MATERIAL_STATE_ALPHA_FUNC |
|
||||
COGL_MATERIAL_STATE_BLEND |
|
||||
COGL_MATERIAL_STATE_USER_SHADER |
|
||||
COGL_MATERIAL_STATE_DEPTH,
|
||||
COGL_MATERIAL_STATE_DEPTH |
|
||||
COGL_MATERIAL_STATE_FOG,
|
||||
|
||||
COGL_MATERIAL_STATE_AFFECTS_BLENDING =
|
||||
COGL_MATERIAL_STATE_COLOR |
|
||||
@ -358,7 +360,8 @@ typedef enum _CoglMaterialState
|
||||
COGL_MATERIAL_STATE_ALPHA_FUNC |
|
||||
COGL_MATERIAL_STATE_BLEND |
|
||||
COGL_MATERIAL_STATE_USER_SHADER |
|
||||
COGL_MATERIAL_STATE_DEPTH
|
||||
COGL_MATERIAL_STATE_DEPTH |
|
||||
COGL_MATERIAL_STATE_FOG
|
||||
|
||||
} CoglMaterialState;
|
||||
|
||||
@ -420,6 +423,16 @@ typedef struct
|
||||
float depth_range_far;
|
||||
} CoglMaterialDepthState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean enabled;
|
||||
CoglColor color;
|
||||
CoglFogMode mode;
|
||||
float density;
|
||||
float z_near;
|
||||
float z_far;
|
||||
} CoglMaterialFogState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglMaterialLightingState lighting_state;
|
||||
@ -427,6 +440,7 @@ typedef struct
|
||||
CoglMaterialBlendState blend_state;
|
||||
CoglHandle user_program;
|
||||
CoglMaterialDepthState depth_state;
|
||||
CoglMaterialFogState fog_state;
|
||||
} CoglMaterialBigState;
|
||||
|
||||
typedef enum
|
||||
|
@ -2934,6 +2934,24 @@ _cogl_material_depth_state_equal (CoglMaterial *authority0,
|
||||
sizeof (CoglMaterialDepthState)) == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cogl_material_fog_state_equal (CoglMaterial *authority0,
|
||||
CoglMaterial *authority1)
|
||||
{
|
||||
CoglMaterialFogState *fog_state0 = &authority0->big_state->fog_state;
|
||||
CoglMaterialFogState *fog_state1 = &authority1->big_state->fog_state;
|
||||
|
||||
if (fog_state0->enabled == fog_state1->enabled &&
|
||||
cogl_color_equal (&fog_state0->color, &fog_state1->color) &&
|
||||
fog_state0->mode == fog_state1->mode &&
|
||||
fog_state0->density == fog_state1->density &&
|
||||
fog_state0->z_near == fog_state1->z_near &&
|
||||
fog_state0->z_far == fog_state1->z_far)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cogl_material_layers_equal (CoglMaterial *authority0,
|
||||
CoglMaterial *authority1)
|
||||
@ -3151,6 +3169,12 @@ _cogl_material_equal (CoglMaterial *material0,
|
||||
_cogl_material_depth_state_equal))
|
||||
return FALSE;
|
||||
|
||||
if (!simple_property_equal (material0, material1,
|
||||
materials_difference,
|
||||
COGL_MATERIAL_STATE_FOG,
|
||||
_cogl_material_fog_state_equal))
|
||||
return FALSE;
|
||||
|
||||
if (!simple_property_equal (material0, material1,
|
||||
materials_difference,
|
||||
COGL_MATERIAL_STATE_LAYERS,
|
||||
@ -4097,6 +4121,41 @@ cogl_material_get_depth_range (CoglMaterial *material,
|
||||
*far_val = authority->big_state->depth_state.depth_range_far;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_material_set_fog_state (CoglMaterial *material,
|
||||
const CoglMaterialFogState *fog_state)
|
||||
{
|
||||
CoglMaterialState state = COGL_MATERIAL_STATE_FOG;
|
||||
CoglMaterial *authority;
|
||||
CoglMaterialFogState *current_fog_state;
|
||||
|
||||
g_return_if_fail (cogl_is_material (material));
|
||||
|
||||
authority = _cogl_material_get_authority (material, state);
|
||||
|
||||
current_fog_state = &authority->big_state->fog_state;
|
||||
|
||||
if (current_fog_state->enabled == fog_state->enabled &&
|
||||
cogl_color_equal (¤t_fog_state->color, &fog_state->color) &&
|
||||
current_fog_state->mode == fog_state->mode &&
|
||||
current_fog_state->density == fog_state->density &&
|
||||
current_fog_state->z_near == fog_state->z_near &&
|
||||
current_fog_state->z_far == fog_state->z_far)
|
||||
return;
|
||||
|
||||
/* - Flush journal primitives referencing the current state.
|
||||
* - Make sure the material has no dependants so it may be modified.
|
||||
* - If the material isn't currently an authority for the state being
|
||||
* changed, then initialize that state from the current authority.
|
||||
*/
|
||||
_cogl_material_pre_change_notify (material, state, NULL);
|
||||
|
||||
material->big_state->fog_state = *fog_state;
|
||||
|
||||
_cogl_material_update_authority (material, authority, state,
|
||||
_cogl_material_fog_state_equal);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
_cogl_material_get_age (CoglMaterial *material)
|
||||
{
|
||||
@ -5895,6 +5954,9 @@ _cogl_material_apply_legacy_state (CoglMaterial *material)
|
||||
|
||||
if (ctx->legacy_depth_test_enabled)
|
||||
cogl_material_set_depth_test_enabled (material, TRUE);
|
||||
|
||||
if (ctx->legacy_fog_state.enabled)
|
||||
_cogl_material_set_fog_state (material, &ctx->legacy_fog_state);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -576,48 +576,17 @@ cogl_set_fog (const CoglColor *fog_color,
|
||||
float z_near,
|
||||
float z_far)
|
||||
{
|
||||
GLfloat fogColor[4];
|
||||
GLenum gl_mode = GL_LINEAR;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* The cogl journal doesn't currently track fog state changes */
|
||||
_cogl_journal_flush ();
|
||||
if (ctx->legacy_fog_state.enabled == FALSE)
|
||||
ctx->legacy_state_set++;
|
||||
|
||||
fogColor[0] = cogl_color_get_red_float (fog_color);
|
||||
fogColor[1] = cogl_color_get_green_float (fog_color);
|
||||
fogColor[2] = cogl_color_get_blue_float (fog_color);
|
||||
fogColor[3] = cogl_color_get_alpha_float (fog_color);
|
||||
|
||||
glEnable (GL_FOG);
|
||||
|
||||
glFogfv (GL_FOG_COLOR, fogColor);
|
||||
|
||||
#if HAVE_COGL_GLES
|
||||
switch (mode)
|
||||
{
|
||||
case COGL_FOG_MODE_LINEAR:
|
||||
gl_mode = GL_LINEAR;
|
||||
break;
|
||||
case COGL_FOG_MODE_EXPONENTIAL:
|
||||
gl_mode = GL_EXP;
|
||||
break;
|
||||
case COGL_FOG_MODE_EXPONENTIAL_SQUARED:
|
||||
gl_mode = GL_EXP2;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* TODO: support other modes for GLES2 */
|
||||
|
||||
/* NB: GLES doesn't have glFogi */
|
||||
glFogf (GL_FOG_MODE, gl_mode);
|
||||
glHint (GL_FOG_HINT, GL_NICEST);
|
||||
|
||||
glFogf (GL_FOG_DENSITY, (GLfloat) density);
|
||||
glFogf (GL_FOG_START, (GLfloat) z_near);
|
||||
glFogf (GL_FOG_END, (GLfloat) z_far);
|
||||
|
||||
ctx->fog_enabled = TRUE;
|
||||
ctx->legacy_fog_state.enabled = TRUE;
|
||||
ctx->legacy_fog_state.color = *fog_color;
|
||||
ctx->legacy_fog_state.mode = mode;
|
||||
ctx->legacy_fog_state.density = density;
|
||||
ctx->legacy_fog_state.z_near = z_near;
|
||||
ctx->legacy_fog_state.z_far = z_far;
|
||||
}
|
||||
|
||||
void
|
||||
@ -625,11 +594,10 @@ cogl_disable_fog (void)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* Currently the journal can't track changes to fog state... */
|
||||
_cogl_journal_flush ();
|
||||
if (ctx->legacy_fog_state.enabled == TRUE)
|
||||
ctx->legacy_state_set--;
|
||||
|
||||
glDisable (GL_FOG);
|
||||
ctx->fog_enabled = FALSE;
|
||||
ctx->legacy_fog_state.enabled = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user