+2008-05-28 Neil Roberts <neil@o-hand.com>
+
+ * clutter/cogl/gles/cogl-gles2-wrapper.c
+ (cogl_gles2_wrapper_init): Get uniforms for fog parameters and
+ initialise them.
+ (cogl_wrap_glDrawArrays): Store the modelview matrix in a uniform
+ as well so that it can be used for fogging calculations.
+ (cogl_wrap_glEnable, cogl_wrap_glDisable): Enable/disable fogging.
+ (cogl_wrap_glFogx, cogl_wrap_glFogxv): Fill in wrapper to set
+ fogging parameters.
+
+ * clutter/cogl/gles/cogl-fixed-vertex-shader.glsl: Calculate the
+ fog amount if fogging is enabled.
+
+ * clutter/cogl/gles/cogl-fixed-fragment-shader.glsl: Mix with fog
+ color.
+
+ * clutter/cogl/gles/cogl-gles2-wrapper.h (CoglGles2Wrapper): Add
+ uniforms for fogging.
+
2008-05-28 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/pango/pangoclutter-font.c: Remove unneeded file.
/* Per vertex attributes */
-attribute vec4 vertex_attrib;
-attribute vec4 tex_coord_attrib;
-attribute vec4 color_attrib;
+attribute vec4 vertex_attrib;
+attribute vec4 tex_coord_attrib;
+attribute vec4 color_attrib;
/* Transformation matrices */
-uniform mat4 mvp_matrix; /* combined modelview and projection matrix */
-uniform mat4 texture_matrix;
+uniform mat4 modelview_matrix;
+uniform mat4 mvp_matrix; /* combined modelview and projection matrix */
+uniform mat4 texture_matrix;
/* Outputs to the fragment shader */
-varying vec4 frag_color;
-varying vec2 tex_coord;
+varying vec4 frag_color;
+varying vec2 tex_coord;
+varying float fog_amount;
+
+/* Fogging options */
+uniform bool fog_enabled;
+uniform int fog_mode;
+uniform float fog_density;
+uniform float fog_start;
+uniform float fog_end;
+
+/* Fogging modes */
+const int GL_LINEAR = 0x2601;
+const int GL_EXP = 0x0800;
+const int GL_EXP2 = 0x0801;
void
main (void)
/* Pass the interpolated vertex color on to the fragment shader */
frag_color = color_attrib;
+
+ if (fog_enabled)
+ {
+ /* Estimate the distance from the eye using just the
+ z-coordinate to use as the fog coord */
+ vec4 eye_coord = modelview_matrix * vertex_attrib;
+ float fog_coord = abs (eye_coord.z / eye_coord.w);
+
+ /* Calculate the fog amount per-vertex and interpolate it for
+ the fragment shader */
+ if (fog_mode == GL_EXP)
+ fog_amount = exp (-fog_density * fog_coord);
+ else if (fog_mode == GL_EXP2)
+ fog_amount = exp (-fog_density * fog_coord
+ * fog_density * fog_coord);
+ else
+ fog_amount = (fog_end - fog_coord) / (fog_end - fog_start);
+
+ fog_amount = clamp (fog_amount, 0.0, 1.0);
+ }
}
cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
{
GLint status;
+ GLfixed default_fog_color[4] = { 0, 0, 0, 0 };
memset (wrapper, 0, sizeof (CoglGles2Wrapper));
wrapper->mvp_matrix_uniform
= glGetUniformLocation (wrapper->program, "mvp_matrix");
+ wrapper->modelview_matrix_uniform
+ = glGetUniformLocation (wrapper->program, "modelview_matrix");
wrapper->texture_matrix_uniform
= glGetUniformLocation (wrapper->program, "texture_matrix");
wrapper->texture_2d_enabled_uniform
wrapper->alpha_only_uniform
= glGetUniformLocation (wrapper->program, "alpha_only");
+ wrapper->fog_enabled_uniform
+ = glGetUniformLocation (wrapper->program, "fog_enabled");
+ wrapper->fog_mode_uniform
+ = glGetUniformLocation (wrapper->program, "fog_mode");
+ wrapper->fog_density_uniform
+ = glGetUniformLocation (wrapper->program, "fog_density");
+ wrapper->fog_start_uniform
+ = glGetUniformLocation (wrapper->program, "fog_start");
+ wrapper->fog_end_uniform
+ = glGetUniformLocation (wrapper->program, "fog_end");
+ wrapper->fog_color_uniform
+ = glGetUniformLocation (wrapper->program, "fog_color");
+
/* Always use the first texture unit */
glUniform1i (wrapper->bound_texture_uniform, 0);
cogl_wrap_glLoadIdentity ();
wrapper->mvp_uptodate = GL_FALSE;
+
+ /* Initialize the fogging options */
+ cogl_wrap_glDisable (GL_FOG);
+ cogl_wrap_glFogx (GL_FOG_MODE, GL_LINEAR);
+ cogl_wrap_glFogx (GL_FOG_DENSITY, CFX_ONE);
+ cogl_wrap_glFogx (GL_FOG_START, 0);
+ cogl_wrap_glFogx (GL_FOG_END, 1);
+ cogl_wrap_glFogxv (GL_FOG_COLOR, default_fog_color);
}
void
if (!w->mvp_uptodate)
{
float mvp_matrix[16];
+ const float *modelview_matrix = w->modelview_stack
+ + w->modelview_stack_pos * 16;
cogl_gles2_wrapper_mult_matrix (mvp_matrix,
w->projection_stack
+ w->projection_stack_pos * 16,
- w->modelview_stack
- + w->modelview_stack_pos * 16);
+ modelview_matrix);
glUniformMatrix4fv (w->mvp_matrix_uniform, 1, GL_FALSE, mvp_matrix);
+ glUniformMatrix4fv (w->modelview_matrix_uniform, 1, GL_FALSE,
+ modelview_matrix);
w->mvp_uptodate = GL_TRUE;
}
glUniform1i (w->texture_2d_enabled_uniform, GL_TRUE);
break;
+ case GL_FOG:
+ glUniform1i (w->fog_enabled_uniform, GL_TRUE);
+ break;
+
default:
glEnable (cap);
}
glUniform1i (w->texture_2d_enabled_uniform, GL_FALSE);
break;
+ case GL_FOG:
+ glUniform1i (w->fog_enabled_uniform, GL_FALSE);
+ break;
+
default:
glDisable (cap);
}
void
cogl_wrap_glFogx (GLenum pname, GLfixed param)
{
- /* FIXME */
+ _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
+
+ switch (pname)
+ {
+ case GL_FOG_MODE:
+ glUniform1i (w->fog_mode_uniform, param);
+ break;
+
+ case GL_FOG_DENSITY:
+ glUniform1f (w->fog_density_uniform, CLUTTER_FIXED_TO_FLOAT (param));
+ break;
+
+ case GL_FOG_START:
+ glUniform1f (w->fog_start_uniform, CLUTTER_FIXED_TO_FLOAT (param));
+ break;
+
+ case GL_FOG_END:
+ glUniform1f (w->fog_end_uniform, CLUTTER_FIXED_TO_FLOAT (param));
+ break;
+ }
}
void
cogl_wrap_glFogxv (GLenum pname, const GLfixed *params)
{
- /* FIXME */
+ _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
+
+ if (pname == GL_FOG_COLOR)
+ glUniform4f (w->fog_color_uniform,
+ CLUTTER_FIXED_TO_FLOAT (params[0]),
+ CLUTTER_FIXED_TO_FLOAT (params[1]),
+ CLUTTER_FIXED_TO_FLOAT (params[2]),
+ CLUTTER_FIXED_TO_FLOAT (params[3]));
}
void