* clutter/cogl/gles/cogl-gles2-wrapper.c
authorNeil Roberts <neil@openedhand.com>
Wed, 28 May 2008 17:14:17 +0000 (17:14 +0000)
committerNeil Roberts <neil@openedhand.com>
Wed, 28 May 2008 17:14:17 +0000 (17:14 +0000)
     (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.

ChangeLog
clutter/cogl/gles/cogl-fixed-fragment-shader.glsl
clutter/cogl/gles/cogl-fixed-vertex-shader.glsl
clutter/cogl/gles/cogl-gles2-wrapper.c
clutter/cogl/gles/cogl-gles2-wrapper.h

index a50af24..ac51e01 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+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.
index 9dd22b8..f321353 100644 (file)
@@ -1,12 +1,17 @@
 /* Inputs from the vertex shader */
-varying vec4 frag_color;
-varying vec2 tex_coord;
+varying vec4       frag_color;
+varying vec2       tex_coord;
+varying float      fog_amount;
 
 /* Texturing options */
 uniform bool       texture_2d_enabled;
 uniform sampler2D  texture_unit;
 uniform bool       alpha_only;
 
+/* Fogging options */
+uniform bool       fog_enabled;
+uniform vec4       fog_color;
+
 void
 main (void)
 {
@@ -26,4 +31,8 @@ main (void)
     }
   else
     gl_FragColor = frag_color;
+
+  if (fog_enabled)
+    /* Mix the calculated color with the fog color */
+    gl_FragColor.rgb = mix (fog_color.rgb, gl_FragColor.rgb, fog_amount);
 }
index ae6288c..7fed843 100644 (file)
@@ -1,15 +1,29 @@
 /* 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)
@@ -23,4 +37,24 @@ 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);
+    }
 }
index f7df088..6a09898 100644 (file)
@@ -84,6 +84,7 @@ void
 cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
 {
   GLint status;
+  GLfixed default_fog_color[4] = { 0, 0, 0, 0 };
 
   memset (wrapper, 0, sizeof (CoglGles2Wrapper));
 
@@ -139,6 +140,8 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
 
   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
@@ -148,6 +151,19 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
   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);
 
@@ -160,6 +176,14 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
   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
@@ -487,14 +511,17 @@ cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count)
   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;
     }
@@ -536,6 +563,10 @@ cogl_wrap_glEnable (GLenum cap)
       glUniform1i (w->texture_2d_enabled_uniform, GL_TRUE);
       break;
 
+    case GL_FOG:
+      glUniform1i (w->fog_enabled_uniform, GL_TRUE);
+      break;
+
     default:
       glEnable (cap);
     }
@@ -552,6 +583,10 @@ cogl_wrap_glDisable (GLenum cap)
       glUniform1i (w->texture_2d_enabled_uniform, GL_FALSE);
       break;
 
+    case GL_FOG:
+      glUniform1i (w->fog_enabled_uniform, GL_FALSE);
+      break;
+
     default:
       glDisable (cap);
     }
@@ -654,13 +689,39 @@ cogl_wrap_glGetFixedv (GLenum pname, GLfixed *params)
 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
index 81d4495..b1adf8c 100644 (file)
@@ -44,11 +44,19 @@ struct _CoglGles2Wrapper
   GLuint    fragment_shader;
 
   GLint     mvp_matrix_uniform;
+  GLint     modelview_matrix_uniform;
   GLint     texture_matrix_uniform;
   GLint     texture_2d_enabled_uniform;
   GLint     bound_texture_uniform;
   GLint     alpha_only_uniform;
 
+  GLint     fog_enabled_uniform;
+  GLint     fog_mode_uniform;
+  GLint     fog_density_uniform;
+  GLint     fog_start_uniform;
+  GLint     fog_end_uniform;
+  GLint     fog_color_uniform;
+
   GLuint    matrix_mode;
   GLfloat   modelview_stack[COGL_GLES2_MODELVIEW_STACK_SIZE * 16];
   GLuint    modelview_stack_pos;