cogl-material: Add a property for setting the point size

This adds cogl_material_{get,set}_point_size. If the point size is not
1.0f then glPointSize will be called when the material is flushed.

http://bugzilla.openedhand.com/show_bug.cgi?id=2047
This commit is contained in:
Neil Roberts 2010-03-22 09:32:17 +00:00 committed by Robert Bragg
parent dcc8c66fdd
commit 06b58baa10
9 changed files with 151 additions and 4 deletions

View File

@ -148,6 +148,8 @@ cogl_create_context (void)
_context->depth_range_near_cache = 0;
_context->depth_range_far_cache = 1;
_context->point_size_cache = 1.0f;
_context->legacy_depth_test_enabled = FALSE;
for (i = 0; i < COGL_BUFFER_BIND_TARGET_COUNT; i++)

View File

@ -119,6 +119,8 @@ typedef struct
gboolean legacy_depth_test_enabled;
float point_size_cache;
CoglBuffer *current_buffer[COGL_BUFFER_BIND_TARGET_COUNT];
/* Framebuffers */

View File

@ -333,8 +333,9 @@ typedef enum _CoglMaterialState
COGL_MATERIAL_STATE_USER_SHADER = 1L<<6,
COGL_MATERIAL_STATE_DEPTH = 1L<<7,
COGL_MATERIAL_STATE_FOG = 1L<<8,
COGL_MATERIAL_STATE_POINT_SIZE = 1L<<9,
COGL_MATERIAL_STATE_REAL_BLEND_ENABLE = 1L<<9,
COGL_MATERIAL_STATE_REAL_BLEND_ENABLE = 1L<<10,
COGL_MATERIAL_STATE_ALL_SPARSE =
COGL_MATERIAL_STATE_COLOR |
@ -345,7 +346,8 @@ typedef enum _CoglMaterialState
COGL_MATERIAL_STATE_BLEND |
COGL_MATERIAL_STATE_USER_SHADER |
COGL_MATERIAL_STATE_DEPTH |
COGL_MATERIAL_STATE_FOG,
COGL_MATERIAL_STATE_FOG |
COGL_MATERIAL_STATE_POINT_SIZE,
COGL_MATERIAL_STATE_AFFECTS_BLENDING =
COGL_MATERIAL_STATE_COLOR |
@ -361,7 +363,8 @@ typedef enum _CoglMaterialState
COGL_MATERIAL_STATE_BLEND |
COGL_MATERIAL_STATE_USER_SHADER |
COGL_MATERIAL_STATE_DEPTH |
COGL_MATERIAL_STATE_FOG
COGL_MATERIAL_STATE_FOG |
COGL_MATERIAL_STATE_POINT_SIZE
} CoglMaterialState;
@ -441,6 +444,7 @@ typedef struct
CoglHandle user_program;
CoglMaterialDepthState depth_state;
CoglMaterialFogState fog_state;
float point_size;
} CoglMaterialBigState;
typedef enum

View File

@ -388,6 +388,8 @@ _cogl_material_init_default_material (void)
depth_state->depth_range_near = 0;
depth_state->depth_range_far = 1;
big_state->point_size = 1.0f;
ctx->default_material = _cogl_material_object_new (material);
}
@ -1018,6 +1020,9 @@ _cogl_material_copy_differences (CoglMaterial *dest,
sizeof (CoglMaterialDepthState));
}
if (differences & COGL_MATERIAL_STATE_POINT_SIZE)
big_state->point_size = src->big_state->point_size;
/* XXX: we shouldn't bother doing this in most cases since
* _copy_differences is typically used to initialize material state
* by copying it from the current authority, so it's not actually
@ -2967,6 +2972,13 @@ _cogl_material_fog_state_equal (CoglMaterial *authority0,
return FALSE;
}
static gboolean
_cogl_material_point_size_equal (CoglMaterial *authority0,
CoglMaterial *authority1)
{
return authority0->big_state->point_size == authority1->big_state->point_size;
}
static gboolean
_cogl_material_layers_equal (CoglMaterial *authority0,
CoglMaterial *authority1)
@ -3190,6 +3202,12 @@ _cogl_material_equal (CoglMaterial *material0,
_cogl_material_fog_state_equal))
return FALSE;
if (!simple_property_equal (material0, material1,
materials_difference,
COGL_MATERIAL_STATE_POINT_SIZE,
_cogl_material_point_size_equal))
return FALSE;
if (!simple_property_equal (material0, material1,
materials_difference,
COGL_MATERIAL_STATE_LAYERS,
@ -4987,6 +5005,48 @@ cogl_material_set_layer_filters (CoglMaterial *material,
}
}
float
cogl_material_get_point_size (CoglHandle handle)
{
CoglMaterial *material = COGL_MATERIAL (handle);
CoglMaterial *authority;
g_return_val_if_fail (cogl_is_material (handle), FALSE);
authority =
_cogl_material_get_authority (material, COGL_MATERIAL_STATE_POINT_SIZE);
return authority->big_state->point_size;
}
void
cogl_material_set_point_size (CoglHandle handle,
float point_size)
{
CoglMaterial *material = COGL_MATERIAL (handle);
CoglMaterialState state = COGL_MATERIAL_STATE_POINT_SIZE;
CoglMaterial *authority;
g_return_if_fail (cogl_is_material (handle));
authority = _cogl_material_get_authority (material, state);
if (authority->big_state->point_size == point_size)
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->point_size = point_size;
_cogl_material_update_authority (material, authority, state,
_cogl_material_point_size_equal);
}
static void
disable_texture_unit (int unit_index)
{
@ -5340,6 +5400,18 @@ _cogl_material_flush_color_blend_alpha_depth_state (
}
}
if (materials_difference & COGL_MATERIAL_STATE_POINT_SIZE)
{
CoglMaterial *authority =
_cogl_material_get_authority (material, COGL_MATERIAL_STATE_POINT_SIZE);
if (ctx->point_size_cache != authority->big_state->point_size)
{
GE( glPointSize (authority->big_state->point_size) );
ctx->point_size_cache = authority->big_state->point_size;
}
}
if (material->real_blend_enable != ctx->gl_blend_enable_cache)
{
if (material->real_blend_enable)

View File

@ -600,6 +600,39 @@ void
cogl_material_set_blend_constant (CoglMaterial *material,
const CoglColor *constant_color);
/**
* cogl_material_set_point_size:
* @material: a #CoglHandle to a material.
* @size: the new point size.
*
* Changes the size of points drawn when %COGL_VERTICES_MODE_POINTS is
* used with the vertex buffer API. Note that typically the GPU will
* only support a limited minimum and maximum range of point sizes. If
* the chosen point size is outside that range then the nearest value
* within that range will be used instead. The size of a point is in
* screen space so it will be the same regardless of any
* transformations. The default point size is 1.0.
*
* Since: 1.4
*/
void
cogl_material_set_point_size (CoglHandle material,
float point_size);
/**
* cogl_material_get_point_size:
* @material: a #CoglHandle to a material.
*
* Get the size of points drawn when %COGL_VERTICES_MODE_POINTS is
* used with the vertex buffer API.
*
* Return value: the point size of the material.
*
* Since: 1.4
*/
float
cogl_material_get_point_size (CoglHandle material);
/**
* cogl_material_set_layer:
* @material: A #CoglMaterial object

View File

@ -23,6 +23,9 @@ uniform float fog_density;
uniform float fog_start;
uniform float fog_end;
/* Point options */
uniform float point_size;
/*** _cogl_fixed_vertex_shader_main_start ***/
void
@ -33,6 +36,9 @@ main (void)
/* Calculate the transformed position */
gl_Position = mvp_matrix * vertex_attrib;
/* Copy across the point size from the uniform */
gl_PointSize = point_size;
/* Calculate the transformed texture coordinate */
/*** _cogl_fixed_vertex_shader_frag_color_start ***/

