/* =========================================================================== Copyright (C) 2006-2009 Robert Beckebans This file is part of XreaL source code. XreaL source code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. XreaL source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with XreaL source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ /* generic_vp.glsl */ attribute vec4 attr_Position; attribute vec4 attr_TexCoord0; attribute vec4 attr_TexCoord1; attribute vec3 attr_Normal; attribute vec4 attr_Color; uniform mat4 u_Texture0Matrix; uniform mat4 u_Texture1Matrix; uniform vec3 u_ViewOrigin; uniform int u_TCGen0; uniform int u_TCGen1; uniform vec4 u_TCGen0Vector0; uniform vec4 u_TCGen0Vector1; uniform vec4 u_TCGen1Vector0; uniform vec4 u_TCGen1Vector1; uniform int u_DeformGen; uniform vec4 u_DeformWave; // [base amplitude phase freq] uniform vec3 u_DeformBulge; // [width height speed] uniform float u_DeformSpread; uniform float u_Time; uniform int u_ColorGen; uniform int u_AlphaGen; uniform vec4 u_Color; uniform mat4 u_ModelViewProjectionMatrix; uniform vec3 u_AmbientLight; uniform vec3 u_DirectedLight; uniform vec3 u_LightDir; uniform int u_PortalClipping; uniform vec4 u_PortalPlane; uniform float u_PortalRange; varying vec3 var_Position; varying vec2 var_Tex1; varying vec2 var_Tex2; varying vec4 var_Color; varying float var_Discard; float triangle(float x) { return max(1.0 - abs(x), 0); } float sawtooth(float x) { return x - floor(x); } vec4 DeformPosition(const vec4 pos, const vec3 normal, const vec2 st) { vec4 deformed = pos; /* define WAVEVALUE( table, base, amplitude, phase, freq ) \ ((base) + table[ Q_ftol( ( ( (phase) + backEnd.refdef.floatTime * (freq) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * (amplitude)) */ if (u_DeformGen == DGEN_WAVE_SIN) { float off = (pos.x + pos.y + pos.z) * u_DeformSpread; float scale = u_DeformWave.x + sin(off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * u_DeformWave.y; vec3 offset = normal * scale; deformed.xyz += offset; } if (u_DeformGen == DGEN_WAVE_SQUARE) { float off = (pos.x + pos.y + pos.z) * u_DeformSpread; float scale = u_DeformWave.x + sign(sin(off + u_DeformWave.z + (u_Time * u_DeformWave.w))) * u_DeformWave.y; vec3 offset = normal * scale; deformed.xyz += offset; } if (u_DeformGen == DGEN_WAVE_TRIANGLE) { float off = (pos.x + pos.y + pos.z) * u_DeformSpread; float scale = u_DeformWave.x + triangle(off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * u_DeformWave.y; vec3 offset = normal * scale; deformed.xyz += offset; } if (u_DeformGen == DGEN_WAVE_SAWTOOTH) { float off = (pos.x + pos.y + pos.z) * u_DeformSpread; float scale = u_DeformWave.x + sawtooth(off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * u_DeformWave.y; vec3 offset = normal * scale; deformed.xyz += offset; } if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH) { float off = (pos.x + pos.y + pos.z) * u_DeformSpread; float scale = u_DeformWave.x + (1.0 - sawtooth(off + u_DeformWave.z + (u_Time * u_DeformWave.w))) * u_DeformWave.y; vec3 offset = normal * scale; deformed.xyz += offset; } if (u_DeformGen == DGEN_BULGE) { float bulgeWidth = u_DeformBulge.x; float bulgeHeight = u_DeformBulge.y; float bulgeSpeed = u_DeformBulge.z; float now = u_Time * bulgeSpeed; float off = (M_PI * 0.25) * st.x * bulgeWidth + now; float scale = sin(off) * bulgeHeight; vec3 offset = normal * scale; deformed.xyz += offset; } return deformed; } vec2 GenTexCoords(int TCGen, vec4 position, mat4 texMatrix, vec4 TCGenVector0, vec4 TCGenVector1) { vec4 tex; if (TCGen == TCGEN_LIGHTMAP) { tex = attr_TexCoord1; } else if (TCGen == TCGEN_TEXTURE) { tex = attr_TexCoord0; } else if (TCGen == TCGEN_FOG) { // TCGenVector0 is fogDistanceVector // TCGenVector1 is fogDepthVector // u_PortalRange is eyeT float s = dot(position, TCGenVector0); float t = dot(position, TCGenVector1); // partially clipped fogs use the T axis if (u_PortalRange < 0) // eyeOutside { if (t < 1.0) { t = 1.0/32; // point is outside, so no fogging } else { t = 1.0/32 + 30.0/32 * t / (t - u_PortalRange); // cut the distance at the fog plane } } else { t = 31.0/32; // FIXME: hack to make fog not flicker, figure out why it's doing that #if 0 if (t < 0) { t = 1.0/32; // point is outside, so no fogging } else { t = 31.0/32; } #endif } tex.s = s; tex.t = t; } else if (TCGen == TCGEN_ENVIRONMENT_MAPPED) { vec3 viewer = normalize(u_ViewOrigin - position.xyz); float d = dot(attr_Normal, viewer); vec3 reflected = attr_Normal * 2.0 * d - viewer; tex.s = 0.5 + reflected.y * 0.5; tex.t = 0.5 - reflected.z * 0.5; } else if (TCGen == TCGEN_VECTOR) { tex.s = dot(position.xyz, TCGenVector0.xyz); tex.t = dot(position.xyz, TCGenVector1.xyz); } else { // if (TCGen == TCGEN_IDENTITY) tex = vec4(0.0); } return (texMatrix * tex).st; } void main() { vec4 position = vec4(0.0); { // transform vertex position into homogenous clip-space position = DeformPosition(attr_Position, attr_Normal, attr_TexCoord0.st); if (bool(u_PortalClipping)) { float dist = dot(position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; if (dist < 0.0) { var_Discard = 1.0f; return; } } var_Discard = 0.0f; gl_Position = u_ModelViewProjectionMatrix * position; } // transform texcoords var_Tex1 = GenTexCoords(u_TCGen0, position, u_Texture0Matrix, u_TCGen0Vector0, u_TCGen0Vector1); var_Tex2 = GenTexCoords(u_TCGen1, position, u_Texture1Matrix, u_TCGen1Vector0, u_TCGen1Vector1); //var_Tex2 = (u_Texture1Matrix * attr_TexCoord1).st; if (u_ColorGen == CGEN_LIGHTING_DIFFUSE) { float incoming = dot(attr_Normal, u_LightDir); if (incoming <= 0) { var_Color.rgb = u_AmbientLight; } else { var_Color.r = min(u_AmbientLight.r + incoming * u_DirectedLight.r, 1.0); var_Color.g = min(u_AmbientLight.g + incoming * u_DirectedLight.g, 1.0); var_Color.b = min(u_AmbientLight.b + incoming * u_DirectedLight.b, 1.0); } } else if (u_ColorGen == CGEN_EXACT_VERTEX) { var_Color.r = attr_Color.r; var_Color.g = attr_Color.g; var_Color.b = attr_Color.b; } else if (u_ColorGen == CGEN_VERTEX) { var_Color.r = attr_Color.r * u_Color.r; var_Color.g = attr_Color.g * u_Color.g; var_Color.b = attr_Color.b * u_Color.b; } else if (u_ColorGen == CGEN_ONE_MINUS_VERTEX) { var_Color.r = (1.0 - attr_Color.r) * u_Color.r; var_Color.g = (1.0 - attr_Color.g) * u_Color.g; var_Color.b = (1.0 - attr_Color.b) * u_Color.b; } else { // if(u_ColorGen == CGEN_IDENTITY) // if(u_ColorGen == CGEN_IDENTITY_LIGHTING) // if(u_ColorGen == CGEN_ENTITY) // if(u_ColorGen == CGEN_ONE_MINUS_ENTITY) // if(u_ColorGen == CGEN_CONST) // if(u_ColorGen == CGEN_WAVEFORM) // if(u_ColorGen == CGEN_FOG) var_Color.r = u_Color.r; var_Color.g = u_Color.g; var_Color.b = u_Color.b; } if (u_AlphaGen == AGEN_LIGHTING_SPECULAR) { vec3 lightDir = vec3(-960, -1980, 96) - position.xyz; lightDir = normalize(lightDir); float d = dot(attr_Normal, lightDir); vec3 reflected = attr_Normal * 2 * d - lightDir; vec3 viewer = u_ViewOrigin - position.xyz; float ilength = 1.0 / length(viewer); float l = dot(reflected, viewer); l *= ilength; if (l < 0) { var_Color.a = 0; } else { l = l*l; l = l*l; var_Color.a = min(l, 1.0); } } else if (u_AlphaGen == AGEN_VERTEX) { var_Color.a = attr_Color.a; } else if (u_AlphaGen == AGEN_ONE_MINUS_VERTEX) { var_Color.a = 1.0 - attr_Color.a; } else if (u_AlphaGen == AGEN_PORTAL) { float len; vec3 v; v = position.xyz - u_ViewOrigin; len = length(v); len /= u_PortalRange; var_Color.a = clamp(len, 0.0, 1.0); } else { // if(u_AlphaGen == AGEN_IDENTITY) // if(u_AlphaGen == AGEN_CONST) // if(u_AlphaGen == AGEN_ENTITY, // if(u_AlphaGen == AGEN_ONE_MINUS_ENTITY) // not supported: AGEN_LIGHTING_SPECULAR // if(u_AlphaGen == AGEN_WAVEFORM) // if(u_AlphaGen == AGEN_PORTAL) // if(u_AlphaGen == AGEN_CONST) var_Color.a = u_Color.a; } }