* 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.
This commit is contained in:
Neil Roberts 2008-05-28 17:14:17 +00:00
parent fe1c9db011
commit 38c9d46a0e
4 changed files with 125 additions and 13 deletions

View 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);
}

View 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);
}
}

View 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

View 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;