View File

@ -194,6 +194,9 @@ _cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
_cogl_wrap_glDisable (GL_ALPHA_TEST);
_cogl_wrap_glAlphaFunc (GL_ALWAYS, 0.0f);
/* Initialize the point size */
_cogl_wrap_glPointSize (1.0f);
initialize_texture_units (wrapper);
}
@ -772,6 +775,9 @@ cogl_gles2_wrapper_get_locations (GLuint program,
uniforms->alpha_test_ref_uniform
= glGetUniformLocation (program, "alpha_test_ref");
uniforms->point_size_uniform
= glGetUniformLocation (program, "point_size");
}
static void
@ -1235,6 +1241,10 @@ _cogl_wrap_prepare_for_draw (void)
}
}
if ((w->dirty_uniforms & COGL_GLES2_DIRTY_POINT_SIZE))
glUniform1f (program->uniforms.point_size_uniform,
w->point_size);
w->dirty_uniforms = 0;
}
@ -1688,6 +1698,15 @@ _cogl_wrap_glMaterialfv (GLenum face, GLenum pname, const GLfloat *params)
function can't do anything */
}
void
_cogl_wrap_glPointSize (GLfloat size)
{
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
w->point_size = size;
w->dirty_uniforms |= COGL_GLES2_DIRTY_POINT_SIZE;
}
void
_cogl_gles2_clear_cache_for_program (CoglHandle user_program)
{

View File

@ -74,8 +74,9 @@ enum
COGL_GLES2_DIRTY_FOG_COLOR = 1 << 6,
COGL_GLES2_DIRTY_ALPHA_TEST_REF = 1 << 7,
COGL_GLES2_DIRTY_TEXTURE_UNITS = 1 << 8,
COGL_GLES2_DIRTY_POINT_SIZE = 1 << 9,
COGL_GLES2_DIRTY_ALL = (1 << 9) - 1
COGL_GLES2_DIRTY_ALL = (1 << 10) - 1
};
/* Dirty flags for shader vertex attribute pointers */
@ -110,6 +111,8 @@ struct _CoglGles2WrapperUniforms
GLint alpha_test_ref_uniform;
GLint texture_unit_uniform;
GLint point_size_uniform;
};
struct _CoglGles2WrapperTexEnv
@ -204,6 +207,7 @@ struct _CoglGles2Wrapper
GLfloat fog_start;
GLfloat fog_end;
GLfloat fog_color[4];
GLfloat point_size;
CoglBoxedValue custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS];
};
@ -377,6 +381,8 @@ void _cogl_wrap_glTexParameteri (GLenum target, GLenum pname, GLfloat param);
void _cogl_wrap_glMaterialfv (GLenum face, GLenum pname, const GLfloat *params);
void _cogl_wrap_glPointSize (GLfloat point_size);
/* This function is only available on GLES 2 */
#define _cogl_wrap_glGenerateMipmap glGenerateMipmap
@ -419,6 +425,7 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program);
#define glFogfv _cogl_wrap_glFogfv
#define glTexParameteri _cogl_wrap_glTexParameteri
#define glMaterialfv _cogl_wrap_glMaterialfv
#define glPointSize _cogl_wrap_glPointSize
#endif /* COGL_GLES2_WRAPPER_NO_REMAP */
#else /* HAVE_COGL_GLES2 */

View File

@ -484,6 +484,8 @@ COGL_BLEND_STRING_ERROR
CoglBlendStringError
cogl_material_set_blend
cogl_material_set_blend_constant
cogl_material_set_point_size
cogl_material_get_point_size
cogl_material_set_layer
cogl_material_remove_layer
cogl_material_set_layer_combine