Merge cand's graphical improvements branch!! There are many known issues folks, so don't cry victory just now, this is just the beginning. Especially, shadows do not work correctly at this time
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14590 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
8c17d21282
commit
5899a26aad
@ -9,7 +9,7 @@
|
||||
y="-0.01"
|
||||
z="0.0" />
|
||||
|
||||
<material file="snowflake.png"/>
|
||||
<material file="snowflake.png" clampu="Y" clampv="Y" />
|
||||
|
||||
<!-- Amount of particles emitted per second -->
|
||||
<rate min="400"
|
||||
@ -23,10 +23,13 @@
|
||||
<size min="0.40"
|
||||
max="0.60" />
|
||||
|
||||
<color min="255 255 255"
|
||||
<color min="40 40 255"
|
||||
max="255 255 255" />
|
||||
|
||||
<!-- How much time in milliseconds before the particle is fully faded out -->
|
||||
<fadeout time="100" />
|
||||
|
||||
<wind speed="0.16"
|
||||
flips="Y" />
|
||||
|
||||
</particles>
|
||||
|
@ -1,18 +1,33 @@
|
||||
<stkgui>
|
||||
|
||||
<div x="2%" y="5%" width="96%" height="90%" layout="vertical-row" >
|
||||
<div x="2%" y="5%" width="96%" height="95%" layout="vertical-row" >
|
||||
|
||||
<header id="title" width="100%" height="fit" text_align="center" word_wrap="true" text="Graphics Settings" />
|
||||
|
||||
<spacer height="25" width="10" />
|
||||
<spacer height="20" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<checkbox id="pixelshaders"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Pixel Shaders (requires restart)" I18N="Video settings"/>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<checkbox id="anim_gfx"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Animated Scenery" I18N="Video settings"/>
|
||||
|
||||
<spacer width="20%" height="10"/>
|
||||
|
||||
<checkbox id="motionblur"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Motion blur" I18N="Video settings"/>
|
||||
|
||||
</div>
|
||||
|
||||
<spacer height="5" width="10" />
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<checkbox id="weather_gfx"/>
|
||||
@ -20,7 +35,7 @@
|
||||
<label text="Weather Effects" I18N="Video settings"/>
|
||||
</div>
|
||||
|
||||
<spacer height="5" width="10" />
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<label text="Animated Characters" I18N="Video settings" width="40%"/>
|
||||
@ -28,7 +43,7 @@
|
||||
<gauge id="steering_animations" min_value="0" max_value="2" width="50%" />
|
||||
</div>
|
||||
|
||||
<spacer height="5" width="10" />
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<label text="Texture filtering" I18N="Video settings" width="40%"/>
|
||||
@ -36,7 +51,7 @@
|
||||
<gauge id="filtering" min_value="0" max_value="5" width="50%" />
|
||||
</div>
|
||||
|
||||
<spacer height="5" width="10" />
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<label text="Anti-aliasing (requires restart)" I18N="Video settings" width="40%" />
|
||||
@ -44,20 +59,28 @@
|
||||
<gauge id="antialiasing" min_value="0" max_value="3" width="50%"/>
|
||||
</div>
|
||||
|
||||
<spacer height="5" width="10" />
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<checkbox id="postprocessing"/>
|
||||
<checkbox id="mlaa"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Post-processing (motion blur)" I18N="Video settings"/>
|
||||
<label text="MLAA (morphological anti-aliasing)" I18N="Video settings"/>
|
||||
</div>
|
||||
|
||||
<spacer height="5" width="10" />
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<checkbox id="pixelshaders"/>
|
||||
<label text="SSAO (Ambient Occlusion, requires restart)" I18N="Video settings"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Pixel Shaders" I18N="Video settings"/>
|
||||
<gauge id="ssao" min_value="0" max_value="2" width="50%"/>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<label text="Shadows (requires restart)" I18N="Video settings"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<gauge id="shadows" min_value="0" max_value="2" width="50%"/>
|
||||
</div>
|
||||
|
||||
<spacer proportion="1"/>
|
||||
|
@ -40,16 +40,6 @@
|
||||
<label height="100%" I18N="In the video settings" text="Vertical Sync (requires restart)"/>
|
||||
</div>
|
||||
|
||||
<spacer height="5" width="10"/>
|
||||
|
||||
<!-- ************ FBO ************ -->
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="2" />
|
||||
<checkbox id="fbos"/>
|
||||
<spacer width="20" height="2" />
|
||||
<label height="100%" I18N="In the video settings" text="Use Frame Buffer Objects (requires restart)"/>
|
||||
</div>
|
||||
|
||||
<spacer height="10" width="10"/>
|
||||
|
||||
<!-- ************ RESOLUTION CHOICE ************ -->
|
||||
|
39
data/shaders/MLAA_COPYING
Normal file
39
data/shaders/MLAA_COPYING
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Jorge Jimenez (jorge@iryoku.com)
|
||||
* Copyright (C) 2010 Belen Masia (bmasia@unizar.es)
|
||||
* Copyright (C) 2010 Jose I. Echevarria (joseignacioechevarria@gmail.com)
|
||||
* Copyright (C) 2010 Fernando Navarro (fernandn@microsoft.com)
|
||||
* Copyright (C) 2010 Diego Gutierrez (diegog@unizar.es)
|
||||
* Copyright (C) 2011 Lauri Kasanen (cand@gmx.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the following statement:
|
||||
*
|
||||
* "Uses Jimenez's MLAA. Copyright (C) 2010 by Jorge Jimenez, Belen Masia,
|
||||
* Jose I. Echevarria, Fernando Navarro and Diego Gutierrez."
|
||||
*
|
||||
* Only for use in the Mesa project, this point 2 is filled by naming the
|
||||
* technique Jimenez's MLAA in the Mesa config options.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
|
||||
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are
|
||||
* those of the authors and should not be interpreted as representing official
|
||||
* policies, either expressed or implied, of the copyright holders.
|
||||
*/
|
13
data/shaders/bloom.frag
Normal file
13
data/shaders/bloom.frag
Normal file
@ -0,0 +1,13 @@
|
||||
uniform sampler2D tex;
|
||||
uniform float low;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 weights = vec3(0.2126, 0.7152, 0.0722); // ITU-R BT. 709
|
||||
vec3 col = texture2D(tex, gl_TexCoord[0].xy).xyz;
|
||||
float luma = dot(weights, col);
|
||||
|
||||
col *= smoothstep(low, 0.9, luma);
|
||||
|
||||
gl_FragColor = vec4(col, 1.0);
|
||||
}
|
10
data/shaders/bloomblend.frag
Normal file
10
data/shaders/bloomblend.frag
Normal file
@ -0,0 +1,10 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture2D(tex, gl_TexCoord[0].xy);
|
||||
|
||||
col.xyz *= 10.0 * col.a;
|
||||
|
||||
gl_FragColor = vec4(col.xyz, 1.0);
|
||||
}
|
11
data/shaders/bloompower.frag
Normal file
11
data/shaders/bloompower.frag
Normal file
@ -0,0 +1,11 @@
|
||||
uniform float power;
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture2D(tex, gl_TexCoord[0].xy);
|
||||
if (col.a < 0.5)
|
||||
discard;
|
||||
|
||||
gl_FragColor = vec4(col.xyz, power);
|
||||
}
|
@ -15,13 +15,12 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
uniform sampler2D main_texture;
|
||||
uniform sampler2D tex;
|
||||
uniform float transparency;
|
||||
varying vec2 uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2D(main_texture, uv);
|
||||
gl_FragColor.a *= transparency;
|
||||
gl_FragColor = texture2D(tex, uv);
|
||||
gl_FragColor.a *= transparency;
|
||||
}
|
||||
|
17
data/shaders/caustics.frag
Normal file
17
data/shaders/caustics.frag
Normal file
@ -0,0 +1,17 @@
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D caustictex;
|
||||
uniform vec2 dir;
|
||||
uniform vec2 dir2;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = gl_TexCoord[0].xy;
|
||||
|
||||
vec3 col = texture2D(tex, tc).xyz;
|
||||
float caustic = texture2D(caustictex, tc + dir).x;
|
||||
float caustic2 = texture2D(caustictex, (tc.yx + dir2 * vec2(-0.6, 0.3)) * vec2(0.6)).x;
|
||||
|
||||
col += caustic * caustic2 * 10.0;
|
||||
|
||||
gl_FragColor = vec4(col, 1.0);
|
||||
}
|
25
data/shaders/collapse.frag
Normal file
25
data/shaders/collapse.frag
Normal file
@ -0,0 +1,25 @@
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D oldtex;
|
||||
uniform vec2 pixel;
|
||||
uniform vec2 multi;
|
||||
uniform int size;
|
||||
|
||||
void main()
|
||||
{
|
||||
float res = 0.0;
|
||||
vec2 tc = gl_TexCoord[0].xy;
|
||||
// tc.y = 1.0 - tc.y;
|
||||
tc *= multi;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
float col = texture2D(tex, tc).x;
|
||||
res = max(col, res);
|
||||
|
||||
tc += pixel;
|
||||
}
|
||||
|
||||
float old = texture2D(oldtex, gl_TexCoord[0].xy).x;
|
||||
|
||||
gl_FragColor = vec4(mix(old, res, 0.7));
|
||||
}
|
6
data/shaders/colorize.frag
Normal file
6
data/shaders/colorize.frag
Normal file
@ -0,0 +1,6 @@
|
||||
uniform vec3 col;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(col, 1.0);
|
||||
}
|
11
data/shaders/colorize_ref.frag
Normal file
11
data/shaders/colorize_ref.frag
Normal file
@ -0,0 +1,11 @@
|
||||
uniform vec3 col;
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
float alpha = texture2D(tex, gl_TexCoord[0].xy).a;
|
||||
if (alpha < 0.5)
|
||||
discard;
|
||||
|
||||
gl_FragColor = vec4(col, 1.0);
|
||||
}
|
40
data/shaders/displace.frag
Normal file
40
data/shaders/displace.frag
Normal file
@ -0,0 +1,40 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 screen;
|
||||
uniform vec2 dir;
|
||||
uniform vec2 dir2;
|
||||
|
||||
varying float camdist;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = gl_TexCoord[0].xy;
|
||||
|
||||
vec4 col = vec4(0.0);
|
||||
const float maxlen = 0.02;
|
||||
|
||||
float horiz = texture2D(tex, tc + dir).x;
|
||||
float vert = texture2D(tex, (tc.yx + dir2) * vec2(0.9)).x;
|
||||
|
||||
vec2 offset = vec2(horiz, vert);
|
||||
offset *= 2.0;
|
||||
offset -= 1.0;
|
||||
|
||||
// Fade according to distance to cam
|
||||
float fade = 1.0 - smoothstep(1.0, 40.0, camdist);
|
||||
|
||||
// Fade according to distance from the edges
|
||||
vec2 edger = gl_TexCoord[1].xy;
|
||||
const float mindist = 0.1;
|
||||
fade *= smoothstep(0.0, mindist, edger.x) * smoothstep(0.0, mindist, edger.y) *
|
||||
(1.0 - smoothstep(1.0 - mindist, 1.0, edger.x)) *
|
||||
(1.0 - smoothstep(1.0 - mindist, 1.0, edger.y));
|
||||
|
||||
offset *= 50.0 * fade * maxlen;
|
||||
|
||||
col.r = step(offset.x, 0.0) * -offset.x;
|
||||
col.g = step(0.0, offset.x) * offset.x;
|
||||
col.b = step(offset.y, 0.0) * -offset.y;
|
||||
col.a = step(0.0, offset.y) * offset.y;
|
||||
|
||||
gl_FragColor = col;
|
||||
}
|
9
data/shaders/displace.vert
Normal file
9
data/shaders/displace.vert
Normal file
@ -0,0 +1,9 @@
|
||||
varying float camdist;
|
||||
|
||||
void main() {
|
||||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[1] = gl_MultiTexCoord1;
|
||||
|
||||
camdist = length((gl_ModelViewMatrix * gl_Vertex).xyz);
|
||||
}
|
6
data/shaders/farplane.vert
Normal file
6
data/shaders/farplane.vert
Normal file
@ -0,0 +1,6 @@
|
||||
void main() {
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[1] = gl_MultiTexCoord1;
|
||||
gl_Position = (gl_ModelViewProjectionMatrix * gl_Vertex).xyww;
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
9
data/shaders/flip.frag
Normal file
9
data/shaders/flip.frag
Normal file
@ -0,0 +1,9 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texc = gl_TexCoord[0].xy;
|
||||
texc.y = 1.0 - texc.y;
|
||||
|
||||
gl_FragColor = texture2D(tex, texc);
|
||||
}
|
34
data/shaders/fog.frag
Normal file
34
data/shaders/fog.frag
Normal file
@ -0,0 +1,34 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float fogmax;
|
||||
uniform float startH;
|
||||
uniform float endH;
|
||||
uniform float start;
|
||||
uniform float end;
|
||||
uniform vec3 col;
|
||||
uniform vec3 campos;
|
||||
uniform mat4 ipvmat;
|
||||
|
||||
float decdepth(vec4 rgba) {
|
||||
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float z = decdepth(vec4(texture2D(tex, gl_TexCoord[0].xy).xyz, 0.0));
|
||||
|
||||
vec3 tmp = vec3(gl_TexCoord[0].xy, z);
|
||||
tmp = tmp * 2.0 - 1.0;
|
||||
|
||||
vec4 xpos = vec4(tmp, 1.0);
|
||||
xpos = ipvmat * xpos;
|
||||
xpos.xyz /= xpos.w;
|
||||
|
||||
float dist = distance(campos, xpos.xyz);
|
||||
float fog = smoothstep(start, end, dist);
|
||||
fog *= 1.0 - smoothstep(startH, endH, xpos.y);
|
||||
|
||||
fog = min(fog, fogmax);
|
||||
|
||||
gl_FragColor = vec4(col, fog);
|
||||
}
|
19
data/shaders/gaussian3h.frag
Normal file
19
data/shaders/gaussian3h.frag
Normal file
@ -0,0 +1,19 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
|
||||
// Gaussian separated blur with radius 3.
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = gl_TexCoord[0].x;
|
||||
float Y = gl_TexCoord[0].y;
|
||||
|
||||
sum += texture2D(tex, vec2(X - 3.0 * pixel.x, Y)) * 0.03125;
|
||||
sum += texture2D(tex, vec2(X - 1.3333 * pixel.x, Y)) * 0.328125;
|
||||
sum += texture2D(tex, vec2(X, Y)) * 0.273438;
|
||||
sum += texture2D(tex, vec2(X + 1.3333 * pixel.x, Y)) * 0.328125;
|
||||
sum += texture2D(tex, vec2(X + 3.0 * pixel.x, Y)) * 0.03125;
|
||||
|
||||
gl_FragColor = sum;
|
||||
}
|
19
data/shaders/gaussian3v.frag
Normal file
19
data/shaders/gaussian3v.frag
Normal file
@ -0,0 +1,19 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
|
||||
// Gaussian separated blur with radius 3.
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = gl_TexCoord[0].x;
|
||||
float Y = gl_TexCoord[0].y;
|
||||
|
||||
sum += texture2D(tex, vec2(X, Y - 3.0 * pixel.y)) * 0.03125;
|
||||
sum += texture2D(tex, vec2(X, Y - 1.3333 * pixel.y)) * 0.328125;
|
||||
sum += texture2D(tex, vec2(X, Y)) * 0.273438;
|
||||
sum += texture2D(tex, vec2(X, Y + 1.3333 * pixel.y)) * 0.328125;
|
||||
sum += texture2D(tex, vec2(X, Y + 3.0 * pixel.y)) * 0.03125;
|
||||
|
||||
gl_FragColor = sum;
|
||||
}
|
21
data/shaders/gaussian6h.frag
Normal file
21
data/shaders/gaussian6h.frag
Normal file
@ -0,0 +1,21 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
|
||||
// Gaussian separated blur with radius 6.
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = gl_TexCoord[0].x;
|
||||
float Y = gl_TexCoord[0].y;
|
||||
|
||||
sum += texture2D(tex, vec2(X - 5.13333 * pixel.x, Y)) * 0.00640869;
|
||||
sum += texture2D(tex, vec2(X - 3.26667 * pixel.x, Y)) * 0.083313;
|
||||
sum += texture2D(tex, vec2(X - 1.4 * pixel.x, Y)) * 0.305481;
|
||||
sum += texture2D(tex, vec2(X, Y)) * 0.209473;
|
||||
sum += texture2D(tex, vec2(X + 1.4 * pixel.x, Y)) * 0.305481;
|
||||
sum += texture2D(tex, vec2(X + 3.26667 * pixel.x, Y)) * 0.083313;
|
||||
sum += texture2D(tex, vec2(X + 5.13333 * pixel.x, Y)) * 0.00640869;
|
||||
|
||||
gl_FragColor = sum;
|
||||
}
|
21
data/shaders/gaussian6v.frag
Normal file
21
data/shaders/gaussian6v.frag
Normal file
@ -0,0 +1,21 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
|
||||
// Gaussian separated blur with radius 6.
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = gl_TexCoord[0].x;
|
||||
float Y = gl_TexCoord[0].y;
|
||||
|
||||
sum += texture2D(tex, vec2(X, Y - 5.13333 * pixel.y)) * 0.00640869;
|
||||
sum += texture2D(tex, vec2(X, Y - 3.26667 * pixel.y)) * 0.083313;
|
||||
sum += texture2D(tex, vec2(X, Y - 1.4 * pixel.y)) * 0.305481;
|
||||
sum += texture2D(tex, vec2(X, Y)) * 0.209473;
|
||||
sum += texture2D(tex, vec2(X, Y + 1.4 * pixel.y)) * 0.305481;
|
||||
sum += texture2D(tex, vec2(X, Y + 3.26667 * pixel.y)) * 0.083313;
|
||||
sum += texture2D(tex, vec2(X, Y + 5.13333 * pixel.y)) * 0.00640869;
|
||||
|
||||
gl_FragColor = sum;
|
||||
}
|
16
data/shaders/glow.frag
Normal file
16
data/shaders/glow.frag
Normal file
@ -0,0 +1,16 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 res;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 coords = gl_FragCoord.xy / res;
|
||||
|
||||
vec4 col = texture2D(tex, coords);
|
||||
float alpha = col.a;
|
||||
|
||||
if (alpha < 0.04) discard;
|
||||
|
||||
col *= vec4(vec3(4.0), 1.5);
|
||||
|
||||
gl_FragColor = col;
|
||||
}
|
16
data/shaders/godfade.frag
Normal file
16
data/shaders/godfade.frag
Normal file
@ -0,0 +1,16 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec3 col;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 res = texture2D(tex, gl_TexCoord[0].xy);
|
||||
|
||||
// Keep the sun fully bright, but fade the sky
|
||||
float mul = distance(res.xyz, col);
|
||||
mul = step(mul, 0.02);
|
||||
mul *= 0.97;
|
||||
|
||||
res = res * vec4(mul);
|
||||
|
||||
gl_FragColor = res;
|
||||
}
|
29
data/shaders/godray.frag
Normal file
29
data/shaders/godray.frag
Normal file
@ -0,0 +1,29 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 sunpos;
|
||||
|
||||
#define SAMPLES 12
|
||||
|
||||
const float decaystep = 0.88;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texc = gl_TexCoord[0].xy;
|
||||
vec2 tosun = sunpos - texc;
|
||||
|
||||
if (dot(tosun, tosun) > 0.49) discard;
|
||||
|
||||
vec2 dist = tosun * 1.0/(float(SAMPLES) * 1.12);
|
||||
|
||||
vec3 col = texture2D(tex, texc).xyz;
|
||||
float decay = 1.0;
|
||||
|
||||
for (int i = 0; i < SAMPLES; i++) {
|
||||
texc += dist;
|
||||
vec3 here = texture2D(tex, texc).xyz;
|
||||
here *= decay;
|
||||
col += here;
|
||||
decay *= decaystep;
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(col, 1.0) * 0.8;
|
||||
}
|
@ -1,54 +1,8 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 the SuperTuxKart team
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
uniform vec4 fogColor;
|
||||
uniform float fogFrom;
|
||||
uniform float fogTo;
|
||||
uniform int fog;
|
||||
uniform sampler2D tex;
|
||||
varying vec4 coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(tex, gl_TexCoord[0].st);
|
||||
vec4 solidColor = vec4(color.r, color.g, color.b, 1);
|
||||
vec4 color = texture2D(tex, gl_TexCoord[0].st);
|
||||
|
||||
if (fog == 1)
|
||||
{
|
||||
if (coord.z > fogTo)
|
||||
{
|
||||
gl_FragColor = fogColor;
|
||||
gl_FragColor.a = color.a;
|
||||
}
|
||||
else if (coord.z > fogFrom)
|
||||
{
|
||||
float fogIntensity = (coord.z - fogFrom) / (fogTo - fogFrom);
|
||||
vec4 color2 = fogIntensity*fogColor + (1.0 - fogIntensity)*solidColor;
|
||||
color2.a = color.a;
|
||||
gl_FragColor = color2;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_FragColor = color;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_FragColor = color;
|
||||
}
|
||||
gl_FragColor = color;
|
||||
}
|
||||
|
@ -1,33 +1,11 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 the SuperTuxKart team
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
uniform float angle;
|
||||
uniform float amplitude;
|
||||
varying vec4 coord;
|
||||
|
||||
uniform vec3 windDir;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
vec4 vertexPosition = ftransform(); //gl_ModelViewMatrix * gl_Vertex;
|
||||
vertexPosition += vec4(1,0,0,0) * amplitude * gl_Color.r * sin(angle);
|
||||
gl_Position = vertexPosition;
|
||||
gl_FrontColor = vec4(1,1,1,1);
|
||||
gl_BackColor = vec4(1,1,1,1);
|
||||
coord = vertexPosition;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
vec4 vertexPosition = gl_Vertex;
|
||||
vertexPosition.xyz += windDir * gl_Color.r;
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix * vertexPosition;
|
||||
}
|
||||
|
19
data/shaders/lightblend.frag
Normal file
19
data/shaders/lightblend.frag
Normal file
@ -0,0 +1,19 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec3 ambient;
|
||||
uniform sampler2D spectex;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texc = gl_TexCoord[0].xy;
|
||||
|
||||
vec4 col = texture2D(tex, texc);
|
||||
vec4 specular = texture2D(spectex, texc);
|
||||
|
||||
col.xyz += ambient;
|
||||
float spec = col.a - 0.05;
|
||||
spec *= specular.a;
|
||||
col.xyz += spec;
|
||||
col.a = 1.0;
|
||||
|
||||
gl_FragColor = col;
|
||||
}
|
52
data/shaders/mipviz.frag
Normal file
52
data/shaders/mipviz.frag
Normal file
@ -0,0 +1,52 @@
|
||||
#version 120
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 texsize;
|
||||
uniform int notex;
|
||||
|
||||
float miplevel(in vec2 texture_coordinate)
|
||||
{
|
||||
// The OpenGL Graphics System: A Specification 4.2
|
||||
// - chapter 3.9.11, equation 3.21
|
||||
|
||||
vec2 dx_vtc = dFdx(texture_coordinate);
|
||||
vec2 dy_vtc = dFdy(texture_coordinate);
|
||||
float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
|
||||
|
||||
return 0.5 * log2(delta_max_sqr); // == log2(sqrt(delta_max_sqr));
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
if (notex != 0) {
|
||||
gl_FragColor = gl_Color;
|
||||
return;
|
||||
}
|
||||
|
||||
// Buggy Intel windows driver workaround
|
||||
vec4 levels[6] = vec4[](
|
||||
vec4(0.0, 0.0, 1.0, 0.8),
|
||||
vec4(0.0, 0.5, 1.0, 0.4),
|
||||
vec4(1.0, 1.0, 1.0, 0.0),
|
||||
vec4(1.0, 0.7, 0.0, 0.2),
|
||||
vec4(1.0, 0.3, 0.0, 0.6),
|
||||
vec4(1.0, 0.0, 0.0, 0.8)
|
||||
);
|
||||
|
||||
float mip = miplevel(texsize * gl_TexCoord[0].xy) + 2.0;
|
||||
mip = clamp(mip, 0.0, 5.0);
|
||||
|
||||
int lowmip = int(mip);
|
||||
int highmip = lowmip + 1;
|
||||
if (highmip > 5)
|
||||
highmip = 5;
|
||||
|
||||
float mixer = fract(mip);
|
||||
|
||||
vec4 mixcol = mix(levels[lowmip], levels[highmip], mixer);
|
||||
vec4 tcol = texture2D(tex, gl_TexCoord[0].xy);
|
||||
|
||||
vec3 col = mix(tcol.xyz, mixcol.xyz, mixcol.a);
|
||||
|
||||
gl_FragColor = vec4(col, tcol.a);
|
||||
}
|
112
data/shaders/mlaa_blend2.frag
Normal file
112
data/shaders/mlaa_blend2.frag
Normal file
@ -0,0 +1,112 @@
|
||||
#define MAX_SEARCH_STEPS 8.0
|
||||
#define MAX_DISTANCE 33.0
|
||||
|
||||
#extension GL_ARB_shader_texture_lod: enable
|
||||
|
||||
uniform sampler2D edgesMap;
|
||||
uniform sampler2D areaMap;
|
||||
|
||||
uniform vec2 PIXEL_SIZE;
|
||||
|
||||
/**
|
||||
* This one just returns the first level of a mip map chain, which allow us to
|
||||
* avoid the nasty ddx/ddy warnings, even improving the performance a little
|
||||
* bit.
|
||||
*/
|
||||
vec4 tex2Doffset(sampler2D map, vec2 texcoord, vec2 offset) {
|
||||
return texture2DLod(map, texcoord + PIXEL_SIZE * offset, 0.0);
|
||||
}
|
||||
|
||||
float SearchXLeft(vec2 texcoord) {
|
||||
// We compare with 0.9 to prevent bilinear access precision problems.
|
||||
float i;
|
||||
float e = 0.0;
|
||||
for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) {
|
||||
e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0)).g;
|
||||
if (e < 0.9) break;
|
||||
}
|
||||
return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS);
|
||||
}
|
||||
|
||||
float SearchXRight(vec2 texcoord) {
|
||||
float i;
|
||||
float e = 0.0;
|
||||
for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) {
|
||||
e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0)).g;
|
||||
if (e < 0.9) break;
|
||||
}
|
||||
return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
|
||||
}
|
||||
|
||||
float SearchYDown(vec2 texcoord) {
|
||||
float i;
|
||||
float e = 0.0;
|
||||
for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) {
|
||||
e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0).yx).r;
|
||||
if (e < 0.9) break;
|
||||
}
|
||||
return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS);
|
||||
}
|
||||
|
||||
float SearchYUp(vec2 texcoord) {
|
||||
float i;
|
||||
float e = 0.0;
|
||||
for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) {
|
||||
e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0).yx).r;
|
||||
if (e < 0.9) break;
|
||||
}
|
||||
return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
|
||||
}
|
||||
|
||||
|
||||
vec2 round(vec2 invec) {
|
||||
return vec2(floor(abs(invec) + vec2(0.5)) * sign(invec));
|
||||
}
|
||||
|
||||
vec2 Area(vec2 distance, float e1, float e2) {
|
||||
// * By dividing by areaSize - 1.0 below we are implicitely offsetting to
|
||||
// always fall inside of a pixel
|
||||
// * Rounding prevents bilinear access precision problems
|
||||
float areaSize = MAX_DISTANCE * 5.0;
|
||||
vec2 pixcoord = MAX_DISTANCE * round(4.0 * vec2(e1, e2)) + distance;
|
||||
vec2 texcoord = pixcoord / (areaSize - 1.0);
|
||||
return texture2DLod(areaMap, texcoord, 0.0).ra;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 areas = vec4(0.0);
|
||||
|
||||
vec2 e = texture2D(edgesMap, gl_TexCoord[0].xy).rg;
|
||||
|
||||
if (e.g != 0.0) { // Edge at north
|
||||
|
||||
// Search distances to the left and to the right:
|
||||
vec2 d = vec2(SearchXLeft(gl_TexCoord[0].xy), SearchXRight(gl_TexCoord[0].xy));
|
||||
|
||||
// Now fetch the crossing edges. Instead of sampling between edgels, we
|
||||
// sample at 0.25, to be able to discern what value has each edgel:
|
||||
vec4 coords = vec4(d.x, 0.25, d.y + 1.0, 0.25) * PIXEL_SIZE.xyxy + gl_TexCoord[0].xyxy;
|
||||
float e1 = texture2DLod(edgesMap, coords.xy, 0.0).r;
|
||||
float e2 = texture2DLod(edgesMap, coords.zw, 0.0).r;
|
||||
|
||||
// Ok, we know how this pattern looks like, now it is time for getting
|
||||
// the actual area:
|
||||
areas.rg = Area(abs(d), e1, e2);
|
||||
}
|
||||
|
||||
if (e.r != 0.0) { // Edge at west
|
||||
|
||||
// Search distances to the top and to the bottom:
|
||||
vec2 d = vec2(SearchYUp(gl_TexCoord[0].xy), SearchYDown(gl_TexCoord[0].xy));
|
||||
|
||||
// Now fetch the crossing edges (yet again):
|
||||
vec4 coords = vec4(-0.25, d.x, -0.25, d.y - 1.0) * PIXEL_SIZE.xyxy + gl_TexCoord[0].xyxy;
|
||||
float e1 = texture2DLod(edgesMap, coords.xy, 0.0).g;
|
||||
float e2 = texture2DLod(edgesMap, coords.zw, 0.0).g;
|
||||
|
||||
// Get the area for this direction:
|
||||
areas.ba = Area(abs(d), e1, e2);
|
||||
}
|
||||
|
||||
gl_FragColor = areas;
|
||||
}
|
25
data/shaders/mlaa_color1.frag
Normal file
25
data/shaders/mlaa_color1.frag
Normal file
@ -0,0 +1,25 @@
|
||||
varying vec4 offset[2];
|
||||
|
||||
uniform sampler2D colorMapG;
|
||||
const float threshold = 0.1f;
|
||||
|
||||
void main() {
|
||||
vec3 weights = vec3(0.2126,0.7152, 0.0722); // ITU-R BT. 709
|
||||
|
||||
/**
|
||||
* Luma calculation requires gamma-corrected colors:
|
||||
*/
|
||||
float L = dot(texture2D(colorMapG, gl_TexCoord[0].xy).rgb, weights);
|
||||
float Lleft = dot(texture2D(colorMapG, offset[0].xy).rgb, weights);
|
||||
float Ltop = dot(texture2D(colorMapG, offset[0].zw).rgb, weights);
|
||||
float Lright = dot(texture2D(colorMapG, offset[1].xy).rgb, weights);
|
||||
float Lbottom = dot(texture2D(colorMapG, offset[1].zw).rgb, weights);
|
||||
|
||||
vec4 delta = abs(vec4(L) - vec4(Lleft, Ltop, Lright, Lbottom));
|
||||
vec4 edges = step(vec4(threshold), delta);
|
||||
|
||||
if (dot(edges, vec4(1.0)) == 0.0)
|
||||
discard;
|
||||
|
||||
gl_FragColor = edges;
|
||||
}
|
38
data/shaders/mlaa_neigh3.frag
Normal file
38
data/shaders/mlaa_neigh3.frag
Normal file
@ -0,0 +1,38 @@
|
||||
varying vec4 offset[2];
|
||||
|
||||
uniform sampler2D blendMap;
|
||||
uniform sampler2D colorMap;
|
||||
|
||||
void main() {
|
||||
// Fetch the blending weights for current pixel:
|
||||
vec4 topLeft = texture2D(blendMap, gl_TexCoord[0].xy);
|
||||
float bottom = texture2D(blendMap, offset[1].zw).g;
|
||||
float right = texture2D(blendMap, offset[1].xy).a;
|
||||
vec4 a = vec4(topLeft.r, bottom, topLeft.b, right);
|
||||
|
||||
// Up to 4 lines can be crossing a pixel (one in each edge). So, we perform
|
||||
// a weighted average, where the weight of each line is 'a' cubed, which
|
||||
// favors blending and works well in practice.
|
||||
vec4 w = a * a * a;
|
||||
|
||||
// There is some blending weight with a value greater than 0.0?
|
||||
float sum = dot(w, vec4(1.0));
|
||||
if (sum < 1e-5)
|
||||
discard;
|
||||
|
||||
vec4 color = vec4(0.0);
|
||||
|
||||
// Add the contributions of the possible 4 lines that can cross this pixel:
|
||||
vec4 C = texture2D(colorMap, gl_TexCoord[0].xy);
|
||||
vec4 Cleft = texture2D(colorMap, offset[0].xy);
|
||||
vec4 Ctop = texture2D(colorMap, offset[0].zw);
|
||||
vec4 Cright = texture2D(colorMap, offset[1].xy);
|
||||
vec4 Cbottom = texture2D(colorMap, offset[1].zw);
|
||||
color = mix(C, Ctop, a.r) * w.r + color;
|
||||
color = mix(C, Cbottom, a.g) * w.g + color;
|
||||
color = mix(C, Cleft, a.b) * w.b + color;
|
||||
color = mix(C, Cright, a.a) * w.a + color;
|
||||
|
||||
// Normalize the resulting color and we are finished!
|
||||
gl_FragColor = color / sum;
|
||||
}
|
12
data/shaders/mlaa_offset.vert
Normal file
12
data/shaders/mlaa_offset.vert
Normal file
@ -0,0 +1,12 @@
|
||||
varying vec4 offset[2];
|
||||
uniform vec2 PIXEL_SIZE;
|
||||
|
||||
void main() {
|
||||
gl_Position = ftransform();
|
||||
vec4 invy = gl_MultiTexCoord0;
|
||||
// invy.y = 1.0 - invy.y;
|
||||
gl_TexCoord[0] = invy;
|
||||
|
||||
offset[0] = invy.xyxy + PIXEL_SIZE.xyxy * vec4(-1.0, 0.0, 0.0, 1.0);
|
||||
offset[1] = invy.xyxy + PIXEL_SIZE.xyxy * vec4( 1.0, 0.0, 0.0, -1.0);
|
||||
}
|
@ -41,7 +41,7 @@ uniform float mask_radius;
|
||||
uniform float max_tex_height;
|
||||
|
||||
// Number of samples used for blurring
|
||||
#define NB_SAMPLES 12
|
||||
#define NB_SAMPLES 8
|
||||
|
||||
void main()
|
||||
{
|
||||
@ -50,14 +50,6 @@ void main()
|
||||
// Sample the color buffer
|
||||
vec3 color = texture2D(color_buffer, texcoords).rgb;
|
||||
|
||||
// If no motion blur is needed, don't do any of the blur computation,
|
||||
// just return the color from the texture.
|
||||
if(boost_amount==0.0)
|
||||
{
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute the blur direction.
|
||||
// IMPORTANT: we don't normalize it so that it avoids a glitch around 'center',
|
||||
// plus it naturally scales the motion blur in a cool way :)
|
||||
|
10
data/shaders/multiply.frag
Normal file
10
data/shaders/multiply.frag
Normal file
@ -0,0 +1,10 @@
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col1 = texture2D(tex1, gl_TexCoord[0].xy);
|
||||
vec4 col2 = vec4(vec3(texture2D(tex2, gl_TexCoord[0].xy).x), 1.0);
|
||||
|
||||
gl_FragColor = col1 * col2;
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
uniform sampler2D BumpTex; //The bump-map
|
||||
uniform sampler2D DecalTex; //The texture
|
||||
uniform sampler2D LightMapTex;
|
||||
int HasLightMap;
|
||||
uniform int HasLightMap;
|
||||
|
||||
// New bumpmapping
|
||||
varying vec3 lightVec;
|
||||
@ -19,18 +19,18 @@ void main()
|
||||
normal = normalize (normal);
|
||||
|
||||
// compute diffuse lighting
|
||||
float lamberFactor = max (dot (lightVec, normal), 0.0) ;
|
||||
float lamberFactor = max (dot (lightVec, normal), 0.0);
|
||||
vec4 diffuseMaterial;
|
||||
|
||||
diffuseMaterial = texture2D (DecalTex, gl_TexCoord[0].st);
|
||||
diffuseMaterial = texture2D (DecalTex, gl_TexCoord[0].st);
|
||||
|
||||
if (HasLightMap < 1)
|
||||
{
|
||||
// 0.5 is the ambient light
|
||||
gl_FragColor = diffuseMaterial * (0.5 + lamberFactor*0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_FragColor = diffuseMaterial * (0.5 + lamberFactor*0.5) * texture2D(LightMapTex, gl_TexCoord[0].st);
|
||||
}
|
||||
if (HasLightMap < 1)
|
||||
{
|
||||
// 0.5 is the ambient light
|
||||
gl_FragColor = diffuseMaterial * (0.5 + lamberFactor*0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_FragColor = diffuseMaterial * (0.5 + lamberFactor*0.5) * texture2D(LightMapTex, gl_TexCoord[0].st);
|
||||
}
|
||||
}
|
||||
|
40
data/shaders/objectpass.frag
Normal file
40
data/shaders/objectpass.frag
Normal file
@ -0,0 +1,40 @@
|
||||
varying vec3 nor;
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D lighttex;
|
||||
uniform float far;
|
||||
uniform int hastex;
|
||||
uniform int haslightmap;
|
||||
uniform float objectid;
|
||||
|
||||
const float near = 1.0;
|
||||
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near));
|
||||
|
||||
// Tune for better inside range without losing outdoors
|
||||
linear_z *= 2.0;
|
||||
|
||||
vec4 light = vec4(1.0);
|
||||
|
||||
if (haslightmap != 0) {
|
||||
light = texture2D(lighttex, gl_TexCoord[1].xy);
|
||||
}
|
||||
|
||||
if (hastex != 0)
|
||||
gl_FragData[0] = texture2D(tex, gl_TexCoord[0].xy) * light;
|
||||
else
|
||||
gl_FragData[0] = gl_Color;
|
||||
|
||||
gl_FragData[1] = vec4(nor, linear_z);
|
||||
gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
|
||||
}
|
||||
|
14
data/shaders/objectpass.vert
Normal file
14
data/shaders/objectpass.vert
Normal file
@ -0,0 +1,14 @@
|
||||
varying vec3 nor;
|
||||
uniform mat4 invtworldm;
|
||||
|
||||
void main() {
|
||||
|
||||
nor = (invtworldm * vec4(gl_Normal, 0.0)).xyz;
|
||||
nor = normalize(nor);
|
||||
nor = nor * 0.5 + 0.5;
|
||||
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[1] = gl_MultiTexCoord1;
|
||||
gl_Position = ftransform();
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
37
data/shaders/objectpass_ref.frag
Normal file
37
data/shaders/objectpass_ref.frag
Normal file
@ -0,0 +1,37 @@
|
||||
varying vec3 nor;
|
||||
uniform sampler2D tex;
|
||||
uniform float far;
|
||||
uniform int hastex;
|
||||
uniform float objectid;
|
||||
|
||||
const float near = 1.0;
|
||||
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near));
|
||||
|
||||
// Tune for better inside range without losing outdoors
|
||||
linear_z *= 2.0;
|
||||
|
||||
if (hastex != 0) {
|
||||
vec4 col = texture2D(tex, gl_TexCoord[0].xy);
|
||||
|
||||
if (col.a < 0.5)
|
||||
discard;
|
||||
|
||||
gl_FragData[0] = col;
|
||||
} else {
|
||||
gl_FragData[0] = gl_Color;
|
||||
}
|
||||
|
||||
gl_FragData[1] = vec4(nor, linear_z);
|
||||
gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
|
||||
}
|
||||
|
45
data/shaders/objectpass_rimlit.frag
Normal file
45
data/shaders/objectpass_rimlit.frag
Normal file
@ -0,0 +1,45 @@
|
||||
varying vec3 nor;
|
||||
uniform sampler2D tex;
|
||||
uniform float far;
|
||||
uniform int hastex;
|
||||
uniform float objectid;
|
||||
|
||||
varying vec3 eyenor;
|
||||
varying vec3 viewpos;
|
||||
|
||||
const float near = 1.0;
|
||||
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near));
|
||||
|
||||
// Tune for better inside range without losing outdoors
|
||||
linear_z *= 2.0;
|
||||
|
||||
float rim = 1.0 - dot(eyenor, viewpos);
|
||||
rim = smoothstep(0.5, 1.5, rim) * 0.35;
|
||||
|
||||
if (hastex != 0) {
|
||||
vec4 col = texture2D(tex, gl_TexCoord[0].xy);
|
||||
|
||||
if (col.a < 0.5)
|
||||
discard;
|
||||
|
||||
col.xyz += rim;
|
||||
|
||||
gl_FragData[0] = col;
|
||||
} else {
|
||||
gl_FragData[0] = gl_Color + vec4(vec3(rim), 0.0);
|
||||
}
|
||||
|
||||
gl_FragData[1] = vec4(nor, linear_z);
|
||||
gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
|
||||
}
|
||||
|
19
data/shaders/objectpass_rimlit.vert
Normal file
19
data/shaders/objectpass_rimlit.vert
Normal file
@ -0,0 +1,19 @@
|
||||
varying vec3 nor;
|
||||
uniform mat4 invtworldm;
|
||||
|
||||
varying vec3 eyenor;
|
||||
varying vec3 viewpos;
|
||||
|
||||
void main() {
|
||||
|
||||
nor = (invtworldm * vec4(gl_Normal, 0.0)).xyz;
|
||||
nor = normalize(nor);
|
||||
nor = nor * 0.5 + 0.5;
|
||||
|
||||
eyenor = gl_NormalMatrix * gl_Normal;
|
||||
viewpos = -normalize((gl_ModelViewMatrix * gl_Vertex).xyz);
|
||||
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = ftransform();
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
42
data/shaders/objectpass_spheremap.frag
Normal file
42
data/shaders/objectpass_spheremap.frag
Normal file
@ -0,0 +1,42 @@
|
||||
varying vec3 nor;
|
||||
uniform sampler2D tex;
|
||||
uniform float far;
|
||||
uniform float objectid;
|
||||
|
||||
varying vec3 eyenor;
|
||||
varying vec3 viewpos;
|
||||
|
||||
const float near = 1.0;
|
||||
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near));
|
||||
|
||||
// Tune for better inside range without losing outdoors
|
||||
linear_z *= 2.0;
|
||||
|
||||
// Calculate the spherical UV
|
||||
const vec3 forward = vec3(0.0, 0.0, 1.0);
|
||||
|
||||
// get the angle between the forward vector and the horizontal portion of the normal
|
||||
vec3 normal_x = normalize(vec3(eyenor.x, 0.0, eyenor.z));
|
||||
float sin_theta_x = length(cross( forward, normal_x )) * eyenor.x/abs(eyenor.x);
|
||||
|
||||
// get the angle between the forward vector and the vertical portion of the normal
|
||||
vec3 normal_y = normalize(vec3(0.0, eyenor.y, eyenor.z));
|
||||
float sin_theta_y = length(cross( forward, normal_y )) * eyenor.y/abs(eyenor.y);
|
||||
|
||||
vec4 detail0 = texture2D(tex, vec2(0.5 + sin_theta_x*0.5, 0.5 + sin_theta_y*0.5));
|
||||
|
||||
gl_FragData[0] = detail0 * gl_Color;
|
||||
|
||||
gl_FragData[1] = vec4(nor, linear_z);
|
||||
gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
|
||||
}
|
6
data/shaders/pass.frag
Normal file
6
data/shaders/pass.frag
Normal file
@ -0,0 +1,6 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);
|
||||
}
|
6
data/shaders/pass.vert
Normal file
6
data/shaders/pass.vert
Normal file
@ -0,0 +1,6 @@
|
||||
void main() {
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[1] = gl_MultiTexCoord1;
|
||||
gl_Position = ftransform();
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
52
data/shaders/penumbrah.frag
Normal file
52
data/shaders/penumbrah.frag
Normal file
@ -0,0 +1,52 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
|
||||
// Separated penumbra, horizontal
|
||||
|
||||
void main()
|
||||
{
|
||||
float sum = 0.0;
|
||||
vec4 tmp;
|
||||
float X = gl_TexCoord[0].x;
|
||||
float Y = gl_TexCoord[0].y;
|
||||
float width = 0.0;
|
||||
float zsum = 0.00001;
|
||||
|
||||
tmp = texture2D(tex, vec2(X - 5.13333 * pixel.x, Y));
|
||||
sum += tmp.x * 0.00640869;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X - 3.26667 * pixel.x, Y));
|
||||
sum += tmp.x * 0.083313;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X - 1.4 * pixel.x, Y));
|
||||
sum += tmp.x * 0.305481;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X, Y));
|
||||
sum += tmp.x * 0.209473;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X + 1.4 * pixel.x, Y));
|
||||
sum += tmp.x * 0.305481;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X + 3.26667 * pixel.x, Y));
|
||||
sum += tmp.x * 0.083313;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X + 5.13333 * pixel.x, Y));
|
||||
sum += tmp.x * 0.00640869;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
float hasz = step(0.7, zsum);
|
||||
gl_FragColor = vec4(sum, (width / zsum) * hasz, hasz, 1.0);
|
||||
}
|
52
data/shaders/penumbrav.frag
Normal file
52
data/shaders/penumbrav.frag
Normal file
@ -0,0 +1,52 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
|
||||
// Separated penumbra, vertical
|
||||
|
||||
void main()
|
||||
{
|
||||
float sum = 0.0;
|
||||
vec4 tmp;
|
||||
float X = gl_TexCoord[0].x;
|
||||
float Y = gl_TexCoord[0].y;
|
||||
float width = 0.0;
|
||||
float zsum = 0.00001;
|
||||
|
||||
tmp = texture2D(tex, vec2(X, Y - 5.13333 * pixel.y));
|
||||
sum += tmp.x * 0.00640869;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X, Y - 3.26667 * pixel.y));
|
||||
sum += tmp.x * 0.083313;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X, Y - 1.4 * pixel.y));
|
||||
sum += tmp.x * 0.305481;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X, Y));
|
||||
sum += tmp.x * 0.209473;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X, Y + 1.4 * pixel.y));
|
||||
sum += tmp.x * 0.305481;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X, Y + 3.26667 * pixel.y));
|
||||
sum += tmp.x * 0.083313;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture2D(tex, vec2(X, Y + 5.13333 * pixel.y));
|
||||
sum += tmp.x * 0.00640869;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
float hasz = step(0.7, zsum);
|
||||
gl_FragColor = vec4(sum, (width / zsum) * hasz, hasz, 1.0);
|
||||
}
|
50
data/shaders/pointlight.frag
Normal file
50
data/shaders/pointlight.frag
Normal file
@ -0,0 +1,50 @@
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D dtex;
|
||||
|
||||
uniform vec3 center;
|
||||
uniform vec3 col;
|
||||
uniform vec3 campos;
|
||||
uniform float r;
|
||||
uniform float spec;
|
||||
uniform vec2 screen;
|
||||
uniform mat4 invprojview;
|
||||
|
||||
float decdepth(vec4 rgba) {
|
||||
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 texc = gl_FragCoord.xy / screen;
|
||||
float z = decdepth(vec4(texture2D(dtex, texc).xyz, 0.0));
|
||||
|
||||
if (z < 0.03) discard;
|
||||
|
||||
vec3 tmp = vec3(texc, z);
|
||||
tmp = tmp * 2.0 - 1.0;
|
||||
|
||||
vec4 xpos = vec4(tmp, 1.0);
|
||||
xpos = invprojview * xpos;
|
||||
xpos.xyz /= xpos.w;
|
||||
|
||||
float d = distance(center, xpos.xyz);
|
||||
if (d > r) discard;
|
||||
|
||||
float att = 1.0 - smoothstep(0.0, r, d);
|
||||
|
||||
vec3 norm = texture2D(ntex, texc).xyz;
|
||||
norm = (norm - 0.5) * 2.0;
|
||||
|
||||
vec3 camdir = normalize(campos - xpos.xyz);
|
||||
|
||||
vec3 L = normalize(center - xpos.xyz);
|
||||
vec3 H = normalize(L + camdir);
|
||||
|
||||
float NdotL = max(0.0, dot(norm, L)) * att;
|
||||
if (NdotL < 0.01) discard;
|
||||
float NdotH = max(0.0, dot(norm, H));
|
||||
NdotH = pow(NdotH, spec);
|
||||
NdotH += 0.05; // offset so that the alpha test doesn't kill us
|
||||
|
||||
gl_FragColor = NdotL * vec4(col, NdotH);
|
||||
}
|
26
data/shaders/ppdisplace.frag
Normal file
26
data/shaders/ppdisplace.frag
Normal file
@ -0,0 +1,26 @@
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D dtex;
|
||||
|
||||
uniform int viz;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = gl_TexCoord[0].xy;
|
||||
|
||||
vec4 shiftval = texture2D(dtex, tc) / vec4(50.0);
|
||||
vec2 shift;
|
||||
shift.x = -shiftval.x + shiftval.y;
|
||||
shift.y = -shiftval.z + shiftval.w;
|
||||
|
||||
tc += shift;
|
||||
|
||||
vec4 newcol = texture2D(tex, tc);
|
||||
|
||||
if (viz < 1)
|
||||
{
|
||||
gl_FragColor = newcol;
|
||||
} else
|
||||
{
|
||||
gl_FragColor = shiftval * vec4(50.0);
|
||||
}
|
||||
}
|
6
data/shaders/rain.frag
Normal file
6
data/shaders/rain.frag
Normal file
@ -0,0 +1,6 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);
|
||||
}
|
33
data/shaders/rain.vert
Normal file
33
data/shaders/rain.vert
Normal file
@ -0,0 +1,33 @@
|
||||
uniform float screenw;
|
||||
uniform float time;
|
||||
uniform mat4 viewm;
|
||||
uniform vec3 campos;
|
||||
|
||||
void main()
|
||||
{
|
||||
const float size = 0.5;
|
||||
|
||||
// This simulation will run accurately for a bit under five days.
|
||||
vec4 start = gl_Vertex;
|
||||
start.y -= time;
|
||||
|
||||
// How many times has it fell?
|
||||
float count = floor(start.y / 24.0);
|
||||
start.x += sin(count);
|
||||
start.z += cos(count);
|
||||
|
||||
vec2 signs = sign(start.xz);
|
||||
start.xz = mod(start.xz, 17.5) * signs;
|
||||
|
||||
start.y = mod(start.y, 24.0) - 3.0;
|
||||
|
||||
start.xyz += campos;
|
||||
|
||||
vec4 eyepos = viewm * start;
|
||||
vec4 projCorner = gl_ProjectionMatrix * vec4(vec2(size), eyepos.z, eyepos.w);
|
||||
|
||||
gl_PointSize = screenw * projCorner.x / projCorner.w;
|
||||
gl_Position = gl_ProjectionMatrix * eyepos;
|
||||
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
}
|
44
data/shaders/shadowgen.frag
Normal file
44
data/shaders/shadowgen.frag
Normal file
@ -0,0 +1,44 @@
|
||||
uniform sampler2D halft; // half is a reserved word
|
||||
uniform sampler2D quarter;
|
||||
uniform sampler2D eighth;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 val[3];
|
||||
val[0] = texture2D(halft, gl_TexCoord[0].xy).xyz;
|
||||
val[1] = texture2D(quarter, gl_TexCoord[0].xy).xyz;
|
||||
val[2] = texture2D(eighth, gl_TexCoord[0].xy).xyz;
|
||||
|
||||
// Find the first level with a penumbra value
|
||||
int i;
|
||||
float q = 0.0;
|
||||
float outval = 1.0;
|
||||
|
||||
float hasshadow = dot(vec3(1.0), vec3(val[0].z, val[1].z, val[2].z));
|
||||
|
||||
if (hasshadow > 0.9)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (val[i].z > 0.9)
|
||||
{
|
||||
q = val[i].y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
q *= 8.0;
|
||||
q = max(1.0, q);
|
||||
q = log2(q);
|
||||
q = min(1.9, q);
|
||||
|
||||
// q is now between 0 and 1.9.
|
||||
int down = int(floor(q));
|
||||
int up = down + 1;
|
||||
float interp = q - float(down);
|
||||
|
||||
outval = 1.0 - mix(val[down].x, val[up].x, interp);
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(vec3(outval), 1.0);
|
||||
}
|
70
data/shaders/shadowimportance.frag
Normal file
70
data/shaders/shadowimportance.frag
Normal file
@ -0,0 +1,70 @@
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D ctex;
|
||||
uniform vec3 campos;
|
||||
uniform int low;
|
||||
|
||||
varying vec3 wpos;
|
||||
varying vec2 texc;
|
||||
|
||||
float luminanceImp()
|
||||
{
|
||||
// A full-res fetch kills on low-end
|
||||
if (low > 0) return 1.0;
|
||||
|
||||
const vec3 weights = vec3(0.2126, 0.7152, 0.0722); // ITU-R BT. 709
|
||||
vec3 col = texture2D(ctex, texc).xyz;
|
||||
|
||||
float luma = dot(weights, col);
|
||||
|
||||
// Dark surfaces need less resolution
|
||||
float f = smoothstep(0.1, 0.4, luma);
|
||||
f = max(0.05, f);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
float normalImp(vec3 normal)
|
||||
{
|
||||
vec3 camdir = normalize(campos - wpos);
|
||||
vec3 N = normalize(normal);
|
||||
|
||||
// Boost surfaces facing the viewer directly
|
||||
float f = 2.0 * max(0.0, dot(N, camdir));
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
float depthImp(float linearz)
|
||||
{
|
||||
/* const float skip = 0.7;
|
||||
|
||||
float f = min(linearz, skip);
|
||||
f *= 1.0/skip;*/
|
||||
|
||||
float z = log(1.0 + linearz * 9.0) / log(10.0);
|
||||
|
||||
float f = 1.0 - (z * 0.9);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 ntmp = texture2D(ntex, texc);
|
||||
vec3 normal = ntmp.xyz * 2.0 - 1.0;
|
||||
float linearz = ntmp.a;
|
||||
|
||||
float importance = normalImp(normal) * depthImp(linearz) * luminanceImp();
|
||||
importance = clamp(importance, 0.0, 1.0);
|
||||
|
||||
float low = step(0.001, importance);
|
||||
|
||||
// Quantize it
|
||||
const float steps = 16.0;
|
||||
importance *= steps;
|
||||
importance = ceil(importance) * low;
|
||||
importance /= steps;
|
||||
|
||||
gl_FragColor = vec4(importance);
|
||||
gl_FragDepth = 1.0 - importance;
|
||||
}
|
30
data/shaders/shadowimportance.vert
Normal file
30
data/shaders/shadowimportance.vert
Normal file
@ -0,0 +1,30 @@
|
||||
uniform sampler2D dtex;
|
||||
uniform mat4 ipvmat;
|
||||
uniform mat4 shadowmat;
|
||||
|
||||
varying vec3 wpos;
|
||||
varying vec2 texc;
|
||||
|
||||
float decdepth(vec4 rgba) {
|
||||
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
texc = gl_Vertex.xy / vec2(32767.0);
|
||||
float z = decdepth(vec4(texture2D(dtex, texc).xyz, 0.0));
|
||||
|
||||
vec3 tmp = vec3(texc, z);
|
||||
tmp = tmp * 2.0 - 1.0;
|
||||
|
||||
vec4 xpos = vec4(tmp, 1.0);
|
||||
xpos = ipvmat * xpos;
|
||||
xpos.xyz /= xpos.w;
|
||||
|
||||
wpos = xpos.xyz;
|
||||
|
||||
// Now we have this pixel's world-space position. Convert to shadow space.
|
||||
vec4 pos = shadowmat * vec4(xpos.xyz, 1.0);
|
||||
|
||||
gl_Position = pos;
|
||||
}
|
34
data/shaders/shadowpass.frag
Normal file
34
data/shaders/shadowpass.frag
Normal file
@ -0,0 +1,34 @@
|
||||
uniform sampler2D tex;
|
||||
uniform int hastex;
|
||||
uniform int viz;
|
||||
uniform int wireframe;
|
||||
uniform float objectid;
|
||||
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
if (hastex != 0) {
|
||||
float alpha = texture2D(tex, gl_TexCoord[0].xy).a;
|
||||
|
||||
if (alpha < 0.5)
|
||||
discard;
|
||||
}
|
||||
|
||||
if (viz < 1)
|
||||
{
|
||||
gl_FragColor = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
|
||||
}
|
||||
else {
|
||||
if (wireframe > 0)
|
||||
gl_FragColor = vec4(1.0);
|
||||
else
|
||||
gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);
|
||||
}
|
||||
}
|
||||
|
25
data/shaders/shadowpass.vert
Normal file
25
data/shaders/shadowpass.vert
Normal file
@ -0,0 +1,25 @@
|
||||
uniform sampler2D warpx;
|
||||
uniform sampler2D warpy;
|
||||
|
||||
float decdepth(vec4 rgba) {
|
||||
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = ftransform();
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
vec2 tc = pos.xy * vec2(0.5) + vec2(0.5);
|
||||
|
||||
float movex = decdepth(texture2D(warpx, tc));
|
||||
float movey = decdepth(texture2D(warpy, tc));
|
||||
|
||||
float dx = movex * 2.0 - 1.0;
|
||||
float dy = movey * 2.0 - 1.0;
|
||||
|
||||
dx *= 2.0;
|
||||
dy *= 2.0;
|
||||
|
||||
gl_Position = pos + vec4(dx, dy, vec2(0.0));
|
||||
}
|
54
data/shaders/shadowwarph.frag
Normal file
54
data/shaders/shadowwarph.frag
Normal file
@ -0,0 +1,54 @@
|
||||
uniform sampler2D tex;
|
||||
uniform int size;
|
||||
uniform vec2 pixel;
|
||||
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 origtc = gl_TexCoord[0].xy;
|
||||
|
||||
// Get total sum
|
||||
float first = 1.0, last = 0.0;
|
||||
float lower = 0.0;
|
||||
float total = 0.0;
|
||||
vec2 tc = 0.5 * pixel;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
float col = texture2D(tex, tc).x;
|
||||
|
||||
lower += col * step(tc.x, origtc.x);
|
||||
total += col;
|
||||
|
||||
if (col > 0.0001)
|
||||
{
|
||||
first = min(first, tc.x);
|
||||
last = max(last, tc.x);
|
||||
}
|
||||
|
||||
tc += pixel;
|
||||
}
|
||||
|
||||
float res = (lower / total) - origtc.x;
|
||||
|
||||
// Outside the edges?
|
||||
if (origtc.x <= first)
|
||||
{
|
||||
res = origtc.x * -2.1;
|
||||
}
|
||||
else if (origtc.x >= last)
|
||||
{
|
||||
res = (1.0 - origtc.x) * 2.1;
|
||||
}
|
||||
|
||||
res = res * 0.5 + 0.5;
|
||||
res = clamp(res, 0.01, 0.99);
|
||||
|
||||
gl_FragColor = encdepth(res);
|
||||
}
|
54
data/shaders/shadowwarpv.frag
Normal file
54
data/shaders/shadowwarpv.frag
Normal file
@ -0,0 +1,54 @@
|
||||
uniform sampler2D tex;
|
||||
uniform int size;
|
||||
uniform vec2 pixel;
|
||||
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 origtc = gl_TexCoord[0].xy;
|
||||
|
||||
// Get total sum
|
||||
float first = 1.0, last = 0.0;
|
||||
float lower = 0.0;
|
||||
float total = 0.0;
|
||||
vec2 tc = pixel * 0.5;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
float col = texture2D(tex, tc).x;
|
||||
|
||||
lower += col * step(tc.y, origtc.y);
|
||||
total += col;
|
||||
|
||||
if (col > 0.0001)
|
||||
{
|
||||
first = min(first, tc.y);
|
||||
last = max(last, tc.y);
|
||||
}
|
||||
|
||||
tc += pixel;
|
||||
}
|
||||
|
||||
float res = (lower / total) - origtc.y;
|
||||
|
||||
// Outside the edges?
|
||||
if (origtc.y <= first)
|
||||
{
|
||||
res = origtc.y * -2.1;
|
||||
}
|
||||
else if (origtc.y >= last)
|
||||
{
|
||||
res = (1.0 - origtc.y) * 2.1;
|
||||
}
|
||||
|
||||
res = res * 0.5 + 0.5;
|
||||
res = clamp(res, 0.01, 0.99);
|
||||
|
||||
gl_FragColor = encdepth(res);
|
||||
}
|
18
data/shaders/snow.frag
Normal file
18
data/shaders/snow.frag
Normal file
@ -0,0 +1,18 @@
|
||||
uniform sampler2D tex;
|
||||
uniform float time;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 change;
|
||||
change.x = abs(sin(time * gl_Color.r));
|
||||
change.y = abs(cos(time * gl_Color.g));
|
||||
|
||||
change = smoothstep(0.0, 1.0, change) * 0.5;
|
||||
|
||||
vec2 tc = gl_TexCoord[0].xy;
|
||||
tc = smoothstep(0.5 - change, 0.5 + change, tc);
|
||||
|
||||
vec4 tcol = texture2D(tex, tc);
|
||||
|
||||
gl_FragColor = tcol;
|
||||
}
|
7
data/shaders/snow.vert
Normal file
7
data/shaders/snow.vert
Normal file
@ -0,0 +1,7 @@
|
||||
void main()
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = ftransform();
|
||||
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
@ -1,44 +1,48 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 the SuperTuxKart team
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
varying vec3 nor;
|
||||
uniform float far;
|
||||
uniform float objectid;
|
||||
|
||||
uniform sampler2D tex_layout;
|
||||
uniform sampler2D tex_detail0;
|
||||
uniform sampler2D tex_detail1;
|
||||
uniform sampler2D tex_detail2;
|
||||
uniform sampler2D tex_detail3;
|
||||
uniform sampler2D tex_detail4;
|
||||
varying vec3 normal;
|
||||
varying vec3 lightdir2;
|
||||
varying vec4 vertex_color;
|
||||
//uniform sampler2D tex_detail4;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 splatting = texture2D(tex_layout, gl_TexCoord[1].st);
|
||||
vec4 detail0 = texture2D(tex_detail0, gl_TexCoord[0].st);
|
||||
vec4 detail1 = texture2D(tex_detail1, gl_TexCoord[0].st);
|
||||
vec4 detail2 = texture2D(tex_detail2, gl_TexCoord[0].st);
|
||||
vec4 detail3 = texture2D(tex_detail3, gl_TexCoord[0].st);
|
||||
vec4 detail4 = texture2D(tex_detail4, gl_TexCoord[0].st);
|
||||
const float near = 1.0;
|
||||
|
||||
gl_FragColor = (splatting.r * detail0 +
|
||||
splatting.g * detail1 +
|
||||
splatting.b * detail2 +
|
||||
(1.0 - splatting.r - splatting.g - splatting.b) * detail3 +
|
||||
(1.0 - splatting.a) * detail4)
|
||||
* min(1.0, 0.2 + dot(lightdir2, normal)) * vertex_color; // 0.2 is the ambient light.
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near));
|
||||
|
||||
// Tune for better inside range without losing outdoors
|
||||
linear_z *= 2.0;
|
||||
|
||||
// Splatting part
|
||||
vec4 splatting = texture2D(tex_layout, gl_TexCoord[1].st);
|
||||
vec4 detail0 = texture2D(tex_detail0, gl_TexCoord[0].st);
|
||||
vec4 detail1 = texture2D(tex_detail1, gl_TexCoord[0].st);
|
||||
vec4 detail2 = texture2D(tex_detail2, gl_TexCoord[0].st);
|
||||
vec4 detail3 = texture2D(tex_detail3, gl_TexCoord[0].st);
|
||||
// vec4 detail4 = texture2D(tex_detail4, gl_TexCoord[0].st);
|
||||
vec4 detail4 = vec4(0.0);
|
||||
|
||||
vec4 splatted = (splatting.r * detail0 +
|
||||
splatting.g * detail1 +
|
||||
splatting.b * detail2 +
|
||||
(1.0 - splatting.r - splatting.g - splatting.b) * detail3 +
|
||||
(1.0 - splatting.a) * detail4)
|
||||
* gl_Color;
|
||||
|
||||
gl_FragData[0] = splatted;
|
||||
|
||||
gl_FragData[1] = vec4(nor, linear_z);
|
||||
gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
|
||||
}
|
||||
|
78
data/shaders/ssao.frag
Normal file
78
data/shaders/ssao.frag
Normal file
@ -0,0 +1,78 @@
|
||||
#version 120
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D oldtex;
|
||||
|
||||
const float totStrength = 2.38;
|
||||
const float strength = 0.07;
|
||||
const float falloff = 0.000002;
|
||||
|
||||
#define SAMPLES 16
|
||||
|
||||
const float invSamples = 1.0 / SAMPLES;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// A set of Random(tm) vec2's. 8 1s, 6 0.7s, 2 0.4
|
||||
// Again not using const because of broken Intel Windows drivers
|
||||
vec2 vecs[16] = vec2[](vec2(0.43589, -0.9), vec2(-0.9, 0.43589),
|
||||
vec2(-0.8, -0.6), vec2(0.6, 0.8),
|
||||
vec2(0.866025, -0.5), vec2(-0.5, 0.866025),
|
||||
vec2(-0.3, -0.953939), vec2(0.953939, 0.3),
|
||||
vec2(0.3, -0.781025), vec2(-0.781025, 0.3),
|
||||
vec2(-0.56, -0.621611), vec2(0.621611, 0.56),
|
||||
vec2(0.734847, -0.4), vec2(-0.4, 0.734847),
|
||||
vec2(-0.2, -0.6), vec2(0.6, 0.2));
|
||||
|
||||
vec2 uv = gl_TexCoord[0].xy;
|
||||
|
||||
vec4 cur = texture2D(tex, uv);
|
||||
float curdepth = cur.a;
|
||||
|
||||
// Will we skip this pixel? (if it's the sky)
|
||||
float len = dot(vec3(1.0), abs(cur.xyz));
|
||||
if (len < 0.2 || curdepth > 0.8) discard;
|
||||
|
||||
float mytotstrength = 3.0 * totStrength * curdepth * (1.0 - curdepth);
|
||||
|
||||
// get the normal of current fragment
|
||||
vec3 norm = normalize(cur.xyz * vec3(2.0) - vec3(1.0));
|
||||
|
||||
float bl = 0.0;
|
||||
|
||||
// adjust for the depth, 0.1 close, 0.01 far
|
||||
float radD = 0.10 - 0.09 * smoothstep(0.0, 0.2, curdepth);
|
||||
|
||||
for(int i = 0; i < SAMPLES; ++i) {
|
||||
|
||||
vec2 ray = uv + radD * vecs[i];
|
||||
|
||||
// get the depth of the occluder fragment
|
||||
vec4 occluderFragment = texture2D(tex, ray);
|
||||
float normAcceptable = step(0.2, dot(vec3(1.0), abs(occluderFragment.xyz)));
|
||||
|
||||
// get the normal of the occluder fragment
|
||||
vec3 occNorm = normalize(occluderFragment.xyz * vec3(2.0) - vec3(1.0));
|
||||
|
||||
// if depthDifference is negative = occluder is behind current fragment
|
||||
float depthDifference = curdepth - occluderFragment.a;
|
||||
|
||||
// calculate the difference between the normals as a weight
|
||||
float normDiff = 1.0 - max(dot(occNorm, norm), 0.0);
|
||||
normDiff = smoothstep(0.1, 0.3, normDiff);
|
||||
|
||||
// the falloff equation, starts at falloff and is kind of 1/x^2 falling
|
||||
bl += step(falloff, depthDifference) * normDiff * normAcceptable *
|
||||
(1.0 - smoothstep(falloff, strength, depthDifference));
|
||||
}
|
||||
|
||||
// output the result
|
||||
float ao = 1.0 - mytotstrength * bl * invSamples;
|
||||
|
||||
// Mix with old result to avoid flicker
|
||||
float oldao = texture2D(oldtex, uv).x;
|
||||
|
||||
ao = mix(ao, oldao, 0.3);
|
||||
|
||||
gl_FragColor = vec4(vec3(ao), curdepth);
|
||||
}
|
58
data/shaders/sunlight.frag
Normal file
58
data/shaders/sunlight.frag
Normal file
@ -0,0 +1,58 @@
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D dtex;
|
||||
uniform sampler2D cloudtex;
|
||||
|
||||
uniform vec3 center;
|
||||
uniform vec3 col;
|
||||
uniform vec2 screen;
|
||||
uniform mat4 invprojview;
|
||||
uniform int hasclouds;
|
||||
uniform vec2 wind;
|
||||
|
||||
float decdepth(vec4 rgba) {
|
||||
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 texc = gl_FragCoord.xy / screen;
|
||||
float z = decdepth(vec4(texture2D(dtex, texc).xyz, 0.0));
|
||||
|
||||
if (z < 0.03)
|
||||
{
|
||||
// Skyboxes are fully lit
|
||||
gl_FragData[0] = vec4(1.0);
|
||||
gl_FragData[1] = vec4(1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 norm = texture2D(ntex, texc).xyz;
|
||||
norm = (norm - 0.5) * 2.0;
|
||||
|
||||
// Normalized on the cpu
|
||||
vec3 L = center;
|
||||
|
||||
float NdotL = max(0.0, dot(norm, L));
|
||||
if (NdotL < 0.01) discard;
|
||||
|
||||
vec3 outcol = NdotL * col;
|
||||
|
||||
if (hasclouds == 1)
|
||||
{
|
||||
vec3 tmp = vec3(texc, z);
|
||||
tmp = tmp * 2.0 - 1.0;
|
||||
|
||||
vec4 xpos = vec4(tmp, 1.0);
|
||||
xpos = invprojview * xpos;
|
||||
xpos.xyz /= xpos.w;
|
||||
|
||||
vec2 cloudcoord = (xpos.xz * 0.00833333) + wind;
|
||||
float cloud = texture2D(cloudtex, cloudcoord).x;
|
||||
//float cloud = step(0.5, cloudcoord.x) * step(0.5, cloudcoord.y);
|
||||
|
||||
outcol *= cloud;
|
||||
}
|
||||
|
||||
gl_FragData[0] = vec4(outcol, 0.05);
|
||||
gl_FragData[1] = vec4(1.0);
|
||||
}
|
106
data/shaders/sunlightshadow.frag
Normal file
106
data/shaders/sunlightshadow.frag
Normal file
@ -0,0 +1,106 @@
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D dtex;
|
||||
uniform sampler2D cloudtex;
|
||||
uniform sampler2D shadowtex;
|
||||
uniform sampler2D warpx;
|
||||
uniform sampler2D warpy;
|
||||
|
||||
uniform vec3 center;
|
||||
uniform vec3 col;
|
||||
uniform vec2 screen;
|
||||
uniform mat4 invprojview;
|
||||
uniform mat4 shadowmat;
|
||||
uniform int hasclouds;
|
||||
uniform vec2 wind;
|
||||
uniform float shadowoffset;
|
||||
|
||||
float decdepth(vec4 rgba) {
|
||||
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 texc = gl_FragCoord.xy / screen;
|
||||
vec4 depthread = texture2D(dtex, texc);
|
||||
float z = decdepth(vec4(depthread.xyz, 0.0));
|
||||
|
||||
if (z < 0.03)
|
||||
{
|
||||
// Skyboxes are fully lit
|
||||
gl_FragData[0] = vec4(1.0);
|
||||
gl_FragData[1] = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 norm = texture2D(ntex, texc).xyz;
|
||||
norm = (norm - 0.5) * 2.0;
|
||||
|
||||
// Normalized on the cpu
|
||||
vec3 L = center;
|
||||
|
||||
float NdotL = max(0.0, dot(norm, L));
|
||||
if (NdotL < 0.01) discard;
|
||||
|
||||
vec3 outcol = NdotL * col;
|
||||
|
||||
// World-space position
|
||||
vec3 tmp = vec3(texc, z);
|
||||
tmp = tmp * 2.0 - 1.0;
|
||||
|
||||
vec4 xpos = vec4(tmp, 1.0);
|
||||
xpos = invprojview * xpos;
|
||||
xpos.xyz /= xpos.w;
|
||||
|
||||
if (hasclouds == 1)
|
||||
{
|
||||
vec2 cloudcoord = (xpos.xz * 0.00833333) + wind;
|
||||
float cloud = texture2D(cloudtex, cloudcoord).x;
|
||||
//float cloud = step(0.5, cloudcoord.x) * step(0.5, cloudcoord.y);
|
||||
|
||||
outcol *= cloud;
|
||||
}
|
||||
|
||||
// Shadows
|
||||
vec3 shadowcoord = (shadowmat * vec4(xpos.xyz, 1.0)).xyz;
|
||||
shadowcoord = (shadowcoord * 0.5) + vec3(0.5);
|
||||
|
||||
float movex = decdepth(texture2D(warpx, shadowcoord.xy));
|
||||
float movey = decdepth(texture2D(warpy, shadowcoord.xy));
|
||||
float dx = movex * 2.0 - 1.0;
|
||||
float dy = movey * 2.0 - 1.0;
|
||||
shadowcoord.xy += vec2(dx, dy);
|
||||
|
||||
vec4 shadowread = texture2D(shadowtex, shadowcoord.xy);
|
||||
float shadowmapz = decdepth(vec4(shadowread.xyz, 0.0));
|
||||
|
||||
float moved = (abs(dx) + abs(dy)) * 0.5;
|
||||
|
||||
float bias = 0.002 * tan(acos(NdotL)); // According to the slope
|
||||
bias += smoothstep(0.001, 0.1, moved) * 0.014; // According to the warping
|
||||
bias = clamp(bias, 0.001, 0.014);
|
||||
|
||||
// This ID, and four IDs around this must match for a shadow pixel
|
||||
float right = texture2D(shadowtex, shadowcoord.xy + vec2(shadowoffset, 0.0)).a;
|
||||
float left = texture2D(shadowtex, shadowcoord.xy + vec2(-shadowoffset, 0.0)).a;
|
||||
float up = texture2D(shadowtex, shadowcoord.xy + vec2(0.0, shadowoffset)).a;
|
||||
float down = texture2D(shadowtex, shadowcoord.xy + vec2(0.0, -shadowoffset)).a;
|
||||
|
||||
float matching = ((right + left + up + down) * 0.25) - shadowread.a;
|
||||
matching = abs(matching) * 400.0;
|
||||
|
||||
// If the ID is different, we're likely in shadow - cut the bias to cut peter panning
|
||||
float off = 7.0 - step(abs(shadowread.a - depthread.a) - matching, 0.004) * 6.0;
|
||||
bias /= off;
|
||||
|
||||
const float softness = 8.0; // How soft is the light?
|
||||
float shadowed = step(shadowmapz + bias, shadowcoord.z);
|
||||
float dist = (shadowcoord.z / shadowmapz) - 1.0;
|
||||
float penumbra = dist * softness / gl_FragCoord.z;
|
||||
penumbra *= shadowed;
|
||||
|
||||
/* outcol.r = (shadowcoord.z - shadowmapz) * 50.0;
|
||||
outcol.g = moved;*/
|
||||
|
||||
gl_FragData[0] = vec4(outcol, 0.05);
|
||||
gl_FragData[1] = vec4(shadowed, penumbra, shadowed, shadowed);
|
||||
}
|
@ -16,11 +16,11 @@ void main()
|
||||
{
|
||||
// lookup normal from normal map, move from [0,1] to [-1, 1] range, normalize
|
||||
vec3 normal = 2.0 * texture2D (BumpTex1, gl_TexCoord[0].st + delta1).rgb - 1.0;
|
||||
vec3 normal2 = 2.0 * texture2D (BumpTex2, gl_TexCoord[0].st + delta2).rgb - 1.0;
|
||||
vec3 normal2 = 2.0 * texture2D (BumpTex2, gl_TexCoord[0].st + delta2).rgb - 1.0;
|
||||
|
||||
// scale normals
|
||||
normal.y = 4.0*normal.y;
|
||||
normal2.y = 4.0*normal2.y;
|
||||
// scale normals
|
||||
normal.y = 4.0*normal.y;
|
||||
normal2.y = 4.0*normal2.y;
|
||||
|
||||
normal = (normalize(normal) + normalize(normal2))/2.0;
|
||||
|
||||
@ -29,31 +29,28 @@ void main()
|
||||
vec4 diffuseMaterial;
|
||||
vec4 diffuseLight;
|
||||
|
||||
diffuseMaterial = texture2D (DecalTex, gl_TexCoord[0].st + vec2(delta1.x, 0.0));
|
||||
diffuseLight = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
diffuseMaterial = texture2D (DecalTex, gl_TexCoord[0].st + vec2(delta1.x, 0.0));
|
||||
diffuseLight = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
//if (lamberFactor < 0.7)
|
||||
//{
|
||||
// lamberFactor = 0.0;
|
||||
//}
|
||||
vec3 col = diffuseMaterial.xyz * (0.3 + lamberFactor*0.7);
|
||||
|
||||
gl_FragColor = diffuseMaterial * (0.3 + lamberFactor*0.7);
|
||||
// specular (phong)
|
||||
vec3 R = normalize(reflect(lightVec, normal));
|
||||
float specular = max(dot(R, eyeVec), 0.0);
|
||||
|
||||
// specular (phong)
|
||||
vec3 R = normalize(reflect(lightVec, normal));
|
||||
float specular = max(dot(R,eyeVec),0.0);
|
||||
// weak specular
|
||||
specular = specular*specular;
|
||||
specular = specular*specular;
|
||||
float specular_weak = specular*0.05;
|
||||
col += vec3(specular_weak, specular_weak, specular_weak);
|
||||
|
||||
if (specular > 0.0)
|
||||
{
|
||||
// weak specular
|
||||
specular = specular*specular;
|
||||
specular = specular*specular;
|
||||
float specular_weak = specular*0.05;
|
||||
gl_FragColor += vec4(specular_weak, specular_weak, specular_weak, 0.0);
|
||||
// strong specular
|
||||
specular = specular*specular;
|
||||
float specular_strong = specular*0.3;
|
||||
col += vec3(specular_strong, specular_strong, specular_strong);
|
||||
|
||||
// strong specular
|
||||
specular = specular*specular;
|
||||
float specular_strong = specular*0.3;
|
||||
gl_FragColor += vec4(specular_strong, specular_strong, specular_strong, 0.0);
|
||||
}
|
||||
float summed = dot(vec3(1.0), col) / 3.0;
|
||||
float alpha = 0.9 + 0.1 * smoothstep(0.0, 1.0, summed);
|
||||
|
||||
gl_FragColor = vec4(col, alpha);
|
||||
}
|
||||
|
@ -1,25 +1,30 @@
|
||||
// Shader based on work by Fabien Sanglard
|
||||
// Released under the terms of CC-BY 3.0
|
||||
|
||||
uniform float speed;
|
||||
uniform float height;
|
||||
uniform float length;
|
||||
|
||||
uniform vec3 lightdir;
|
||||
|
||||
varying vec3 lightVec;
|
||||
varying vec3 halfVec;
|
||||
varying vec3 eyeVec;
|
||||
|
||||
uniform vec3 lightdir;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = gl_Vertex;
|
||||
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
pos.y += (sin(pos.x/length + speed) + cos(pos.z/length + speed)) * height;
|
||||
|
||||
vec3 vertexPosition = vec3(gl_ModelViewMatrix * pos);
|
||||
|
||||
// Building the matrix Eye Space -> Tangent Space
|
||||
vec3 n = normalize (gl_NormalMatrix * gl_Normal);
|
||||
// gl_MultiTexCoord1.xyz
|
||||
// gl_MultiTexCoord1.xyz
|
||||
vec3 t = normalize (gl_NormalMatrix * vec3(1.0, 0.0, 0.0)); // tangent
|
||||
vec3 b = cross (n, t);
|
||||
|
||||
vec3 vertexPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
|
||||
|
||||
// transform light and half angle vectors by tangent basis
|
||||
vec3 v;
|
||||
v.x = dot (lightdir, t);
|
||||
@ -29,7 +34,7 @@ void main()
|
||||
|
||||
vertexPosition = normalize(vertexPosition);
|
||||
|
||||
eyeVec = normalize(-vertexPosition); // we are in Eye Coordinates, so EyePos is (0,0,0)
|
||||
eyeVec = normalize(-vertexPosition); // we are in Eye Coordinates, so EyePos is (0,0,0)
|
||||
|
||||
// Normalize the halfVector to pass it to the fragment shader
|
||||
|
||||
@ -44,5 +49,7 @@ void main()
|
||||
//normalize (v);
|
||||
halfVec = v ;
|
||||
|
||||
gl_Position = ftransform();
|
||||
gl_Position = gl_ModelViewProjectionMatrix * pos;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[1] = gl_MultiTexCoord1;
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
// Shader based on work by Fabien Sanglard
|
||||
// Released under the terms of CC-BY 3.0
|
||||
|
||||
uniform sampler2D BumpTex1; // Normal map 1
|
||||
uniform sampler2D BumpTex2; // Normal map 2
|
||||
uniform sampler2D DecalTex; //The texture
|
||||
|
||||
uniform vec2 delta1;
|
||||
uniform vec2 delta2;
|
||||
|
||||
varying vec3 lightVec;
|
||||
varying vec3 halfVec;
|
||||
varying vec3 eyeVec;
|
||||
varying vec4 coord;
|
||||
|
||||
uniform vec4 fogColor;
|
||||
uniform float fogFrom;
|
||||
uniform float fogTo;
|
||||
|
||||
void main()
|
||||
{
|
||||
// lookup normal from normal map, move from [0,1] to [-1, 1] range, normalize
|
||||
vec3 normal = 2.0 * texture2D (BumpTex1, gl_TexCoord[0].st + delta1).rgb - 1.0;
|
||||
vec3 normal2 = 2.0 * texture2D (BumpTex2, gl_TexCoord[0].st + delta2).rgb - 1.0;
|
||||
|
||||
// scale normals
|
||||
normal.y = 4.0*normal.y;
|
||||
normal2.y = 4.0*normal2.y;
|
||||
|
||||
normal = (normalize(normal) + normalize(normal2))/2.0;
|
||||
|
||||
// compute diffuse lighting
|
||||
float lamberFactor = max (dot (lightVec, normal), 0.0);
|
||||
vec4 diffuseMaterial;
|
||||
vec4 diffuseLight;
|
||||
|
||||
diffuseMaterial = texture2D (DecalTex, gl_TexCoord[0].st + vec2(delta1.x, 0.0));
|
||||
diffuseLight = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
//if (lamberFactor < 0.7)
|
||||
//{
|
||||
// lamberFactor = 0.0;
|
||||
//}
|
||||
|
||||
gl_FragColor = diffuseMaterial * (0.3 + lamberFactor*0.7);
|
||||
|
||||
// specular (phong)
|
||||
vec3 R = normalize(reflect(lightVec, normal));
|
||||
float specular = max(dot(R,eyeVec),0.0);
|
||||
|
||||
if (specular > 0.0)
|
||||
{
|
||||
// weak specular
|
||||
specular = specular*specular;
|
||||
specular = specular*specular;
|
||||
float specular_weak = specular*0.05;
|
||||
gl_FragColor += vec4(specular_weak, specular_weak, specular_weak, 0.0);
|
||||
|
||||
// strong specular
|
||||
specular = specular*specular;
|
||||
float specular_strong = specular*0.3;
|
||||
gl_FragColor += vec4(specular_strong, specular_strong, specular_strong, 0.0);
|
||||
}
|
||||
|
||||
if (coord.z > fogTo)
|
||||
{
|
||||
gl_FragColor = fogColor;
|
||||
}
|
||||
else if (coord.z > fogFrom)
|
||||
{
|
||||
float fogIntensity = (coord.z - fogFrom) / (fogTo - fogFrom);
|
||||
gl_FragColor = fogIntensity*fogColor + (1.0 - fogIntensity)*gl_FragColor;
|
||||
}
|
||||
}
|
||||
|
@ -1,49 +0,0 @@
|
||||
// Shader based on work by Fabien Sanglard
|
||||
// Released under the terms of CC-BY 3.0
|
||||
|
||||
varying vec3 lightVec;
|
||||
varying vec3 halfVec;
|
||||
varying vec3 eyeVec;
|
||||
varying vec4 coord;
|
||||
uniform vec3 lightdir;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
// Building the matrix Eye Space -> Tangent Space
|
||||
vec3 n = normalize (gl_NormalMatrix * gl_Normal);
|
||||
// gl_MultiTexCoord1.xyz
|
||||
vec3 t = normalize (gl_NormalMatrix * vec3(1.0, 0.0, 0.0)); // tangent
|
||||
vec3 b = cross (n, t);
|
||||
|
||||
vec3 vertexPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
|
||||
|
||||
// transform light and half angle vectors by tangent basis
|
||||
vec3 v;
|
||||
v.x = dot (lightdir, t);
|
||||
v.y = dot (lightdir, b);
|
||||
v.z = dot (lightdir, n);
|
||||
lightVec = normalize (v);
|
||||
|
||||
vertexPosition = normalize(vertexPosition);
|
||||
|
||||
eyeVec = normalize(-vertexPosition); // we are in Eye Coordinates, so EyePos is (0,0,0)
|
||||
|
||||
// Normalize the halfVector to pass it to the fragment shader
|
||||
|
||||
// No need to divide by two, the result is normalized anyway.
|
||||
// vec3 halfVector = normalize((vertexPosition + lightDir) / 2.0);
|
||||
vec3 halfVector = normalize(vertexPosition + lightdir);
|
||||
v.x = dot (halfVector, t);
|
||||
v.y = dot (halfVector, b);
|
||||
v.z = dot (halfVector, n);
|
||||
|
||||
// No need to normalize, t,b,n and halfVector are normal vectors.
|
||||
//normalize (v);
|
||||
halfVec = v ;
|
||||
|
||||
gl_Position = ftransform();
|
||||
coord = gl_Position;
|
||||
}
|
4
data/shaders/white.frag
Normal file
4
data/shaders/white.frag
Normal file
@ -0,0 +1,4 @@
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(1.0);
|
||||
}
|
@ -135,6 +135,9 @@
|
||||
<steer disable-while-unskid="false"
|
||||
camera-follow-skid="true" />
|
||||
|
||||
<!-- Glow colors for the items -->
|
||||
<glow-colors nitro="0 0 255" box="255 0 0" />
|
||||
|
||||
<!-- Default values for all karts
|
||||
============================ -->
|
||||
<general-kart-defaults>
|
||||
|
21
doc/graphics_views.txt
Normal file
21
doc/graphics_views.txt
Normal file
@ -0,0 +1,21 @@
|
||||
Graphics debug views
|
||||
====================
|
||||
|
||||
There are some graphics debug views, to be used both by artists when developing,
|
||||
and by users when reporting bugs.
|
||||
|
||||
These should be available in normal (non-artist) mode
|
||||
to enable easier bug reports (go there, press this key, screenshot)
|
||||
without requiring editing the UTF-32 config files (which is inconvenient, most editors
|
||||
do not support that weird encoding).
|
||||
|
||||
They don't give gameplay advantages like the item keys, so there should be little harm
|
||||
leaving them available. Accidental keypresses ought to be minimized by their location.
|
||||
|
||||
Home - wireframe view
|
||||
End - mipmap visualization (is a texture too high or low resolution, red = too high)
|
||||
Del - normal view
|
||||
PgDown - SSAO view
|
||||
PgUp - light view
|
||||
Ins - shadow view
|
||||
ScrlLock - displacement view
|
157
doc/graphics_xml.txt
Normal file
157
doc/graphics_xml.txt
Normal file
@ -0,0 +1,157 @@
|
||||
Graphics GSOC XML additions
|
||||
===========================
|
||||
|
||||
This document will list in depth all new XML values added during the graphics GSOC, for use
|
||||
by the blender exporter scripts.
|
||||
|
||||
Glow colors
|
||||
-----------
|
||||
|
||||
The glow colors for nitro bottles and boxes are settable in stk_config.xml.
|
||||
They are three-value RGB colors.
|
||||
|
||||
Example: <glow-colors nitro="0 0 255" box="255 0 0" />
|
||||
|
||||
|
||||
Particle wind
|
||||
-------------
|
||||
|
||||
Particles may be affected by wind. This is used with the snow particles.
|
||||
|
||||
Flips is a boolean controlling whether each particle will spin about its own two axis.
|
||||
It is only applicable to symmetric textures, such as snow flakes.
|
||||
|
||||
Speed is a float in no real units.
|
||||
|
||||
Example: <wind speed="0.16" flips="Y" />
|
||||
|
||||
|
||||
Forced bloom objects
|
||||
--------------------
|
||||
|
||||
Any object may be marked as forced bloom. This will include the object in the bloom pass
|
||||
regardless of its brightness.
|
||||
|
||||
Example: forcedbloom="Y" inside the <object> tag, in scene.xml.
|
||||
|
||||
Forced bloom objects may optionally include a multiplier, ranging from 0.5 to 10:
|
||||
bloompower="2.5"
|
||||
|
||||
|
||||
Glowing objects
|
||||
---------------
|
||||
|
||||
Any object may be marked as glowing. The glow is a RGB value.
|
||||
|
||||
Example: glow="0 255 0" inside the <object> tag, in scene.xml.
|
||||
|
||||
|
||||
Caustics
|
||||
--------
|
||||
|
||||
A material effect, ie GE_CAUSTICS, to mark a texture as receiving caustics. To be used
|
||||
for the ocean floor, puddle floor, etc.
|
||||
|
||||
Example: graphics-effect="caustics" in materials.xml.
|
||||
|
||||
|
||||
Refractions/reflections
|
||||
-----------------------
|
||||
|
||||
A per-object boolean flag, typically set for subsea windows or the ocean surface.
|
||||
|
||||
Example: displacing="Y" in the <object> tag in scene.xml.
|
||||
|
||||
|
||||
|
||||
Per-track tags
|
||||
--------------
|
||||
|
||||
These are all specified inside track.xml, among the track's author, music, etc.
|
||||
|
||||
Cloud shadows
|
||||
-------------
|
||||
|
||||
Boolean whether to have the sun blocked by cloud shadows, moving with the wind.
|
||||
Disabled by default.
|
||||
|
||||
The effect is completely fake, doesn't correspond to any real or simulated clouds, but
|
||||
nobody's checking, so it looks nice.
|
||||
|
||||
Example: clouds="Y" inside the <track> tag.
|
||||
|
||||
|
||||
Bloom
|
||||
-----
|
||||
|
||||
Boolean whether to enable global bloom for this track. Enabled by default.
|
||||
|
||||
Example: bloom="Y" inside the <track> tag.
|
||||
|
||||
|
||||
Bloom threshold
|
||||
---------------
|
||||
|
||||
Float that specifies the minimum luminance needed for a pixel to participate in the bloom.
|
||||
The default is 0.75.
|
||||
|
||||
Example: bloom-threshold="0.75"
|
||||
|
||||
|
||||
Lens flare
|
||||
----------
|
||||
|
||||
Boolean that specifies whether a lens flare is shown when the player looks at the sun.
|
||||
The strength and angle depend on the relation of the camera to the sun. Disabled by default.
|
||||
|
||||
Example: lens-flare="Y"
|
||||
|
||||
|
||||
Dynamic shadows
|
||||
---------------
|
||||
|
||||
Boolean on whether this track should use dynamic shadows. Enabled by default.
|
||||
|
||||
If disabled, the fallback fake kart shadows will be used.
|
||||
|
||||
Example: shadows="N"
|
||||
|
||||
|
||||
God rays
|
||||
--------
|
||||
|
||||
Boolean on rendering god rays when the player looks at the sun. Disabled by default.
|
||||
|
||||
Example: god-rays="Y"
|
||||
|
||||
|
||||
Displacement speed
|
||||
------------------
|
||||
|
||||
Float on the relative speed of any displacing objects in this level. Default 1.0.
|
||||
2.0 = double speed, 0.5 = half speed, etc.
|
||||
|
||||
Example: displacement-speed="1.5"
|
||||
|
||||
|
||||
Caustics speed
|
||||
--------------
|
||||
|
||||
Float on the relative speed of any caustics objects in this level. Default 1.0.
|
||||
2.0 = double speed, 0.5 = half speed, etc.
|
||||
|
||||
Example: caustics-speed="1.5"
|
||||
|
||||
|
||||
Fog
|
||||
---
|
||||
|
||||
The density tag was removed (it was unused anyway).
|
||||
The max, height start, and height end tags were added.
|
||||
|
||||
fog-max: float capping the amount of fog to apply, default 1.0.
|
||||
fog-start-height: minimum height of fog, default 0.0.
|
||||
fog-end-height: maximum height of fog, default 100.0.
|
||||
|
||||
The fog scales smoothly according to both the height, and the distance from
|
||||
camera.
|
44
doc/pipeline_overview.txt
Normal file
44
doc/pipeline_overview.txt
Normal file
@ -0,0 +1,44 @@
|
||||
New pipeline overview
|
||||
=====================
|
||||
|
||||
Organized by RTTs
|
||||
-----------------
|
||||
|
||||
To color:
|
||||
- initialize the glow representations (no rendering yet)
|
||||
- render the 3d skybox, if any (includes the usual skybox)
|
||||
|
||||
To the MRT (color, normals, depth):
|
||||
- solids
|
||||
|
||||
To quarter1:
|
||||
- glowmap
|
||||
|
||||
To various shadow maps:
|
||||
- shadows
|
||||
|
||||
To tmp1:
|
||||
- lights
|
||||
|
||||
To color:
|
||||
- lights from tmp1 are multiplicatively blended
|
||||
- skybox if there is no 3d skybox
|
||||
- lens flare/god rays occlusion query (no rendering)
|
||||
- solid post-processing
|
||||
- transparents
|
||||
|
||||
To displace:
|
||||
- displacing nodes, if any
|
||||
|
||||
To the screen:
|
||||
- the post-processing chain
|
||||
- GUI
|
||||
|
||||
|
||||
Organized by passes
|
||||
-------------------
|
||||
|
||||
Init: glow init -> 3d skybox
|
||||
Main: solids -> glows -> shadows -> lights -> occlusion query -> solid PP
|
||||
Transparent: transparents -> displacing -> PP
|
||||
GUI: gui
|
@ -25,12 +25,16 @@ src/config/player.cpp
|
||||
src/config/saved_grand_prix.cpp
|
||||
src/config/stk_config.cpp
|
||||
src/config/user_config.cpp
|
||||
src/graphics/callbacks.cpp
|
||||
src/graphics/camera.cpp
|
||||
src/graphics/CBatchingMesh.cpp
|
||||
src/graphics/explosion.cpp
|
||||
src/graphics/glow.cpp
|
||||
src/graphics/hardware_skinning.cpp
|
||||
src/graphics/hit_sfx.cpp
|
||||
src/graphics/irr_driver.cpp
|
||||
src/graphics/lens_flare.cpp
|
||||
src/graphics/light.cpp
|
||||
src/graphics/lod_node.cpp
|
||||
src/graphics/material.cpp
|
||||
src/graphics/material_manager.cpp
|
||||
@ -43,11 +47,19 @@ src/graphics/per_camera_node.cpp
|
||||
src/graphics/post_processing.cpp
|
||||
src/graphics/rain.cpp
|
||||
src/graphics/referee.cpp
|
||||
src/graphics/render.cpp
|
||||
src/graphics/rtts.cpp
|
||||
src/graphics/screenquad.cpp
|
||||
src/graphics/shaders.cpp
|
||||
src/graphics/shadow.cpp
|
||||
src/graphics/shadow_importance.cpp
|
||||
src/graphics/show_curve.cpp
|
||||
src/graphics/skid_marks.cpp
|
||||
src/graphics/slip_stream.cpp
|
||||
src/graphics/stars.cpp
|
||||
src/graphics/sun.cpp
|
||||
src/graphics/water.cpp
|
||||
src/graphics/wind.cpp
|
||||
src/guiengine/abstract_state_manager.cpp
|
||||
src/guiengine/abstract_top_level_container.cpp
|
||||
src/guiengine/CGUISpriteBank.cpp
|
||||
@ -234,6 +246,7 @@ src/tracks/track_object_presentation.cpp
|
||||
src/tracks/track_sector.cpp
|
||||
src/utils/constants.cpp
|
||||
src/utils/crash_reporting.cpp
|
||||
src/utils/helpers.cpp
|
||||
src/utils/leak_check.cpp
|
||||
src/utils/log.cpp
|
||||
src/utils/profiler.cpp
|
||||
@ -274,17 +287,24 @@ src/config/player.hpp
|
||||
src/config/saved_grand_prix.hpp
|
||||
src/config/stk_config.hpp
|
||||
src/config/user_config.hpp
|
||||
src/graphics/callbacks.hpp
|
||||
src/graphics/camera.hpp
|
||||
src/graphics/CBatchingMesh.hpp
|
||||
src/graphics/explosion.hpp
|
||||
src/graphics/glow.hpp
|
||||
src/graphics/glwrap.hpp
|
||||
src/graphics/hardware_skinning.hpp
|
||||
src/graphics/hit_effect.hpp
|
||||
src/graphics/hit_sfx.hpp
|
||||
src/graphics/irr_driver.hpp
|
||||
src/graphics/large_mesh_buffer.hpp
|
||||
src/graphics/lens_flare.hpp
|
||||
src/graphics/light.hpp
|
||||
src/graphics/lod_node.hpp
|
||||
src/graphics/material.hpp
|
||||
src/graphics/material_manager.hpp
|
||||
src/graphics/mesh_tools.hpp
|
||||
src/graphics/mlaa_areamap.hpp
|
||||
src/graphics/moving_texture.hpp
|
||||
src/graphics/particle_emitter.hpp
|
||||
src/graphics/particle_kind.hpp
|
||||
@ -293,11 +313,18 @@ src/graphics/per_camera_node.hpp
|
||||
src/graphics/post_processing.hpp
|
||||
src/graphics/rain.hpp
|
||||
src/graphics/referee.hpp
|
||||
src/graphics/rtts.hpp
|
||||
src/graphics/screenquad.hpp
|
||||
src/graphics/shaders.hpp
|
||||
src/graphics/shadow.hpp
|
||||
src/graphics/shadow_importance.hpp
|
||||
src/graphics/show_curve.hpp
|
||||
src/graphics/skid_marks.hpp
|
||||
src/graphics/slip_stream.hpp
|
||||
src/graphics/stars.hpp
|
||||
src/graphics/sun.hpp
|
||||
src/graphics/water.hpp
|
||||
src/graphics/wind.hpp
|
||||
src/guiengine/abstract_state_manager.hpp
|
||||
src/guiengine/abstract_top_level_container.hpp
|
||||
src/guiengine/engine.hpp
|
||||
@ -499,6 +526,7 @@ src/tracks/track_object_presentation.hpp
|
||||
src/tracks/track_sector.hpp
|
||||
src/utils/aligned_array.hpp
|
||||
src/utils/constants.hpp
|
||||
src/utils/helpers.hpp
|
||||
src/utils/interpolation_array.hpp
|
||||
src/utils/crash_reporting.hpp
|
||||
src/utils/leak_check.hpp
|
||||
@ -512,4 +540,5 @@ src/utils/synchronised.hpp
|
||||
src/utils/time.hpp
|
||||
src/utils/translation.hpp
|
||||
src/utils/vec3.hpp
|
||||
src/utils/vs.hpp
|
||||
)
|
||||
|
@ -69,10 +69,14 @@ supertuxkart_SOURCES = \
|
||||
config/device_config.hpp \
|
||||
graphics/CBatchingMesh.cpp \
|
||||
graphics/CBatchingMesh.hpp \
|
||||
graphics/callbacks.cpp \
|
||||
graphics/callbacks.hpp \
|
||||
graphics/camera.cpp \
|
||||
graphics/camera.hpp \
|
||||
graphics/explosion.cpp \
|
||||
graphics/explosion.hpp \
|
||||
graphics/glow.cpp \
|
||||
graphics/glow.hpp \
|
||||
graphics/hardware_skinning.cpp \
|
||||
graphics/hardware_skinning.hpp \
|
||||
graphics/hit_effect.hpp \
|
||||
@ -80,6 +84,11 @@ supertuxkart_SOURCES = \
|
||||
graphics/hit_sfx.hpp \
|
||||
graphics/irr_driver.cpp \
|
||||
graphics/irr_driver.hpp \
|
||||
graphics/large_mesh_buffer.hpp \
|
||||
graphics/lens_flare.cpp \
|
||||
graphics/lens_flare.hpp \
|
||||
graphics/light.hpp \
|
||||
graphics/light.cpp \
|
||||
graphics/lod_node.cpp \
|
||||
graphics/lod_node.hpp \
|
||||
graphics/material.cpp \
|
||||
@ -102,10 +111,19 @@ supertuxkart_SOURCES = \
|
||||
graphics/post_processing.hpp \
|
||||
graphics/rain.cpp \
|
||||
graphics/rain.hpp \
|
||||
graphics/render.cpp \
|
||||
graphics/referee.cpp \
|
||||
graphics/referee.hpp \
|
||||
graphics/rtts.hpp \
|
||||
graphics/rtts.cpp \
|
||||
graphics/screenquad.cpp \
|
||||
graphics/screenquad.hpp \
|
||||
graphics/shaders.cpp \
|
||||
graphics/shaders.hpp \
|
||||
graphics/shadow.cpp \
|
||||
graphics/shadow.hpp \
|
||||
graphics/shadow_importance.cpp \
|
||||
graphics/shadow_importance.hpp \
|
||||
graphics/show_curve.cpp \
|
||||
graphics/show_curve.hpp \
|
||||
graphics/skid_marks.cpp \
|
||||
@ -114,6 +132,12 @@ supertuxkart_SOURCES = \
|
||||
graphics/slip_stream.hpp \
|
||||
graphics/stars.cpp \
|
||||
graphics/stars.hpp \
|
||||
graphics/sun.hpp \
|
||||
graphics/sun.cpp \
|
||||
graphics/water.hpp \
|
||||
graphics/water.cpp \
|
||||
graphics/wind.hpp \
|
||||
graphics/wind.cpp \
|
||||
guiengine/CGUISpriteBank.cpp \
|
||||
guiengine/CGUISpriteBank.h \
|
||||
guiengine/abstract_state_manager.cpp \
|
||||
@ -496,6 +520,8 @@ supertuxkart_SOURCES = \
|
||||
utils/aligned_array.hpp \
|
||||
utils/constants.hpp \
|
||||
utils/constants.cpp \
|
||||
utils/helpers.hpp \
|
||||
utils/helpers.cpp \
|
||||
utils/leak_check.cpp \
|
||||
utils/leak_check.hpp \
|
||||
utils/log.cpp \
|
||||
@ -518,7 +544,8 @@ supertuxkart_SOURCES = \
|
||||
utils/utf8/core.h \
|
||||
utils/utf8/unchecked.h \
|
||||
utils/vec3.cpp \
|
||||
utils/vec3.hpp
|
||||
utils/vec3.hpp \
|
||||
utils/vs.hpp
|
||||
|
||||
# Link in the specific gcc 4.1 bug work around
|
||||
supertuxkart_LDADD = \
|
||||
|
@ -24,14 +24,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
# include <windows.h>
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <sys/time.h>
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "addons/news_manager.hpp"
|
||||
#include "addons/request.hpp"
|
||||
@ -42,6 +35,7 @@
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/time.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Create a thread that handles all network functions independent of the
|
||||
|
@ -21,14 +21,10 @@
|
||||
#include "animations/ipo.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
|
||||
AnimationBase::AnimationBase(const XMLNode &node)
|
||||
|
@ -19,15 +19,11 @@
|
||||
#include "animations/ipo.hpp"
|
||||
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
const std::string Ipo::m_all_channel_names[IPO_MAX] =
|
||||
{"LocX", "LocY", "LocZ", "LocXYZ",
|
||||
|
@ -181,6 +181,13 @@ void STKConfig::init_defaults()
|
||||
m_disable_steer_while_unskid = false;
|
||||
m_camera_follow_skid = false;
|
||||
|
||||
m_nitro_glow_color[0] = 1.0f;
|
||||
m_nitro_glow_color[1] = 1.0f;
|
||||
m_nitro_glow_color[2] = 1.0f;
|
||||
m_box_glow_color[0] = 1.0f;
|
||||
m_box_glow_color[1] = 1.0f;
|
||||
m_box_glow_color[2] = 1.0f;
|
||||
|
||||
m_score_increase.clear();
|
||||
m_leader_intervals.clear();
|
||||
m_switch_items.clear();
|
||||
@ -362,6 +369,25 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
replay_node->get("delta-pos", &m_replay_delta_pos2 );
|
||||
replay_node->get("delta-t", &m_replay_dt );
|
||||
}
|
||||
|
||||
if(const XMLNode *colors = root->getNode("glow-colors"))
|
||||
{
|
||||
video::SColor tmpcol;
|
||||
if (colors->get("nitro", &tmpcol))
|
||||
{
|
||||
m_nitro_glow_color[0] = tmpcol.getRed() / 255.0f;
|
||||
m_nitro_glow_color[1] = tmpcol.getGreen() / 255.0f;
|
||||
m_nitro_glow_color[2] = tmpcol.getBlue() / 255.0f;
|
||||
}
|
||||
|
||||
if (colors->get("box", &tmpcol))
|
||||
{
|
||||
m_box_glow_color[0] = tmpcol.getRed() / 255.0f;
|
||||
m_box_glow_color[1] = tmpcol.getGreen() / 255.0f;
|
||||
m_box_glow_color[2] = tmpcol.getBlue() / 255.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the default KartProperties
|
||||
// ------------------------------
|
||||
const XMLNode *node = root -> getNode("general-kart-defaults");
|
||||
|
@ -148,6 +148,11 @@ public:
|
||||
* be generated. */
|
||||
float m_replay_delta_angle;
|
||||
|
||||
/** Colors for glows */
|
||||
float m_nitro_glow_color[3];
|
||||
|
||||
float m_box_glow_color[3];
|
||||
|
||||
private:
|
||||
/** True if stk_config has been loaded. This is necessary if the
|
||||
* --stk-config command line parameter has been specified to avoid
|
||||
|
@ -510,10 +510,6 @@ namespace UserConfigParams
|
||||
#define FBO_DEFAULT true
|
||||
#endif
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_fbo
|
||||
PARAM_DEFAULT( BoolUserConfigParam(FBO_DEFAULT, "fbo",
|
||||
&m_graphics_quality, "Use frame buffer objects (FBOs)") );
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_graphical_effects
|
||||
PARAM_DEFAULT( BoolUserConfigParam(true, "anim_gfx",
|
||||
&m_graphics_quality, "Scenery animations") );
|
||||
@ -552,11 +548,22 @@ namespace UserConfigParams
|
||||
PARAM_DEFAULT( BoolUserConfigParam(true, "pixel_shaders",
|
||||
&m_graphics_quality,
|
||||
"Whether to enable pixel shaders (splatting, normal maps, ...)") );
|
||||
PARAM_PREFIX BoolUserConfigParam m_postprocess_enabled
|
||||
PARAM_PREFIX BoolUserConfigParam m_motionblur
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false,
|
||||
"postprocess_enabled", &m_graphics_quality,
|
||||
"Whether post-processing (motion blur...) should "
|
||||
"be enabled") );
|
||||
"motionblur_enabled", &m_graphics_quality,
|
||||
"Whether motion blur should be enabled") );
|
||||
PARAM_PREFIX BoolUserConfigParam m_mlaa
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false,
|
||||
"mlaa", &m_graphics_quality,
|
||||
"Whether MLAA should be enabled") );
|
||||
PARAM_PREFIX IntUserConfigParam m_ssao
|
||||
PARAM_DEFAULT( IntUserConfigParam(0,
|
||||
"ssao", &m_graphics_quality,
|
||||
"Whether SSAO is enabled (0 = disabled, 1 = low, 2 = high") );
|
||||
PARAM_PREFIX IntUserConfigParam m_shadows
|
||||
PARAM_DEFAULT( IntUserConfigParam(0,
|
||||
"shadows", &m_graphics_quality,
|
||||
"Whether shadows are enabled (0 = disabled, 1 = low, 2 = high") );
|
||||
|
||||
// ---- Misc
|
||||
PARAM_PREFIX BoolUserConfigParam m_cache_overworld
|
||||
|
775
src/graphics/callbacks.cpp
Normal file
775
src/graphics/callbacks.cpp
Normal file
@ -0,0 +1,775 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/helpers.hpp"
|
||||
|
||||
using namespace video;
|
||||
using namespace core;
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void NormalMapProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
s32 decaltex = 0;
|
||||
srv->setPixelShaderConstant("DecalTex", &decaltex, 1);
|
||||
|
||||
s32 bumptex = 1;
|
||||
srv->setPixelShaderConstant("BumpTex", &bumptex, 1);
|
||||
|
||||
s32 lightmapTex = (m_with_lightmap ? 2 : 0);
|
||||
srv->setPixelShaderConstant("LightMapTex", &lightmapTex, 1);
|
||||
|
||||
s32 hasLightMap = (m_with_lightmap ? 1 : 0);
|
||||
srv->setPixelShaderConstant("HasLightMap", &hasLightMap, 1);
|
||||
|
||||
// We could calculate light direction as coming from the sun (then we'd need to
|
||||
// transform it into camera space). But I find that pretending light
|
||||
// comes from the camera gives good results
|
||||
const float lightdir[] = {0.1852f, -0.1852f, -0.9259f};
|
||||
srv->setVertexShaderConstant("lightdir", lightdir, 3);
|
||||
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void WaterShaderProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
|
||||
float strength = time;
|
||||
strength = 1.4f - fabsf(noise2d(strength / 30.0f + 133)) * 0.8f;
|
||||
|
||||
m_dx_1 += GUIEngine::getLatestDt() * m_water_shader_speed_1 * strength;
|
||||
m_dy_1 += GUIEngine::getLatestDt() * m_water_shader_speed_1 * strength;
|
||||
|
||||
m_dx_2 += GUIEngine::getLatestDt() * m_water_shader_speed_2 * strength;
|
||||
m_dy_2 -= GUIEngine::getLatestDt() * m_water_shader_speed_2 * strength;
|
||||
|
||||
if (m_dx_1 > 1.0f) m_dx_1 -= 1.0f;
|
||||
if (m_dy_1 > 1.0f) m_dy_1 -= 1.0f;
|
||||
if (m_dx_2 > 1.0f) m_dx_2 -= 1.0f;
|
||||
if (m_dy_2 < 0.0f) m_dy_2 += 1.0f;
|
||||
|
||||
const float d1[2] = { m_dx_1, m_dy_1 };
|
||||
const float d2[2] = { m_dx_2, m_dy_2 };
|
||||
|
||||
srv->setVertexShaderConstant("delta1", d1, 2);
|
||||
srv->setVertexShaderConstant("delta2", d2, 2);
|
||||
|
||||
const float speed = irr_driver->getDevice()->getTimer()->getTime() / m_speed;
|
||||
const float height = m_height * strength;
|
||||
|
||||
srv->setVertexShaderConstant("height", &height, 1);
|
||||
srv->setVertexShaderConstant("speed", &speed, 1);
|
||||
srv->setVertexShaderConstant("length", &m_length, 1);
|
||||
|
||||
// Can't use the firstdone optimization, as the callback is shared
|
||||
//if (!firstdone)
|
||||
{
|
||||
s32 decaltex = 0;
|
||||
srv->setPixelShaderConstant("DecalTex", &decaltex, 1);
|
||||
|
||||
s32 bumptex = 1;
|
||||
srv->setPixelShaderConstant("BumpTex1", &bumptex, 1);
|
||||
|
||||
bumptex = 2;
|
||||
srv->setPixelShaderConstant("BumpTex2", &bumptex, 1);
|
||||
|
||||
// Calculate light direction as coming from the sun.
|
||||
matrix4 normalm = srv->getVideoDriver()->getTransform(ETS_VIEW);
|
||||
normalm.makeInverse();
|
||||
normalm = normalm.getTransposed();
|
||||
vector3df tmp = m_sunpos;
|
||||
normalm.transformVect(tmp);
|
||||
tmp.normalize();
|
||||
|
||||
const float lightdir[] = {tmp.X, tmp.Y, tmp.Z};
|
||||
srv->setVertexShaderConstant("lightdir", lightdir, 3);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void GrassShaderProvider::OnSetConstants(IMaterialRendererServices *srv, int userData)
|
||||
{
|
||||
IVideoDriver * const drv = srv->getVideoDriver();
|
||||
const core::vector3df pos = drv->getTransform(ETS_WORLD).getTranslation();
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
|
||||
float strength = (pos.X + pos.Y + pos.Z) * 1.2f + time * m_speed;
|
||||
strength = noise2d(strength / 10.0f) * m_amplitude * 5;
|
||||
// * 5 is to work with the existing amplitude values.
|
||||
|
||||
// Pre-multiply on the cpu
|
||||
vector3df wind = irr_driver->getWind() * strength;
|
||||
|
||||
srv->setVertexShaderConstant("windDir", &wind.X, 3);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
s32 tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void SplattingProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float camfar = irr_driver->getSceneManager()->getActiveCamera()->getFarValue();
|
||||
srv->setVertexShaderConstant("far", &camfar, 1);
|
||||
|
||||
// The normal is transformed by the inverse transposed world matrix
|
||||
// because we want world-space normals
|
||||
matrix4 invtworldm = irr_driver->getVideoDriver()->getTransform(ETS_WORLD);
|
||||
invtworldm.makeInverse();
|
||||
invtworldm = invtworldm.getTransposed();
|
||||
|
||||
srv->setVertexShaderConstant("invtworldm", invtworldm.pointer(), 16);
|
||||
|
||||
float objectid = 0;
|
||||
const stringc name = mat.TextureLayer[0].Texture->getName().getPath();
|
||||
objectid = shash8((const u8 *) name.c_str(), name.size()) / 255.0f;
|
||||
srv->setVertexShaderConstant("objectid", &objectid, 1);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
s32 tex_layout = 1;
|
||||
srv->setPixelShaderConstant("tex_layout", &tex_layout, 1);
|
||||
|
||||
s32 tex_detail0 = 2;
|
||||
srv->setPixelShaderConstant("tex_detail0", &tex_detail0, 1);
|
||||
|
||||
s32 tex_detail1 = 3;
|
||||
srv->setPixelShaderConstant("tex_detail1", &tex_detail1, 1);
|
||||
|
||||
s32 tex_detail2 = 4;
|
||||
srv->setPixelShaderConstant("tex_detail2", &tex_detail2, 1);
|
||||
|
||||
s32 tex_detail3 = 5;
|
||||
srv->setPixelShaderConstant("tex_detail3", &tex_detail3, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void BubbleEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float start = fabsf(mat.MaterialTypeParam2);
|
||||
const bool visible = mat.MaterialTypeParam2 > 0;
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
float transparency;
|
||||
|
||||
const float diff = (time - start) / 3.0f;
|
||||
|
||||
if (visible)
|
||||
{
|
||||
transparency = diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
transparency = 1.0 - diff;
|
||||
}
|
||||
|
||||
transparency = clampf(transparency, 0, 1);
|
||||
|
||||
srv->setVertexShaderConstant("time", &time, 1);
|
||||
srv->setVertexShaderConstant("transparency", &transparency, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void RainEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float screenw = UserConfigParams::m_width;
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f;
|
||||
const matrix4 viewm = srv->getVideoDriver()->getTransform(ETS_VIEW);
|
||||
const vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition();
|
||||
|
||||
srv->setVertexShaderConstant("screenw", &screenw, 1);
|
||||
srv->setVertexShaderConstant("time", &time, 1);
|
||||
srv->setVertexShaderConstant("viewm", viewm.pointer(), 16);
|
||||
srv->setVertexShaderConstant("campos", &campos.X, 3);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void SnowEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
|
||||
srv->setVertexShaderConstant("time", &time, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MotionBlurProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
// We need the maximum texture coordinates:
|
||||
float max_tex_height = m_maxheight[m_current_camera];
|
||||
srv->setPixelShaderConstant("max_tex_height", &max_tex_height, 1);
|
||||
|
||||
// Scale the boost time to get a usable boost amount:
|
||||
float boost_amount = m_boost_time[m_current_camera] * 0.7f;
|
||||
|
||||
// Especially for single screen the top of the screen is less blurred
|
||||
// in the fragment shader by multiplying the blurr factor by
|
||||
// (max_tex_height - texcoords.t), where max_tex_height is the maximum
|
||||
// texture coordinate (1.0 or 0.5). In split screen this factor is too
|
||||
// small (half the value compared with non-split screen), so we
|
||||
// multiply this by 2.
|
||||
if(Camera::getNumCameras() > 1)
|
||||
boost_amount *= 2.0f;
|
||||
|
||||
srv->setPixelShaderConstant("boost_amount", &boost_amount, 1);
|
||||
srv->setPixelShaderConstant("center",
|
||||
&(m_center[m_current_camera].X), 2);
|
||||
srv->setPixelShaderConstant("direction",
|
||||
&(m_direction[m_current_camera].X), 2);
|
||||
|
||||
// Use a radius of 0.15 when showing a single kart, otherwise (2-4 karts
|
||||
// on splitscreen) use only 0.75.
|
||||
float radius = Camera::getNumCameras()==1 ? 0.15f : 0.075f;
|
||||
srv->setPixelShaderConstant("mask_radius", &radius, 1);
|
||||
|
||||
const int texunit = 0;
|
||||
srv->setPixelShaderConstant("color_buffer", &texunit, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void GaussianBlurProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("pixel", m_pixel, 2);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MipVizProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const ITexture * const tex = mat.TextureLayer[0].Texture;
|
||||
|
||||
const int notex = (mat.TextureLayer[0].Texture == NULL);
|
||||
srv->setVertexShaderConstant("notex", ¬ex, 1);
|
||||
if (!tex) return;
|
||||
|
||||
const dimension2du size = tex->getSize();
|
||||
|
||||
const float texsize[2] = {
|
||||
size.Width,
|
||||
size.Height
|
||||
};
|
||||
|
||||
srv->setVertexShaderConstant("texsize", texsize, 2);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ColorizeProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("col", m_color, 3);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void GlowProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("res", m_res, 2);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ObjectPassProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float camfar = irr_driver->getSceneManager()->getActiveCamera()->getFarValue();
|
||||
srv->setVertexShaderConstant("far", &camfar, 1);
|
||||
|
||||
// The normal is transformed by the inverse transposed world matrix
|
||||
// because we want world-space normals
|
||||
matrix4 invtworldm = irr_driver->getVideoDriver()->getTransform(ETS_WORLD);
|
||||
invtworldm.makeInverse();
|
||||
invtworldm = invtworldm.getTransposed();
|
||||
|
||||
srv->setVertexShaderConstant("invtworldm", invtworldm.pointer(), 16);
|
||||
|
||||
const int hastex = mat.TextureLayer[0].Texture != NULL;
|
||||
srv->setVertexShaderConstant("hastex", &hastex, 1);
|
||||
|
||||
const int haslightmap = mat.TextureLayer[1].Texture != NULL;
|
||||
srv->setVertexShaderConstant("haslightmap", &haslightmap, 1);
|
||||
|
||||
float objectid = 0;
|
||||
if (hastex)
|
||||
{
|
||||
const stringc name = mat.TextureLayer[0].Texture->getName().getPath();
|
||||
objectid = shash8((const u8 *) name.c_str(), name.size()) / 255.0f;
|
||||
}
|
||||
srv->setVertexShaderConstant("objectid", &objectid, 1);
|
||||
|
||||
//if (!firstdone)
|
||||
// Can't use the firstdone optimization, as this callback is used for multiple shaders
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("lighttex", &tex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void LightBlendProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const SColorf s = irr_driver->getSceneManager()->getAmbientLight();
|
||||
|
||||
float ambient[3] = { s.r, s.g, s.b };
|
||||
srv->setVertexShaderConstant("ambient", ambient, 3);
|
||||
|
||||
int spectex = 1;
|
||||
srv->setVertexShaderConstant("spectex", &spectex, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void PointLightProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("screen", m_screen, 2);
|
||||
srv->setVertexShaderConstant("spec", &m_specular, 1);
|
||||
srv->setVertexShaderConstant("col", m_color, 3);
|
||||
srv->setVertexShaderConstant("campos", m_campos, 3);
|
||||
srv->setVertexShaderConstant("center", m_pos, 3);
|
||||
srv->setVertexShaderConstant("r", &m_radius, 1);
|
||||
srv->setVertexShaderConstant("invprojview", m_invprojview.pointer(), 16);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("ntex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("dtex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void SunLightProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const int hasclouds = World::getWorld()->getTrack()->hasClouds() &&
|
||||
UserConfigParams::m_weather_effects;
|
||||
|
||||
srv->setVertexShaderConstant("screen", m_screen, 2);
|
||||
srv->setVertexShaderConstant("col", m_color, 3);
|
||||
srv->setVertexShaderConstant("center", m_pos, 3);
|
||||
srv->setVertexShaderConstant("invprojview", m_invprojview.pointer(), 16);
|
||||
srv->setVertexShaderConstant("hasclouds", &hasclouds, 1);
|
||||
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
|
||||
float strength = time;
|
||||
strength = fabsf(noise2d(strength / 10.0f)) * 0.003f;
|
||||
|
||||
const vector3df winddir = irr_driver->getWind() * strength;
|
||||
m_wind[0] += winddir.X;
|
||||
m_wind[1] += winddir.Z;
|
||||
srv->setVertexShaderConstant("wind", m_wind, 2);
|
||||
|
||||
if (UserConfigParams::m_shadows)
|
||||
{
|
||||
srv->setVertexShaderConstant("shadowmat", m_shadowmat.pointer(), 16);
|
||||
}
|
||||
|
||||
// Can't use the firstdone optimization, as this callback is used for multiple shaders
|
||||
//if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("ntex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("dtex", &tex, 1);
|
||||
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("cloudtex", &tex, 1);
|
||||
|
||||
tex = 3;
|
||||
srv->setVertexShaderConstant("shadowtex", &tex, 1);
|
||||
|
||||
tex = 4;
|
||||
srv->setVertexShaderConstant("warpx", &tex, 1);
|
||||
|
||||
tex = 5;
|
||||
srv->setVertexShaderConstant("warpy", &tex, 1);
|
||||
|
||||
const float shadowoffset = 1.0f / irr_driver->getRTT(RTT_SHADOW)->getSize().Width;
|
||||
srv->setVertexShaderConstant("shadowoffset", &shadowoffset, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void BloomProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("low", &m_threshold, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MLAAColor1Provider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
const float pixels[2] = {
|
||||
1.0f / UserConfigParams::m_width,
|
||||
1.0f / UserConfigParams::m_height
|
||||
};
|
||||
|
||||
srv->setPixelShaderConstant("PIXEL_SIZE", pixels, 2);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MLAABlend2Provider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
const float pixels[2] = {
|
||||
1.0f / UserConfigParams::m_width,
|
||||
1.0f / UserConfigParams::m_height
|
||||
};
|
||||
|
||||
srv->setPixelShaderConstant("PIXEL_SIZE", pixels, 2);
|
||||
|
||||
|
||||
int tex = 0;
|
||||
srv->setPixelShaderConstant("edgesMap", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setPixelShaderConstant("areaMap", &tex, 1);
|
||||
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MLAANeigh3Provider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
const float pixels[2] = {
|
||||
1.0f / UserConfigParams::m_width,
|
||||
1.0f / UserConfigParams::m_height
|
||||
};
|
||||
|
||||
srv->setPixelShaderConstant("PIXEL_SIZE", pixels, 2);
|
||||
|
||||
|
||||
int tex = 0;
|
||||
srv->setPixelShaderConstant("blendMap", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setPixelShaderConstant("colorMap", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void SSAOProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setPixelShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setPixelShaderConstant("oldtex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void GodRayProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setPixelShaderConstant("sunpos", m_sunpos, 2);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ShadowPassProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const int hastex = mat.TextureLayer[0].Texture != NULL;
|
||||
srv->setVertexShaderConstant("hastex", &hastex, 1);
|
||||
|
||||
int viz = irr_driver->getShadowViz();
|
||||
srv->setVertexShaderConstant("viz", &viz, 1);
|
||||
|
||||
int wireframe = mat.Wireframe;
|
||||
srv->setVertexShaderConstant("wireframe", &wireframe, 1);
|
||||
|
||||
float objectid = 0;
|
||||
if (hastex)
|
||||
{
|
||||
const stringc name = mat.TextureLayer[0].Texture->getName().getPath();
|
||||
objectid = shash8((const u8 *) name.c_str(), name.size()) / 255.0f;
|
||||
}
|
||||
srv->setVertexShaderConstant("objectid", &objectid, 1);
|
||||
|
||||
//if (!firstdone)
|
||||
// Can't use the firstdone optimization, as this callback is used for multiple shaders
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("warpx", &tex, 1);
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("warpy", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ShadowImportanceProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("shadowmat", m_shadowmat.pointer(), 16);
|
||||
srv->setVertexShaderConstant("ipvmat", m_invprojview.pointer(), 16);
|
||||
|
||||
srv->setVertexShaderConstant("campos", m_campos, 3);
|
||||
|
||||
int low = UserConfigParams::m_shadows == 1;
|
||||
srv->setVertexShaderConstant("low", &low, 1);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("ntex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("dtex", &tex, 1);
|
||||
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("ctex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CollapseProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("pixel", m_pixel, 2);
|
||||
srv->setVertexShaderConstant("multi", m_multi, 2);
|
||||
srv->setVertexShaderConstant("size", &m_size, 1);
|
||||
|
||||
//if (!firstdone)
|
||||
// Can't use the firstdone optimization, as this callback is used for multiple shaders
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("oldtex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void BloomPowerProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("power", &m_power, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MultiplyProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex1", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("tex2", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ShadowGenProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("halft", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("quarter", &tex, 1);
|
||||
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("eighth", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CausticsProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
const float speed = World::getWorld()->getTrack()->getCausticsSpeed();
|
||||
|
||||
float strength = time;
|
||||
strength = fabsf(noise2d(strength / 10.0f)) * 0.006f + 0.001f;
|
||||
|
||||
vector3df wind = irr_driver->getWind() * strength * speed;
|
||||
m_dir[0] += wind.X;
|
||||
m_dir[1] += wind.Z;
|
||||
|
||||
strength = time * 0.56f + sinf(time);
|
||||
strength = fabsf(noise2d(0.0, strength / 6.0f)) * 0.0095f + 0.001f;
|
||||
|
||||
wind = irr_driver->getWind() * strength * speed;
|
||||
wind.rotateXZBy(cosf(time));
|
||||
m_dir2[0] += wind.X;
|
||||
m_dir2[1] += wind.Z;
|
||||
|
||||
srv->setVertexShaderConstant("dir", m_dir, 2);
|
||||
srv->setVertexShaderConstant("dir2", m_dir2, 2);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("caustictex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void DisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
const float speed = World::getWorld()->getTrack()->getDisplacementSpeed();
|
||||
|
||||
float strength = time;
|
||||
strength = fabsf(noise2d(strength / 10.0f)) * 0.006f + 0.002f;
|
||||
|
||||
vector3df wind = irr_driver->getWind() * strength * speed;
|
||||
m_dir[0] += wind.X;
|
||||
m_dir[1] += wind.Z;
|
||||
|
||||
strength = time * 0.56f + sinf(time);
|
||||
strength = fabsf(noise2d(0.0, strength / 6.0f)) * 0.0095f + 0.0025f;
|
||||
|
||||
wind = irr_driver->getWind() * strength * speed;
|
||||
wind.rotateXZBy(cosf(time));
|
||||
m_dir2[0] += wind.X;
|
||||
m_dir2[1] += wind.Z;
|
||||
|
||||
srv->setVertexShaderConstant("dir", m_dir, 2);
|
||||
srv->setVertexShaderConstant("dir2", m_dir2, 2);
|
||||
|
||||
srv->setVertexShaderConstant("screen", m_screen, 2);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void PPDisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
int viz = irr_driver->getDistortViz();
|
||||
srv->setPixelShaderConstant("viz", &viz, 1);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setPixelShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setPixelShaderConstant("dtex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void FogProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const Track * const track = World::getWorld()->getTrack();
|
||||
|
||||
// This function is only called once per frame - thus no need for setters.
|
||||
const float fogmax = track->getFogMax();
|
||||
const float startH = track->getFogStartHeight();
|
||||
const float endH = track->getFogEndHeight();
|
||||
const float start = track->getFogStart();
|
||||
const float end = track->getFogEnd();
|
||||
const SColor tmpcol = track->getFogColor();
|
||||
|
||||
const float col[3] = { tmpcol.getRed() / 255.0f,
|
||||
tmpcol.getGreen() / 255.0f,
|
||||
tmpcol.getBlue() / 255.0f };
|
||||
|
||||
srv->setPixelShaderConstant("fogmax", &fogmax, 1);
|
||||
srv->setPixelShaderConstant("startH", &startH, 1);
|
||||
srv->setPixelShaderConstant("endH", &endH, 1);
|
||||
srv->setPixelShaderConstant("start", &start, 1);
|
||||
srv->setPixelShaderConstant("end", &end, 1);
|
||||
srv->setPixelShaderConstant("col", col, 3);
|
||||
srv->setVertexShaderConstant("ipvmat", m_invprojview.pointer(), 16);
|
||||
srv->setVertexShaderConstant("campos", m_campos, 3);
|
||||
}
|
712
src/graphics/callbacks.hpp
Normal file
712
src/graphics/callbacks.hpp
Normal file
@ -0,0 +1,712 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_CALLBACKS_HPP
|
||||
#define HEADER_CALLBACKS_HPP
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
|
||||
#include <IShaderConstantSetCallBack.h>
|
||||
#include <SMaterial.h>
|
||||
#include <ISceneManager.h>
|
||||
#include <ICameraSceneNode.h>
|
||||
#include <IMaterialRendererServices.h>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
class CallBase: public video::IShaderConstantSetCallBack
|
||||
{
|
||||
public:
|
||||
CallBase()
|
||||
{
|
||||
firstdone = 0;
|
||||
}
|
||||
|
||||
virtual void OnSetMaterial(const video::SMaterial &material)
|
||||
{
|
||||
mat = material;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool firstdone;
|
||||
video::SMaterial mat;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class NormalMapProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
NormalMapProvider(bool withLightmap)
|
||||
{
|
||||
m_with_lightmap = withLightmap;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_with_lightmap;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class WaterShaderProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setSpeed(const float s1, const float s2)
|
||||
{
|
||||
m_water_shader_speed_1 = s1;
|
||||
m_water_shader_speed_2 = s2;
|
||||
}
|
||||
|
||||
WaterShaderProvider()
|
||||
{
|
||||
m_dx_1 = 0.0f;
|
||||
m_dx_2 = 0.0f;
|
||||
m_dy_1 = 0.0f;
|
||||
m_dy_2 = 0.0f;
|
||||
|
||||
m_water_shader_speed_1 =
|
||||
m_water_shader_speed_2 = 0.0f;
|
||||
}
|
||||
|
||||
void setSunPosition(const core::vector3df &in)
|
||||
{
|
||||
m_sunpos = in;
|
||||
m_sunpos.normalize();
|
||||
}
|
||||
|
||||
void setSpeed(float speed) { m_speed = speed; }
|
||||
void setHeight(float height) { m_height = height; }
|
||||
void setLength(float length) { m_length = length; }
|
||||
|
||||
private:
|
||||
core::vector3df m_sunpos;
|
||||
|
||||
float m_dx_1, m_dy_1, m_dx_2, m_dy_2;
|
||||
float m_water_shader_speed_1;
|
||||
float m_water_shader_speed_2;
|
||||
|
||||
float m_speed;
|
||||
float m_height;
|
||||
float m_length;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class GrassShaderProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
GrassShaderProvider()
|
||||
{
|
||||
m_amplitude =
|
||||
m_speed = 0.0f;
|
||||
}
|
||||
|
||||
void setSpeed(float speed)
|
||||
{
|
||||
m_speed = speed;
|
||||
}
|
||||
|
||||
void setAmplitude(float amp)
|
||||
{
|
||||
m_amplitude = amp;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_amplitude, m_speed;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class SplattingProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class BubbleEffectProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
BubbleEffectProvider()
|
||||
{
|
||||
}
|
||||
|
||||
// We hijack the material type param 2 of bubbles.
|
||||
// It's time to start the fade, negative if fade out, positive if in.
|
||||
// It'd be unused otherwise.
|
||||
|
||||
void onMadeVisible(scene::IMeshBuffer * const mb)
|
||||
{
|
||||
if (!contains(mb))
|
||||
return;
|
||||
|
||||
video::SMaterial &mat = mb->getMaterial();
|
||||
mat.MaterialTypeParam2 = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
}
|
||||
|
||||
void onHidden(scene::IMeshBuffer * const mb)
|
||||
{
|
||||
if (!contains(mb))
|
||||
return;
|
||||
|
||||
video::SMaterial &mat = mb->getMaterial();
|
||||
mat.MaterialTypeParam2 = irr_driver->getDevice()->getTimer()->getTime() / -1000.0f;
|
||||
}
|
||||
|
||||
void isInitiallyHidden(scene::IMeshBuffer * const mb)
|
||||
{
|
||||
if (!contains(mb))
|
||||
return;
|
||||
|
||||
video::SMaterial &mat = mb->getMaterial();
|
||||
mat.MaterialTypeParam2 = irr_driver->getDevice()->getTimer()->getTime() / -1000.0f;
|
||||
}
|
||||
|
||||
void removeBubble(const scene::IMeshBuffer * const mb)
|
||||
{
|
||||
m_bubbles.erase(mb);
|
||||
}
|
||||
|
||||
void addBubble(scene::IMeshBuffer * const mb)
|
||||
{
|
||||
m_bubbles.insert(mb);
|
||||
|
||||
video::SMaterial &mat = mb->getMaterial();
|
||||
mat.MaterialTypeParam2 = 1;
|
||||
}
|
||||
|
||||
bool contains(const scene::IMeshBuffer * const mb) const
|
||||
{
|
||||
return m_bubbles.count(mb);
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<const scene::IMeshBuffer *> m_bubbles;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class RainEffectProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class SnowEffectProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MotionBlurProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setMaxHeight(u32 who, float height)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
m_maxheight[who] = height;
|
||||
}
|
||||
|
||||
void setBoostTime(u32 who, float time)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
m_boost_time[who] = time;
|
||||
}
|
||||
|
||||
void setCenter(u32 who, float X, float Y)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
m_center[who].X = X;
|
||||
m_center[who].Y = Y;
|
||||
}
|
||||
|
||||
void setDirection(u32 who, float X, float Y)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
m_direction[who].X = X;
|
||||
m_direction[who].Y = Y;
|
||||
}
|
||||
|
||||
void setCurrentCamera(u32 who)
|
||||
{
|
||||
m_current_camera = who;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_maxheight[MAX_PLAYER_COUNT];
|
||||
u32 m_current_camera;
|
||||
float m_boost_time[MAX_PLAYER_COUNT];
|
||||
core::vector2df m_center[MAX_PLAYER_COUNT];
|
||||
core::vector2df m_direction[MAX_PLAYER_COUNT];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class GaussianBlurProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
GaussianBlurProvider()
|
||||
{
|
||||
m_pixel[0] = 1.0f / UserConfigParams::m_width;
|
||||
m_pixel[1] = 1.0f / UserConfigParams::m_height;
|
||||
}
|
||||
|
||||
void setResolution(float x, float y)
|
||||
{
|
||||
m_pixel[0] = 1.0f / x;
|
||||
m_pixel[1] = 1.0f / y;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
private:
|
||||
float m_pixel[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MipVizProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ColorizeProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setColor(float r, float g, float b)
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_color[3];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class GlowProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setResolution(float x, float y)
|
||||
{
|
||||
m_res[0] = x;
|
||||
m_res[1] = y;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_res[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ObjectPassProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class LightBlendProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class PointLightProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
PointLightProvider()
|
||||
{
|
||||
m_screen[0] = UserConfigParams::m_width;
|
||||
m_screen[1] = UserConfigParams::m_height;
|
||||
|
||||
m_specular = 200;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setColor(float r, float g, float b)
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
}
|
||||
|
||||
void setPosition(float x, float y, float z)
|
||||
{
|
||||
m_pos[0] = x;
|
||||
m_pos[1] = y;
|
||||
m_pos[2] = z;
|
||||
}
|
||||
|
||||
void setRadius(float r)
|
||||
{
|
||||
m_radius = r;
|
||||
}
|
||||
|
||||
void setSpecular(float s)
|
||||
{
|
||||
m_specular = s;
|
||||
}
|
||||
|
||||
void updateIPVMatrix()
|
||||
{
|
||||
// Update the campos and IPV matrix, only once per frame since it's costly
|
||||
const core::vector3df &campos =
|
||||
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
|
||||
m_campos[0] = campos.X;
|
||||
m_campos[1] = campos.Y;
|
||||
m_campos[2] = campos.Z;
|
||||
|
||||
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
m_invprojview = drv->getTransform(video::ETS_PROJECTION);
|
||||
m_invprojview *= drv->getTransform(video::ETS_VIEW);
|
||||
m_invprojview.makeInverse();
|
||||
}
|
||||
|
||||
private:
|
||||
core::matrix4 m_invprojview;
|
||||
|
||||
float m_campos[3];
|
||||
float m_color[3];
|
||||
float m_pos[3];
|
||||
float m_screen[2];
|
||||
float m_radius;
|
||||
float m_specular;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class SunLightProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
SunLightProvider()
|
||||
{
|
||||
m_screen[0] = UserConfigParams::m_width;
|
||||
m_screen[1] = UserConfigParams::m_height;
|
||||
|
||||
m_wind[0] = m_wind[1] = 0;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setColor(float r, float g, float b)
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
}
|
||||
|
||||
void setPosition(float x, float y, float z)
|
||||
{
|
||||
m_pos[0] = x;
|
||||
m_pos[1] = y;
|
||||
m_pos[2] = z;
|
||||
}
|
||||
|
||||
void updateIPVMatrix()
|
||||
{
|
||||
// Update the IPV matrix, only once per frame since it's costly
|
||||
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
m_invprojview = drv->getTransform(video::ETS_PROJECTION);
|
||||
m_invprojview *= drv->getTransform(video::ETS_VIEW);
|
||||
m_invprojview.makeInverse();
|
||||
}
|
||||
|
||||
void setShadowMatrix(const core::matrix4 &mat)
|
||||
{
|
||||
m_shadowmat = mat;
|
||||
}
|
||||
|
||||
private:
|
||||
core::matrix4 m_invprojview, m_shadowmat;
|
||||
float m_color[3];
|
||||
float m_pos[3];
|
||||
float m_screen[2];
|
||||
float m_wind[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class BloomProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
BloomProvider() { m_threshold = 0.75f; }
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setThreshold(const float f) { m_threshold = f; }
|
||||
|
||||
private:
|
||||
float m_threshold;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MLAAColor1Provider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MLAABlend2Provider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MLAANeigh3Provider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class SSAOProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class GodRayProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
// In texcoords
|
||||
void setSunPosition(float x, float y) { m_sunpos[0] = x; m_sunpos[1] = y; }
|
||||
|
||||
private:
|
||||
float m_sunpos[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ShadowPassProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ShadowImportanceProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void updateIPVMatrix()
|
||||
{
|
||||
// Update the IPV matrix, only once per frame since it's costly
|
||||
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
const core::vector3df &campos =
|
||||
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
|
||||
m_campos[0] = campos.X;
|
||||
m_campos[1] = campos.Y;
|
||||
m_campos[2] = campos.Z;
|
||||
|
||||
m_invprojview = drv->getTransform(video::ETS_PROJECTION);
|
||||
m_invprojview *= drv->getTransform(video::ETS_VIEW);
|
||||
m_invprojview.makeInverse();
|
||||
}
|
||||
|
||||
void setShadowMatrix(const core::matrix4 &mat)
|
||||
{
|
||||
m_shadowmat = mat;
|
||||
}
|
||||
|
||||
private:
|
||||
core::matrix4 m_invprojview, m_shadowmat;
|
||||
float m_campos[3];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class CollapseProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setResolution(const float x, const float y)
|
||||
{
|
||||
m_pixel[0] = 1.0f / x;
|
||||
m_pixel[1] = 1.0f / y;
|
||||
|
||||
m_multi[0] = m_multi[1] = 1;
|
||||
|
||||
if (x < 2 || y < 2)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
// No increase for the other direction
|
||||
if (m_pixel[i] > 0.9f) m_pixel[i] = m_multi[i] = 0;
|
||||
}
|
||||
|
||||
std::swap(m_multi[0], m_multi[1]);
|
||||
}
|
||||
|
||||
m_size = std::max(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
float m_pixel[2];
|
||||
int m_size;
|
||||
float m_multi[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class BloomPowerProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setPower(float power)
|
||||
{
|
||||
m_power = power / 10.0f;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_power;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MultiplyProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ShadowGenProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class CausticsProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
CausticsProvider() { m_dir[0] = m_dir[1] = m_dir2[0] = m_dir2[1] = 0; }
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
private:
|
||||
float m_dir[2], m_dir2[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class DisplaceProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
DisplaceProvider()
|
||||
{
|
||||
m_screen[0] = UserConfigParams::m_width;
|
||||
m_screen[1] = UserConfigParams::m_height;
|
||||
|
||||
m_dir[0] = m_dir[1] = m_dir2[0] = m_dir2[1] = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_screen[2];
|
||||
float m_dir[2], m_dir2[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class PPDisplaceProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class FogProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void updateIPVMatrix()
|
||||
{
|
||||
// Update the campos and IPV matrix, only once per frame since it's costly
|
||||
const core::vector3df &campos =
|
||||
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
|
||||
m_campos[0] = campos.X;
|
||||
m_campos[1] = campos.Y;
|
||||
m_campos[2] = campos.Z;
|
||||
|
||||
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
m_invprojview = drv->getTransform(video::ETS_PROJECTION);
|
||||
m_invprojview *= drv->getTransform(video::ETS_VIEW);
|
||||
m_invprojview.makeInverse();
|
||||
}
|
||||
|
||||
private:
|
||||
core::matrix4 m_invprojview;
|
||||
float m_campos[3];
|
||||
};
|
||||
|
||||
#endif
|
@ -19,11 +19,7 @@
|
||||
|
||||
#include "graphics/camera.hpp"
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "audio/music_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
@ -40,6 +36,7 @@
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/aligned_array.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#include "ICameraSceneNode.h"
|
||||
#include "ISceneManager.h"
|
||||
|
85
src/graphics/glow.cpp
Normal file
85
src/graphics/glow.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Lauri Kasanen
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "graphics/glow.hpp"
|
||||
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
|
||||
using namespace video;
|
||||
using namespace scene;
|
||||
using namespace core;
|
||||
|
||||
IMesh * GlowNode::sphere = NULL;
|
||||
SMaterial GlowNode::mat;
|
||||
aabbox3df GlowNode::box;
|
||||
|
||||
|
||||
GlowNode::GlowNode(scene::ISceneManager* mgr, float radius): ISceneNode(mgr->getRootSceneNode(), mgr, -1)
|
||||
{
|
||||
if (!sphere)
|
||||
{
|
||||
mat.Lighting = false;
|
||||
mat.MaterialType = irr_driver->getShader(ES_GLOW);
|
||||
|
||||
mat.setTexture(0, irr_driver->getRTT(RTT_QUARTER1));
|
||||
mat.TextureLayer[0].TextureWrapU =
|
||||
mat.TextureLayer[0].TextureWrapV = ETC_CLAMP_TO_EDGE;
|
||||
mat.setFlag(EMF_TRILINEAR_FILTER, true);
|
||||
mat.BlendOperation = EBO_ADD;
|
||||
|
||||
sphere = mgr->getGeometryCreator()->createSphereMesh(1, 4, 4);
|
||||
box = sphere->getBoundingBox();
|
||||
}
|
||||
|
||||
setScale(vector3df(radius));
|
||||
}
|
||||
|
||||
GlowNode::~GlowNode()
|
||||
{
|
||||
}
|
||||
|
||||
void GlowNode::render()
|
||||
{
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
drv->setTransform(ETS_WORLD, AbsoluteTransformation);
|
||||
drv->setMaterial(mat);
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL, 0, ~0);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
drv->drawMeshBuffer(sphere->getMeshBuffer(0));
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
void GlowNode::OnRegisterSceneNode()
|
||||
{
|
||||
if (IsVisible)
|
||||
{
|
||||
SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT);
|
||||
}
|
||||
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
}
|
53
src/graphics/glow.hpp
Normal file
53
src/graphics/glow.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Lauri Kasanen
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_GLOW_HPP
|
||||
#define HEADER_GLOW_HPP
|
||||
|
||||
#include <ISceneNode.h>
|
||||
#include <IMesh.h>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
// The actual node
|
||||
class GlowNode: public scene::ISceneNode
|
||||
{
|
||||
public:
|
||||
GlowNode(scene::ISceneManager* mgr, float radius);
|
||||
~GlowNode();
|
||||
|
||||
virtual void render();
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const
|
||||
{
|
||||
return box;
|
||||
}
|
||||
|
||||
virtual void OnRegisterSceneNode();
|
||||
|
||||
virtual u32 getMaterialCount() const { return 1; }
|
||||
virtual video::SMaterial& getMaterial(u32 i) { return mat; }
|
||||
|
||||
private:
|
||||
static video::SMaterial mat;
|
||||
static core::aabbox3df box;
|
||||
|
||||
static scene::IMesh *sphere;
|
||||
};
|
||||
|
||||
#endif
|
21
src/graphics/glwrap.hpp
Normal file
21
src/graphics/glwrap.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef GLWRAP_HEADER_H
|
||||
#define GLWRAP_HEADER_H
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <OpenGL/gl.h>
|
||||
#elif defined(ANDROID)
|
||||
# include <GLES/gl.h>
|
||||
#elif defined(WIN32)
|
||||
# define _WINSOCKAPI_
|
||||
// has to be included before gl.h because of WINGDIAPI and APIENTRY definitions
|
||||
# include <windows.h>
|
||||
# include <GL/gl.h>
|
||||
#else
|
||||
# include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
// already includes glext.h, which defines useful GL constants.
|
||||
// COpenGLDriver has already loaded the extension GL functions we use (e.g glBeginQuery)
|
||||
#include "../../lib/irrlicht/source/Irrlicht/COpenGLDriver.h"
|
||||
|
||||
#endif
|
@ -19,13 +19,23 @@
|
||||
#include "graphics/irr_driver.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/hardware_skinning.hpp"
|
||||
#include "graphics/lens_flare.hpp"
|
||||
#include "graphics/light.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/particle_kind_manager.hpp"
|
||||
#include "graphics/per_camera_node.hpp"
|
||||
#include "graphics/post_processing.hpp"
|
||||
#include "graphics/referee.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/shadow_importance.hpp"
|
||||
#include "graphics/sun.hpp"
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/water.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/modaldialog.hpp"
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
@ -47,6 +57,7 @@
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#include <irrlicht.h>
|
||||
|
||||
@ -62,19 +73,12 @@
|
||||
|
||||
using namespace irr;
|
||||
|
||||
#ifndef round
|
||||
# define round(x) (floor(x+0.5f))
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
namespace X11
|
||||
{
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
}
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
/** singleton */
|
||||
@ -96,6 +100,11 @@ IrrDriver::IrrDriver()
|
||||
m_resolution_changing = RES_CHANGE_NONE;
|
||||
m_device = createDevice(video::EDT_NULL);
|
||||
m_request_screenshot = false;
|
||||
m_shaders = NULL;
|
||||
m_rtts = NULL;
|
||||
m_wind = new Wind();
|
||||
m_mipviz = m_wireframe = m_normals = m_ssaoviz = \
|
||||
m_lightviz = m_shadowviz = m_distortviz = 0;
|
||||
} // IrrDriver
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -117,6 +126,9 @@ IrrDriver::~IrrDriver()
|
||||
m_device->drop();
|
||||
m_device = NULL;
|
||||
m_modes.clear();
|
||||
|
||||
delete m_shaders;
|
||||
delete m_wind;
|
||||
} // ~IrrDriver
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -124,7 +136,7 @@ IrrDriver::~IrrDriver()
|
||||
*/
|
||||
void IrrDriver::reset()
|
||||
{
|
||||
m_post_processing->reset();
|
||||
if (m_glsl) m_post_processing->reset();
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -135,22 +147,22 @@ Returns the parent window of "window" (i.e. the ancestor of window
|
||||
that is a direct child of the root, or window itself if it is a direct child).
|
||||
If window is the root window, returns window.
|
||||
*/
|
||||
X11::Window get_toplevel_parent(X11::Display* display, X11::Window window)
|
||||
Window get_toplevel_parent(Display* display, Window window)
|
||||
{
|
||||
X11::Window parent;
|
||||
X11::Window root;
|
||||
X11::Window * children;
|
||||
Window parent;
|
||||
Window root;
|
||||
Window * children;
|
||||
unsigned int num_children;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (0 == X11::XQueryTree(display, window, &root,
|
||||
if (0 == XQueryTree(display, window, &root,
|
||||
&parent, &children, &num_children))
|
||||
{
|
||||
Log::fatal("irr_driver", "XQueryTree error\n");
|
||||
}
|
||||
if (children) { //must test for null
|
||||
X11::XFree(children);
|
||||
XFree(children);
|
||||
}
|
||||
if (window == root || parent == root) {
|
||||
return window;
|
||||
@ -201,7 +213,6 @@ void IrrDriver::updateConfigIfRelevant()
|
||||
Log::warn("irr_driver", "Could not retrieve window location\n");
|
||||
}
|
||||
#elif defined(__linux__) && !defined(ANDROID)
|
||||
using namespace X11;
|
||||
const video::SExposedVideoData& videoData =
|
||||
m_device->getVideoDriver()->getExposedVideoData();
|
||||
Display* display = (Display*)videoData.OpenGLLinux.X11Display;
|
||||
@ -384,7 +395,8 @@ void IrrDriver::initDevice()
|
||||
m_gui_env = m_device->getGUIEnvironment();
|
||||
m_video_driver = m_device->getVideoDriver();
|
||||
m_glsl = m_video_driver->queryFeature(video::EVDF_ARB_GLSL) &&
|
||||
m_video_driver->queryFeature(video::EVDF_TEXTURE_NPOT);
|
||||
m_video_driver->queryFeature(video::EVDF_TEXTURE_NPOT) &&
|
||||
UserConfigParams::m_pixel_shaders;
|
||||
|
||||
// This remaps the window, so it has to be done before the clear to avoid flicker
|
||||
m_device->setResizable(false);
|
||||
@ -396,6 +408,44 @@ void IrrDriver::initDevice()
|
||||
if (m_glsl)
|
||||
{
|
||||
Log::info("irr_driver", "GLSL supported.");
|
||||
|
||||
// Order matters, create RTTs as soon as possible, as they are the largest blocks.
|
||||
m_rtts = new RTT();
|
||||
m_shaders = new Shaders();
|
||||
m_shadow_importance = new ShadowImportance();
|
||||
|
||||
m_mrt.clear();
|
||||
m_mrt.reallocate(3);
|
||||
m_mrt.push_back(m_rtts->getRTT(RTT_COLOR));
|
||||
m_mrt.push_back(m_rtts->getRTT(RTT_NORMAL));
|
||||
m_mrt.push_back(m_rtts->getRTT(RTT_DEPTH));
|
||||
|
||||
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
|
||||
gl_driver->extGlGenQueries(1, &m_lensflare_query);
|
||||
|
||||
scene::IMesh * const sphere = m_scene_manager->getGeometryCreator()->createSphereMesh(1, 16, 16);
|
||||
m_sun_interposer = m_scene_manager->addMeshSceneNode(sphere);
|
||||
m_sun_interposer->grab();
|
||||
m_sun_interposer->setParent(NULL);
|
||||
m_sun_interposer->setScale(core::vector3df(20));
|
||||
|
||||
m_sun_interposer->getMaterial(0).Lighting = false;
|
||||
m_sun_interposer->getMaterial(0).ColorMask = video::ECP_NONE;
|
||||
m_sun_interposer->getMaterial(0).ZWriteEnable = false;
|
||||
m_sun_interposer->getMaterial(0).MaterialType = m_shaders->getShader(ES_PASSFAR);
|
||||
|
||||
sphere->drop();
|
||||
|
||||
m_lensflare = new scene::CLensFlareSceneNode(NULL, m_scene_manager, -1);
|
||||
video::ITexture * const tex =
|
||||
m_video_driver->getTexture((file_manager->getTextureDir() + "lensflare.png").c_str());
|
||||
if (!tex) Log::fatal("irr_driver", "Cannot find lens flare texture");
|
||||
m_lensflare->setMaterialTexture(0, tex);
|
||||
m_lensflare->setAutomaticCulling(scene::EAC_OFF);
|
||||
|
||||
m_suncam = m_scene_manager->addCameraSceneNode(0, vector3df(0), vector3df(0), -1, false);
|
||||
m_suncam->grab();
|
||||
m_suncam->setParent(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -407,7 +457,6 @@ void IrrDriver::initDevice()
|
||||
{
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
// Set class hints on Linux, used by Window Managers.
|
||||
using namespace X11;
|
||||
const video::SExposedVideoData& videoData = m_video_driver
|
||||
->getExposedVideoData();
|
||||
XClassHint* classhint = XAllocClassHint();
|
||||
@ -423,11 +472,6 @@ void IrrDriver::initDevice()
|
||||
->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
|
||||
m_device->getVideoDriver()
|
||||
->setTextureCreationFlag(video::ETCF_OPTIMIZED_FOR_QUALITY, true);
|
||||
if (!UserConfigParams::m_fbo)
|
||||
{
|
||||
m_device->getVideoDriver()
|
||||
->disableFeature(video::EVDF_FRAMEBUFFER_OBJECT);
|
||||
}
|
||||
|
||||
// Force creation of mipmaps even if the mipmaps flag in a b3d file
|
||||
// does not set the 'enable mipmap' flag.
|
||||
@ -526,7 +570,6 @@ bool IrrDriver::moveWindow(const int x, const int y)
|
||||
return false;
|
||||
}
|
||||
#elif defined(__linux__) && !defined(ANDROID)
|
||||
using namespace X11;
|
||||
const video::SExposedVideoData& videoData = m_video_driver->getExposedVideoData();
|
||||
// TODO: Actually handle possible failure
|
||||
XMoveWindow((Display*)videoData.OpenGLLinux.X11Display,
|
||||
@ -771,6 +814,7 @@ void IrrDriver::setAllMaterialFlags(scene::IMesh *mesh) const
|
||||
* \param wave_length Lenght of a water wave.
|
||||
*/
|
||||
scene::ISceneNode* IrrDriver::addWaterNode(scene::IMesh *mesh,
|
||||
scene::IMesh **welded,
|
||||
float wave_height,
|
||||
float wave_speed,
|
||||
float wave_length)
|
||||
@ -778,11 +822,24 @@ scene::ISceneNode* IrrDriver::addWaterNode(scene::IMesh *mesh,
|
||||
mesh->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);
|
||||
scene::IMesh* welded_mesh = m_scene_manager->getMeshManipulator()
|
||||
->createMeshWelded(mesh);
|
||||
scene::ISceneNode* out = m_scene_manager->addWaterSurfaceSceneNode(welded_mesh,
|
||||
scene::ISceneNode* out = NULL;
|
||||
|
||||
if (!m_glsl)
|
||||
{
|
||||
out = m_scene_manager->addWaterSurfaceSceneNode(welded_mesh,
|
||||
wave_height, wave_speed,
|
||||
wave_length);
|
||||
} else
|
||||
{
|
||||
out = new WaterNode(m_scene_manager, welded_mesh, wave_height, wave_speed,
|
||||
wave_length);
|
||||
}
|
||||
|
||||
out->getMaterial(0).setFlag(video::EMF_GOURAUD_SHADING, true);
|
||||
welded_mesh->drop(); // The scene node keeps a reference
|
||||
|
||||
*welded = welded_mesh;
|
||||
|
||||
return out;
|
||||
} // addWaterNode
|
||||
|
||||
@ -841,11 +898,22 @@ PerCameraNode *IrrDriver::addPerCameraMesh(scene::IMesh* mesh,
|
||||
scene::ICameraSceneNode* camera,
|
||||
scene::ISceneNode *parent)
|
||||
{
|
||||
scene::ISceneNode *node = m_scene_manager->addMeshSceneNode(mesh);
|
||||
|
||||
return new PerCameraNode((parent ? parent
|
||||
: m_scene_manager->getRootSceneNode()),
|
||||
m_scene_manager, -1, camera, mesh);
|
||||
m_scene_manager, -1, camera, node);
|
||||
} // addMesh
|
||||
|
||||
PerCameraNode *IrrDriver::addPerCameraNode(scene::ISceneNode* node,
|
||||
scene::ICameraSceneNode* camera,
|
||||
scene::ISceneNode *parent)
|
||||
{
|
||||
return new PerCameraNode((parent ? parent
|
||||
: m_scene_manager->getRootSceneNode()),
|
||||
m_scene_manager, -1, camera, node);
|
||||
} // addNode
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Adds a billboard node to scene.
|
||||
@ -1627,6 +1695,8 @@ void IrrDriver::update(float dt)
|
||||
m_resolution_changing = RES_CHANGE_NONE;
|
||||
}
|
||||
|
||||
m_wind->update();
|
||||
|
||||
World *world = World::getWorld();
|
||||
|
||||
// Handle cut scenes (which do not have any karts in it)
|
||||
@ -1651,97 +1721,24 @@ void IrrDriver::update(float dt)
|
||||
m_video_driver->endScene();
|
||||
return;
|
||||
}
|
||||
|
||||
const bool inRace = world!=NULL;
|
||||
|
||||
if (inRace)
|
||||
else if (!world)
|
||||
{
|
||||
// Start the RTT for post-processing.
|
||||
// We do this before beginScene() because we want to capture the glClear()
|
||||
// because of tracks that do not have skyboxes (generally add-on tracks)
|
||||
m_post_processing->beginCapture();
|
||||
}
|
||||
|
||||
m_video_driver->beginScene(/*backBuffer clear*/ true, /*zBuffer*/ true,
|
||||
world ? world->getClearColor()
|
||||
: video::SColor(255,100,101,140));
|
||||
video::SColor(255,100,101,140));
|
||||
|
||||
if (inRace)
|
||||
{
|
||||
irr_driver->getVideoDriver()->enableMaterial2D();
|
||||
|
||||
RaceGUIBase *rg = world->getRaceGUI();
|
||||
if (rg) rg->update(dt);
|
||||
|
||||
|
||||
for(unsigned int i=0; i<Camera::getNumCameras(); i++)
|
||||
{
|
||||
Camera *camera = Camera::getCamera(i);
|
||||
|
||||
#ifdef ENABLE_PROFILER
|
||||
std::ostringstream oss;
|
||||
oss << "drawAll() for kart " << i << std::flush;
|
||||
PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), (i+1)*60,
|
||||
0x00, 0x00);
|
||||
#endif
|
||||
camera->activate();
|
||||
rg->preRenderCallback(camera); // adjusts start referee
|
||||
m_scene_manager->drawAll();
|
||||
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
// Note that drawAll must be called before rendering
|
||||
// the bullet debug view, since otherwise the camera
|
||||
// is not set up properly. This is only used for
|
||||
// the bullet debug view.
|
||||
if (UserConfigParams::m_artist_debug_mode)
|
||||
World::getWorld()->getPhysics()->draw();
|
||||
} // for i<world->getNumKarts()
|
||||
|
||||
// Stop capturing for the post-processing
|
||||
m_post_processing->endCapture();
|
||||
|
||||
// Render the post-processed scene
|
||||
m_post_processing->render();
|
||||
|
||||
// Set the viewport back to the full screen for race gui
|
||||
m_video_driver->setViewPort(core::recti(0, 0,
|
||||
UserConfigParams::m_width,
|
||||
UserConfigParams::m_height));
|
||||
|
||||
for(unsigned int i=0; i<Camera::getNumCameras(); i++)
|
||||
{
|
||||
Camera *camera = Camera::getCamera(i);
|
||||
char marker_name[100];
|
||||
sprintf(marker_name, "renderPlayerView() for kart %d", i);
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER(marker_name, 0x00, 0x00, (i+1)*60);
|
||||
rg->renderPlayerView(camera, dt);
|
||||
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
} // for i<getNumKarts
|
||||
}
|
||||
|
||||
// Either render the gui, or the global elements of the race gui.
|
||||
GUIEngine::render(dt);
|
||||
|
||||
// Render the profiler
|
||||
if(UserConfigParams::m_profiler_enabled)
|
||||
{
|
||||
PROFILER_DRAW();
|
||||
m_video_driver->endScene();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
drawDebugMeshes();
|
||||
#endif
|
||||
|
||||
m_video_driver->endScene();
|
||||
if (m_glsl)
|
||||
renderGLSL(dt);
|
||||
else
|
||||
renderFixed(dt);
|
||||
|
||||
if (m_request_screenshot) doScreenShot();
|
||||
|
||||
getPostProcessing()->update(dt);
|
||||
|
||||
// Enable this next print statement to get render information printed
|
||||
// E.g. number of triangles rendered, culled etc. The stats is only
|
||||
// printed while the race is running and not while the in-game menu
|
||||
@ -1775,7 +1772,7 @@ bool IrrDriver::OnEvent(const irr::SEvent &event)
|
||||
// Ignore 'normal' messages
|
||||
if (event.LogEvent.Level > 1)
|
||||
{
|
||||
printf("[IrrDriver Temp Logger] Level %d: %s\n",
|
||||
Log::warn("[IrrDriver Temp Logger]", "Level %d: %s\n",
|
||||
event.LogEvent.Level,event.LogEvent.Text);
|
||||
}
|
||||
return true;
|
||||
@ -1791,7 +1788,7 @@ bool IrrDriver::OnEvent(const irr::SEvent &event)
|
||||
|
||||
bool IrrDriver::supportsSplatting()
|
||||
{
|
||||
return UserConfigParams::m_pixel_shaders && m_glsl;
|
||||
return m_glsl;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -1977,6 +1974,11 @@ video::ITexture* IrrDriver::RTTProvider::renderToTexture(float angle,
|
||||
if (angle != -1 && m_rtt_main_node != NULL)
|
||||
m_rtt_main_node->setRotation( core::vector3df(0, angle, 0) );
|
||||
|
||||
video::SOverrideMaterial &overridemat = m_video_driver->getOverrideMaterial();
|
||||
overridemat.EnablePasses = scene::ESNRP_SOLID;
|
||||
overridemat.EnableFlags = video::EMF_MATERIAL_TYPE;
|
||||
overridemat.Material.MaterialType = video::EMT_SOLID;
|
||||
|
||||
if (m_rtt_main_node == NULL)
|
||||
{
|
||||
irr_driver->getSceneManager()->drawAll();
|
||||
@ -1990,6 +1992,129 @@ video::ITexture* IrrDriver::RTTProvider::renderToTexture(float angle,
|
||||
m_light->setVisible(false);
|
||||
}
|
||||
|
||||
overridemat.EnablePasses = 0;
|
||||
|
||||
m_video_driver->setRenderTarget(0, false, false);
|
||||
return m_render_target_texture;
|
||||
}
|
||||
|
||||
void IrrDriver::applyObjectPassShader(scene::ISceneNode * const node, bool rimlit)
|
||||
{
|
||||
if (!m_glsl)
|
||||
return;
|
||||
|
||||
// Don't override sky
|
||||
if (node->getType() == scene::ESNT_SKY_DOME ||
|
||||
node->getType() == scene::ESNT_SKY_BOX)
|
||||
return;
|
||||
|
||||
const u32 mcount = node->getMaterialCount();
|
||||
u32 i;
|
||||
const video::E_MATERIAL_TYPE ref = rimlit ? m_shaders->getShader(ES_OBJECTPASS_RIMLIT):
|
||||
m_shaders->getShader(ES_OBJECTPASS_REF);
|
||||
const video::E_MATERIAL_TYPE pass = rimlit ? m_shaders->getShader(ES_OBJECTPASS_RIMLIT):
|
||||
m_shaders->getShader(ES_OBJECTPASS);
|
||||
|
||||
const video::E_MATERIAL_TYPE origref = m_shaders->getShader(ES_OBJECTPASS_REF);
|
||||
const video::E_MATERIAL_TYPE origpass = m_shaders->getShader(ES_OBJECTPASS);
|
||||
|
||||
bool viamb = false;
|
||||
scene::IMesh *mesh = NULL;
|
||||
if (node->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
{
|
||||
viamb = ((scene::IAnimatedMeshSceneNode *) node)->isReadOnlyMaterials();
|
||||
mesh = ((scene::IAnimatedMeshSceneNode *) node)->getMesh();
|
||||
}
|
||||
else if (node->getType() == scene::ESNT_MESH)
|
||||
{
|
||||
viamb = ((scene::IMeshSceneNode *) node)->isReadOnlyMaterials();
|
||||
mesh = ((scene::IMeshSceneNode *) node)->getMesh();
|
||||
}
|
||||
|
||||
for (i = 0; i < mcount; i++)
|
||||
{
|
||||
video::SMaterial &nodemat = node->getMaterial(i);
|
||||
video::SMaterial &mbmat = mesh ? mesh->getMeshBuffer(i)->getMaterial() : nodemat;
|
||||
video::SMaterial *mat = &nodemat;
|
||||
|
||||
if (viamb)
|
||||
mat = &mbmat;
|
||||
|
||||
if (mat->MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF ||
|
||||
mat->MaterialType == origref)
|
||||
mat->MaterialType = ref;
|
||||
else if (mat->MaterialType == video::EMT_SOLID ||
|
||||
mat->MaterialType == origpass ||
|
||||
(mat->MaterialType >= video::EMT_LIGHTMAP &&
|
||||
mat->MaterialType <= video::EMT_LIGHTMAP_LIGHTING_M4))
|
||||
mat->MaterialType = pass;
|
||||
}
|
||||
|
||||
|
||||
core::list<scene::ISceneNode*> kids = node->getChildren();
|
||||
scene::ISceneNodeList::Iterator it = kids.begin();
|
||||
for (; it != kids.end(); ++it)
|
||||
{
|
||||
applyObjectPassShader(*it, rimlit);
|
||||
}
|
||||
}
|
||||
|
||||
void IrrDriver::applyObjectPassShader()
|
||||
{
|
||||
if (!m_glsl)
|
||||
return;
|
||||
|
||||
applyObjectPassShader(m_scene_manager->getRootSceneNode());
|
||||
}
|
||||
|
||||
scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float radius,
|
||||
float r, float g, float b, bool sun)
|
||||
{
|
||||
if (m_glsl)
|
||||
{
|
||||
LightNode *light = NULL;
|
||||
|
||||
if (!sun)
|
||||
light = new LightNode(m_scene_manager, radius, r, g, b);
|
||||
else
|
||||
light = new SunNode(m_scene_manager, r, g, b);
|
||||
|
||||
light->grab();
|
||||
light->setParent(NULL);
|
||||
|
||||
light->setPosition(pos);
|
||||
light->updateAbsolutePosition();
|
||||
|
||||
m_lights.push_back(light);
|
||||
|
||||
if (sun) {
|
||||
m_sun_interposer->setPosition(pos);
|
||||
m_sun_interposer->updateAbsolutePosition();
|
||||
|
||||
m_lensflare->setPosition(pos);
|
||||
m_lensflare->updateAbsolutePosition();
|
||||
|
||||
m_suncam->setPosition(pos);
|
||||
m_suncam->updateAbsolutePosition();
|
||||
|
||||
((WaterShaderProvider *) m_shaders->m_callbacks[ES_WATER])->setSunPosition(pos);
|
||||
}
|
||||
|
||||
return light;
|
||||
} else
|
||||
{
|
||||
return m_scene_manager->addLightSceneNode(NULL, pos, video::SColorf(r, g, b), radius);
|
||||
}
|
||||
}
|
||||
|
||||
void IrrDriver::clearLights()
|
||||
{
|
||||
u32 i;
|
||||
const u32 max = m_lights.size();
|
||||
for (i = 0; i < max; i++)
|
||||
{
|
||||
m_lights[i]->drop();
|
||||
}
|
||||
|
||||
m_lights.clear();
|
||||
}
|
||||
|
@ -39,11 +39,15 @@
|
||||
namespace irr
|
||||
{
|
||||
namespace scene { class ISceneManager; class IMesh; class IAnimatedMeshSceneNode; class IAnimatedMesh;
|
||||
class IMeshSceneNode; class IParticleSystemSceneNode; class ICameraSceneNode; class ILightSceneNode; }
|
||||
class IMeshSceneNode; class IParticleSystemSceneNode; class ICameraSceneNode; class ILightSceneNode;
|
||||
class CLensFlareSceneNode; }
|
||||
namespace gui { class IGUIEnvironment; class IGUIFont; }
|
||||
}
|
||||
using namespace irr;
|
||||
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "utils/aligned_array.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
@ -53,6 +57,8 @@ class AbstractKart;
|
||||
class Camera;
|
||||
class PerCameraNode;
|
||||
class PostProcessing;
|
||||
class LightNode;
|
||||
class ShadowImportance;
|
||||
|
||||
/**
|
||||
* \brief class that creates the irrLicht device and offers higher-level
|
||||
@ -74,11 +80,22 @@ private:
|
||||
gui::IGUIFont *m_race_font;
|
||||
/** Post-processing. */
|
||||
PostProcessing *m_post_processing;
|
||||
/** Shaders. */
|
||||
Shaders *m_shaders;
|
||||
/** Wind. */
|
||||
Wind *m_wind;
|
||||
/** RTTs. */
|
||||
RTT *m_rtts;
|
||||
/** Shadow importance. */
|
||||
ShadowImportance *m_shadow_importance;
|
||||
|
||||
/** Additional details to be shown in case that a texture is not found.
|
||||
* This is used to specify details like: "while loading kart '...'" */
|
||||
std::string m_texture_error_message;
|
||||
|
||||
/** The main MRT setup. */
|
||||
core::array<video::IRenderTarget> m_mrt;
|
||||
|
||||
/** Flag to indicate if a resolution change is pending (which will be
|
||||
* acted upon in the next update). None means no change, yes means
|
||||
* change to new resolution and trigger confirmation dialog.
|
||||
@ -99,6 +116,12 @@ public:
|
||||
int getWidth() const {return m_width; }
|
||||
int getHeight() const {return m_height; }
|
||||
}; // VideoMode
|
||||
|
||||
struct BloomData {
|
||||
scene::ISceneNode * node;
|
||||
float power;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<VideoMode> m_modes;
|
||||
|
||||
@ -116,6 +139,34 @@ private:
|
||||
|
||||
bool m_request_screenshot;
|
||||
|
||||
bool m_wireframe;
|
||||
bool m_mipviz;
|
||||
bool m_normals;
|
||||
bool m_ssaoviz;
|
||||
bool m_shadowviz;
|
||||
bool m_lightviz;
|
||||
bool m_distortviz;
|
||||
u32 m_renderpass;
|
||||
u32 m_lensflare_query;
|
||||
scene::IMeshSceneNode *m_sun_interposer;
|
||||
scene::CLensFlareSceneNode *m_lensflare;
|
||||
scene::ICameraSceneNode *m_suncam;
|
||||
|
||||
struct GlowData {
|
||||
scene::ISceneNode * node;
|
||||
float r, g, b;
|
||||
};
|
||||
|
||||
std::vector<GlowData> m_glowing;
|
||||
|
||||
std::vector<LightNode *> m_lights;
|
||||
|
||||
std::vector<BloomData> m_forcedbloom;
|
||||
|
||||
std::vector<scene::ISceneNode *> m_displacing;
|
||||
|
||||
std::vector<scene::ISceneNode *> m_background;
|
||||
|
||||
#ifdef DEBUG
|
||||
/** Used to visualise skeletons. */
|
||||
std::vector<irr::scene::IAnimatedMeshSceneNode*> m_debug_meshes;
|
||||
@ -126,6 +177,9 @@ private:
|
||||
irr::scene::ISkinnedMesh* mesh, int id);
|
||||
#endif
|
||||
|
||||
void renderFixed(float dt);
|
||||
void renderGLSL(float dt);
|
||||
|
||||
void doScreenShot();
|
||||
public:
|
||||
IrrDriver();
|
||||
@ -151,7 +205,8 @@ public:
|
||||
bool create_one_quad=false);
|
||||
scene::IMesh *createTexturedQuadMesh(const video::SMaterial *material,
|
||||
const double w, const double h);
|
||||
scene::ISceneNode *addWaterNode(scene::IMesh *mesh, float wave_height,
|
||||
scene::ISceneNode *addWaterNode(scene::IMesh *mesh, scene::IMesh **welded,
|
||||
float wave_height,
|
||||
float wave_speed, float wave_length);
|
||||
scene::IMeshSceneNode*addOctTree(scene::IMesh *mesh);
|
||||
scene::IMeshSceneNode*addSphere(float radius,
|
||||
@ -161,6 +216,9 @@ public:
|
||||
PerCameraNode *addPerCameraMesh(scene::IMesh* mesh,
|
||||
scene::ICameraSceneNode* node,
|
||||
scene::ISceneNode *parent = NULL);
|
||||
PerCameraNode *addPerCameraNode(scene::ISceneNode* node,
|
||||
scene::ICameraSceneNode* cam,
|
||||
scene::ISceneNode *parent = NULL);
|
||||
scene::ISceneNode *addBillboard(const core::dimension2d< f32 > size,
|
||||
video::ITexture *texture,
|
||||
scene::ISceneNode* parent=NULL, bool alphaTesting = false);
|
||||
@ -286,9 +344,86 @@ public:
|
||||
/** Returns a pointer to the post processing object. */
|
||||
inline PostProcessing* getPostProcessing() {return m_post_processing;}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
inline core::vector3df getWind() {return m_wind->getWind();}
|
||||
// ------------------------------------------------------------------------
|
||||
inline video::E_MATERIAL_TYPE getShader(const ShaderType num) {return m_shaders->getShader(num);}
|
||||
// ------------------------------------------------------------------------
|
||||
inline video::IShaderConstantSetCallBack* getCallback(const ShaderType num) {return m_shaders->m_callbacks[num];}
|
||||
// ------------------------------------------------------------------------
|
||||
inline video::ITexture* getRTT(TypeRTT which) {return m_rtts->getRTT(which);}
|
||||
// ------------------------------------------------------------------------
|
||||
inline bool isGLSL() const { return m_glsl; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleWireframe() { m_wireframe ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleMipVisualization() { m_mipviz ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleNormals() { m_normals ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getNormals() { return m_normals; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleSSAOViz() { m_ssaoviz ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleLightViz() { m_lightviz ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getSSAOViz() { return m_ssaoviz; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleShadowViz() { m_shadowviz ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getShadowViz() { return m_shadowviz; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleDistortViz() { m_distortviz ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getDistortViz() { return m_distortviz; }
|
||||
// ------------------------------------------------------------------------
|
||||
u32 getRenderPass() { return m_renderpass; }
|
||||
// ------------------------------------------------------------------------
|
||||
void addGlowingNode(scene::ISceneNode *n, float r = 1.0f, float g = 1.0f, float b = 1.0f)
|
||||
{
|
||||
GlowData dat;
|
||||
dat.node = n;
|
||||
dat.r = r;
|
||||
dat.g = g;
|
||||
dat.b = b;
|
||||
|
||||
m_glowing.push_back(dat);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void clearGlowingNodes() { m_glowing.clear(); }
|
||||
// ------------------------------------------------------------------------
|
||||
void addForcedBloomNode(scene::ISceneNode *n, float power = 1)
|
||||
{
|
||||
BloomData dat;
|
||||
dat.node = n;
|
||||
dat.power = power;
|
||||
|
||||
m_forcedbloom.push_back(dat);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void clearForcedBloom() { m_forcedbloom.clear(); }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::vector<BloomData> &getForcedBloom() const { return m_forcedbloom; }
|
||||
// ------------------------------------------------------------------------
|
||||
void clearDisplacingNodes() { m_displacing.clear(); }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::vector<scene::ISceneNode *> &getDisplacingNodes() const { return m_displacing; }
|
||||
// ------------------------------------------------------------------------
|
||||
void addDisplacingNode(scene::ISceneNode * const n) { m_displacing.push_back(n); }
|
||||
// ------------------------------------------------------------------------
|
||||
void clearBackgroundNodes() { m_background.clear(); }
|
||||
// ------------------------------------------------------------------------
|
||||
void addBackgroundNode(scene::ISceneNode * const n) { m_background.push_back(n); }
|
||||
// ------------------------------------------------------------------------
|
||||
void applyObjectPassShader();
|
||||
void applyObjectPassShader(scene::ISceneNode * const node, bool rimlit = false);
|
||||
// ------------------------------------------------------------------------
|
||||
scene::ISceneNode *addLight(const core::vector3df &pos, float radius = 1.0f, float r = 1.0f,
|
||||
float g = 1.0f, float b = 1.0f, bool sun = false);
|
||||
// ------------------------------------------------------------------------
|
||||
void clearLights();
|
||||
// ------------------------------------------------------------------------
|
||||
scene::IMeshSceneNode *getSunInterposer() { return m_sun_interposer; }
|
||||
|
||||
#ifdef DEBUG
|
||||
/** Removes debug meshes. */
|
||||
void clearDebugMesh() { m_debug_meshes.clear(); }
|
||||
|
58
src/graphics/large_mesh_buffer.hpp
Normal file
58
src/graphics/large_mesh_buffer.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef __LARGE_MESH_BUFFER_H_INCLUDED__
|
||||
#define __LARGE_MESH_BUFFER_H_INCLUDED__
|
||||
|
||||
#include "irrArray.h"
|
||||
#include "IMeshBuffer.h"
|
||||
#include "CMeshBuffer.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
//! A SMeshBuffer with 32-bit indices
|
||||
class LargeMeshBuffer : public SMeshBuffer
|
||||
{
|
||||
public:
|
||||
//! Get type of index data which is stored in this meshbuffer.
|
||||
/** \return Index type of this buffer. */
|
||||
virtual video::E_INDEX_TYPE getIndexType() const
|
||||
{
|
||||
return video::EIT_32BIT;
|
||||
}
|
||||
|
||||
//! Get pointer to indices
|
||||
/** \return Pointer to indices. */
|
||||
virtual const u16* getIndices() const
|
||||
{
|
||||
return (u16 *) Indices.const_pointer();
|
||||
}
|
||||
|
||||
|
||||
//! Get pointer to indices
|
||||
/** \return Pointer to indices. */
|
||||
virtual u16* getIndices()
|
||||
{
|
||||
return (u16 *) Indices.pointer();
|
||||
}
|
||||
|
||||
|
||||
//! Get number of indices
|
||||
/** \return Number of indices. */
|
||||
virtual u32 getIndexCount() const
|
||||
{
|
||||
return Indices.size();
|
||||
}
|
||||
|
||||
//! Indices into the vertices of this buffer.
|
||||
core::array<u32> Indices;
|
||||
};
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
||||
|
||||
|
264
src/graphics/lens_flare.cpp
Normal file
264
src/graphics/lens_flare.cpp
Normal file
@ -0,0 +1,264 @@
|
||||
/* TODO: copyright */
|
||||
|
||||
#include "graphics/lens_flare.hpp"
|
||||
#include "IVideoDriver.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "ISceneCollisionManager.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
|
||||
CLensFlareSceneNode::CLensFlareSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) :
|
||||
scene::ISceneNode(parent, mgr, id)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CLensFlareSceneNode");
|
||||
#endif
|
||||
|
||||
// set the bounding box
|
||||
BBox.MaxEdge.set(0,0,0);
|
||||
BBox.MinEdge.set(0,0,0);
|
||||
|
||||
// set the initial Strength
|
||||
Strength = 1.0f;
|
||||
|
||||
// setup the vertices
|
||||
Vertices[0] = video::S3DVertex(-1.f, -1.f, 0.f, 0.f, 0.f, 1.f, 0xffffffff, 0.f, 1.f);
|
||||
Vertices[1] = video::S3DVertex(-1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 0xffffffff, 0.f, 0.f);
|
||||
Vertices[2] = video::S3DVertex( 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 0xffffffff, 1.f, 0.f);
|
||||
Vertices[3] = video::S3DVertex( 1.f, -1.f, 0.f, 0.f, 0.f, 1.f, 0xffffffff, 1.f, 1.f);
|
||||
|
||||
// setup the indices
|
||||
Indices[0] = 0;
|
||||
Indices[1] = 1;
|
||||
Indices[2] = 2;
|
||||
Indices[3] = 2;
|
||||
Indices[4] = 3;
|
||||
Indices[5] = 0;
|
||||
|
||||
// set the default material properties
|
||||
Material.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||
Material.Lighting = false;
|
||||
Material.ZBuffer = video::ECFN_NEVER;
|
||||
|
||||
FlareData.reallocate(30);
|
||||
|
||||
// prepare the flare data array
|
||||
// circles, halos and ring behind the sun
|
||||
FlareData.push_back(SFlareData(EFT_CIRCLE, 0.5f, 0.12f, video::SColor(120, 60, 180, 35)));
|
||||
FlareData.push_back(SFlareData(EFT_HALO, 0.45f, 0.4f, video::SColor(200, 100, 200, 60)));
|
||||
FlareData.push_back(SFlareData(EFT_CIRCLE, 0.4f, 0.17f, video::SColor(240, 120, 220, 40)));
|
||||
FlareData.push_back(SFlareData(EFT_CIRCLE, 0.2f, 0.35f, video::SColor(175, 175, 255, 20)));
|
||||
FlareData.push_back(SFlareData(EFT_RING, 0.15f, 0.2f, video::SColor(120, 60, 255, 100)));
|
||||
|
||||
// sun and glow effect at sun position
|
||||
FlareData.push_back(SFlareData(EFT_SUN, 0.0f, 0.75f, video::SColor(255, 255, 255, 255)));
|
||||
// FlareData.push_back(SFlareData(EFT_STREAKS, 0.0f, 2.9f, video::SColor(255, 255, 255, 255)));
|
||||
FlareData.push_back(SFlareData(EFT_GLOW, 0.0f, 3.5f, video::SColor(255, 255, 255, 255)));
|
||||
// FlareData.push_back(SFlareData(EFT_RING, 0.0f, 1.5f, video::SColor(120, 120, 120, 150)));
|
||||
|
||||
// some lenses, halos and circles
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.15f, 0.15f, video::SColor(255, 60, 60, 90)));
|
||||
FlareData.push_back(SFlareData(EFT_HALO, -0.3f, 0.3f, video::SColor(120, 60, 255, 180)));
|
||||
FlareData.push_back(SFlareData(EFT_HALO, -0.4f, 0.2f, video::SColor(220, 80, 80, 98)));
|
||||
FlareData.push_back(SFlareData(EFT_CIRCLE, -0.45f, 0.1f, video::SColor(220, 80, 80, 85)));
|
||||
FlareData.push_back(SFlareData(EFT_RING, -0.42f, 0.3f, video::SColor(180, 60, 255, 110)));
|
||||
|
||||
// some small lenses, halos and rings
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.55f, 0.2f, video::SColor(255, 60, 60, 130)));
|
||||
FlareData.push_back(SFlareData(EFT_HALO, -0.6f, 0.3f, video::SColor(120, 60, 255, 80)));
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.7f, 0.2f, video::SColor(200, 60, 60, 130)));
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.71f, 0.2f, video::SColor(200, 60, 130, 60)));
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.72f, 0.2f, video::SColor(200, 130, 130, 60)));
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.74f, 0.2f, video::SColor(200, 130, 60, 60)));
|
||||
|
||||
// some polyons, lenses and circle
|
||||
FlareData.push_back(SFlareData(scene::EFT_POLY, -0.79f, 0.2f, video::SColor(200, 60, 130, 60)));
|
||||
FlareData.push_back(SFlareData(scene::EFT_POLY, -0.86f, 0.3f, video::SColor(200, 130, 130, 60)));
|
||||
FlareData.push_back(SFlareData(scene::EFT_LENS, -0.87f, 0.3f, video::SColor(180,255,192,178)));
|
||||
FlareData.push_back(SFlareData(scene::EFT_CIRCLE, -0.9f, 0.1f, video::SColor(200, 60, 60, 130)));
|
||||
FlareData.push_back(SFlareData(scene::EFT_POLY, -0.93f, 0.4f, video::SColor(200, 130, 60, 60)));
|
||||
|
||||
// finally som polygons
|
||||
FlareData.push_back(SFlareData(EFT_POLY, -0.95f, 0.6f, video::SColor(120, 60, 255, 120)));
|
||||
FlareData.push_back(SFlareData(EFT_POLY, -1.0f, 0.15f, video::SColor(120, 20, 255, 85)));
|
||||
}
|
||||
|
||||
CLensFlareSceneNode::~CLensFlareSceneNode()
|
||||
{
|
||||
}
|
||||
|
||||
u32 CLensFlareSceneNode::getMaterialCount() const
|
||||
{
|
||||
// return the material count (always one in our case)
|
||||
return 1;
|
||||
}
|
||||
|
||||
video::SMaterial& CLensFlareSceneNode::getMaterial(u32 i)
|
||||
{
|
||||
// return the material
|
||||
return Material;
|
||||
}
|
||||
|
||||
core::array<SFlareData>& CLensFlareSceneNode::getFlareData()
|
||||
{
|
||||
// return the flare data array
|
||||
return FlareData;
|
||||
}
|
||||
|
||||
void CLensFlareSceneNode::OnRegisterSceneNode()
|
||||
{
|
||||
// if node is visible and Strength is greater than 0 register it for the ESNRP_TRANSPARENT_EFFECT pass
|
||||
if(IsVisible && Strength > 0.0f)
|
||||
{
|
||||
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT_EFFECT);
|
||||
}
|
||||
|
||||
// call base OnRegisterSceneNode
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
|
||||
void CLensFlareSceneNode::render()
|
||||
{
|
||||
// get the videodriver and the active camera
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
ICameraSceneNode* camera = SceneManager->getActiveCamera();
|
||||
|
||||
// return if we don't have a valid driver or a valid camera
|
||||
// or if we have no texture attached to the material
|
||||
if (!camera || !driver || !Material.getTexture(0))
|
||||
return;
|
||||
|
||||
// get screencenter
|
||||
const core::vector2d<s32> screenCenter = core::vector2d<s32>(
|
||||
SceneManager->getVideoDriver()->getScreenSize().Width,
|
||||
SceneManager->getVideoDriver()->getScreenSize().Height)/2;
|
||||
|
||||
// get screencoordinates of the node
|
||||
const core::vector2d<s32> lightPos = SceneManager->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(
|
||||
getAbsolutePosition(),
|
||||
camera);
|
||||
|
||||
// store old projection matrix
|
||||
core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
|
||||
|
||||
// store old view matrix
|
||||
core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
|
||||
|
||||
// clear the projection matrix
|
||||
driver->setTransform(video::ETS_PROJECTION, core::IdentityMatrix);
|
||||
|
||||
// clear the view matrix
|
||||
driver->setTransform(video::ETS_VIEW, core::IdentityMatrix);
|
||||
|
||||
// set the transform
|
||||
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
|
||||
|
||||
// set the material
|
||||
driver->setMaterial(Material);
|
||||
|
||||
// calculate some handy constants
|
||||
const f32 texPos = 1.0f/EFT_COUNT;
|
||||
const s32 texHeight = s32(Material.getTexture(0)->getSize().Height*0.5f);
|
||||
const f32 screenWidth = f32(driver->getScreenSize().Width);
|
||||
const f32 screenHeight = f32(driver->getScreenSize().Height);
|
||||
|
||||
// render the flares
|
||||
for (u32 i=0; i<FlareData.size(); ++i)
|
||||
{
|
||||
// get the flare element
|
||||
SFlareData& flare = FlareData[i];
|
||||
|
||||
// calculate center of the flare
|
||||
core::vector2d<s32>flarePos = screenCenter.getInterpolated(lightPos, -2.0*flare.Position);
|
||||
|
||||
// calculate flareposition in vertex coordinates using the scalefactor of the flare
|
||||
s32 flareScale = s32((texHeight*flare.Scale));
|
||||
core::rect<f32> flareRect = core::rect<f32>(
|
||||
-1.f + 2.f * f32(flarePos.X-flareScale) / screenWidth,
|
||||
-1.f + 2.f * f32(screenHeight-flarePos.Y-flareScale) / screenHeight,
|
||||
-1.f + 2.f * f32(flarePos.X+flareScale) / screenWidth,
|
||||
-1.f + 2.f * f32(screenHeight-flarePos.Y+flareScale) / screenHeight);
|
||||
|
||||
// calculate flarecolor in dependence of occlusion
|
||||
f32 flareAlpha = f32(flare.Color.getAlpha()) / 255.f;
|
||||
video::SColor flareColor(255,
|
||||
(u32)(Strength * flareAlpha * flare.Color.getRed()),
|
||||
(u32)(Strength * flareAlpha * flare.Color.getGreen()),
|
||||
(u32)(Strength * flareAlpha * flare.Color.getBlue()));
|
||||
|
||||
// set vertex colors
|
||||
Vertices[0].Color = flareColor;
|
||||
Vertices[1].Color = flareColor;
|
||||
Vertices[2].Color = flareColor;
|
||||
Vertices[3].Color = flareColor;
|
||||
|
||||
// set texture coordinates
|
||||
Vertices[0].TCoords.set( flare.Type * texPos, 1.0f);
|
||||
Vertices[1].TCoords.set( flare.Type * texPos, 0.0f);
|
||||
Vertices[2].TCoords.set((flare.Type+1) * texPos, 0.0f);
|
||||
Vertices[3].TCoords.set((flare.Type+1) * texPos, 1.0f);
|
||||
|
||||
// set vertex positions
|
||||
Vertices[0].Pos.set(flareRect.UpperLeftCorner.X, flareRect.UpperLeftCorner.Y, 0);
|
||||
Vertices[1].Pos.set(flareRect.UpperLeftCorner.X, flareRect.LowerRightCorner .Y, 0);
|
||||
Vertices[2].Pos.set(flareRect.LowerRightCorner.X, flareRect.LowerRightCorner.Y, 0);
|
||||
Vertices[3].Pos.set(flareRect.LowerRightCorner.X, flareRect.UpperLeftCorner.Y, 0);
|
||||
|
||||
//draw the mesh
|
||||
driver->drawIndexedTriangleList(Vertices, 4, Indices, 2);
|
||||
}
|
||||
|
||||
// restore view matrix
|
||||
driver->setTransform(video::ETS_VIEW, oldViewMat);
|
||||
|
||||
// restore projection matrix
|
||||
driver->setTransform(video::ETS_PROJECTION, oldProjMat);
|
||||
}
|
||||
|
||||
const core::aabbox3df& CLensFlareSceneNode::getBoundingBox() const
|
||||
{
|
||||
// return the bounding box
|
||||
return BBox;
|
||||
}
|
||||
|
||||
ESCENE_NODE_TYPE CLensFlareSceneNode::getType() const
|
||||
{
|
||||
// return type of the scene node
|
||||
// (important when using with a custom scene node factory)
|
||||
return scene::ESNT_UNKNOWN; //(ESCENE_NODE_TYPE) ECSNT_LENSFLARE;
|
||||
}
|
||||
|
||||
void CLensFlareSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
|
||||
{
|
||||
// write attributes of the scene node.
|
||||
ISceneNode::serializeAttributes(out, options);
|
||||
}
|
||||
|
||||
void CLensFlareSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
|
||||
{
|
||||
// read attributes of the scene node.
|
||||
ISceneNode::deserializeAttributes(in, options);
|
||||
}
|
||||
|
||||
ISceneNode* CLensFlareSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
|
||||
{
|
||||
if (!newParent)
|
||||
newParent = Parent;
|
||||
if (!newManager)
|
||||
newManager = SceneManager;
|
||||
|
||||
CLensFlareSceneNode* nb = new CLensFlareSceneNode(newParent, newManager, ID);
|
||||
|
||||
nb->cloneMembers(this, newManager);
|
||||
nb->Material = Material;
|
||||
|
||||
nb->drop();
|
||||
return nb;
|
||||
}
|
||||
|
||||
}// end irr namespace
|
||||
}// end scene namespace
|
||||
|
117
src/graphics/lens_flare.hpp
Normal file
117
src/graphics/lens_flare.hpp
Normal file
@ -0,0 +1,117 @@
|
||||
#ifndef _CLENSFLARESCENENODE_H
|
||||
#define _CLENSFLARESCENENODE_H
|
||||
|
||||
#include <ISceneNode.h>
|
||||
#include <S3DVertex.h>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
// enum with different flare types (used by SFlareData)
|
||||
enum E_FLARE_TYPE
|
||||
{
|
||||
EFT_SUN = 0,
|
||||
EFT_GLOW,
|
||||
EFT_LENS,
|
||||
EFT_STREAKS,
|
||||
EFT_RING,
|
||||
EFT_HALO,
|
||||
EFT_CIRCLE,
|
||||
EFT_POLY,
|
||||
EFT_COUNT
|
||||
};
|
||||
|
||||
// struct holding the flare specification
|
||||
struct SFlareData
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
SFlareData(const E_FLARE_TYPE type, const float position,
|
||||
const float scale, const video::SColor &color)
|
||||
{
|
||||
Type = type;
|
||||
Position = position;
|
||||
Scale = scale;
|
||||
Color = color;
|
||||
}
|
||||
|
||||
// flare type
|
||||
E_FLARE_TYPE Type;
|
||||
// position
|
||||
f32 Position;
|
||||
// flare scale
|
||||
f32 Scale;
|
||||
// flare color
|
||||
video::SColor Color;
|
||||
};
|
||||
|
||||
class CLensFlareSceneNode : public ISceneNode
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CLensFlareSceneNode(ISceneNode* parent, scene::ISceneManager* mgr, s32 id = -1);
|
||||
|
||||
// destructor
|
||||
virtual ~CLensFlareSceneNode();
|
||||
|
||||
protected:
|
||||
// material of the node
|
||||
video::SMaterial Material;
|
||||
|
||||
// Bounding box
|
||||
core::aabbox3d<f32> BBox;
|
||||
|
||||
// vertices and indices of a flare element
|
||||
video::S3DVertex Vertices[4];
|
||||
u16 Indices[6];
|
||||
|
||||
// flare data array
|
||||
core::array<SFlareData> FlareData;
|
||||
|
||||
// Strength of the flare effect (between 0 and 1)
|
||||
f32 Strength;
|
||||
|
||||
public:
|
||||
// typical OnRegisterSceneNode function
|
||||
virtual void OnRegisterSceneNode();
|
||||
|
||||
// renders the node
|
||||
virtual void render();
|
||||
|
||||
// returns the bounding box
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const;
|
||||
|
||||
// returns the node type
|
||||
virtual ESCENE_NODE_TYPE getType() const;
|
||||
|
||||
// returns the material count
|
||||
virtual u32 getMaterialCount() const;
|
||||
|
||||
// returns the material
|
||||
virtual video::SMaterial& getMaterial(u32 i);
|
||||
|
||||
// writes attributes of the scene node.
|
||||
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options = 0) const;
|
||||
|
||||
// reads attributes of the scene node.
|
||||
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options = 0);
|
||||
|
||||
// clones the node
|
||||
virtual ISceneNode* clone(ISceneNode* newParent = 0, ISceneManager* newManager = 0);
|
||||
|
||||
// returns the flare data array
|
||||
core::array<SFlareData>& getFlareData();
|
||||
|
||||
// returns the strength (visibility) of the flares
|
||||
f32 getStrength() { return Strength; }
|
||||
|
||||
// sets the strength (visibility) of the flares
|
||||
void setStrength(f32 strength) { Strength = core::clamp(strength, 0.0f, 0.7f); }
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
||||
|
93
src/graphics/light.cpp
Normal file
93
src/graphics/light.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Lauri Kasanen
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "graphics/light.hpp"
|
||||
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
|
||||
using namespace video;
|
||||
using namespace scene;
|
||||
using namespace core;
|
||||
|
||||
IMesh * LightNode::sphere = NULL;
|
||||
SMaterial LightNode::mat;
|
||||
aabbox3df LightNode::box;
|
||||
|
||||
|
||||
LightNode::LightNode(scene::ISceneManager* mgr, float radius, float r, float g, float b):
|
||||
ISceneNode(mgr->getRootSceneNode(), mgr, -1)
|
||||
{
|
||||
if (!sphere)
|
||||
{
|
||||
mat.Lighting = false;
|
||||
mat.MaterialType = irr_driver->getShader(ES_POINTLIGHT);
|
||||
|
||||
mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL));
|
||||
mat.setTexture(1, irr_driver->getRTT(RTT_DEPTH));
|
||||
|
||||
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
|
||||
{
|
||||
mat.TextureLayer[i].TextureWrapU =
|
||||
mat.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
mat.setFlag(EMF_BILINEAR_FILTER, false);
|
||||
mat.setFlag(EMF_ZWRITE_ENABLE, false);
|
||||
|
||||
mat.MaterialTypeParam = pack_textureBlendFunc(EBF_ONE, EBF_ONE);
|
||||
mat.BlendOperation = EBO_ADD;
|
||||
|
||||
sphere = mgr->getGeometryCreator()->createSphereMesh(1, 16, 16);
|
||||
box = sphere->getBoundingBox();
|
||||
}
|
||||
|
||||
setScale(vector3df(radius));
|
||||
m_radius = radius;
|
||||
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
}
|
||||
|
||||
LightNode::~LightNode()
|
||||
{
|
||||
}
|
||||
|
||||
void LightNode::render()
|
||||
{
|
||||
PointLightProvider * const cb = (PointLightProvider *) irr_driver->getCallback(ES_POINTLIGHT);
|
||||
cb->setColor(m_color[0], m_color[1], m_color[2]);
|
||||
cb->setPosition(getPosition().X, getPosition().Y, getPosition().Z);
|
||||
cb->setRadius(m_radius);
|
||||
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
drv->setTransform(ETS_WORLD, AbsoluteTransformation);
|
||||
drv->setMaterial(mat);
|
||||
|
||||
drv->drawMeshBuffer(sphere->getMeshBuffer(0));
|
||||
}
|
||||
|
||||
void LightNode::OnRegisterSceneNode()
|
||||
{ // This node is only drawn manually.
|
||||
}
|
64
src/graphics/light.hpp
Normal file
64
src/graphics/light.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Lauri Kasanen
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_LIGHT_HPP
|
||||
#define HEADER_LIGHT_HPP
|
||||
|
||||
#include <ISceneNode.h>
|
||||
#include <utils/cpp2011.h>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene { class IMesh; }
|
||||
}
|
||||
|
||||
// The actual node
|
||||
class LightNode: public scene::ISceneNode
|
||||
{
|
||||
public:
|
||||
LightNode(scene::ISceneManager* mgr, float radius, float r, float g, float b);
|
||||
virtual ~LightNode();
|
||||
|
||||
virtual void render() OVERRIDE;
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const OVERRIDE
|
||||
{
|
||||
return box;
|
||||
}
|
||||
|
||||
virtual void OnRegisterSceneNode() OVERRIDE;
|
||||
|
||||
virtual u32 getMaterialCount() const OVERRIDE { return 1; }
|
||||
virtual video::SMaterial& getMaterial(u32 i) OVERRIDE { return mat; }
|
||||
|
||||
float getRadius() const { return m_radius; }
|
||||
void getColor(float out[3]) const { memcpy(out, m_color, 3 * sizeof(float)); }
|
||||
|
||||
protected:
|
||||
static video::SMaterial mat;
|
||||
static core::aabbox3df box;
|
||||
|
||||
static scene::IMesh *sphere;
|
||||
|
||||
float m_radius;
|
||||
float m_color[3];
|
||||
};
|
||||
|
||||
#endif
|
@ -49,6 +49,7 @@ LODNode::LODNode(std::string group_name, scene::ISceneNode* parent,
|
||||
drop();
|
||||
|
||||
m_forced_lod = -1;
|
||||
m_last_tick = 0;
|
||||
}
|
||||
|
||||
LODNode::~LODNode()
|
||||
@ -81,6 +82,11 @@ int LODNode::getLevel()
|
||||
if (dist < m_detail[n])
|
||||
return n;
|
||||
}
|
||||
|
||||
// If it's the shadow pass, and we would have otherwise hidden the item, show the min one
|
||||
if (curr_cam->isOrthogonal())
|
||||
return m_detail.size() - 1;
|
||||
|
||||
return -1;
|
||||
} // getLevel
|
||||
|
||||
@ -139,9 +145,12 @@ void LODNode::OnRegisterSceneNode()
|
||||
shown = true;
|
||||
}
|
||||
|
||||
const u32 now = irr_driver->getDevice()->getTimer()->getTime();
|
||||
|
||||
// support an optional, mostly hard-coded fade-in/out effect for objects with a single level
|
||||
if (m_nodes.size() == 1 && (m_nodes[0]->getType() == scene::ESNT_MESH ||
|
||||
m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH))
|
||||
m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH) &&
|
||||
now > m_last_tick)
|
||||
{
|
||||
if (m_previous_visibility == WAS_HIDDEN && shown)
|
||||
{
|
||||
@ -237,6 +246,7 @@ void LODNode::OnRegisterSceneNode()
|
||||
}
|
||||
|
||||
m_previous_visibility = (shown ? WAS_SHOWN : WAS_HIDDEN);
|
||||
m_last_tick = now;
|
||||
|
||||
// If this node has children other than the LOD nodes, draw them
|
||||
core::list<ISceneNode*>::Iterator it;
|
||||
@ -279,7 +289,13 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
|
||||
if(UserConfigParams::m_hw_skinning_enabled && node->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
HardwareSkinning::prepareNode((scene::IAnimatedMeshSceneNode*)node);
|
||||
|
||||
if (node->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
((scene::IAnimatedMeshSceneNode *) node)->setReadOnlyMaterials(true);
|
||||
if (node->getType() == scene::ESNT_MESH)
|
||||
((scene::IMeshSceneNode *) node)->setReadOnlyMaterials(true);
|
||||
|
||||
node->drop();
|
||||
|
||||
node->updateAbsolutePosition();
|
||||
irr_driver->applyObjectPassShader(node);
|
||||
}
|
||||
|
@ -71,6 +71,8 @@ private:
|
||||
|
||||
PreviousVisibility m_previous_visibility;
|
||||
|
||||
u32 m_last_tick;
|
||||
|
||||
public:
|
||||
|
||||
LODNode(std::string group_name, scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id=-1);
|
||||
|
@ -27,8 +27,10 @@
|
||||
#include "config/user_config.hpp"
|
||||
#include "config/stk_config.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/particle_kind_manager.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
@ -36,7 +38,6 @@
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include <IGPUProgrammingServices.h>
|
||||
#include <IMaterialRendererServices.h>
|
||||
#include <ISceneNode.h>
|
||||
#include <IShaderConstantSetCallBack.h>
|
||||
@ -46,351 +47,6 @@ using namespace irr::video;
|
||||
const unsigned int UCLAMP = 1;
|
||||
const unsigned int VCLAMP = 2;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class NormalMapProvider : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
bool m_with_lightmap;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
NormalMapProvider(bool withLightmap)
|
||||
{
|
||||
m_with_lightmap = withLightmap;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(
|
||||
irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
s32 decaltex = 0;
|
||||
services->setPixelShaderConstant("DecalTex", &decaltex, 1);
|
||||
|
||||
s32 bumptex = 1;
|
||||
services->setPixelShaderConstant("BumpTex", &bumptex, 1);
|
||||
|
||||
s32 lightmapTex = (m_with_lightmap ? 2 : 0);
|
||||
services->setPixelShaderConstant("LightMapTex", &lightmapTex, 1);
|
||||
|
||||
s32 hasLightMap = (m_with_lightmap ? 1 : 0);
|
||||
services->setPixelShaderConstant("HasLightMap", &hasLightMap, 1);
|
||||
|
||||
// We could calculate light direction as coming from the sun (then we'd need to
|
||||
// transform it into camera space). But I find that pretending light
|
||||
// comes from the camera gives good results
|
||||
const float lightdir[] = {0.1852f, -0.1852f, -0.9259f};
|
||||
services->setVertexShaderConstant("lightdir", lightdir, 3);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class WaterShaderProvider : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
float m_dx_1, m_dy_1, m_dx_2, m_dy_2;
|
||||
float m_water_shader_speed_1;
|
||||
float m_water_shader_speed_2;
|
||||
bool m_fog;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
void enableFog(bool enable)
|
||||
{
|
||||
m_fog = enable;
|
||||
}
|
||||
|
||||
|
||||
WaterShaderProvider(float water_shader_speed_1,
|
||||
float water_shader_speed_2)
|
||||
{
|
||||
m_dx_1 = 0.0f;
|
||||
m_dy_1 = 0.0f;
|
||||
m_dx_2 = 0.0f;
|
||||
m_dy_2 = 0.0f;
|
||||
|
||||
m_water_shader_speed_1 = water_shader_speed_1/100.0f;
|
||||
m_water_shader_speed_2 = water_shader_speed_2/100.0f;
|
||||
|
||||
m_fog = false;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(
|
||||
irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
m_dx_1 += GUIEngine::getLatestDt()*m_water_shader_speed_1;
|
||||
m_dy_1 += GUIEngine::getLatestDt()*m_water_shader_speed_1;
|
||||
|
||||
m_dx_2 += GUIEngine::getLatestDt()*m_water_shader_speed_2;
|
||||
m_dy_2 -= GUIEngine::getLatestDt()*m_water_shader_speed_2;
|
||||
|
||||
if (m_dx_1 > 1.0f) m_dx_1 -= 1.0f;
|
||||
if (m_dy_1 > 1.0f) m_dy_1 -= 1.0f;
|
||||
if (m_dx_2 > 1.0f) m_dx_2 -= 1.0f;
|
||||
if (m_dy_2 < 0.0f) m_dy_2 += 1.0f;
|
||||
|
||||
s32 decaltex = 0;
|
||||
services->setPixelShaderConstant("DecalTex", &decaltex, 1);
|
||||
|
||||
s32 bumptex = 1;
|
||||
services->setPixelShaderConstant("BumpTex1", &bumptex, 1);
|
||||
|
||||
bumptex = 2;
|
||||
services->setPixelShaderConstant("BumpTex2", &bumptex, 1);
|
||||
|
||||
// We could calculate light direction as coming from the sun (then we'd need to
|
||||
// transform it into camera space). But I find that pretending light
|
||||
// comes from the camera gives good results
|
||||
const float lightdir[] = {-0.315f, 0.91f, -0.3f};
|
||||
services->setVertexShaderConstant("lightdir", lightdir, 3);
|
||||
|
||||
services->setVertexShaderConstant("delta1", &m_dx_1, 2);
|
||||
services->setVertexShaderConstant("delta2", &m_dx_2, 2);
|
||||
|
||||
if (m_fog)
|
||||
{
|
||||
Track* t = World::getWorld()->getTrack();
|
||||
|
||||
float fogStart = t->getFogStart();
|
||||
services->setPixelShaderConstant("fogFrom", &fogStart, 1);
|
||||
|
||||
float fogEnd = t->getFogEnd();
|
||||
services->setPixelShaderConstant("fogTo", &fogEnd, 1);
|
||||
|
||||
video::SColor fogColor = t->getFogColor();
|
||||
float fogColorVec[] = {fogColor.getRed()/255.0f,
|
||||
fogColor.getGreen()/255.0f,
|
||||
fogColor.getBlue()/255.0f, 1.0f};
|
||||
services->setVertexShaderConstant("fogColor", fogColorVec, 4);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// FIXME: refactor this hack to get per-instance properties, and apply the
|
||||
// clean fix to all shaders why we're at it......
|
||||
std::map<int, float> grass_shaders_times;
|
||||
int grass_shaders_times_index = 0;
|
||||
|
||||
class GrassShaderProvider : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
bool m_fog;
|
||||
float m_angle;
|
||||
float m_amplitude;
|
||||
float m_speed;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
|
||||
GrassShaderProvider(float amplitude, float speed)
|
||||
{
|
||||
m_fog = false;
|
||||
m_angle = 0.0f;
|
||||
m_amplitude = amplitude;
|
||||
m_speed = speed;
|
||||
}
|
||||
|
||||
|
||||
void enableFog(bool enable)
|
||||
{
|
||||
m_fog = enable;
|
||||
}
|
||||
|
||||
void update(float dt)
|
||||
{
|
||||
m_angle += GUIEngine::getLatestDt()*m_speed;
|
||||
if (m_angle > M_PI*2) m_angle -= M_PI*2;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
grass_shaders_times[userData] += GUIEngine::getLatestDt()*m_speed;
|
||||
if (grass_shaders_times[userData] > M_PI*2) grass_shaders_times[userData] -= M_PI*2;
|
||||
|
||||
services->setVertexShaderConstant("angle", &grass_shaders_times[userData], 1);
|
||||
|
||||
int fog = (m_fog ? 1 : 0);
|
||||
services->setVertexShaderConstant("fog", &fog, 1);
|
||||
|
||||
s32 tex = 0;
|
||||
services->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
services->setVertexShaderConstant("amplitude", &m_amplitude, 1);
|
||||
|
||||
if (m_fog)
|
||||
{
|
||||
Track* t = World::getWorld()->getTrack();
|
||||
|
||||
float fogStart = t->getFogStart();
|
||||
services->setPixelShaderConstant("fogFrom", &fogStart, 1);
|
||||
|
||||
float fogEnd = t->getFogEnd();
|
||||
services->setPixelShaderConstant("fogTo", &fogEnd, 1);
|
||||
|
||||
video::SColor fogColor = t->getFogColor();
|
||||
float fogColorVec[] = {fogColor.getRed()/255.0f,
|
||||
fogColor.getGreen()/255.0f,
|
||||
fogColor.getBlue()/255.0f, 1.0f};
|
||||
services->setVertexShaderConstant("fogColor", fogColorVec, 4);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
class SplattingProvider : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
core::vector3df m_light_direction;
|
||||
bool m_light_dir_calculated;
|
||||
bool m_lightmap;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
SplattingProvider(bool lightmap)
|
||||
{
|
||||
m_light_dir_calculated = false;
|
||||
m_lightmap = lightmap;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(
|
||||
irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
if (!m_light_dir_calculated)
|
||||
{
|
||||
m_light_dir_calculated = true;
|
||||
m_light_direction = -World::getWorld()->getTrack()->getSunRotation().rotationToDirection();
|
||||
}
|
||||
|
||||
s32 tex_layout = 1;
|
||||
services->setPixelShaderConstant("tex_layout", &tex_layout, 1);
|
||||
|
||||
s32 tex_detail0 = 2;
|
||||
services->setPixelShaderConstant("tex_detail0", &tex_detail0, 1);
|
||||
|
||||
s32 tex_detail1 = 3;
|
||||
services->setPixelShaderConstant("tex_detail1", &tex_detail1, 1);
|
||||
|
||||
s32 tex_detail2 = 4;
|
||||
services->setPixelShaderConstant("tex_detail2", &tex_detail2, 1);
|
||||
|
||||
s32 tex_detail3 = 5;
|
||||
services->setPixelShaderConstant("tex_detail3", &tex_detail3, 1);
|
||||
|
||||
if (m_lightmap)
|
||||
{
|
||||
s32 tex_lightmap = 6;
|
||||
services->setPixelShaderConstant("tex_lightmap", &tex_lightmap, 1);
|
||||
}
|
||||
|
||||
services->setVertexShaderConstant("lightdir", &m_light_direction.X, 3);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
class SphereMapProvider: public video::IShaderConstantSetCallBack
|
||||
{
|
||||
core::vector3df m_light_direction;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
SphereMapProvider()
|
||||
{
|
||||
m_light_direction = core::vector3df(-0.6f, -0.5f, -0.63f);
|
||||
//m_light_direction = core::vector3df(-0.315f, 0.91f, -0.3f);
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(
|
||||
irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
s32 texture = 0;
|
||||
services->setPixelShaderConstant("texture", &texture, 1);
|
||||
|
||||
services->setVertexShaderConstant("lightdir", &m_light_direction.X, 3);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
class BubbleEffectProvider : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
irr::u32 initial_time;
|
||||
float m_transparency;
|
||||
bool m_is_visible;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
BubbleEffectProvider()
|
||||
{
|
||||
initial_time = irr_driver->getDevice()->getTimer()->getRealTime();
|
||||
m_transparency = 1.0f;
|
||||
m_is_visible = true;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(
|
||||
irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
if (m_is_visible && m_transparency < 1.0f)
|
||||
{
|
||||
m_transparency += GUIEngine::getLatestDt()*0.3f;
|
||||
if (m_transparency > 1.0f) m_transparency = 1.0f;
|
||||
}
|
||||
else if (!m_is_visible && m_transparency > 0.0f)
|
||||
{
|
||||
m_transparency -= GUIEngine::getLatestDt()*0.3f;
|
||||
if (m_transparency < 0.0f) m_transparency = 0.0f;
|
||||
}
|
||||
|
||||
float time = (irr_driver->getDevice()->getTimer()->getRealTime() - initial_time) / 1000.0f;
|
||||
services->setVertexShaderConstant("time", &time, 1);
|
||||
services->setVertexShaderConstant("transparency", &m_transparency, 1);
|
||||
}
|
||||
|
||||
void onMadeVisible()
|
||||
{
|
||||
m_is_visible = true;
|
||||
}
|
||||
|
||||
void onHidden()
|
||||
{
|
||||
m_is_visible = false;
|
||||
m_transparency = 0.0f;
|
||||
}
|
||||
|
||||
void isInitiallyHidden()
|
||||
{
|
||||
m_is_visible = false;
|
||||
m_transparency = 0.0f;
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Create a new material using the parameters specified in the xml file.
|
||||
* \param node Node containing the parameters for this material.
|
||||
@ -568,7 +224,10 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
node->get("splatting-texture-2", &m_splatting_texture_2);
|
||||
node->get("splatting-texture-3", &m_splatting_texture_3);
|
||||
node->get("splatting-texture-4", &m_splatting_texture_4);
|
||||
node->get("splatting-lightmap", &m_splatting_lightmap);
|
||||
}
|
||||
else if (s == "caustics")
|
||||
{
|
||||
m_graphical_effect = GE_CAUSTICS;
|
||||
}
|
||||
else if (s == "none")
|
||||
{
|
||||
@ -740,8 +399,6 @@ void Material::init(unsigned int index)
|
||||
m_water_splash = false;
|
||||
m_is_jump_texture = false;
|
||||
|
||||
m_shaders.resize(SHADER_COUNT, NULL);
|
||||
|
||||
for (int n=0; n<EMIT_KINDS_COUNT; n++)
|
||||
{
|
||||
m_particles_effects[n] = NULL;
|
||||
@ -800,20 +457,6 @@ Material::~Material()
|
||||
irr_driver->removeTexture(m_texture);
|
||||
}
|
||||
|
||||
for (unsigned int n=0; n<m_shaders.size(); n++)
|
||||
{
|
||||
if (m_shaders[n])
|
||||
{
|
||||
m_shaders[n]->drop();
|
||||
}
|
||||
}
|
||||
|
||||
for (std::map<scene::IMeshBuffer*, BubbleEffectProvider*>::iterator it = m_bubble_provider.begin();
|
||||
it != m_bubble_provider.end(); it++)
|
||||
{
|
||||
it->second->drop();
|
||||
}
|
||||
|
||||
// If a special sfx is installed (that isn't part of stk itself), the
|
||||
// entry needs to be removed from the sfx_manager's mapping, since other
|
||||
// tracks might use the same name.
|
||||
@ -1032,24 +675,10 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
}
|
||||
if (m_smooth_reflection_shader)
|
||||
{
|
||||
if (UserConfigParams::m_pixel_shaders &&
|
||||
irr_driver->isGLSL())
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
if (m_shaders[SHADER_SPHERE_MAP] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_SPHERE_MAP] = new SphereMapProvider();
|
||||
m->MaterialType = irr_driver->getShader(ES_SPHERE_MAP);
|
||||
}
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
irr_driver->getVideoDriver()->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + "spheremap.vert").c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + "spheremap.frag").c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
m_shaders[SHADER_SPHERE_MAP], video::EMT_SOLID_2_LAYER );
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||
@ -1068,6 +697,12 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
}
|
||||
if (m_graphical_effect == GE_SPHERE_MAP)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_SPHERE_MAP);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||
|
||||
// sphere map + alpha blending is a supported combination so in
|
||||
@ -1081,7 +716,8 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
modes++;
|
||||
}
|
||||
}
|
||||
#if !LIGHTMAP_VISUALISATION
|
||||
}
|
||||
|
||||
if (m_lightmap)
|
||||
{
|
||||
m->MaterialType = video::EMT_LIGHTMAP;
|
||||
@ -1092,7 +728,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
m->MaterialType = video::EMT_LIGHTMAP_ADD;
|
||||
modes++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_add)
|
||||
{
|
||||
//m->MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||
@ -1111,8 +747,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
if (m_graphical_effect == GE_NORMAL_MAP)
|
||||
{
|
||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
if (UserConfigParams::m_pixel_shaders &&
|
||||
irr_driver->isGLSL())
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
if (m_is_heightmap)
|
||||
@ -1130,37 +765,9 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
with_lightmap = true;
|
||||
}
|
||||
|
||||
if (with_lightmap)
|
||||
{
|
||||
if (m_shaders[SHADER_NORMAL_MAP_WITH_LIGHTMAP] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_NORMAL_MAP_WITH_LIGHTMAP] =
|
||||
new NormalMapProvider(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_shaders[SHADER_NORMAL_MAP] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_NORMAL_MAP] = new NormalMapProvider(false);
|
||||
}
|
||||
}
|
||||
|
||||
const char* vertex_shader = "normalmap.vert";
|
||||
const char* pixel_shader = "normalmap.frag";
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
video_driver->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + vertex_shader).c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + pixel_shader).c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
m_shaders[with_lightmap ? SHADER_NORMAL_MAP_WITH_LIGHTMAP
|
||||
: SHADER_NORMAL_MAP],
|
||||
video::EMT_SOLID_2_LAYER );
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
m->MaterialType = irr_driver->getShader(
|
||||
with_lightmap ? ES_NORMAL_MAP_LIGHTMAP : ES_NORMAL_MAP );
|
||||
m->Lighting = false;
|
||||
m->ZWriteEnable = true;
|
||||
|
||||
@ -1210,64 +817,20 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
}
|
||||
m->setTexture(5, tex);
|
||||
|
||||
if (m_splatting_lightmap.size() > 0)
|
||||
{
|
||||
tex = irr_driver->getTexture(m_splatting_lightmap);
|
||||
}
|
||||
m->setTexture(6, tex);
|
||||
|
||||
if (m_splatting_lightmap.size() > 0)
|
||||
{
|
||||
if (m_shaders[SHADER_SPLATTING_LIGHTMAP] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_SPLATTING_LIGHTMAP] =
|
||||
new SplattingProvider(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_shaders[SHADER_SPLATTING] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_SPLATTING] = new SplattingProvider(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
irr_driver->getVideoDriver()->getGPUProgrammingServices();
|
||||
|
||||
if (m_splatting_lightmap.size() > 0)
|
||||
{
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir()
|
||||
+ "splatting_lightmap.vert").c_str(),
|
||||
"main",video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir()
|
||||
+ "splatting_lightmap.frag").c_str(),
|
||||
"main",video::EPST_PS_2_0,
|
||||
m_shaders[SHADER_SPLATTING_LIGHTMAP],
|
||||
video::EMT_SOLID );
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
m->MaterialType = irr_driver->getShader(ES_SPLATTING);
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir()
|
||||
+ "splatting.vert").c_str(),
|
||||
"main",video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir()
|
||||
+ "splatting.frag").c_str(),
|
||||
"main",video::EPST_PS_2_0,
|
||||
m_shaders[SHADER_SPLATTING], video::EMT_SOLID );
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
m->MaterialType = video::EMT_SOLID;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (m_graphical_effect == GE_CAUSTICS && irr_driver->isGLSL())
|
||||
{
|
||||
m->MaterialType = video::EMT_SOLID;
|
||||
m->MaterialType = irr_driver->getShader(ES_CAUSTICS);
|
||||
|
||||
m->setTexture(1, irr_driver->getTexture((file_manager->getTextureDir() + "caustics.png").c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Modify lightmap materials so that vertex colors are taken into account.
|
||||
@ -1284,26 +847,14 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
|
||||
if (m_graphical_effect == GE_BUBBLE && mb != NULL)
|
||||
{
|
||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
if (UserConfigParams::m_pixel_shaders &&
|
||||
irr_driver->isGLSL())
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
if (m_bubble_provider.find(mb) == m_bubble_provider.end())
|
||||
{
|
||||
m_bubble_provider[mb] = new BubbleEffectProvider();
|
||||
}
|
||||
BubbleEffectProvider * bubble = (BubbleEffectProvider *)
|
||||
irr_driver->getCallback(ES_BUBBLES);
|
||||
bubble->addBubble(mb);
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu = video_driver->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + "bubble.vert").c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + "bubble.frag").c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
m_bubble_provider[mb],
|
||||
(m_alpha_blending ? video::EMT_TRANSPARENT_ALPHA_CHANNEL
|
||||
: video::EMT_SOLID) );
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
m->MaterialType = irr_driver->getShader(ES_BUBBLES);
|
||||
m->BlendOperation = video::EBO_ADD;
|
||||
|
||||
// alpha blending and bubble shading can work together so when both are enabled
|
||||
// don't increment the 'modes' counter to not get the 'too many modes' warning
|
||||
@ -1317,70 +868,40 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
|
||||
if (m_graphical_effect == GE_WATER_SHADER)
|
||||
{
|
||||
if (UserConfigParams::m_pixel_shaders &&
|
||||
irr_driver->isGLSL())
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
if (m_shaders[SHADER_WATER] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_WATER] =
|
||||
new WaterShaderProvider(m_water_shader_speed_1,
|
||||
m_water_shader_speed_2);
|
||||
}
|
||||
|
||||
m->setTexture(1, irr_driver->getTexture(file_manager->getTextureFile("waternormals.jpg")));
|
||||
m->setTexture(2, irr_driver->getTexture(file_manager->getTextureFile("waternormals2.jpg")));
|
||||
|
||||
bool fog = World::getWorld()->getTrack()->isFogEnabled();
|
||||
const char* vertex_shader = (fog ? "water_fog.vert" : "water.vert");
|
||||
const char* pixel_shader = (fog ? "water_fog.frag" : "water.frag");
|
||||
((WaterShaderProvider *) irr_driver->getCallback(ES_WATER))->
|
||||
setSpeed(m_water_shader_speed_1/100.0f, m_water_shader_speed_2/100.0f);
|
||||
|
||||
((WaterShaderProvider*)m_shaders[SHADER_WATER])->enableFog(fog);
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
irr_driver->getVideoDriver()->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + vertex_shader).c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + pixel_shader ).c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
m_shaders[SHADER_WATER],
|
||||
video::EMT_TRANSPARENT_ALPHA_CHANNEL);
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
m->MaterialType = irr_driver->getShader(ES_WATER);
|
||||
}
|
||||
modes++;
|
||||
}
|
||||
|
||||
if (m_graphical_effect == GE_GRASS)
|
||||
{
|
||||
if (UserConfigParams::m_pixel_shaders &&
|
||||
if (UserConfigParams::m_weather_effects &&
|
||||
irr_driver->isGLSL())
|
||||
{
|
||||
if (m_shaders[SHADER_GRASS] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_GRASS] =
|
||||
new GrassShaderProvider(m_grass_amplitude, m_grass_speed);
|
||||
}
|
||||
|
||||
bool fog = World::getWorld()->getTrack()->isFogEnabled();
|
||||
((GrassShaderProvider*)m_shaders[SHADER_GRASS])->enableFog(fog);
|
||||
|
||||
grass_shaders_times[grass_shaders_times_index] = (rand() % 500)/500.0f * M_PI * 2.0f;
|
||||
// Only one grass speed & amplitude per map for now
|
||||
((GrassShaderProvider *) irr_driver->getCallback(ES_GRASS))->
|
||||
setSpeed(m_grass_speed);
|
||||
((GrassShaderProvider *) irr_driver->getCallback(ES_GRASS))->
|
||||
setAmplitude(m_grass_amplitude);
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
irr_driver->getVideoDriver()->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + "grass.vert").c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + "grass.frag").c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
m_shaders[SHADER_GRASS],
|
||||
video::EMT_TRANSPARENT_ALPHA_CHANNEL,
|
||||
grass_shaders_times_index);
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
if (m_alpha_testing)
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_GRASS_REF);
|
||||
}
|
||||
else {
|
||||
m->MaterialType = irr_driver->getShader(ES_GRASS);
|
||||
m->BlendOperation = video::EBO_ADD;
|
||||
}
|
||||
|
||||
grass_shaders_times_index++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1475,6 +996,10 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
void Material::adjustForFog(scene::ISceneNode* parent, video::SMaterial *m,
|
||||
bool use_fog) const
|
||||
{
|
||||
// The new pipeline does fog as a post-process effect.
|
||||
if (irr_driver->isGLSL())
|
||||
return;
|
||||
|
||||
m->setFlag(video::EMF_FOG_ENABLE, m_fog && use_fog);
|
||||
|
||||
if (parent != NULL)
|
||||
@ -1488,10 +1013,9 @@ void Material::adjustForFog(scene::ISceneNode* parent, video::SMaterial *m,
|
||||
/** Callback from LOD nodes to create some effects */
|
||||
void Material::onMadeVisible(scene::IMeshBuffer* who)
|
||||
{
|
||||
if (m_bubble_provider.find(who) != m_bubble_provider.end())
|
||||
{
|
||||
m_bubble_provider[who]->onMadeVisible();
|
||||
}
|
||||
BubbleEffectProvider * bubble = (BubbleEffectProvider *)
|
||||
irr_driver->getCallback(ES_BUBBLES);
|
||||
bubble->onMadeVisible(who);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1499,20 +1023,18 @@ void Material::onMadeVisible(scene::IMeshBuffer* who)
|
||||
/** Callback from LOD nodes to create some effects */
|
||||
void Material::onHidden(scene::IMeshBuffer* who)
|
||||
{
|
||||
if (m_bubble_provider.find(who) != m_bubble_provider.end())
|
||||
{
|
||||
m_bubble_provider[who]->onHidden();
|
||||
}
|
||||
BubbleEffectProvider * bubble = (BubbleEffectProvider *)
|
||||
irr_driver->getCallback(ES_BUBBLES);
|
||||
bubble->onHidden(who);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Material::isInitiallyHidden(scene::IMeshBuffer* who)
|
||||
{
|
||||
if (m_bubble_provider.find(who) != m_bubble_provider.end())
|
||||
{
|
||||
m_bubble_provider[who]->isInitiallyHidden();
|
||||
}
|
||||
BubbleEffectProvider * bubble = (BubbleEffectProvider *)
|
||||
irr_driver->getCallback(ES_BUBBLES);
|
||||
bubble->isInitiallyHidden(who);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -28,8 +28,6 @@
|
||||
|
||||
#include <IShaderConstantSetCallBack.h>
|
||||
|
||||
#define LIGHTMAP_VISUALISATION 0
|
||||
|
||||
|
||||
namespace irr
|
||||
{
|
||||
@ -42,10 +40,6 @@ class XMLNode;
|
||||
class SFXBase;
|
||||
class ParticleKind;
|
||||
|
||||
class NormalMapProvider;
|
||||
class SplattingProvider;
|
||||
class BubbleEffectProvider;
|
||||
|
||||
/**
|
||||
* \ingroup graphics
|
||||
*/
|
||||
@ -60,7 +54,8 @@ public:
|
||||
GE_WATER_SHADER,
|
||||
GE_SPHERE_MAP,
|
||||
GE_SPLATTING,
|
||||
GE_NORMAL_MAP};
|
||||
GE_NORMAL_MAP,
|
||||
GE_CAUSTICS};
|
||||
|
||||
enum ParticleConditions
|
||||
{
|
||||
@ -80,18 +75,6 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
enum Shaders
|
||||
{
|
||||
SHADER_NORMAL_MAP,
|
||||
SHADER_NORMAL_MAP_WITH_LIGHTMAP,
|
||||
SHADER_SPLATTING,
|
||||
SHADER_WATER,
|
||||
SHADER_SPHERE_MAP,
|
||||
SHADER_SPLATTING_LIGHTMAP,
|
||||
SHADER_GRASS,
|
||||
SHADER_COUNT
|
||||
};
|
||||
|
||||
video::ITexture *m_texture;
|
||||
unsigned int m_index;
|
||||
std::string m_texname;
|
||||
@ -234,13 +217,6 @@ private:
|
||||
/** If m_splatting is true, indicates the fourth splatting texture */
|
||||
std::string m_splatting_texture_4;
|
||||
|
||||
std::string m_splatting_lightmap;
|
||||
|
||||
std::vector<irr::video::IShaderConstantSetCallBack*> m_shaders;
|
||||
|
||||
/** Only used if bubble effect is enabled */
|
||||
std::map<scene::IMeshBuffer*, BubbleEffectProvider*> m_bubble_provider;
|
||||
|
||||
bool m_deprecated;
|
||||
|
||||
void init (unsigned int index);
|
||||
|
@ -60,10 +60,6 @@ MaterialManager::~MaterialManager()
|
||||
m_materials.clear();
|
||||
} // ~MaterialManager
|
||||
|
||||
#if LIGHTMAP_VISUALISATION
|
||||
std::set<scene::IMeshBuffer*> g_processed;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Material* MaterialManager::getMaterialFor(video::ITexture* t,
|
||||
|
200
src/graphics/mlaa_areamap.hpp
Normal file
200
src/graphics/mlaa_areamap.hpp
Normal file
@ -0,0 +1,200 @@
|
||||
#ifndef AREAMAP_H
|
||||
#define AREAMAP_H
|
||||
|
||||
static const unsigned char AreaMap33[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa5,
|
||||
0x08, 0x04, 0x00, 0x00, 0x00, 0x97, 0x22, 0xf5, 0x51, 0x00, 0x00, 0x00,
|
||||
0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
|
||||
0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x87, 0x8f, 0xcc, 0xbf,
|
||||
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13,
|
||||
0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00,
|
||||
0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, 0x07, 0x09, 0x17, 0x12,
|
||||
0x5f, 0x51, 0x45, 0x04, 0x00, 0x00, 0x08, 0x87, 0x49, 0x44, 0x41, 0x54,
|
||||
0x78, 0xda, 0xed, 0x5d, 0x4b, 0x6e, 0xdb, 0x48, 0x14, 0x2c, 0x89, 0x2f,
|
||||
0x4e, 0xe2, 0x09, 0x30, 0x9b, 0x38, 0x5b, 0xf9, 0x24, 0x73, 0xbb, 0xb9,
|
||||
0x49, 0x6e, 0x32, 0x67, 0x98, 0x7d, 0xbc, 0xf2, 0xc2, 0x18, 0x78, 0x31,
|
||||
0x81, 0xc6, 0xa6, 0xc4, 0xd7, 0xc3, 0x8f, 0x1a, 0x0d, 0x9a, 0x92, 0x5b,
|
||||
0x64, 0x91, 0x7a, 0x1d, 0xa1, 0xab, 0x41, 0x28, 0x41, 0x80, 0x42, 0xd5,
|
||||
0x63, 0x93, 0x32, 0x9c, 0x42, 0x35, 0xc0, 0x63, 0x03, 0x73, 0x6c, 0x60,
|
||||
0x8f, 0x35, 0x78, 0xdc, 0xe3, 0x16, 0x2c, 0x78, 0x09, 0x57, 0x31, 0xca,
|
||||
0x6f, 0xb8, 0xc3, 0x0d, 0x68, 0xd8, 0x4b, 0xb0, 0x1f, 0xe5, 0x2d, 0xbe,
|
||||
0xe2, 0x77, 0x08, 0x48, 0xd8, 0x4b, 0xb0, 0x1f, 0xe5, 0x47, 0x7c, 0xa9,
|
||||
0x7d, 0xfc, 0x86, 0x02, 0x06, 0x48, 0x46, 0x02, 0x64, 0x16, 0x8e, 0xcf,
|
||||
0xb5, 0x8b, 0x17, 0x54, 0xd8, 0x42, 0x41, 0xc0, 0x5a, 0x82, 0xfd, 0x28,
|
||||
0x0b, 0x7c, 0xac, 0x9d, 0xdc, 0x62, 0x07, 0xc5, 0x0b, 0xe1, 0xc4, 0x5c,
|
||||
0x82, 0xfd, 0x28, 0xd7, 0xb8, 0xa9, 0x9d, 0x7c, 0xc2, 0x2b, 0xf6, 0x70,
|
||||
0x78, 0x25, 0x9c, 0x98, 0x4b, 0xb0, 0x1f, 0xa5, 0x1c, 0x9c, 0xec, 0xa1,
|
||||
0x50, 0x94, 0x70, 0x20, 0x60, 0x27, 0xc1, 0x7e, 0x94, 0x2b, 0x14, 0xf8,
|
||||
0x50, 0xaf, 0xda, 0x4b, 0xeb, 0x04, 0x84, 0x13, 0x73, 0x09, 0xf6, 0xa3,
|
||||
0x94, 0xd6, 0x47, 0x59, 0x3b, 0x51, 0x28, 0x1c, 0x76, 0x84, 0x13, 0x53,
|
||||
0x09, 0xf6, 0xa3, 0x2c, 0xf0, 0xa1, 0xf5, 0xb2, 0xc7, 0xbe, 0xf5, 0xe1,
|
||||
0xb0, 0x27, 0x9c, 0x98, 0x49, 0xb0, 0x1f, 0xe5, 0x1a, 0xd2, 0x38, 0xf1,
|
||||
0x3e, 0x5a, 0x27, 0x20, 0x9c, 0x18, 0x4a, 0xb0, 0x1f, 0x65, 0xe7, 0x44,
|
||||
0xda, 0x6d, 0x51, 0x1d, 0x9c, 0x38, 0x54, 0x84, 0x13, 0x13, 0x09, 0xf6,
|
||||
0xa3, 0xf4, 0x4e, 0xe4, 0xe0, 0xc4, 0xfb, 0x00, 0xe1, 0xc4, 0x40, 0x82,
|
||||
0xfd, 0x28, 0x81, 0x35, 0x8a, 0x6e, 0xb5, 0x3e, 0x2a, 0x54, 0x84, 0x13,
|
||||
0x53, 0x09, 0xf6, 0xbb, 0xd2, 0x6f, 0x8a, 0xe0, 0x26, 0xf8, 0x70, 0xa8,
|
||||
0xc0, 0x23, 0x7d, 0x09, 0x90, 0x79, 0x9c, 0xf4, 0x3c, 0x54, 0xa8, 0xda,
|
||||
0x4f, 0x77, 0x58, 0x20, 0x9c, 0x18, 0x48, 0xb0, 0x1f, 0xa5, 0xf7, 0xb2,
|
||||
0x46, 0xd8, 0x14, 0xda, 0xba, 0x00, 0xe1, 0xc4, 0x48, 0x82, 0xfd, 0x03,
|
||||
0x1e, 0x9e, 0x30, 0x6d, 0x2f, 0x47, 0x6c, 0x8b, 0x5f, 0x4d, 0x02, 0x64,
|
||||
0x36, 0x27, 0xc1, 0xc5, 0x3a, 0xf8, 0x68, 0x2e, 0x62, 0x5b, 0x18, 0x48,
|
||||
0xb0, 0x1e, 0x25, 0x06, 0x9b, 0xa2, 0x7a, 0xe3, 0xc3, 0x2d, 0xe8, 0x84,
|
||||
0x90, 0x90, 0xe6, 0xbb, 0xb2, 0xbf, 0x0a, 0x68, 0xbb, 0x0a, 0xb8, 0x76,
|
||||
0x15, 0x40, 0xfb, 0xa9, 0x60, 0xc1, 0x4b, 0x48, 0xfb, 0x5d, 0x39, 0xd8,
|
||||
0x14, 0x55, 0xf7, 0x19, 0x5e, 0x54, 0x07, 0x2f, 0x20, 0x9c, 0x18, 0x48,
|
||||
0xb0, 0x7a, 0xc0, 0xfb, 0x4e, 0xb4, 0x59, 0xfe, 0x6f, 0xde, 0x05, 0xe1,
|
||||
0x24, 0x79, 0x09, 0x32, 0xf3, 0x17, 0xa8, 0x77, 0x12, 0xf4, 0xf7, 0x9f,
|
||||
0x2e, 0x47, 0x38, 0x31, 0x90, 0x60, 0xbd, 0x2b, 0x87, 0xab, 0xf0, 0x5e,
|
||||
0x88, 0x6d, 0x91, 0xbc, 0x04, 0x99, 0xd7, 0xc5, 0x09, 0x2f, 0xae, 0xbd,
|
||||
0xc2, 0x96, 0x70, 0x11, 0x27, 0x56, 0x12, 0xec, 0xbf, 0x76, 0x06, 0x4f,
|
||||
0x58, 0x70, 0x13, 0x5e, 0x53, 0x7d, 0x17, 0x88, 0x38, 0xb1, 0x95, 0x60,
|
||||
0xbf, 0x2b, 0x7b, 0x0e, 0x56, 0x6f, 0x36, 0x44, 0xe1, 0x5d, 0xb4, 0x9f,
|
||||
0x8e, 0x70, 0x62, 0x20, 0xc1, 0xe0, 0x5d, 0x79, 0xf4, 0x09, 0x53, 0xac,
|
||||
0xfb, 0xef, 0x7d, 0x62, 0x5b, 0x24, 0x2c, 0x41, 0xe6, 0x77, 0x32, 0xfc,
|
||||
0x1a, 0xed, 0xd4, 0x7b, 0x3f, 0xde, 0x07, 0xe1, 0x24, 0x49, 0x09, 0x32,
|
||||
0xf7, 0x4f, 0xc8, 0xde, 0x4b, 0xcf, 0x55, 0x70, 0xb1, 0x1e, 0xf8, 0x70,
|
||||
0x70, 0xd7, 0x21, 0x61, 0x85, 0x0d, 0xee, 0xf1, 0x0d, 0xb7, 0xf8, 0x08,
|
||||
0x41, 0x71, 0xb8, 0x9d, 0x61, 0x85, 0x37, 0x3a, 0xfc, 0xe7, 0xe0, 0x4f,
|
||||
0x7f, 0x61, 0x45, 0x32, 0xfc, 0x09, 0x12, 0x9b, 0xcd, 0x03, 0xe9, 0x62,
|
||||
0xf3, 0x9d, 0x65, 0x10, 0x3c, 0xe0, 0x09, 0x77, 0xf8, 0x8a, 0x2f, 0xf8,
|
||||
0x5c, 0xd3, 0xdc, 0xb4, 0x44, 0x85, 0x27, 0xeb, 0x11, 0x22, 0x90, 0xf6,
|
||||
0xc8, 0x57, 0xf8, 0x1b, 0x3f, 0x28, 0x06, 0x1a, 0xf7, 0x0f, 0x4f, 0x4f,
|
||||
0x5b, 0xca, 0x05, 0xcf, 0x20, 0x00, 0xb6, 0x78, 0xc4, 0xb6, 0xcd, 0xd4,
|
||||
0x75, 0x24, 0x1f, 0x5a, 0x1a, 0x69, 0x49, 0x8a, 0x37, 0x3f, 0x5d, 0xe0,
|
||||
0x08, 0xe1, 0x37, 0xfc, 0xc0, 0x3f, 0x0c, 0xc3, 0x2c, 0x51, 0xd5, 0xed,
|
||||
0xe3, 0x63, 0x49, 0x68, 0xe0, 0x19, 0x04, 0x0d, 0x4a, 0x3c, 0xd7, 0xd7,
|
||||
0x0b, 0x6e, 0xf1, 0xa9, 0x26, 0xf9, 0xd0, 0xae, 0x8e, 0xa4, 0xe8, 0xd1,
|
||||
0xd4, 0xd7, 0x60, 0x75, 0x39, 0xd1, 0x2d, 0xfe, 0x25, 0x18, 0x38, 0x78,
|
||||
0x09, 0xe5, 0xf3, 0xf3, 0x7e, 0xb2, 0x06, 0x9e, 0x41, 0xd0, 0x61, 0x8f,
|
||||
0x9f, 0xa8, 0xb0, 0xc3, 0x6b, 0x4d, 0x72, 0x53, 0x2f, 0x39, 0x90, 0x14,
|
||||
0x07, 0x1a, 0xbf, 0x56, 0x43, 0xa2, 0x43, 0x4e, 0xb4, 0xc4, 0x7f, 0x93,
|
||||
0x19, 0x58, 0x78, 0x09, 0xfb, 0x9f, 0x3f, 0xab, 0x89, 0x1a, 0x78, 0x06,
|
||||
0x81, 0x47, 0x97, 0xf2, 0xdc, 0xd7, 0xeb, 0x23, 0xca, 0xf6, 0x7e, 0x88,
|
||||
0x7f, 0x5f, 0xf4, 0x49, 0x06, 0xf7, 0xe5, 0x16, 0x3e, 0x27, 0xfa, 0x32,
|
||||
0x8d, 0x61, 0xc6, 0xa8, 0x6a, 0xb5, 0xdd, 0xea, 0x24, 0x0d, 0x73, 0x30,
|
||||
0x04, 0x68, 0xcd, 0xe4, 0xa0, 0x0d, 0x49, 0x4b, 0x25, 0x81, 0x24, 0xdc,
|
||||
0x93, 0x01, 0xc9, 0xba, 0x97, 0x13, 0x2d, 0xa7, 0x30, 0xcc, 0x1a, 0x55,
|
||||
0xd5, 0x97, 0x17, 0x9d, 0xa0, 0x81, 0x67, 0x90, 0x9e, 0x22, 0xc5, 0x2b,
|
||||
0xb4, 0x59, 0x2d, 0x85, 0xbf, 0x1f, 0xd2, 0x12, 0x78, 0x8a, 0x21, 0x4d,
|
||||
0x3f, 0x27, 0xba, 0x1b, 0xcf, 0x30, 0x73, 0x54, 0x55, 0x5f, 0x5f, 0x75,
|
||||
0xb4, 0x06, 0x9e, 0x41, 0xd0, 0x87, 0xa2, 0x04, 0xd0, 0xd1, 0x54, 0x6d,
|
||||
0xf8, 0xa6, 0x40, 0xd5, 0x11, 0x9c, 0x22, 0x19, 0xe4, 0x44, 0x77, 0x63,
|
||||
0x19, 0x66, 0x8f, 0xaa, 0x6a, 0x59, 0xba, 0x91, 0x1a, 0x78, 0x06, 0xc1,
|
||||
0x5b, 0x38, 0x94, 0x70, 0xf5, 0xf2, 0x34, 0xd2, 0x50, 0x44, 0xb6, 0xf7,
|
||||
0xdb, 0x9c, 0xe8, 0x6e, 0x1c, 0xc3, 0x02, 0x51, 0x55, 0x57, 0x8f, 0x62,
|
||||
0x94, 0x06, 0x9e, 0x41, 0x30, 0x84, 0xeb, 0x8d, 0x42, 0xfd, 0xff, 0xce,
|
||||
0xfb, 0x3b, 0xe3, 0x29, 0x02, 0xd1, 0x91, 0x9c, 0xe8, 0x7e, 0x0c, 0xc3,
|
||||
0x22, 0x51, 0x55, 0xb7, 0xdb, 0xb9, 0x11, 0x1a, 0x78, 0x06, 0xc1, 0x11,
|
||||
0xb4, 0xa3, 0x00, 0x3c, 0x8d, 0x34, 0x34, 0xed, 0x52, 0xac, 0x9b, 0xab,
|
||||
0x4f, 0x72, 0x22, 0x27, 0x5a, 0xa1, 0x3c, 0x97, 0x61, 0xa1, 0xa8, 0xaa,
|
||||
0xdb, 0xef, 0xdd, 0xd9, 0x2e, 0x78, 0x06, 0xc1, 0x71, 0x74, 0xfb, 0xca,
|
||||
0x2f, 0xf5, 0x2b, 0x50, 0x04, 0xa2, 0x13, 0x39, 0xd1, 0x12, 0xd5, 0xb9,
|
||||
0x0c, 0x8b, 0x45, 0x55, 0x9b, 0x51, 0x9c, 0xa9, 0x81, 0x67, 0x10, 0x1c,
|
||||
0x87, 0x8f, 0x7f, 0x79, 0x0a, 0xff, 0x59, 0x34, 0x57, 0x9f, 0xe2, 0x9d,
|
||||
0x9c, 0xa8, 0x62, 0x77, 0x0e, 0xc3, 0x82, 0x51, 0x55, 0x57, 0x55, 0xee,
|
||||
0x2c, 0x17, 0x3c, 0x83, 0x00, 0x91, 0x61, 0x06, 0x1a, 0x45, 0xd1, 0xfd,
|
||||
0x8e, 0xaa, 0x4f, 0xf1, 0x4e, 0x4e, 0x74, 0x07, 0xc5, 0x3e, 0xce, 0xb0,
|
||||
0x68, 0x54, 0xb5, 0x1d, 0x45, 0x5c, 0x03, 0xcf, 0x20, 0x40, 0x64, 0x98,
|
||||
0x2d, 0x1b, 0x9c, 0x5f, 0x03, 0x8a, 0xf5, 0xbb, 0x39, 0xd1, 0x3d, 0x14,
|
||||
0xbb, 0x18, 0xc3, 0x62, 0x51, 0xd5, 0x30, 0x8a, 0xa8, 0x0b, 0x9e, 0x41,
|
||||
0x80, 0xe8, 0x30, 0x71, 0x94, 0xa2, 0x80, 0xeb, 0xde, 0x17, 0x91, 0x9c,
|
||||
0xe8, 0x2e, 0xce, 0xb0, 0x78, 0x54, 0xd5, 0x55, 0x51, 0x0d, 0x3c, 0x83,
|
||||
0x20, 0x8e, 0xaa, 0xa5, 0xf0, 0x44, 0x45, 0x77, 0x75, 0x44, 0xed, 0x67,
|
||||
0x3c, 0x27, 0x1a, 0x67, 0x58, 0x3e, 0xaa, 0x1a, 0xd1, 0xc0, 0x33, 0x08,
|
||||
0xce, 0x81, 0xbf, 0x23, 0x05, 0xd0, 0x11, 0xf4, 0x62, 0x0f, 0x91, 0x9c,
|
||||
0x68, 0x9c, 0xe1, 0x42, 0x51, 0xd5, 0x88, 0x06, 0x96, 0x41, 0x80, 0x11,
|
||||
0xc3, 0x0c, 0x34, 0xcd, 0xea, 0x48, 0xf4, 0x9c, 0x9c, 0x68, 0x84, 0xe1,
|
||||
0x52, 0x51, 0xd5, 0x77, 0x34, 0xf0, 0x0c, 0x82, 0x73, 0x51, 0xf5, 0xee,
|
||||
0x87, 0x27, 0x51, 0xac, 0xe3, 0x39, 0xd1, 0x18, 0xc3, 0x05, 0xa3, 0xaa,
|
||||
0x27, 0x35, 0xf0, 0x0c, 0x82, 0xf3, 0x51, 0x21, 0x44, 0x1b, 0x3c, 0xf7,
|
||||
0x1a, 0xee, 0xbc, 0x9c, 0x68, 0x84, 0xe1, 0x72, 0x51, 0xd5, 0x13, 0x1a,
|
||||
0x78, 0x06, 0xc1, 0x18, 0x28, 0x02, 0x05, 0x0e, 0x44, 0xeb, 0xb1, 0x39,
|
||||
0xd1, 0x21, 0xc3, 0x85, 0xa3, 0xaa, 0x47, 0x35, 0xf0, 0x0c, 0x82, 0x71,
|
||||
0x50, 0x04, 0xb8, 0x6e, 0x11, 0x39, 0x51, 0xff, 0xaf, 0x97, 0x8e, 0xaa,
|
||||
0x1e, 0xd1, 0xc0, 0x33, 0x08, 0x30, 0x71, 0x98, 0xce, 0xaf, 0xa9, 0x39,
|
||||
0xd1, 0xc0, 0x60, 0x10, 0x55, 0x1d, 0x68, 0xe0, 0x19, 0x04, 0x98, 0x34,
|
||||
0x4c, 0x47, 0xe7, 0x44, 0x9d, 0x71, 0x54, 0xd5, 0x6b, 0x20, 0x19, 0xd8,
|
||||
0xa0, 0x8b, 0xf6, 0xee, 0xc7, 0xc4, 0x9c, 0x68, 0x60, 0x30, 0x8a, 0xaa,
|
||||
0xf6, 0x34, 0xf0, 0x0c, 0x82, 0x69, 0xd0, 0xab, 0x88, 0xaa, 0xea, 0x9c,
|
||||
0x0c, 0x82, 0xa9, 0xd0, 0xab, 0x88, 0xaa, 0xea, 0x7c, 0x0c, 0x42, 0xe8,
|
||||
0xd7, 0xab, 0x88, 0xaa, 0xea, 0x5c, 0x0c, 0x02, 0x06, 0x7a, 0x15, 0x51,
|
||||
0x55, 0x9d, 0x87, 0x41, 0xc0, 0x41, 0xe1, 0xe8, 0x9c, 0xa8, 0x33, 0x8f,
|
||||
0xaa, 0x2a, 0x1c, 0xcf, 0x20, 0x60, 0xe1, 0xae, 0x22, 0xaa, 0xea, 0xc0,
|
||||
0x33, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
|
||||
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
|
||||
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
|
||||
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x83, 0x15, 0x5f, 0xaa,
|
||||
0xfa, 0x7d, 0x73, 0xff, 0x60, 0x5c, 0xaa, 0x8a, 0x3f, 0xb0, 0x32, 0x77,
|
||||
0x21, 0x7c, 0xa9, 0xea, 0xc3, 0xfd, 0xd3, 0xd3, 0xdd, 0x96, 0x61, 0xe0,
|
||||
0xc1, 0x17, 0xbb, 0xf2, 0x2e, 0x84, 0x2f, 0x55, 0xc5, 0xb7, 0xed, 0xdd,
|
||||
0xe3, 0xe3, 0xb6, 0x24, 0x18, 0x68, 0xf0, 0xc5, 0xae, 0xbc, 0x0b, 0x61,
|
||||
0x4b, 0x55, 0xbb, 0x4a, 0xd3, 0x72, 0xfb, 0xfc, 0x5c, 0xee, 0x8d, 0x4a,
|
||||
0x55, 0x43, 0xb1, 0xab, 0xa9, 0x0b, 0xe1, 0x4b, 0x55, 0xbb, 0x4a, 0xd3,
|
||||
0x7d, 0xd9, 0xf4, 0x91, 0x1a, 0x95, 0xaa, 0x86, 0x62, 0x57, 0x43, 0x17,
|
||||
0xc2, 0x97, 0xaa, 0xfa, 0x4a, 0xd3, 0xae, 0x8f, 0x74, 0x0a, 0x03, 0x0f,
|
||||
0xa1, 0x8b, 0x5d, 0x79, 0x17, 0xc2, 0x97, 0xaa, 0x86, 0x4a, 0xd3, 0xa6,
|
||||
0x8f, 0xd4, 0xe9, 0x78, 0x06, 0x1e, 0x7c, 0xb1, 0x2b, 0xef, 0x42, 0xe8,
|
||||
0x52, 0xd5, 0x5e, 0xa5, 0xa9, 0xba, 0xa6, 0x8f, 0x74, 0x2c, 0x03, 0x0f,
|
||||
0xbe, 0xd8, 0x95, 0x77, 0x21, 0x7c, 0xa9, 0x6a, 0xbf, 0xd2, 0x54, 0xb5,
|
||||
0x2c, 0xe1, 0xc6, 0x31, 0xf0, 0xe0, 0x8b, 0x5d, 0x79, 0x17, 0x42, 0x97,
|
||||
0xaa, 0x0e, 0x2a, 0x4d, 0x1d, 0x9a, 0x3e, 0xd2, 0x31, 0x0c, 0x3c, 0xf8,
|
||||
0x62, 0x57, 0xde, 0x85, 0xf0, 0xa5, 0xaa, 0xc3, 0x4a, 0xd3, 0xae, 0x8f,
|
||||
0x74, 0x04, 0x03, 0x0d, 0xbe, 0xd8, 0x95, 0x77, 0x21, 0x74, 0xa9, 0xea,
|
||||
0xd1, 0x4a, 0xd3, 0xa6, 0x8f, 0x14, 0xee, 0x5c, 0x06, 0x1e, 0x7c, 0xb1,
|
||||
0x2b, 0xef, 0x42, 0xe8, 0x52, 0xd5, 0x13, 0x95, 0xa6, 0x0e, 0x4d, 0x1f,
|
||||
0xe9, 0x79, 0x0c, 0x3c, 0xf8, 0x62, 0x57, 0xde, 0x85, 0xd0, 0xa5, 0xaa,
|
||||
0x27, 0x2b, 0x4d, 0xdb, 0xa2, 0x42, 0x77, 0x0e, 0x03, 0x0f, 0xbe, 0xd8,
|
||||
0x95, 0x77, 0x21, 0x7c, 0xa9, 0xea, 0xe9, 0x4a, 0x53, 0x87, 0x46, 0x46,
|
||||
0x9c, 0x81, 0x07, 0x5f, 0xec, 0xca, 0xbb, 0x10, 0xba, 0x54, 0xf5, 0x44,
|
||||
0xa5, 0x69, 0x90, 0xe1, 0x5c, 0x8c, 0x81, 0x07, 0x5f, 0xec, 0xca, 0xbb,
|
||||
0x10, 0xba, 0x54, 0x35, 0x52, 0x69, 0xda, 0x3c, 0x20, 0x31, 0x06, 0x1e,
|
||||
0x7c, 0xb1, 0x2b, 0xef, 0x42, 0xf8, 0x52, 0xd5, 0x78, 0xa5, 0x69, 0x55,
|
||||
0x45, 0x18, 0x48, 0x44, 0x25, 0x5c, 0xc4, 0x85, 0xf0, 0xa5, 0xaa, 0xf1,
|
||||
0x4a, 0xd3, 0x46, 0x46, 0x84, 0x81, 0x44, 0x5c, 0xc2, 0xf2, 0x2e, 0x84,
|
||||
0x2e, 0x55, 0x3d, 0xb3, 0xd2, 0xb4, 0xaa, 0x4e, 0x32, 0xcc, 0xf5, 0x80,
|
||||
0x47, 0x24, 0x2c, 0xed, 0x42, 0xe8, 0x52, 0xd5, 0xb3, 0x2b, 0x4d, 0xab,
|
||||
0x6a, 0xb9, 0x52, 0xd5, 0xb8, 0x84, 0xe5, 0x5d, 0x08, 0x5d, 0xaa, 0x3a,
|
||||
0xa2, 0xd2, 0xb4, 0xaa, 0x16, 0x2c, 0x55, 0x8d, 0x4b, 0x58, 0xd8, 0x85,
|
||||
0xd0, 0xa5, 0xaa, 0xa3, 0x2a, 0x4d, 0x55, 0x8f, 0x31, 0x5c, 0xb4, 0x55,
|
||||
0x75, 0x31, 0x17, 0x42, 0x97, 0xaa, 0x8e, 0xac, 0x34, 0x55, 0x1d, 0x32,
|
||||
0x5c, 0xb0, 0x55, 0x75, 0x41, 0x17, 0x42, 0x97, 0xaa, 0x8e, 0xae, 0x34,
|
||||
0x55, 0x7d, 0xcb, 0x60, 0xd0, 0xaa, 0xba, 0x80, 0x0b, 0x99, 0x58, 0xaa,
|
||||
0x4a, 0x55, 0x9a, 0xaa, 0x7a, 0x06, 0x93, 0x56, 0xd5, 0x85, 0x5c, 0x08,
|
||||
0x5d, 0xaa, 0x3a, 0xa9, 0xd2, 0x54, 0xb5, 0xc7, 0x60, 0xd0, 0xaa, 0x3a,
|
||||
0xbf, 0x0b, 0xc1, 0x24, 0x28, 0x5d, 0x69, 0xaa, 0xd6, 0xad, 0xaa, 0xb3,
|
||||
0xbb, 0x10, 0x4c, 0x84, 0xd2, 0x95, 0xa6, 0x6a, 0xd9, 0xaa, 0xba, 0x80,
|
||||
0x0b, 0xc1, 0x64, 0x28, 0x5d, 0x69, 0xaa, 0xb6, 0xad, 0xaa, 0x33, 0xbb,
|
||||
0x10, 0x10, 0x50, 0xba, 0xd2, 0x54, 0x2d, 0x5b, 0x55, 0x67, 0x76, 0x21,
|
||||
0x74, 0xa9, 0x2a, 0x59, 0x69, 0xaa, 0xea, 0x60, 0xdd, 0xaa, 0xca, 0xbb,
|
||||
0x68, 0x5c, 0x08, 0x48, 0x38, 0xba, 0xd2, 0xd4, 0xd9, 0xb7, 0xaa, 0xce,
|
||||
0xe2, 0x62, 0x05, 0x1a, 0x1b, 0xc3, 0xa8, 0x6a, 0xd0, 0xf0, 0x70, 0x0f,
|
||||
0x63, 0x11, 0x02, 0x16, 0x49, 0x44, 0x55, 0xf9, 0xe3, 0xfb, 0x01, 0xfb,
|
||||
0x51, 0x26, 0x11, 0x55, 0xe5, 0x8f, 0xef, 0xb7, 0x1f, 0x65, 0x22, 0x51,
|
||||
0x55, 0xfe, 0xf8, 0xfe, 0x14, 0x46, 0x99, 0x44, 0x54, 0x95, 0x3f, 0xbe,
|
||||
0x3f, 0x85, 0x51, 0x26, 0x11, 0x55, 0x25, 0x8e, 0xef, 0x4f, 0x68, 0x94,
|
||||
0x49, 0x44, 0x55, 0xf9, 0xe3, 0xfb, 0x53, 0x18, 0x65, 0x12, 0x51, 0x55,
|
||||
0xfe, 0xf8, 0xfe, 0x44, 0x46, 0x69, 0x1f, 0x55, 0x65, 0x8f, 0xef, 0x4f,
|
||||
0x63, 0x94, 0x49, 0x44, 0x55, 0x89, 0xe3, 0xfb, 0xd3, 0x1a, 0xa5, 0x7d,
|
||||
0x54, 0x95, 0x3f, 0xbe, 0x3f, 0x91, 0x51, 0xda, 0x47, 0x55, 0xf9, 0xe3,
|
||||
0xfb, 0x13, 0x19, 0xa5, 0x7d, 0x54, 0x95, 0x39, 0xbe, 0x3f, 0xa9, 0x51,
|
||||
0xda, 0x47, 0x55, 0x89, 0xe3, 0xfb, 0x59, 0x11, 0xf3, 0x8e, 0xd2, 0x3e,
|
||||
0xaa, 0x4a, 0x1c, 0xdf, 0x9f, 0xd0, 0x28, 0x93, 0x88, 0xaa, 0xf2, 0xc7,
|
||||
0xf7, 0xa7, 0x30, 0xca, 0x24, 0xa2, 0xaa, 0xdc, 0xf1, 0xfd, 0xa9, 0x8c,
|
||||
0x32, 0x89, 0xa8, 0x2a, 0x7f, 0x7c, 0x7f, 0x4a, 0xa3, 0x4c, 0x3f, 0xaa,
|
||||
0x1a, 0xc9, 0xaa, 0xda, 0x8f, 0x32, 0x89, 0xa8, 0x2a, 0x7f, 0x7c, 0x7f,
|
||||
0x0a, 0xa3, 0x4c, 0x22, 0xaa, 0xca, 0x1f, 0xdf, 0x9f, 0xc8, 0x28, 0xed,
|
||||
0xa3, 0xaa, 0xfc, 0xf1, 0xfd, 0x89, 0x8c, 0xd2, 0x3e, 0xaa, 0xca, 0x1f,
|
||||
0xdf, 0x9f, 0xc2, 0x28, 0x7f, 0xc5, 0xa8, 0xaa, 0x22, 0x20, 0xa1, 0xaf,
|
||||
0x9d, 0x5f, 0x33, 0xaa, 0xaa, 0x7e, 0x90, 0xf6, 0xa3, 0xfc, 0xf5, 0xa3,
|
||||
0xaa, 0x8a, 0x99, 0x45, 0xc8, 0xc5, 0x73, 0xa2, 0xe9, 0x44, 0x55, 0x35,
|
||||
0x8d, 0x07, 0xfc, 0x3a, 0xa2, 0xaa, 0x9a, 0xc6, 0xae, 0xbc, 0x8e, 0xa8,
|
||||
0xaa, 0xa6, 0x31, 0xca, 0xeb, 0x88, 0xaa, 0x6a, 0x1a, 0xa3, 0xbc, 0x8e,
|
||||
0xa8, 0xaa, 0xa6, 0x32, 0xca, 0x6b, 0x88, 0xaa, 0x6a, 0x1a, 0x5f, 0x3b,
|
||||
0xd7, 0x11, 0x55, 0x75, 0xa0, 0xf1, 0x3f, 0x19, 0xc2, 0xb4, 0x90, 0x78,
|
||||
0xb9, 0x76, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
|
||||
0x42, 0x60, 0x82,
|
||||
};
|
||||
|
||||
#endif
|
@ -22,9 +22,12 @@
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/particle_kind.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/helpers.hpp"
|
||||
|
||||
#include <SParticle.h>
|
||||
#include <IParticleAffector.h>
|
||||
@ -174,6 +177,46 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
|
||||
class WindAffector : public scene::IParticleAffector
|
||||
{
|
||||
/** (Squared) distance from camera at which a particle is completely faded out */
|
||||
float m_speed;
|
||||
float m_seed;
|
||||
|
||||
public:
|
||||
WindAffector(float speed): m_speed(speed)
|
||||
{
|
||||
m_seed = (rand() % 1000) - 500;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
virtual void affect(u32 now, scene::SParticle* particlearray, u32 count)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 10000.0f;
|
||||
core::vector3df dir = irr_driver->getWind();
|
||||
dir *= m_speed * std::min(noise2d(time, m_seed), -0.2f);
|
||||
|
||||
for (u32 n = 0; n < count; n++)
|
||||
{
|
||||
scene::SParticle& cur = particlearray[n];
|
||||
|
||||
cur.pos += dir;
|
||||
} // for n<count
|
||||
} // affect
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
virtual scene::E_PARTICLE_AFFECTOR_TYPE getType() const
|
||||
{
|
||||
// FIXME: this method seems to make sense only for built-in affectors
|
||||
return scene::EPAT_FADE_OUT;
|
||||
}
|
||||
|
||||
}; // WindAffector
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@ -499,6 +542,21 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
||||
m_node->addAffector(scale_affector);
|
||||
scale_affector->drop();
|
||||
}
|
||||
|
||||
const float windspeed = type->getWindSpeed();
|
||||
if (windspeed > 0.01f)
|
||||
{
|
||||
WindAffector *waf = new WindAffector(windspeed);
|
||||
m_node->addAffector(waf);
|
||||
waf->drop();
|
||||
}
|
||||
|
||||
const bool flips = type->getFlips();
|
||||
if (flips)
|
||||
{
|
||||
m_node->getMaterial(0).MaterialType = irr_driver->getShader(ES_SNOW);
|
||||
m_node->getMaterial(0).BlendOperation = video::EBO_ADD;
|
||||
}
|
||||
}
|
||||
} // setParticleType
|
||||
|
||||
|
@ -54,6 +54,8 @@ ParticleKind::ParticleKind(const std::string file) : m_min_start_color(255,255,2
|
||||
m_has_scale_affector = NULL;
|
||||
m_scale_affector_factor_x = 0.0f;
|
||||
m_scale_affector_factor_y = 0.0f;
|
||||
m_wind_speed = 0;
|
||||
m_flips = false;
|
||||
|
||||
|
||||
// ----- Read XML file
|
||||
@ -219,6 +221,14 @@ ParticleKind::ParticleKind(const std::string file) : m_min_start_color(255,255,2
|
||||
m_material_file = material_manager->getLatestMaterial()->getTexFname();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const XMLNode* wind = xml->getNode("wind");
|
||||
if (wind != NULL)
|
||||
{
|
||||
wind->get("speed", &m_wind_speed);
|
||||
wind->get("flips", &m_flips);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user