Merge branch 'master' into NewRTTWidget
This commit is contained in:
commit
5f1413e140
@ -9,7 +9,7 @@
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<scrollable_ribbon id="players" height="120" y="10" x="10" width="98%" align="center" label_location="each"
|
||||
square_items="true" child_width="160" child_height="120" />
|
||||
square_items="true" child_width="128" child_height="128" />
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit">
|
||||
@ -61,5 +61,6 @@
|
||||
</box>
|
||||
<spacer width="20" height="15"/>
|
||||
</div>
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
|
||||
</stkgui>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<scrollable_ribbon id="players" height="120" y="10" x="10" width="98%" align="center" label_location="each"
|
||||
square_items="true" child_width="160" child_height="120" />
|
||||
square_items="true" child_width="128" child_height="128" />
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit">
|
||||
@ -70,5 +70,6 @@
|
||||
</box>
|
||||
<spacer width="20" height="15"/>
|
||||
</div>
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
|
||||
</stkgui>
|
||||
|
@ -1,22 +1,16 @@
|
||||
uniform sampler2D tex;
|
||||
uniform float low;
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
vec3 getCIEYxy(vec3 rgbColor);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 col = texture(tex, uv).xyz;
|
||||
float luma = getCIEYxy(col).x;
|
||||
vec2 uv = gl_FragCoord.xy / 512;
|
||||
vec3 col = texture(tex, uv).xyz;
|
||||
float luma = getCIEYxy(col).x;
|
||||
|
||||
col *= smoothstep(1., 10., luma);
|
||||
|
||||
FragColor = vec4(col, 1.0);
|
||||
col *= smoothstep(1., 10., luma);
|
||||
FragColor = vec4(col, 1.0);
|
||||
}
|
||||
|
@ -1,19 +1,24 @@
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D tex_128;
|
||||
uniform sampler2D tex_256;
|
||||
uniform sampler2D tex_512;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture(tex, uv);
|
||||
|
||||
col.xyz *= 10.0 * col.a;
|
||||
|
||||
FragColor = vec4(col.xyz, 1.);
|
||||
vec2 uv = gl_FragCoord.xy / screen;
|
||||
vec4 col = .125 * texture(tex_128, uv);
|
||||
col += .25 * texture(tex_256, uv);
|
||||
col += .5 * texture(tex_512, uv);
|
||||
FragColor = vec4(col.xyz, 1.);
|
||||
}
|
||||
|
@ -3,16 +3,17 @@ uniform float greenLmn[9];
|
||||
uniform float redLmn[9];
|
||||
uniform sampler2D ntex;
|
||||
uniform mat4 TransposeViewMatrix;
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 Diff;
|
||||
out vec4 Spec;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define Diff gl_FragData[0]
|
||||
#define Spec gl_FragData[1]
|
||||
#endif
|
||||
|
||||
vec3 DecodeNormal(vec2 n);
|
||||
|
||||
@ -30,6 +31,7 @@ mat4 getMatrix(float L[9])
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / screen;
|
||||
vec3 normal = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
|
||||
// Convert normal in world space (where SH coordinates were computed)
|
||||
vec4 extendednormal = TransposeViewMatrix * vec4(normal, 1.);
|
||||
@ -43,5 +45,4 @@ void main(void)
|
||||
float b = dot(extendednormal, bmat * extendednormal);
|
||||
|
||||
Diff = max(0.25 * vec4(r, g, b, .1), vec4(0.));
|
||||
Spec = vec4(0.);
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ layout (std140) uniform MatrixesData
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
float focalDepth = 10.;
|
||||
@ -20,6 +19,7 @@ float range = 100.;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / screen;
|
||||
float curdepth = texture(dtex, uv).x;
|
||||
vec4 FragPos = InverseProjectionMatrix * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f);
|
||||
FragPos /= FragPos.w;
|
||||
|
@ -24,7 +24,6 @@ layout (std140) uniform MatrixesData
|
||||
};
|
||||
#endif
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
|
||||
@ -32,6 +31,7 @@ vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / screen;
|
||||
float z = texture(tex, uv).x;
|
||||
vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);
|
||||
|
||||
|
@ -4,15 +4,14 @@ uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
uniform float sigma = 5.;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
|
||||
float g0, g1, g2;
|
||||
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
|
||||
g1 = exp(-0.5 / (sigma * sigma));
|
||||
|
@ -4,15 +4,14 @@ uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
uniform float sigma = 5.;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
|
||||
float g0, g1, g2;
|
||||
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
|
||||
g1 = exp(-0.5 / (sigma * sigma));
|
||||
|
@ -3,25 +3,20 @@ uniform vec2 pixel;
|
||||
|
||||
// Gaussian separated blur with radius 3.
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
sum += texture(tex, vec2(X - 3.0 * pixel.x, Y)) * 0.03125;
|
||||
sum += texture(tex, vec2(X - 1.3333 * pixel.x, Y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X, Y)) * 0.273438;
|
||||
sum += texture(tex, vec2(X + 1.3333 * pixel.x, Y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X + 3.0 * pixel.x, Y)) * 0.03125;
|
||||
sum += texture(tex, vec2(X - 3.0 * pixel.x, Y)) * 0.03125;
|
||||
sum += texture(tex, vec2(X - 1.3333 * pixel.x, Y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X, Y)) * 0.273438;
|
||||
sum += texture(tex, vec2(X + 1.3333 * pixel.x, Y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X + 3.0 * pixel.x, Y)) * 0.03125;
|
||||
|
||||
FragColor = sum;
|
||||
FragColor = sum;
|
||||
}
|
||||
|
@ -3,25 +3,20 @@ uniform vec2 pixel;
|
||||
|
||||
// Gaussian separated blur with radius 3.
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
sum += texture(tex, vec2(X, Y - 3.0 * pixel.y)) * 0.03125;
|
||||
sum += texture(tex, vec2(X, Y - 1.3333 * pixel.y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X, Y)) * 0.273438;
|
||||
sum += texture(tex, vec2(X, Y + 1.3333 * pixel.y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X, Y + 3.0 * pixel.y)) * 0.03125;
|
||||
sum += texture(tex, vec2(X, Y - 3.0 * pixel.y)) * 0.03125;
|
||||
sum += texture(tex, vec2(X, Y - 1.3333 * pixel.y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X, Y)) * 0.273438;
|
||||
sum += texture(tex, vec2(X, Y + 1.3333 * pixel.y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X, Y + 3.0 * pixel.y)) * 0.03125;
|
||||
|
||||
FragColor = sum;
|
||||
FragColor = sum;
|
||||
}
|
||||
|
@ -3,27 +3,22 @@ uniform vec2 pixel;
|
||||
|
||||
// Gaussian separated blur with radius 6.
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
sum += texture(tex, vec2(X - 5.13333 * pixel.x, Y)) * 0.00640869;
|
||||
sum += texture(tex, vec2(X - 3.26667 * pixel.x, Y)) * 0.083313;
|
||||
sum += texture(tex, vec2(X - 1.4 * pixel.x, Y)) * 0.305481;
|
||||
sum += texture(tex, vec2(X, Y)) * 0.209473;
|
||||
sum += texture(tex, vec2(X + 1.4 * pixel.x, Y)) * 0.305481;
|
||||
sum += texture(tex, vec2(X + 3.26667 * pixel.x, Y)) * 0.083313;
|
||||
sum += texture(tex, vec2(X + 5.13333 * pixel.x, Y)) * 0.00640869;
|
||||
sum += texture(tex, vec2(X - 5.13333 * pixel.x, Y)) * 0.00640869;
|
||||
sum += texture(tex, vec2(X - 3.26667 * pixel.x, Y)) * 0.083313;
|
||||
sum += texture(tex, vec2(X - 1.4 * pixel.x, Y)) * 0.305481;
|
||||
sum += texture(tex, vec2(X, Y)) * 0.209473;
|
||||
sum += texture(tex, vec2(X + 1.4 * pixel.x, Y)) * 0.305481;
|
||||
sum += texture(tex, vec2(X + 3.26667 * pixel.x, Y)) * 0.083313;
|
||||
sum += texture(tex, vec2(X + 5.13333 * pixel.x, Y)) * 0.00640869;
|
||||
|
||||
FragColor = sum;
|
||||
FragColor = sum;
|
||||
}
|
||||
|
@ -3,27 +3,22 @@ uniform vec2 pixel;
|
||||
|
||||
// Gaussian separated blur with radius 6.
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
sum += texture(tex, vec2(X, Y - 5.13333 * pixel.y)) * 0.00640869;
|
||||
sum += texture(tex, vec2(X, Y - 3.26667 * pixel.y)) * 0.083313;
|
||||
sum += texture(tex, vec2(X, Y - 1.4 * pixel.y)) * 0.305481;
|
||||
sum += texture(tex, vec2(X, Y)) * 0.209473;
|
||||
sum += texture(tex, vec2(X, Y + 1.4 * pixel.y)) * 0.305481;
|
||||
sum += texture(tex, vec2(X, Y + 3.26667 * pixel.y)) * 0.083313;
|
||||
sum += texture(tex, vec2(X, Y + 5.13333 * pixel.y)) * 0.00640869;
|
||||
sum += texture(tex, vec2(X, Y - 5.13333 * pixel.y)) * 0.00640869;
|
||||
sum += texture(tex, vec2(X, Y - 3.26667 * pixel.y)) * 0.083313;
|
||||
sum += texture(tex, vec2(X, Y - 1.4 * pixel.y)) * 0.305481;
|
||||
sum += texture(tex, vec2(X, Y)) * 0.209473;
|
||||
sum += texture(tex, vec2(X, Y + 1.4 * pixel.y)) * 0.305481;
|
||||
sum += texture(tex, vec2(X, Y + 3.26667 * pixel.y)) * 0.083313;
|
||||
sum += texture(tex, vec2(X, Y + 5.13333 * pixel.y)) * 0.00640869;
|
||||
|
||||
FragColor = sum;
|
||||
FragColor = sum;
|
||||
}
|
||||
|
@ -38,9 +38,7 @@ vec3 SH2RGB (in vec4 sh_r, in vec4 sh_g, in vec4 sh_b, in vec3 dir)
|
||||
return vec3 (dot(Y,sh_r), dot(Y,sh_g), dot(Y,sh_b));
|
||||
}
|
||||
|
||||
in vec2 uv;
|
||||
layout (location = 0) out vec4 Diffuse;
|
||||
layout (location = 1) out vec4 Specular;
|
||||
out vec4 Diffuse;
|
||||
|
||||
vec3 DecodeNormal(vec2 n);
|
||||
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
|
||||
@ -49,6 +47,7 @@ vec3 resolution = vec3(32, 16, 32);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / screen;
|
||||
vec3 GI = vec3(0.);
|
||||
|
||||
float depth = texture2D(dtex, uv).x;
|
||||
@ -97,5 +96,4 @@ void main()
|
||||
GI /= 4;
|
||||
|
||||
Diffuse = max(16. * vec4(GI, 1.), vec4(0.));
|
||||
Specular = vec4(0.);
|
||||
}
|
||||
|
@ -2,11 +2,21 @@ uniform sampler2D tex;
|
||||
uniform float zn;
|
||||
uniform float zf;
|
||||
|
||||
in vec2 uv;
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
out float Depth;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / screen;
|
||||
float d = texture(tex, uv).x;
|
||||
float c0 = zn * zf, c1 = zn - zf, c2 = zf;
|
||||
Depth = c0 / (d * c1 + c2);
|
||||
|
@ -40,20 +40,24 @@ uniform float mask_radius;
|
||||
// Maximum height of texture used
|
||||
uniform float max_tex_height;
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
// Number of samples used for blurring
|
||||
#define NB_SAMPLES 8
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texcoords = uv;
|
||||
vec2 texcoords = gl_FragCoord.xy / screen;
|
||||
|
||||
// Sample the color buffer
|
||||
vec3 color = texture(color_buffer, texcoords).rgb;
|
||||
|
@ -34,7 +34,6 @@ vec4 DirToSh(vec3 dir, float flux)
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
||||
vec3 normalizedRHCenter = 2. * vec3(gl_FragCoord.xy, slice) / resolution - 1.;
|
||||
vec3 RHcenter = (RHMatrix * vec4(normalizedRHCenter * extents, 1.)).xyz;
|
||||
|
||||
|
@ -22,7 +22,6 @@ layout (std140) uniform MatrixesData
|
||||
};
|
||||
#endif
|
||||
|
||||
in vec2 uv;
|
||||
out float AO;
|
||||
|
||||
const float sigma = 1.;
|
||||
@ -46,6 +45,7 @@ vec3 getXcYcZc(int x, int y, float zC)
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / screen;
|
||||
float lineardepth = textureLod(dtex, uv, 0.).x;
|
||||
int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y);
|
||||
vec3 FragPos = getXcYcZc(x, y, lineardepth);
|
||||
@ -58,14 +58,19 @@ void main(void)
|
||||
float r = radius / FragPos.z;
|
||||
float phi = 30. * (x ^ y) + 10. * x * y;
|
||||
float bl = 0.0;
|
||||
float m = log2(r) + 6 + log2(invSamples);
|
||||
|
||||
float theta = 2. * 3.14 * tau * .5 * invSamples + phi;
|
||||
vec2 rotations = vec2(cos(theta), sin(theta)) * screen;
|
||||
vec2 offset = vec2(cos(invSamples), sin(invSamples));
|
||||
|
||||
for(int i = 0; i < SAMPLES; ++i) {
|
||||
float alpha = (i + .5) * invSamples;
|
||||
float theta = 2. * 3.14 * tau * alpha + phi;
|
||||
rotations = vec2(rotations.x * offset.x - rotations.y * offset.y, rotations.x * offset.y + rotations.y * offset.x);
|
||||
float h = r * alpha;
|
||||
vec2 offset = h * vec2(cos(theta), sin(theta)) * screen;
|
||||
vec2 offset = h * rotations;
|
||||
|
||||
float m = round(log2(h) + 6);
|
||||
m = m + .5;
|
||||
ivec2 ioccluder_uv = ivec2(x, y) + ivec2(offset);
|
||||
|
||||
if (ioccluder_uv.x < 0 || ioccluder_uv.x > screen.x || ioccluder_uv.y < 0 || ioccluder_uv.y > screen.y) continue;
|
||||
|
@ -21,25 +21,19 @@ layout (std140) uniform MatrixesData
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 Diff;
|
||||
out vec4 Spec;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define Diff gl_FragData[0]
|
||||
#define Spec gl_FragData[1]
|
||||
#endif
|
||||
|
||||
|
||||
vec3 DecodeNormal(vec2 n);
|
||||
vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
|
||||
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
|
||||
|
||||
void main() {
|
||||
vec2 uv = gl_FragCoord.xy / screen;
|
||||
float z = texture(dtex, uv).x;
|
||||
vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);
|
||||
|
||||
|
@ -24,6 +24,7 @@ layout (std140) uniform MatrixesData
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -68,6 +69,7 @@ float getShadowFactor(vec3 pos, float bias, int index)
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = gl_FragCoord.xy / screen;
|
||||
float z = texture(dtex, uv).x;
|
||||
vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);
|
||||
|
||||
|
@ -5,7 +5,16 @@ uniform sampler2D logluminancetex;
|
||||
uniform float exposure = .09;
|
||||
uniform float Lwhite = 1.;
|
||||
|
||||
in vec2 uv;
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
vec3 getCIEYxy(vec3 rgbColor);
|
||||
@ -17,6 +26,7 @@ float saturation = 1.;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / screen;
|
||||
vec4 col = texture(tex, uv);
|
||||
float avgLw = textureLod(logluminancetex, uv, 10.).x;
|
||||
avgLw = max(exp(avgLw) - delta, delta);
|
||||
|
@ -89,6 +89,19 @@ static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs_ARB;
|
||||
static HGLRC getMeAGLContext(HDC HDc)
|
||||
{
|
||||
HGLRC hrc = 0;
|
||||
int ctx44[] =
|
||||
{
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||
0
|
||||
};
|
||||
|
||||
hrc = wglCreateContextAttribs_ARB(HDc, 0, ctx44);
|
||||
if (hrc)
|
||||
return hrc;
|
||||
|
||||
int ctx40[] =
|
||||
{
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
|
@ -1,3 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
@ -49,9 +49,10 @@ NewsManager::~NewsManager()
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** This function initialises the data for the news manager. It starts a
|
||||
* separate thread to execute downloadNews() - which (if necessary) the
|
||||
* news.xml file and updating the list of news messages. It also initialises
|
||||
* the addons manager (which can trigger another download of news.xml).
|
||||
* separate thread to execute downloadNews() - which (if necessary) downaloads
|
||||
* the news.xml file and updates the list of news messages. It also
|
||||
* initialises the addons manager (which can trigger another download of
|
||||
* news.xml).
|
||||
* \param force_refresh Re-download news.xml, even if
|
||||
*/
|
||||
void NewsManager::init(bool force_refresh)
|
||||
@ -183,7 +184,7 @@ void* NewsManager::downloadNews(void *obj)
|
||||
|
||||
if(xml) delete xml;
|
||||
xml = NULL;
|
||||
|
||||
|
||||
// Process new.xml now.
|
||||
if(file_manager->fileExists(xml_file))
|
||||
{
|
||||
@ -194,6 +195,10 @@ void* NewsManager::downloadNews(void *obj)
|
||||
delete xml;
|
||||
}
|
||||
|
||||
// We can't finish stk (esp. delete the file manager) before
|
||||
// this part of the code is reached (since otherwise the file
|
||||
// manager might be access after it was deleted).
|
||||
me->setCanBeDeleted();
|
||||
pthread_exit(NULL);
|
||||
return 0; // prevent warning
|
||||
} // downloadNews
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <irrString.h>
|
||||
using namespace irr;
|
||||
|
||||
#include "utils/can_be_deleted.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
|
||||
class XMLNode;
|
||||
@ -32,7 +33,7 @@ class XMLNode;
|
||||
/**
|
||||
* \ingroup addonsgroup
|
||||
*/
|
||||
class NewsManager
|
||||
class NewsManager : public CanBeDeleted
|
||||
{
|
||||
private:
|
||||
static NewsManager *m_news_manager;
|
||||
|
@ -272,10 +272,12 @@ void PlayerManager::save()
|
||||
<< m_current_player->getName() << L"\"/>\n";
|
||||
}
|
||||
|
||||
// Save all non-guest players
|
||||
PlayerProfile *player;
|
||||
for_in(player, m_all_players)
|
||||
{
|
||||
player->save(players_file);
|
||||
if(!player->isGuestAccount())
|
||||
player->save(players_file);
|
||||
}
|
||||
players_file << L"</players>\n";
|
||||
players_file.close();
|
||||
@ -373,10 +375,36 @@ void PlayerManager::addDefaultPlayer()
|
||||
// screen to be shown.
|
||||
m_all_players.push_back(new Online::OnlinePlayerProfile(username.c_str()) );
|
||||
|
||||
// add default guest player
|
||||
m_all_players.push_back(new Online::OnlinePlayerProfile(_LTR("Guest"), /*guest*/true));
|
||||
} // addDefaultPlayer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Makes sure at least n guest players exist. This is used by the multiplayer
|
||||
* KartSelection screen to make sure enough guest players can be picked by
|
||||
* the players.
|
||||
* \param n Minimum number of guest players that must exist.
|
||||
*/
|
||||
void PlayerManager::createGuestPlayers(int n)
|
||||
{
|
||||
int num_guests = m_all_players.size() - getNumNonGuestPlayers();
|
||||
for(int i=num_guests; i<n; i++)
|
||||
{
|
||||
core::stringw guest_name;
|
||||
if(i==0)
|
||||
{
|
||||
// I18N: Name of first guest player (without number)
|
||||
guest_name = _LTR("Guest");
|
||||
}
|
||||
else
|
||||
{
|
||||
// I18N: Name of further guest players, with a 1, 2, ... attached
|
||||
guest_name = _LTR("Guest %d", i);
|
||||
}
|
||||
PlayerProfile *guest = new Online::OnlinePlayerProfile(guest_name,
|
||||
/*guest*/ true);
|
||||
m_all_players.push_back(guest);
|
||||
}
|
||||
} // createGuestPlayers
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the number of 'real' (non-guest) players.
|
||||
*/
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
unsigned int getUniqueId() const;
|
||||
void addDefaultPlayer();
|
||||
PlayerProfile* addNewPlayer(const irr::core::stringw& name);
|
||||
void createGuestPlayers(int n);
|
||||
void deletePlayer(PlayerProfile *player);
|
||||
void setCurrentPlayer(PlayerProfile *player);
|
||||
const PlayerProfile *getPlayerById(unsigned int id);
|
||||
|
@ -146,7 +146,7 @@ void PlayerProfile::initRemainingData()
|
||||
*/
|
||||
void PlayerProfile::addIcon()
|
||||
{
|
||||
if (m_icon_filename.size() > 0)
|
||||
if (m_icon_filename.size() > 0 || isGuestAccount())
|
||||
return;
|
||||
|
||||
int n = m_unique_id % kart_properties_manager->getNumberOfKarts();
|
||||
|
@ -71,6 +71,9 @@ PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
|
||||
PFNGLBLENDCOLORPROC glBlendColor;
|
||||
PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
|
||||
PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
|
||||
PFNGLTEXSTORAGE1DPROC glTexStorage1D;
|
||||
PFNGLTEXSTORAGE2DPROC glTexStorage2D;
|
||||
PFNGLTEXSTORAGE3DPROC glTexStorage3D;
|
||||
#endif
|
||||
|
||||
static bool is_gl_init = false;
|
||||
@ -220,6 +223,9 @@ void initGL()
|
||||
glBlendColor = (PFNGLBLENDCOLORPROC)IRR_OGL_LOAD_EXTENSION("glBlendColor");
|
||||
glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D");
|
||||
glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)IRR_OGL_LOAD_EXTENSION("glGetCompressedTexImage");
|
||||
glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage1D");
|
||||
glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage2D");
|
||||
glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage3D");
|
||||
#ifdef DEBUG
|
||||
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB");
|
||||
#endif
|
||||
|
@ -94,6 +94,9 @@ extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
|
||||
extern PFNGLBLENDCOLORPROC glBlendColor;
|
||||
extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
|
||||
extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
|
||||
extern PFNGLTEXSTORAGE1DPROC glTexStorage1D;
|
||||
extern PFNGLTEXSTORAGE2DPROC glTexStorage2D;
|
||||
extern PFNGLTEXSTORAGE3DPROC glTexStorage3D;
|
||||
#ifdef DEBUG
|
||||
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
|
||||
#endif
|
||||
|
@ -211,7 +211,10 @@ Window get_toplevel_parent(Display* display, Window window)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** If the position of the window should be remembered, store it in the config
|
||||
* file.
|
||||
* \post The user config file must still be saved!
|
||||
*/
|
||||
void IrrDriver::updateConfigIfRelevant()
|
||||
{
|
||||
if (!UserConfigParams::m_fullscreen &&
|
||||
@ -241,7 +244,6 @@ void IrrDriver::updateConfigIfRelevant()
|
||||
{
|
||||
UserConfigParams::m_window_x = x;
|
||||
UserConfigParams::m_window_y = y;
|
||||
user_config->saveConfig();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -265,11 +267,10 @@ void IrrDriver::updateConfigIfRelevant()
|
||||
{
|
||||
UserConfigParams::m_window_x = wx;
|
||||
UserConfigParams::m_window_y = wy;
|
||||
user_config->saveConfig();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // updateConfigIfRelevant
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Gets a list of supported video modes from the irrlicht device. This data
|
||||
|
@ -364,7 +364,8 @@ private:
|
||||
void renderShadows();
|
||||
void renderGlow(std::vector<GlowData>& glows);
|
||||
void renderSSAO();
|
||||
void renderLights(scene::ICameraSceneNode * const camnode, float dt);
|
||||
unsigned UpdateLightsInfo(scene::ICameraSceneNode * const camnode, float dt);
|
||||
void renderLights(unsigned pointlightCount);
|
||||
void renderDisplacement();
|
||||
void doScreenShot();
|
||||
public:
|
||||
@ -696,7 +697,7 @@ public:
|
||||
void onLoadWorld();
|
||||
void onUnloadWorld();
|
||||
|
||||
void renderScene(scene::ICameraSceneNode * const camnode, std::vector<GlowData>& glows, float dt, bool hasShadows, bool forceRTT);
|
||||
void renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadows, bool forceRTT);
|
||||
void computeCameraMatrix(scene::ICameraSceneNode * const camnode, size_t width, size_t height);
|
||||
|
||||
// --------------------- RTT --------------------
|
||||
|
@ -760,32 +760,31 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
// FIXME; cannot perform this check atm, because setMaterialProperties
|
||||
// is sometimes called before calculating tangents
|
||||
//if (mb->getVertexType() != video::EVT_TANGENTS)
|
||||
//{
|
||||
// Log::warn("material", "Requiring normal map without tangent enabled mesh for <%s>",
|
||||
// m_texname.c_str());
|
||||
//}
|
||||
|
||||
ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
m->setTexture(1, tex);
|
||||
|
||||
if (mb->getVertexType() != video::EVT_TANGENTS)
|
||||
{
|
||||
Log::warn("material", "Requiring normal map without tangent enabled mesh for <%s>",
|
||||
m_texname.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
m->setTexture(1, tex);
|
||||
bool with_lightmap = false;
|
||||
|
||||
bool with_lightmap = false;
|
||||
//if (m_normal_map_shader_lightmap.size() > 0)
|
||||
//{
|
||||
// ITexture* lm_tex = irr_driver->getTexture(m_normal_map_shader_lightmap);
|
||||
// m->setTexture(2, lm_tex);
|
||||
// with_lightmap = true;
|
||||
//}
|
||||
|
||||
//if (m_normal_map_shader_lightmap.size() > 0)
|
||||
//{
|
||||
// ITexture* lm_tex = irr_driver->getTexture(m_normal_map_shader_lightmap);
|
||||
// m->setTexture(2, lm_tex);
|
||||
// with_lightmap = true;
|
||||
//}
|
||||
|
||||
// Material and shaders
|
||||
m->MaterialType = irr_driver->getShader(
|
||||
with_lightmap ? ES_NORMAL_MAP_LIGHTMAP : ES_NORMAL_MAP);
|
||||
m->Lighting = false;
|
||||
m->ZWriteEnable = true;
|
||||
}
|
||||
// Material and shaders
|
||||
m->MaterialType = irr_driver->getShader(
|
||||
with_lightmap ? ES_NORMAL_MAP_LIGHTMAP : ES_NORMAL_MAP);
|
||||
m->Lighting = false;
|
||||
m->ZWriteEnable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -217,29 +217,7 @@ void renderBloom(GLuint in)
|
||||
setTexture(0, in, GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::BloomShader::setUniforms(0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
static
|
||||
void renderColorLevel(GLuint in)
|
||||
{
|
||||
core::vector3df m_inlevel = World::getWorld()->getTrack()->getColorLevelIn();
|
||||
core::vector2df m_outlevel = World::getWorld()->getTrack()->getColorLevelOut();
|
||||
|
||||
|
||||
glUseProgram(FullScreenShader::ColorLevelShader::Program);
|
||||
glBindVertexArray(FullScreenShader::ColorLevelShader::vao);
|
||||
glUniform3f(FullScreenShader::ColorLevelShader::uniform_inlevel, m_inlevel.X, m_inlevel.Y, m_inlevel.Z);
|
||||
glUniform2f(FullScreenShader::ColorLevelShader::uniform_outlevel, m_outlevel.X, m_outlevel.Y);
|
||||
|
||||
setTexture(0, in, GL_NEAREST, GL_NEAREST);
|
||||
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
glUniform1i(FullScreenShader::ColorLevelShader::uniform_tex, 0);
|
||||
glUniform1i(FullScreenShader::ColorLevelShader::uniform_dtex, 1);
|
||||
setTexture(2, irr_driver->getRenderTargetTexture(RTT_LOG_LUMINANCE), GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST);
|
||||
glUniformMatrix4fv(FullScreenShader::ColorLevelShader::uniform_invprojm, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer());
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff)
|
||||
@ -256,7 +234,7 @@ void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSH
|
||||
core::matrix4 TVM = irr_driver->getViewMatrix().getTransposed();
|
||||
FullScreenShader::DiffuseEnvMapShader::setUniforms(TVM, bSHCoeff, gSHCoeff, rSHCoeff, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
@ -290,7 +268,7 @@ void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3
|
||||
setTexture(3, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(4, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::GlobalIlluminationReconstructionShader::setUniforms(RHMatrix, rh_extend, 3, 4, 0, 1, 2);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
void PostProcessing::renderSunlight()
|
||||
@ -307,7 +285,7 @@ void PostProcessing::renderSunlight()
|
||||
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::SunLightShader::setUniforms(cb->getPosition(), cb->getRed(), cb->getGreen(), cb->getBlue(), 0, 1);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
@ -344,7 +322,7 @@ void PostProcessing::renderShadowedSunlight(const std::vector<core::matrix4> &su
|
||||
glBindVertexArray(FullScreenShader::ShadowedSunLightShader::vao);
|
||||
FullScreenShader::ShadowedSunLightShader::setUniforms(cb->getPosition(), cb->getRed(), cb->getGreen(), cb->getBlue(), 0, 1, 2);
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
@ -365,7 +343,7 @@ void PostProcessing::renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glUniform1i(FullScreenShader::Gaussian3VBlurShader::uniform_tex, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
{
|
||||
in_fbo.Bind();
|
||||
@ -379,7 +357,7 @@ void PostProcessing::renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glUniform1i(FullScreenShader::Gaussian3HBlurShader::uniform_tex, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,7 +377,7 @@ void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glUniform1i(FullScreenShader::Gaussian6VBlurShader::uniform_tex, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
{
|
||||
in_fbo.Bind();
|
||||
@ -413,7 +391,7 @@ void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glUniform1i(FullScreenShader::Gaussian6HBlurShader::uniform_tex, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,7 +411,7 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glUniform1i(FullScreenShader::Gaussian17TapHShader::uniform_tex, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
{
|
||||
in_fbo.Bind();
|
||||
@ -447,7 +425,7 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glUniform1i(FullScreenShader::Gaussian17TapVShader::uniform_tex, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -492,7 +470,7 @@ void PostProcessing::renderSSAO()
|
||||
glBindVertexArray(FullScreenShader::LinearizeDepthShader::vao);
|
||||
setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::LinearizeDepthShader::setUniforms(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue(), 0);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
irr_driver->getFBO(FBO_SSAO).Bind();
|
||||
|
||||
if (!noise_tex)
|
||||
@ -501,15 +479,15 @@ void PostProcessing::renderSSAO()
|
||||
glUseProgram(FullScreenShader::SSAOShader::Program);
|
||||
glBindVertexArray(FullScreenShader::SSAOShader::vao);
|
||||
|
||||
setTexture(0, irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
|
||||
setTexture(0, irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH), GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR);
|
||||
|
||||
FullScreenShader::SSAOShader::setUniforms(core::vector2df(float(UserConfigParams::m_width),
|
||||
FullScreenShader::SSAOShader::setUniforms(core::vector2df(float(UserConfigParams::m_width),
|
||||
float(UserConfigParams::m_height)),
|
||||
0, 1);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
void PostProcessing::renderFog()
|
||||
@ -539,7 +517,7 @@ void PostProcessing::renderFog()
|
||||
setTexture(0, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::FogShader::setUniforms(fogmax, startH, endH, start, end, col, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
@ -579,7 +557,7 @@ void PostProcessing::renderMotionBlur(unsigned cam, FrameBuffer &in_fbo, FrameBu
|
||||
cb->getDirection(cam), 0.15f,
|
||||
cb->getMaxHeight(cam) * 0.7f, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
static void renderGodFade(GLuint tex, const SColor &col)
|
||||
@ -611,7 +589,7 @@ static void toneMap(FrameBuffer &fbo, GLuint rtt)
|
||||
setTexture(1, irr_driver->getRenderTargetTexture(RTT_LOG_LUMINANCE), GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST);
|
||||
FullScreenShader::ToneMapShader::setUniforms(irr_driver->getExposure(), irr_driver->getLwhite(), 0, 1);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
static void renderDoF(FrameBuffer &fbo, GLuint rtt)
|
||||
@ -623,7 +601,7 @@ static void renderDoF(FrameBuffer &fbo, GLuint rtt)
|
||||
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::DepthOfFieldShader::setUniforms(0, 1);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
static void averageTexture(GLuint tex)
|
||||
@ -633,19 +611,6 @@ static void averageTexture(GLuint tex)
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
static void computeLogLuminance(GLuint tex)
|
||||
{
|
||||
irr_driver->getFBO(FBO_LOG_LUMINANCE).Bind();
|
||||
glUseProgram(FullScreenShader::LogLuminanceShader::Program);
|
||||
glBindVertexArray(FullScreenShader::LogLuminanceShader::vao);
|
||||
setTexture(0, tex, GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::LogLuminanceShader::setUniforms(0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
averageTexture(irr_driver->getRenderTargetTexture(RTT_LOG_LUMINANCE));
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
}
|
||||
|
||||
void PostProcessing::applyMLAA()
|
||||
{
|
||||
const core::vector2df &PIXEL_SIZE = core::vector2df(1.0f / UserConfigParams::m_width, 1.0f / UserConfigParams::m_height);
|
||||
@ -825,14 +790,16 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
// Additively blend on top of tmp1
|
||||
in_fbo->Bind();
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_CONSTANT_COLOR, GL_ONE);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendColor(.125, .125, .125, .125);
|
||||
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_128));
|
||||
glBlendColor(.25, .25, .25, .25);
|
||||
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_256));
|
||||
glBlendColor(.5, .5, .5, .5);
|
||||
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_512));
|
||||
setTexture(0, irr_driver->getRenderTargetTexture(RTT_BLOOM_128), GL_LINEAR, GL_LINEAR);
|
||||
setTexture(1, irr_driver->getRenderTargetTexture(RTT_BLOOM_256), GL_LINEAR, GL_LINEAR);
|
||||
setTexture(2, irr_driver->getRenderTargetTexture(RTT_BLOOM_512), GL_LINEAR, GL_LINEAR);
|
||||
glUseProgram(FullScreenShader::BloomBlendShader::Program);
|
||||
FullScreenShader::BloomBlendShader::setUniforms(0, 1, 2);
|
||||
glBindVertexArray(FullScreenShader::BloomBlendShader::vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
} // end if bloom
|
||||
|
@ -143,8 +143,9 @@ void IrrDriver::renderGLSL(float dt)
|
||||
|
||||
const core::recti &viewport = camera->getViewport();
|
||||
|
||||
unsigned plc = UpdateLightsInfo(camnode, dt);
|
||||
computeCameraMatrix(camnode, viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
|
||||
renderScene(camnode, glows, dt, track->hasShadows(), false);
|
||||
renderScene(camnode, plc, glows, dt, track->hasShadows(), false);
|
||||
|
||||
// Debug physic
|
||||
// Note that drawAll must be called before rendering
|
||||
@ -260,7 +261,7 @@ void IrrDriver::renderGLSL(float dt)
|
||||
getPostProcessing()->update(dt);
|
||||
}
|
||||
|
||||
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector<GlowData>& glows, float dt, bool hasShadow, bool forceRTT)
|
||||
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow, bool forceRTT)
|
||||
{
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
|
||||
|
||||
@ -287,7 +288,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
|
||||
ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT));
|
||||
renderLights(camnode, dt);
|
||||
renderLights(pointlightcount);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
@ -759,14 +760,14 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
|
||||
|
||||
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||
}
|
||||
|
||||
if (!(tick % 100))
|
||||
if ((tick % 100) == 2)
|
||||
rsm_matrix = sun_ortho_matrix[3];
|
||||
rh_extend = core::vector3df(128, 64, 128);
|
||||
core::vector3df campos = camnode->getAbsolutePosition();
|
||||
core::vector3df translation(8 * floor(campos.X / 8), 8 * floor(campos.Y / 8), 8 * floor(campos.Z / 8));
|
||||
rh_matrix.setTranslation(translation);
|
||||
|
||||
|
||||
assert(sun_ortho_matrix.size() == 4);
|
||||
camnode->setNearValue(oldnear);
|
||||
camnode->setFarValue(oldfar);
|
||||
@ -916,37 +917,8 @@ static void renderPointLights(unsigned count)
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
|
||||
}
|
||||
|
||||
void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
unsigned IrrDriver::UpdateLightsInfo(scene::ICameraSceneNode * const camnode, float dt)
|
||||
{
|
||||
//RH
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
m_rtts->getRH().Bind();
|
||||
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::RadianceHintsConstructionShader::vao);
|
||||
setTexture(0, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(1, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(2, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::RadianceHintsConstructionShader::setUniforms(rsm_matrix, rh_matrix, rh_extend, 0, 1, 2);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
|
||||
sun_ortho_matrix[i] *= getInvViewMatrix();
|
||||
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
glClearColor(.5, .5, .5, .5);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
return;
|
||||
|
||||
if (UserConfigParams::m_gi)
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
|
||||
if (SkyboxCubeMap)
|
||||
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
||||
|
||||
const u32 lightcount = m_lights.size();
|
||||
const core::vector3df &campos = camnode->getAbsolutePosition();
|
||||
|
||||
@ -956,15 +928,6 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
if (!m_lights[i]->isPointLight())
|
||||
{
|
||||
m_lights[i]->render();
|
||||
if (UserConfigParams::m_shadows && World::getWorld() != NULL &&
|
||||
World::getWorld()->getTrack()->hasShadows())
|
||||
{
|
||||
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_post_processing->renderSunlight();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
|
||||
@ -1019,10 +982,56 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
}
|
||||
|
||||
lightnum++;
|
||||
return lightnum;
|
||||
}
|
||||
|
||||
renderPointLights(MIN2(lightnum, MAXLIGHT));
|
||||
if (SkyboxCubeMap)
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
void IrrDriver::renderLights(unsigned pointlightcount)
|
||||
{
|
||||
//RH
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
m_rtts->getRH().Bind();
|
||||
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::RadianceHintsConstructionShader::vao);
|
||||
setTexture(0, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(1, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(2, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::RadianceHintsConstructionShader::setUniforms(rsm_matrix, rh_matrix, rh_extend, 0, 1, 2);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
|
||||
sun_ortho_matrix[i] *= getInvViewMatrix();
|
||||
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
glClearColor(.5, .5, .5, .5);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
return;
|
||||
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
m_rtts->getFBO(FBO_TMP1_WITH_DS).Bind();
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
if (SkyboxCubeMap)
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
|
||||
}
|
||||
|
||||
if (SkyboxCubeMap && UserConfigParams::m_gi)
|
||||
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
||||
|
||||
// Render sunlight if and only if track supports shadow
|
||||
if (World::getWorld()->getTrack()->hasShadows())
|
||||
{
|
||||
if (UserConfigParams::m_shadows)
|
||||
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
|
||||
else
|
||||
m_post_processing->renderSunlight();
|
||||
}
|
||||
|
||||
renderPointLights(MIN2(pointlightcount, MAXLIGHT));
|
||||
}
|
||||
|
||||
void IrrDriver::renderSSAO()
|
||||
|
@ -22,12 +22,15 @@
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
static GLuint generateRTT(const core::dimension2du &res, GLint internalFormat, GLint format, GLint type)
|
||||
static GLuint generateRTT(const core::dimension2du &res, GLint internalFormat, GLint format, GLint type, unsigned mipmaplevel = 1)
|
||||
{
|
||||
GLuint result;
|
||||
glGenTextures(1, &result);
|
||||
glBindTexture(GL_TEXTURE_2D, result);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, res.Width, res.Height, 0, format, type, 0);
|
||||
if (irr_driver->getGLSLVersion() < 420)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, res.Width, res.Height, 0, format, type, 0);
|
||||
else
|
||||
glTexStorage2D(GL_TEXTURE_2D, mipmaplevel, internalFormat, res.Width, res.Height);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -75,6 +78,8 @@ RTT::RTT(size_t width, size_t height)
|
||||
const dimension2du warpvsize(1, 512);
|
||||
const dimension2du warphsize(512, 1);
|
||||
|
||||
unsigned linear_depth_mip_levels = ceil(log2(max_(res.Width, res.Height)));
|
||||
|
||||
glGenTextures(1, &DepthStencilTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, DepthStencilTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, res.Width, res.Height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
|
||||
@ -86,10 +91,10 @@ RTT::RTT(size_t width, size_t height)
|
||||
RenderTargetTextures[RTT_TMP2] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_TMP3] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_TMP4] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_LINEAR_DEPTH] = generateRTT(res, GL_R32F, GL_RED, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_LINEAR_DEPTH] = generateRTT(res, GL_R32F, GL_RED, GL_FLOAT, linear_depth_mip_levels);
|
||||
RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGBA16F, GL_RGBA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB_ALPHA, GL_BGRA, GL_UNSIGNED_BYTE);
|
||||
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB8_ALPHA8, GL_BGR, GL_UNSIGNED_BYTE);
|
||||
RenderTargetTextures[RTT_SSAO] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
|
||||
@ -189,7 +194,7 @@ RTT::RTT(size_t width, size_t height)
|
||||
somevector.push_back(RenderTargetTextures[RTT_TMP_128]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, 128, 128));
|
||||
|
||||
if (irr_driver->getGLSLVersion() >= 150)
|
||||
if (UserConfigParams::m_shadows)
|
||||
{
|
||||
glGenTextures(1, &shadowColorTex);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowColorTex);
|
||||
@ -201,7 +206,10 @@ RTT::RTT(size_t width, size_t height)
|
||||
somevector.clear();
|
||||
somevector.push_back(shadowColorTex);
|
||||
m_shadow_FBO = new FrameBuffer(somevector, shadowDepthTex, 1024, 1024, true);
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
//Todo : use "normal" shadowtex
|
||||
glGenTextures(1, &RSM_Color);
|
||||
glBindTexture(GL_TEXTURE_2D, RSM_Color);
|
||||
@ -241,10 +249,13 @@ RTT::~RTT()
|
||||
{
|
||||
glDeleteTextures(RTT_COUNT, RenderTargetTextures);
|
||||
glDeleteTextures(1, &DepthStencilTexture);
|
||||
if (irr_driver->getGLSLVersion() >= 150)
|
||||
if (UserConfigParams::m_shadows)
|
||||
{
|
||||
glDeleteTextures(1, &shadowColorTex);
|
||||
glDeleteTextures(1, &shadowDepthTex);
|
||||
}
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
glDeleteTextures(1, &RSM_Color);
|
||||
glDeleteTextures(1, &RSM_Normal);
|
||||
glDeleteTextures(1, &RSM_Depth);
|
||||
|
@ -50,7 +50,7 @@ Shaders::Shaders()
|
||||
loadShaders();
|
||||
}
|
||||
|
||||
GLuint quad_vbo;
|
||||
GLuint quad_vbo, tri_vbo;
|
||||
|
||||
static void initQuadVBO()
|
||||
{
|
||||
@ -64,6 +64,16 @@ static void initQuadVBO()
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quad_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
const float tri_vertex[] = {
|
||||
-1., -1.,
|
||||
-1., 3.,
|
||||
3., -1.,
|
||||
};
|
||||
glGenBuffers(1, &tri_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tri_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), tri_vertex, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
// It should be possible to merge it with previous one...
|
||||
@ -265,7 +275,6 @@ void Shaders::loadShaders()
|
||||
FullScreenShader::BloomBlendShader::init();
|
||||
FullScreenShader::BloomShader::init();
|
||||
FullScreenShader::DepthOfFieldShader::init();
|
||||
FullScreenShader::ColorLevelShader::init();
|
||||
FullScreenShader::FogShader::init();
|
||||
FullScreenShader::Gaussian17TapHShader::init();
|
||||
FullScreenShader::Gaussian3HBlurShader::init();
|
||||
@ -287,7 +296,6 @@ void Shaders::loadShaders()
|
||||
FullScreenShader::MotionBlurShader::init();
|
||||
FullScreenShader::GodFadeShader::init();
|
||||
FullScreenShader::GodRayShader::init();
|
||||
FullScreenShader::LogLuminanceShader::init();
|
||||
FullScreenShader::ToneMapShader::init();
|
||||
FullScreenShader::MLAAColorEdgeDetectionSHader::init();
|
||||
FullScreenShader::MLAABlendWeightSHader::init();
|
||||
@ -2031,6 +2039,19 @@ namespace ParticleShader
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint createFullScreenVAO(GLuint Program)
|
||||
{
|
||||
GLuint vao;
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
GLuint attrib_position = glGetAttribLocation(Program, "Position");
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tri_vbo);
|
||||
glEnableVertexAttribArray(attrib_position);
|
||||
glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
|
||||
glBindVertexArray(0);
|
||||
return vao;
|
||||
}
|
||||
|
||||
static GLuint createVAO(GLuint Program)
|
||||
{
|
||||
GLuint vao;
|
||||
@ -2059,7 +2080,7 @@ namespace FullScreenShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getCIEXYZ.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/bloom.frag").c_str());
|
||||
uniform_texture = glGetUniformLocation(Program, "tex");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
void BloomShader::setUniforms(unsigned TU_tex)
|
||||
@ -2068,20 +2089,27 @@ namespace FullScreenShader
|
||||
}
|
||||
|
||||
GLuint BloomBlendShader::Program;
|
||||
GLuint BloomBlendShader::uniform_texture;
|
||||
GLuint BloomBlendShader::uniform_tex_128;
|
||||
GLuint BloomBlendShader::uniform_tex_256;
|
||||
GLuint BloomBlendShader::uniform_tex_512;
|
||||
GLuint BloomBlendShader::vao;
|
||||
|
||||
void BloomBlendShader::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/bloomblend.frag").c_str());
|
||||
uniform_texture = glGetUniformLocation(Program, "tex");
|
||||
vao = createVAO(Program);
|
||||
uniform_tex_128 = glGetUniformLocation(Program, "tex_128");
|
||||
uniform_tex_256 = glGetUniformLocation(Program, "tex_256");
|
||||
uniform_tex_512 = glGetUniformLocation(Program, "tex_512");
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
void BloomBlendShader::setUniforms(unsigned TU_tex)
|
||||
void BloomBlendShader::setUniforms(unsigned TU_tex_128, unsigned TU_tex_256, unsigned TU_tex_512)
|
||||
{
|
||||
glUniform1i(FullScreenShader::BloomShader::uniform_texture, TU_tex);
|
||||
glUniform1i(uniform_tex_128, TU_tex_128);
|
||||
glUniform1i(uniform_tex_256, TU_tex_256);
|
||||
glUniform1i(uniform_tex_512, TU_tex_512);
|
||||
}
|
||||
|
||||
GLuint ToneMapShader::Program;
|
||||
@ -2102,7 +2130,7 @@ namespace FullScreenShader
|
||||
uniform_logluminancetex = glGetUniformLocation(Program, "logluminancetex");
|
||||
uniform_exposure = glGetUniformLocation(Program, "exposure");
|
||||
uniform_lwhite = glGetUniformLocation(Program, "Lwhite");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
void ToneMapShader::setUniforms(float exposure, float Lwhite, unsigned TU_tex, unsigned TU_loglum)
|
||||
@ -2125,7 +2153,7 @@ namespace FullScreenShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/dof.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_depth = glGetUniformLocation(Program, "dtex");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
@ -2136,28 +2164,6 @@ namespace FullScreenShader
|
||||
glUniform1i(uniform_depth, TU_dtex);
|
||||
}
|
||||
|
||||
GLuint ColorLevelShader::Program;
|
||||
GLuint ColorLevelShader::uniform_tex;
|
||||
GLuint ColorLevelShader::uniform_inlevel;
|
||||
GLuint ColorLevelShader::uniform_outlevel;
|
||||
GLuint ColorLevelShader::vao;
|
||||
GLuint ColorLevelShader::uniform_invprojm;
|
||||
GLuint ColorLevelShader::uniform_dtex;
|
||||
void ColorLevelShader::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getRGBfromCIEXxy.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getCIEXYZ.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/color_levels.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_dtex = glGetUniformLocation(Program, "dtex");
|
||||
uniform_inlevel = glGetUniformLocation(Program, "inlevel");
|
||||
uniform_outlevel = glGetUniformLocation(Program, "outlevel");
|
||||
uniform_invprojm = glGetUniformLocation(Program, "invprojm");
|
||||
vao = createVAO(Program);
|
||||
}
|
||||
|
||||
GLuint SunLightShader::Program;
|
||||
GLuint SunLightShader::uniform_ntex;
|
||||
GLuint SunLightShader::uniform_dtex;
|
||||
@ -2177,7 +2183,7 @@ namespace FullScreenShader
|
||||
uniform_dtex = glGetUniformLocation(Program, "dtex");
|
||||
uniform_direction = glGetUniformLocation(Program, "direction");
|
||||
uniform_col = glGetUniformLocation(Program, "col");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
if (!UserConfigParams::m_ubo_disabled)
|
||||
{
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
@ -2214,7 +2220,7 @@ namespace FullScreenShader
|
||||
uniform_greenLmn = glGetUniformLocation(Program, "greenLmn[0]");
|
||||
uniform_redLmn = glGetUniformLocation(Program, "redLmn[0]");
|
||||
uniform_TVM = glGetUniformLocation(Program, "TransposeViewMatrix");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
void DiffuseEnvMapShader::setUniforms(const core::matrix4 &TransposeViewMatrix, const float *blueSHCoeff, const float *greenSHCoeff, const float *redSHCoeff, unsigned TU_ntex)
|
||||
@ -2247,7 +2253,7 @@ namespace FullScreenShader
|
||||
uniform_shadowtex = glGetUniformLocation(Program, "shadowtex");
|
||||
uniform_direction = glGetUniformLocation(Program, "direction");
|
||||
uniform_col = glGetUniformLocation(Program, "col");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
if (!UserConfigParams::m_ubo_disabled)
|
||||
{
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
@ -2336,7 +2342,7 @@ namespace FullScreenShader
|
||||
uniform_extents = glGetUniformLocation(Program, "extents");
|
||||
uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix");
|
||||
uniform_RSMMatrix = glGetUniformLocation(Program, "RSMMatrix");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
void RadianceHintsConstructionShader::setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ctex, unsigned TU_ntex, unsigned TU_dtex)
|
||||
@ -2403,7 +2409,7 @@ namespace FullScreenShader
|
||||
uniform_SHB = glGetUniformLocation(Program, "SHB");
|
||||
uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix");
|
||||
uniform_extents = glGetUniformLocation(Program, "extents");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
@ -2430,7 +2436,7 @@ namespace FullScreenShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian17taph.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_pixel = glGetUniformLocation(Program, "pixel");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
GLuint Gaussian6HBlurShader::Program;
|
||||
@ -2444,7 +2450,7 @@ namespace FullScreenShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian6h.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_pixel = glGetUniformLocation(Program, "pixel");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
GLuint Gaussian3HBlurShader::Program;
|
||||
@ -2458,7 +2464,7 @@ namespace FullScreenShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian3h.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_pixel = glGetUniformLocation(Program, "pixel");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
GLuint Gaussian17TapVShader::Program;
|
||||
@ -2472,7 +2478,7 @@ namespace FullScreenShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian17tapv.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_pixel = glGetUniformLocation(Program, "pixel");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
GLuint Gaussian6VBlurShader::Program;
|
||||
@ -2486,7 +2492,7 @@ namespace FullScreenShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian6v.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_pixel = glGetUniformLocation(Program, "pixel");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
GLuint Gaussian3VBlurShader::Program;
|
||||
@ -2500,7 +2506,7 @@ namespace FullScreenShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian3v.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_pixel = glGetUniformLocation(Program, "pixel");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
GLuint PassThroughShader::Program;
|
||||
@ -2528,7 +2534,7 @@ namespace FullScreenShader
|
||||
uniform_texture = glGetUniformLocation(Program, "texture");
|
||||
uniform_zf = glGetUniformLocation(Program, "zf");
|
||||
uniform_zn = glGetUniformLocation(Program, "zn");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
void LinearizeDepthShader::setUniforms(float zn, float zf, unsigned TU_tex)
|
||||
@ -2569,7 +2575,7 @@ namespace FullScreenShader
|
||||
uniform_dtex = glGetUniformLocation(Program, "dtex");
|
||||
uniform_noise_texture = glGetUniformLocation(Program, "noise_texture");
|
||||
uniform_samplePoints = glGetUniformLocation(Program, "samplePoints[0]");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
if (!UserConfigParams::m_ubo_disabled)
|
||||
{
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
@ -2723,7 +2729,7 @@ namespace FullScreenShader
|
||||
uniform_start = glGetUniformLocation(Program, "start");
|
||||
uniform_end = glGetUniformLocation(Program, "end");
|
||||
uniform_col = glGetUniformLocation(Program, "col");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
if (!UserConfigParams::m_ubo_disabled)
|
||||
{
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
@ -2764,7 +2770,7 @@ namespace FullScreenShader
|
||||
uniform_direction = glGetUniformLocation(Program, "direction");
|
||||
uniform_mask_radius = glGetUniformLocation(Program, "mask_radius");
|
||||
uniform_max_tex_height = glGetUniformLocation(Program, "max_tex_height");
|
||||
vao = createVAO(Program);
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
void MotionBlurShader::setUniforms(float boost_amount, const core::vector2df ¢er, const core::vector2df &direction, float mask_radius, float max_tex_height, unsigned TU_cb)
|
||||
@ -2819,24 +2825,6 @@ namespace FullScreenShader
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
|
||||
GLuint LogLuminanceShader::Program;
|
||||
GLuint LogLuminanceShader::uniform_tex;
|
||||
GLuint LogLuminanceShader::vao;
|
||||
|
||||
void LogLuminanceShader::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/logluminance.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
vao = createVAO(Program);
|
||||
}
|
||||
|
||||
void LogLuminanceShader::setUniforms(unsigned TU_tex)
|
||||
{
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
|
||||
GLuint MLAAColorEdgeDetectionSHader::Program;
|
||||
GLuint MLAAColorEdgeDetectionSHader::uniform_colorMapG;
|
||||
GLuint MLAAColorEdgeDetectionSHader::uniform_PIXEL_SIZE;
|
||||
|
@ -526,11 +526,11 @@ class BloomBlendShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_texture;
|
||||
static GLuint uniform_tex_128, uniform_tex_256, uniform_tex_512;
|
||||
static GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(unsigned TU_tex);
|
||||
static void setUniforms(unsigned TU_tex_128, unsigned TU_tex_256, unsigned TU_tex_512);
|
||||
};
|
||||
|
||||
class ToneMapShader
|
||||
@ -555,16 +555,6 @@ public:
|
||||
static void setUniforms(unsigned TU_tex, unsigned TU_depth);
|
||||
};
|
||||
|
||||
class ColorLevelShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_tex, uniform_invprojm, uniform_dtex, uniform_inlevel, uniform_outlevel;
|
||||
static GLuint vao;
|
||||
|
||||
static void init();
|
||||
};
|
||||
|
||||
class SunLightShader
|
||||
{
|
||||
public:
|
||||
@ -788,17 +778,6 @@ public:
|
||||
static void setUniforms(const core::vector2df &sunpos, unsigned TU_tex);
|
||||
};
|
||||
|
||||
class LogLuminanceShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_tex;
|
||||
static GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(unsigned TU_tex);
|
||||
};
|
||||
|
||||
class MLAAColorEdgeDetectionSHader
|
||||
{
|
||||
public:
|
||||
|
@ -668,6 +668,7 @@ namespace GUIEngine
|
||||
#include "guiengine/widget.hpp"
|
||||
#include "guiengine/dialog_queue.hpp"
|
||||
#include "modes/demo_world.hpp"
|
||||
#include "modes/cutscene_world.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "states_screens/race_gui_base.hpp"
|
||||
|
||||
@ -1210,6 +1211,12 @@ namespace GUIEngine
|
||||
}
|
||||
|
||||
|
||||
if (gamestate == INGAME_MENU && dynamic_cast<CutsceneWorld*>(World::getWorld()) != NULL)
|
||||
{
|
||||
RaceGUIBase* rg = World::getWorld()->getRaceGUI();
|
||||
if (rg != NULL) rg->renderGlobal(elapsed_time);
|
||||
}
|
||||
|
||||
if (gamestate == MENU || gamestate == INGAME_MENU)
|
||||
{
|
||||
g_skin->drawTooltips();
|
||||
|
@ -309,6 +309,17 @@ namespace GUIEngine
|
||||
virtual void onDialogClose() {}
|
||||
};
|
||||
|
||||
class CutsceneScreen : public Screen
|
||||
{
|
||||
public:
|
||||
CutsceneScreen(const char* name) : Screen(name, false)
|
||||
{
|
||||
setNeeds3D(true);
|
||||
m_throttle_FPS = false;
|
||||
}
|
||||
|
||||
virtual void onCutsceneEnd() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -94,6 +94,9 @@ void TextBoxWidget::add()
|
||||
(m_parent ? m_parent : GUIEngine::getGUIEnv()->getRootGUIElement()),
|
||||
getNewID(), widget_size);
|
||||
|
||||
if (m_deactivated)
|
||||
m_element->setEnabled(false);
|
||||
|
||||
//m_element = GUIEngine::getGUIEnv()->addEditBox(text.c_str(), widget_size,
|
||||
// true /* border */, m_parent, getNewID());
|
||||
m_id = m_element->getID();
|
||||
@ -168,3 +171,33 @@ void TextBoxWidget::elementRemoved()
|
||||
m_element->drop();
|
||||
Widget::elementRemoved();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TextBoxWidget::setActivated()
|
||||
{
|
||||
Widget::setActivated();
|
||||
|
||||
if (m_element != NULL)
|
||||
{
|
||||
IGUIEditBox* textCtrl = Widget::getIrrlichtElement<IGUIEditBox>();
|
||||
assert(textCtrl != NULL);
|
||||
textCtrl->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TextBoxWidget::setDeactivated()
|
||||
{
|
||||
Widget::setDeactivated();
|
||||
|
||||
if (m_element != NULL)
|
||||
{
|
||||
IGUIEditBox* textCtrl = Widget::getIrrlichtElement<IGUIEditBox>();
|
||||
assert(textCtrl != NULL);
|
||||
textCtrl->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -71,6 +71,12 @@ namespace GUIEngine
|
||||
void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*');
|
||||
|
||||
virtual void elementRemoved();
|
||||
|
||||
/** Override method from base class Widget */
|
||||
virtual void setActivated();
|
||||
|
||||
/** Override method from base class Widget */
|
||||
virtual void setDeactivated();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -585,7 +585,7 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
|
||||
|
||||
if (device != NULL)
|
||||
{
|
||||
KartSelectionScreen::getRunningInstance()->playerJoin(device,
|
||||
KartSelectionScreen::getRunningInstance()->joinPlayer(device,
|
||||
false );
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ void AbstractKart::reset()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a name to be displayed for this kart. */
|
||||
const wchar_t* AbstractKart::getName() const
|
||||
core::stringw AbstractKart::getName() const
|
||||
{
|
||||
return m_kart_properties->getName();
|
||||
} // getName;
|
||||
|
@ -83,6 +83,7 @@ public:
|
||||
int world_kart_id,
|
||||
int position, const btTransform& init_transform);
|
||||
virtual ~AbstractKart();
|
||||
virtual core::stringw getName() const;
|
||||
virtual void reset();
|
||||
virtual void init(RaceManager::KartType type) = 0;
|
||||
// ========================================================================
|
||||
@ -109,8 +110,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the kart properties. */
|
||||
void setKartProperties(const KartProperties *kp) { m_kart_properties=kp; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual const wchar_t* getName() const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a unique identifier for this kart (name of the directory the
|
||||
* kart was loaded from). */
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "addons/addon.hpp"
|
||||
#include "config/stk_config.hpp"
|
||||
#include "config/player_manager.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
@ -732,6 +733,28 @@ void KartProperties::checkAllSet(const std::string &filename)
|
||||
m_ai_properties[i]->checkAllSet(filename);
|
||||
} // checkAllSet
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool KartProperties::operator<(const KartProperties &other) const
|
||||
{
|
||||
PlayerProfile *p = PlayerManager::getCurrentPlayer();
|
||||
bool this_is_locked = p->isLocked(getIdent());
|
||||
bool other_is_locked = p->isLocked(other.getIdent());
|
||||
if (this_is_locked == other_is_locked)
|
||||
{
|
||||
return getName() < other.getName();
|
||||
}
|
||||
else
|
||||
return other_is_locked;
|
||||
|
||||
return true;
|
||||
} // operator<
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool KartProperties::isInGroup(const std::string &group) const
|
||||
{
|
||||
return std::find(m_groups.begin(), m_groups.end(), group) != m_groups.end();
|
||||
} // isInGroups
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called the first time a kart accelerates after 'ready-set-go'. It searches
|
||||
* through m_startup_times to find the appropriate slot, and returns the
|
||||
|
@ -387,6 +387,8 @@ public:
|
||||
void getAllData (const XMLNode * root);
|
||||
void checkAllSet (const std::string &filename);
|
||||
float getStartupBoost () const;
|
||||
bool isInGroup (const std::string &group) const;
|
||||
bool operator<(const KartProperties &other) const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the (maximum) speed for a given turn radius.
|
||||
@ -431,9 +433,9 @@ public:
|
||||
/** Returns the name of this kart.
|
||||
\note Pass it through fridibi as needed, this is the LTR name
|
||||
*/
|
||||
const wchar_t* getName() const
|
||||
core::stringw getName() const
|
||||
{
|
||||
return translations->w_gettext(m_name.c_str());
|
||||
return core::stringw(translations->w_gettext(m_name.c_str()));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
59
src/main.cpp
59
src/main.cpp
@ -403,7 +403,7 @@ void setupRaceStart()
|
||||
|
||||
// Create player and associate player with keyboard
|
||||
StateManager::get()->createActivePlayer(
|
||||
PlayerManager::get()->getPlayer(0), device, NULL);
|
||||
PlayerManager::get()->getPlayer(0), device);
|
||||
|
||||
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
|
||||
{
|
||||
@ -1375,13 +1375,6 @@ int main(int argc, char *argv[] )
|
||||
|
||||
/* Program closing...*/
|
||||
|
||||
if(user_config)
|
||||
{
|
||||
// In case that abort is triggered before user_config exists
|
||||
if (UserConfigParams::m_crashed) UserConfigParams::m_crashed = false;
|
||||
user_config->saveConfig();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WIIUSE
|
||||
if(wiimote_manager)
|
||||
delete wiimote_manager;
|
||||
@ -1433,27 +1426,15 @@ static void cleanSuperTuxKart()
|
||||
|
||||
delete main_loop;
|
||||
|
||||
irr_driver->updateConfigIfRelevant();
|
||||
|
||||
if(Online::RequestManager::isRunning())
|
||||
Online::RequestManager::get()->stopNetworkThread();
|
||||
|
||||
//delete in reverse order of what they were created in.
|
||||
//see InitTuxkart()
|
||||
Online::RequestManager::deallocate();
|
||||
Online::ServersManager::deallocate();
|
||||
Online::ProfileManager::destroy();
|
||||
GUIEngine::DialogQueue::deallocate();
|
||||
|
||||
irr_driver->updateConfigIfRelevant();
|
||||
AchievementsManager::destroy();
|
||||
Referee::cleanup();
|
||||
|
||||
if(ReplayPlay::get()) ReplayPlay::destroy();
|
||||
if(race_manager) delete race_manager;
|
||||
NewsManager::deallocate();
|
||||
if(addons_manager) delete addons_manager;
|
||||
NetworkManager::kill();
|
||||
|
||||
if(grand_prix_manager) delete grand_prix_manager;
|
||||
if(highscore_manager) delete highscore_manager;
|
||||
if(attachment_manager) delete attachment_manager;
|
||||
@ -1470,6 +1451,33 @@ static void cleanSuperTuxKart()
|
||||
delete ParticleKindManager::get();
|
||||
PlayerManager::destroy();
|
||||
if(unlock_manager) delete unlock_manager;
|
||||
Online::ProfileManager::destroy();
|
||||
GUIEngine::DialogQueue::deallocate();
|
||||
|
||||
// Now finish shutting down objects which a separate thread. The
|
||||
// RequestManager has been signaled to shut down as early as possible,
|
||||
// the NewsManager thread should have finished quite early on anyway.
|
||||
// But still give them some additional time to finish. It avoids a
|
||||
// race condition where a thread might access the file manager after it
|
||||
// was deleted (in cleanUserConfig below), but before STK finishes and
|
||||
// the os takes all threads down.
|
||||
|
||||
if(!NewsManager::get()->waitForReadyToDeleted(2.0f))
|
||||
{
|
||||
Log::info("Thread", "News manager not stopping, exiting anyway.");
|
||||
}
|
||||
NewsManager::deallocate();
|
||||
|
||||
if(!Online::RequestManager::get()->waitForReadyToDeleted(5.0f))
|
||||
{
|
||||
Log::info("Thread", "Request Manager not aborting in time, aborting.");
|
||||
}
|
||||
Online::RequestManager::deallocate();
|
||||
|
||||
// FIXME: do we need to wait for threads there, can they be
|
||||
// moved further up?
|
||||
Online::ServersManager::deallocate();
|
||||
NetworkManager::kill();
|
||||
|
||||
cleanUserConfig();
|
||||
|
||||
@ -1485,7 +1493,14 @@ static void cleanUserConfig()
|
||||
{
|
||||
if(stk_config) delete stk_config;
|
||||
if(translations) delete translations;
|
||||
if(user_config) delete user_config;
|
||||
if (user_config)
|
||||
{
|
||||
// In case that abort is triggered before user_config exists
|
||||
if (UserConfigParams::m_crashed) UserConfigParams::m_crashed = false;
|
||||
user_config->saveConfig();
|
||||
delete user_config;
|
||||
}
|
||||
|
||||
if(file_manager) delete file_manager;
|
||||
if(irr_driver) delete irr_driver;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <IMeshSceneNode.h>
|
||||
#include <ISceneManager.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
bool CutsceneWorld::s_use_duration = false;
|
||||
@ -187,12 +188,12 @@ void CutsceneWorld::update(float dt)
|
||||
{
|
||||
/*
|
||||
{
|
||||
PtrVector<TrackObject>& objects = m_track->getTrackObjectManager()->getObjects();
|
||||
TrackObject* curr;
|
||||
for_in(curr, objects)
|
||||
{
|
||||
printf("* %s\n", curr->getType().c_str());
|
||||
}
|
||||
PtrVector<TrackObject>& objects = m_track->getTrackObjectManager()->getObjects();
|
||||
TrackObject* curr;
|
||||
for_in(curr, objects)
|
||||
{
|
||||
printf("* %s\n", curr->getType().c_str());
|
||||
}
|
||||
}
|
||||
**/
|
||||
|
||||
@ -235,18 +236,29 @@ void CutsceneWorld::update(float dt)
|
||||
dt = (float)(m_time - prev_time);
|
||||
}
|
||||
|
||||
float fade;
|
||||
float fade = 0.0f;
|
||||
float fadeIn = -1.0f;
|
||||
float fadeOut = -1.0f;
|
||||
if (m_time < 2.0f)
|
||||
{
|
||||
fade = 1.0f - (float)m_time / 2.0f;
|
||||
fadeIn = 1.0f - (float)m_time / 2.0f;
|
||||
}
|
||||
else if (m_time > m_duration - 2.0f)
|
||||
if (m_time > m_duration - 2.0f)
|
||||
{
|
||||
fade = (float)(m_time - (m_duration - 2.0f)) / 2.0f;
|
||||
fadeOut = (float)(m_time - (m_duration - 2.0f)) / 2.0f;
|
||||
}
|
||||
else
|
||||
|
||||
if (fadeIn >= 0.0f && fadeOut >= 0.0f)
|
||||
{
|
||||
fade = 0.0f;
|
||||
fade = std::max(fadeIn, fadeOut);
|
||||
}
|
||||
else if (fadeIn >= 0.0f)
|
||||
{
|
||||
fade = fadeIn;
|
||||
}
|
||||
else if (fadeOut >= 0.0f)
|
||||
{
|
||||
fade = fadeOut;
|
||||
}
|
||||
dynamic_cast<CutsceneGUI*>(m_race_gui)->setFadeLevel(fade);
|
||||
|
||||
@ -354,6 +366,15 @@ void CutsceneWorld::update(float dt)
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
bool isOver = (m_time > m_duration);
|
||||
if (isOver && (s_use_duration || m_aborted))
|
||||
{
|
||||
GUIEngine::CutsceneScreen* cs = dynamic_cast<GUIEngine::CutsceneScreen*>(
|
||||
GUIEngine::getCurrentScreen());
|
||||
if (cs != NULL)
|
||||
cs->onCutsceneEnd();
|
||||
}
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -440,10 +461,12 @@ void CutsceneWorld::enterRaceOverState()
|
||||
*/
|
||||
bool CutsceneWorld::isRaceOver()
|
||||
{
|
||||
bool isOver = (m_time > m_duration);
|
||||
|
||||
if (!s_use_duration && !m_aborted)
|
||||
return false;
|
||||
|
||||
return m_time > m_duration;
|
||||
return isOver;
|
||||
} // isRaceOver
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -142,7 +142,7 @@ bool DemoWorld::updateIdleTimeAndStartDemo(float dt)
|
||||
// Use keyboard 0 by default in --no-start-screen
|
||||
device = input_manager->getDeviceList()->getKeyboard(0);
|
||||
StateManager::get()->createActivePlayer(
|
||||
PlayerManager::get()->getPlayer(0), device , NULL);
|
||||
PlayerManager::get()->getPlayer(0), device);
|
||||
// ASSIGN should make sure that only input from assigned devices
|
||||
// is read.
|
||||
input_manager->getDeviceList()->setAssignMode(ASSIGN);
|
||||
|
@ -67,7 +67,7 @@ void OverWorld::enterOverWorld()
|
||||
|
||||
// Create player and associate player with keyboard
|
||||
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
|
||||
device, NULL);
|
||||
device);
|
||||
|
||||
if (!kart_properties_manager->getKart(UserConfigParams::m_default_kart))
|
||||
{
|
||||
|
@ -824,7 +824,7 @@ void World::updateWorld(float dt)
|
||||
|
||||
// Create player and associate player with keyboard
|
||||
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
|
||||
device, NULL);
|
||||
device);
|
||||
|
||||
if (!kart_properties_manager->getKart(UserConfigParams::m_default_kart))
|
||||
{
|
||||
|
@ -122,7 +122,7 @@ void StartGameProtocol::update()
|
||||
if (StateManager::get()->getActivePlayers().size() >= 1) // more than one player, we're the first
|
||||
new_player_id = 0;
|
||||
else
|
||||
new_player_id = StateManager::get()->createActivePlayer( profile_to_use, device , players[i]->user_profile);
|
||||
new_player_id = StateManager::get()->createActivePlayer( profile_to_use, device);
|
||||
device->setPlayer(StateManager::get()->getActivePlayer(new_player_id));
|
||||
input_manager->getDeviceList()->setSinglePlayer(StateManager::get()->getActivePlayer(new_player_id));
|
||||
|
||||
@ -147,7 +147,7 @@ void StartGameProtocol::update()
|
||||
|
||||
if (!is_me)
|
||||
{
|
||||
StateManager::get()->createActivePlayer( NULL, NULL , players[i]->user_profile);
|
||||
StateManager::get()->createActivePlayer( NULL, NULL );
|
||||
|
||||
race_manager->setPlayerKart(i, rki);
|
||||
}
|
||||
|
@ -322,7 +322,8 @@ namespace Online
|
||||
|
||||
// Check if we are asked to abort the download. If so, signal this
|
||||
// back to libcurl by returning a non-zero status.
|
||||
if(request_manager->getAbort() || request->isCancelled() )
|
||||
if( (request_manager->getAbort() || request->isCancelled()) &&
|
||||
request->isAbortable() )
|
||||
{
|
||||
// Indicates to abort the current download, which means that this
|
||||
// thread will go back to the mainloop and handle the next request.
|
||||
|
@ -240,6 +240,7 @@ namespace Online
|
||||
m_player->setUserDetails(this,
|
||||
UserConfigParams::m_remember_user ? "client-quit"
|
||||
:"disconnect");
|
||||
setAbortable(false);
|
||||
} // SignOutRequest
|
||||
}; // SignOutRequest
|
||||
// ----------------------------------------------------------------
|
||||
|
@ -44,6 +44,7 @@ namespace Online
|
||||
{
|
||||
m_cancel.setAtomic(false);
|
||||
m_state.setAtomic(S_PREPARING);
|
||||
m_is_abortable.setAtomic(true);
|
||||
} // Request
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -105,6 +105,12 @@ namespace Online
|
||||
|
||||
/** Cancel this request if it is active. */
|
||||
Synchronised<bool> m_cancel;
|
||||
|
||||
/** If this request can be aborted (at the end of STK). Most requests
|
||||
* can, except the (final) logout and client-quit/signout-request,
|
||||
* which must be finished even when STK is quitting. */
|
||||
Synchronised<bool> m_is_abortable;
|
||||
|
||||
/** Set to though if the reply of the request is in and callbacks are
|
||||
* executed */
|
||||
Synchronised<State> m_state;
|
||||
@ -156,6 +162,12 @@ namespace Online
|
||||
/** Returns if this request is to be canceled. */
|
||||
bool isCancelled() const { return m_cancel.getAtomic(); }
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns if this request can be aborted. */
|
||||
bool isAbortable() const { return m_is_abortable.getAtomic(); }
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets if this request is abortable or not. */
|
||||
void setAbortable(bool b) { m_is_abortable.setAtomic(b); }
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets the request state to busy. */
|
||||
void setBusy()
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010-2014 Lucas Baudin
|
||||
// 2011-201 Joerg Henrichs
|
||||
// 2011-2014 Joerg Henrichs
|
||||
// 2013-2014 Glenn De Jonghe
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
@ -83,7 +83,7 @@ namespace Online
|
||||
pthread_cond_init(&m_cond_request, NULL);
|
||||
m_abort.setAtomic(false);
|
||||
m_time_since_poll = MENU_POLLING_INTERVAL * 0.9;
|
||||
}
|
||||
} // RequestManager
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
RequestManager::~RequestManager()
|
||||
@ -94,8 +94,7 @@ namespace Online
|
||||
m_thread_id.unlock();
|
||||
pthread_cond_destroy(&m_cond_request);
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
} // ~RequestManager
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Start the actual network thread. This can not be done as part of
|
||||
@ -147,28 +146,26 @@ namespace Online
|
||||
*/
|
||||
void RequestManager::stopNetworkThread()
|
||||
{
|
||||
// If a download should be active (which means it was cancelled by the
|
||||
// user, in which case it will still be ongoing in the background)
|
||||
// we can't get the mutex, and would have to wait for a timeout,
|
||||
// and we couldn't finish STK. This way we request an abort of
|
||||
// a download, which mean we can get the mutex and ask the service
|
||||
// thread here to cancel properly.
|
||||
//cancelAllDownloads(); FIXME if used this way it also cancels the client-quit action
|
||||
// This will queue a sign-out or client-quit request
|
||||
PlayerManager::onSTKQuit();
|
||||
addRequest(new Request(true, HTTP_MAX_PRIORITY, Request::RT_QUIT));
|
||||
} // stopNetworkThread
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Signals to the progress function to request any ongoing download to be
|
||||
* cancelled. This function can also be called if there is actually no
|
||||
* download atm. The function progressDownload checks m_abort and will
|
||||
* return a non-zero value which causes libcurl to abort. */
|
||||
void RequestManager::cancelAllDownloads()
|
||||
{
|
||||
// Put in a high priortity quit request in. It has the same priority
|
||||
// as a sign-out request (so the sign-out will be executed before the
|
||||
// quit request).
|
||||
Request *quit = new Request(true, HTTP_MAX_PRIORITY, Request::RT_QUIT);
|
||||
quit->setAbortable(false);
|
||||
addRequest(quit);
|
||||
|
||||
// It is possible that downloads are still ongoing (either an addon
|
||||
// download that the user aborted, or the addon icons etc are still
|
||||
// queued). In order to allow a quick exit of stk we set a flag that
|
||||
// will cause libcurl to abort downloading asap, and then allow the
|
||||
// other requests (sign-out and quit) to be executed asap. Note that
|
||||
// the sign-out request is set to be not abortable, so it still will
|
||||
// be executed (before the quit request is executed, which causes this
|
||||
// thread to exit).
|
||||
m_abort.setAtomic(true);
|
||||
// FIXME doesn't get called at the moment. When using this again,
|
||||
// be sure that HTTP_MAX_PRIORITY requests still get executed.
|
||||
} // cancelAllDownloads
|
||||
} // stopNetworkThread
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Inserts a request into the queue of all requests. The request will be
|
||||
@ -222,6 +219,11 @@ namespace Online
|
||||
me->m_request_queue.lock();
|
||||
} // while
|
||||
|
||||
// Signal that the request manager can now be deleted.
|
||||
// We signal this even before cleaning up memory, since there's no
|
||||
// need to keep the user waiting for STK to exit.
|
||||
me->setCanBeDeleted();
|
||||
|
||||
// At this stage we have the lock for m_request_queue
|
||||
while(!me->m_request_queue.getData().empty())
|
||||
{
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "io/xml_node.hpp"
|
||||
#include "online/request.hpp"
|
||||
#include "utils/can_be_deleted.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
|
||||
@ -42,11 +43,41 @@
|
||||
namespace Online
|
||||
{
|
||||
|
||||
/**
|
||||
* \brief Class to connect with a server over HTTP(S)
|
||||
* \ingroup online
|
||||
*/
|
||||
class RequestManager
|
||||
/** A class to execute requests in a separate thread. Typically the
|
||||
* requests involve a http(s) requests to be sent to the stk server, and
|
||||
* receive an answer (e.g. to sign in; or to download an addon). The
|
||||
* requests are sorted by priority (e.g. sign in and out have higher
|
||||
* priority than downloading addon icons).
|
||||
* A request is created and initialised from the main thread. When it
|
||||
* is moved into the request queue, it must not be handled by the main
|
||||
* thread anymore, only the RequestManager thread can handle it.
|
||||
* Once the request is finished, it is put in a separate ready queue.
|
||||
* The main thread regularly checks the ready queue for any ready
|
||||
* request, and executes a callback. So there is no need to protect
|
||||
* any functions or data members in requests, since they will either
|
||||
* be handled by the main thread, or RequestManager thread, never by
|
||||
* both.
|
||||
* On exit, if necessary a high priority sign-out or client-quit request
|
||||
* is put into the queue, and a flag is set which causes libcurl to
|
||||
* abort any ongoing download. Then an additional 'quit' event with
|
||||
* same priority as the sign-out is added to the queue (since it will
|
||||
* be added later, the sign-out will be executed first, making sure that
|
||||
* a logged in user is logged out (or its session saved). Once this is
|
||||
* done, most of stk is deleted (except a few objects like the file
|
||||
* manager which might be accessed if a download just finished before the
|
||||
* abort). On executing the quit request, the request manager will set
|
||||
* a flag that it is ready to be deleted (using the CanBeDeleted class).
|
||||
* The main thread will wait for a certain amount of time for the
|
||||
* RequestManager to be ready to be deleted (i.e. the sign-out and quit
|
||||
* request have been processes), before deleting the RequestManager.
|
||||
* Typically the RequestManager will finish while the rest of stk is
|
||||
* shutting down, so the user will not experience any waiting time. Only
|
||||
* on first start of stk (which will trigger downloading of all addon
|
||||
* icons) is it possible that actually a download request is running,
|
||||
* which might take a bit before it can be deleted.
|
||||
* \ingroup online
|
||||
*/
|
||||
class RequestManager : public CanBeDeleted
|
||||
{
|
||||
public:
|
||||
/** If stk has permission to access the internet (for news
|
||||
@ -102,7 +133,6 @@ namespace Online
|
||||
static bool isRunning();
|
||||
|
||||
void addRequest(Online::Request *request);
|
||||
void cancelAllDownloads();
|
||||
void startNetworkThread();
|
||||
void stopNetworkThread();
|
||||
|
||||
|
@ -98,12 +98,20 @@ void GrandPrixData::reload()
|
||||
{
|
||||
Log::error("GrandPrixData",
|
||||
"Error while trying to read grandprix file '%s': "
|
||||
"missing 'name' attribute", m_filename.c_str());
|
||||
"Missing 'name' attribute", m_filename.c_str());
|
||||
throw std::runtime_error("Missing name attribute");
|
||||
}
|
||||
|
||||
// Every iteration means parsing one track entry
|
||||
const int amount = root->getNumNodes();
|
||||
if (amount == 0)
|
||||
{
|
||||
Log::error("GrandPrixData",
|
||||
"Error while trying to read grandprix file '%s': "
|
||||
"There is no track defined", m_filename.c_str());
|
||||
throw std::runtime_error("No track defined");
|
||||
}
|
||||
|
||||
// Every iteration means parsing one track entry
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
const XMLNode* node = root->getNode(i);
|
||||
@ -235,7 +243,7 @@ bool GrandPrixData::checkConsistency(bool log_error) const
|
||||
* is unlocked). It also prevents people from using the grand prix editor as
|
||||
* a way to play tracks that still haven't been unlocked
|
||||
*/
|
||||
bool GrandPrixData::isTrackAvailable(const std::string &id,
|
||||
bool GrandPrixData::isTrackAvailable(const std::string &id,
|
||||
bool includeLocked ) const
|
||||
{
|
||||
if (includeLocked)
|
||||
@ -357,7 +365,7 @@ void GrandPrixData::addTrack(Track* track, unsigned int laps, bool reverse,
|
||||
int n = getNumberOfTracks(true);
|
||||
assert (track != NULL);
|
||||
assert (laps > 0);
|
||||
assert (-1 < position && position < n);
|
||||
assert (-1 <= position && position < n);
|
||||
|
||||
if (position < 0 || position == (n - 1) || m_tracks.empty())
|
||||
{
|
||||
|
@ -57,13 +57,7 @@ GPInfoDialog::GPInfoDialog(const std::string& gpIdent, const float w, const floa
|
||||
m_gp_ident = gpIdent;
|
||||
|
||||
const GrandPrixData* gp = grand_prix_manager->getGrandPrix(gpIdent);
|
||||
if (gp == NULL)
|
||||
{
|
||||
assert(false);
|
||||
std::cerr << "ERROR at " << __FILE__ << " : " << __LINE__ << "; trying to continue\n";
|
||||
ModalDialog::dismiss();
|
||||
return;
|
||||
}
|
||||
assert (gp != NULL);
|
||||
|
||||
// ---- GP Name
|
||||
core::rect< s32 > area_top(0, 0, m_area.getWidth(), y1);
|
||||
@ -183,14 +177,14 @@ GPInfoDialog::GPInfoDialog(const std::string& gpIdent, const float w, const floa
|
||||
continueBtn->add();
|
||||
continueBtn->getIrrlichtElement()->setTabStop(true);
|
||||
continueBtn->getIrrlichtElement()->setTabGroup(false);
|
||||
|
||||
|
||||
okBtn->m_x = m_area.getWidth()/2 - 310;
|
||||
}
|
||||
else
|
||||
{
|
||||
okBtn->m_x = m_area.getWidth()/2 - 200;
|
||||
}
|
||||
|
||||
|
||||
okBtn->m_y = y2;
|
||||
okBtn->m_w = 400;
|
||||
okBtn->m_h = m_area.getHeight() - y2 - 15;
|
||||
@ -201,7 +195,7 @@ GPInfoDialog::GPInfoDialog(const std::string& gpIdent, const float w, const floa
|
||||
okBtn->getIrrlichtElement()->setTabGroup(false);
|
||||
|
||||
okBtn->setFocusForPlayer( PLAYER_ID_GAME_MASTER );
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
|
@ -184,12 +184,16 @@ void EditTrackScreen::loadTrackList()
|
||||
{
|
||||
Track* t = track_manager->getTrack(i);
|
||||
const std::vector<std::string>& groups = t->getGroups();
|
||||
belongsToGroup = (m_track_group.empty() || m_track_group == ALL_TRACKS_GROUP_ID ||
|
||||
std::find(groups.begin(), groups.end(), m_track_group) != groups.end());
|
||||
if (!t->isArena() && !t->isSoccer() && !t->isInternal() && belongsToGroup)
|
||||
belongsToGroup = (m_track_group.empty() ||
|
||||
m_track_group == ALL_TRACKS_GROUP_ID ||
|
||||
t->isInGroup(m_track_group) );
|
||||
if (!t->isArena() && !t->isSoccer() &&
|
||||
!t->isInternal() && belongsToGroup )
|
||||
{
|
||||
tracks_widget->addItem(translations->fribidize(t->getName()), t->getIdent(),
|
||||
t->getScreenshotFile(), 0, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
|
||||
tracks_widget->addItem(translations->fribidize(t->getName()),
|
||||
t->getIdent(),
|
||||
t->getScreenshotFile(), 0,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "io/file_manager.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "modes/cutscene_world.hpp"
|
||||
#include "modes/overworld.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "race/grand_prix_manager.hpp"
|
||||
@ -50,6 +51,10 @@ using namespace irr::core;
|
||||
using namespace irr::gui;
|
||||
using namespace irr::video;
|
||||
|
||||
const float ANIM_FROM = 3.0f;
|
||||
const float ANIM_TO = 7.0f;
|
||||
const int GIFT_EXIT_FROM = (int)ANIM_TO;
|
||||
const int GIFT_EXIT_TO = GIFT_EXIT_FROM + 7;
|
||||
|
||||
DEFINE_SCREEN_SINGLETON( FeatureUnlockedCutScene );
|
||||
|
||||
@ -66,6 +71,7 @@ FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(std::string model,
|
||||
m_unlock_message = msg;
|
||||
m_unlock_model = model;
|
||||
m_curr_image = -1;
|
||||
m_scale = 1.0f;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
@ -77,6 +83,7 @@ FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(KartProperties* kart,
|
||||
m_unlocked_kart = kart;
|
||||
m_unlock_message = msg;
|
||||
m_curr_image = -1;
|
||||
m_scale = 1.0f;
|
||||
} // UnlockedThing::UnlockedThing
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
@ -91,6 +98,7 @@ FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(irr::video::ITexture* pict
|
||||
m_h = h;
|
||||
m_unlock_message = msg;
|
||||
m_curr_image = -1;
|
||||
m_scale = 1.0f;
|
||||
} // UnlockedThing::UnlockedThing
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -105,6 +113,7 @@ FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(std::vector<irr::video::IT
|
||||
m_h = h;
|
||||
m_unlock_message = msg;
|
||||
m_curr_image = 0;
|
||||
m_scale = 1.0f;
|
||||
} // UnlockedThing::UnlockedThing
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -123,12 +132,10 @@ FeatureUnlockedCutScene::UnlockedThing::~UnlockedThing()
|
||||
#endif
|
||||
|
||||
FeatureUnlockedCutScene::FeatureUnlockedCutScene()
|
||||
: Screen("feature_unlocked.stkgui")
|
||||
: CutsceneScreen("feature_unlocked.stkgui")
|
||||
{
|
||||
m_key_angle = 0;
|
||||
setNeeds3D(true);
|
||||
|
||||
m_throttle_FPS = false;
|
||||
#ifdef USE_IRRLICHT_BUG_WORKAROUND
|
||||
m_avoid_irrlicht_bug = NULL;
|
||||
#endif
|
||||
@ -140,6 +147,23 @@ void FeatureUnlockedCutScene::loadedFromFile()
|
||||
{
|
||||
} // loadedFromFile
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
void FeatureUnlockedCutScene::onCutsceneEnd()
|
||||
{
|
||||
#ifdef USE_IRRLICHT_BUG_WORKAROUND
|
||||
if (m_avoid_irrlicht_bug)
|
||||
irr_driver->removeNode(m_avoid_irrlicht_bug);
|
||||
m_avoid_irrlicht_bug = NULL;
|
||||
#endif
|
||||
|
||||
m_unlocked_stuff.clearAndDeleteAll();
|
||||
m_all_kart_models.clearAndDeleteAll();
|
||||
|
||||
// update point count and the list of locked/unlocked stuff
|
||||
PlayerManager::getCurrentPlayer()->computeActive();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void FeatureUnlockedCutScene::findWhatWasUnlocked(RaceManager::Difficulty difficulty)
|
||||
@ -248,71 +272,10 @@ void FeatureUnlockedCutScene::addUnlockedPictures(std::vector<irr::video::ITextu
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const float CAMERA_INITIAL_X = 0.0f;
|
||||
const float CAMERA_INITIAL_Y = 30.0f;
|
||||
const float CAMERA_INITIAL_Z = 70.0f;
|
||||
|
||||
void FeatureUnlockedCutScene::init()
|
||||
{
|
||||
m_sky_angle = 0.0f;
|
||||
m_global_time = 0.0f;
|
||||
|
||||
std::vector<std::string> texture_names(6);
|
||||
texture_names[0] = file_manager->getAsset(FileManager::TEXTURE, "purplenebula.jpg");
|
||||
texture_names[1] = file_manager->getAsset(FileManager::TEXTURE, "purplenebula2.png");
|
||||
texture_names[2] = file_manager->getAsset(FileManager::TEXTURE, "purplenebula.jpg");
|
||||
texture_names[3] = file_manager->getAsset(FileManager::TEXTURE, "purplenebula2.png");
|
||||
texture_names[4] = file_manager->getAsset(FileManager::TEXTURE, "purplenebula.jpg");
|
||||
texture_names[5] = file_manager->getAsset(FileManager::TEXTURE, "purplenebula2.png");
|
||||
std::vector<video::ITexture*> textures;
|
||||
for(unsigned int i=0; i<texture_names.size(); i++)
|
||||
{
|
||||
video::ITexture *t = irr_driver->getTexture(texture_names[i]);
|
||||
textures.push_back(t);
|
||||
}
|
||||
std::vector<video::ITexture*> sh_textures;
|
||||
m_sky = irr_driver->addSkyBox(textures, sh_textures);
|
||||
#ifdef DEBUG
|
||||
m_sky->setName("skybox");
|
||||
#endif
|
||||
|
||||
m_camera = irr_driver->addCameraSceneNode();
|
||||
#ifdef DEBUG
|
||||
m_camera->setName("camera");
|
||||
#endif
|
||||
m_camera->setPosition( core::vector3df(CAMERA_INITIAL_X, CAMERA_INITIAL_Y, CAMERA_INITIAL_Z) );
|
||||
m_camera->setUpVector( core::vector3df(0.0, 1.0, 0.0) );
|
||||
m_camera->setTarget( core::vector3df(0, 10, 0.0f) );
|
||||
m_camera->setFOV( DEGREE_TO_RAD*50.0f );
|
||||
m_camera->updateAbsolutePosition();
|
||||
irr_driver->getSceneManager()->setActiveCamera(m_camera);
|
||||
|
||||
scene::IAnimatedMesh* model_chest =
|
||||
irr_driver->getAnimatedMesh( file_manager->getAsset(FileManager::MODEL,"chest.b3d") );
|
||||
assert(model_chest != NULL);
|
||||
m_chest = irr_driver->addAnimatedMesh(model_chest);
|
||||
#ifdef DEBUG
|
||||
m_chest->setName("chest");
|
||||
#endif
|
||||
m_chest->setPosition( core::vector3df(2, -3, 0) );
|
||||
m_chest->setScale( core::vector3df(10.0f, 10.0f, 10.0f) );
|
||||
m_chest->setMaterialFlag(video::EMF_FOG_ENABLE, false);
|
||||
|
||||
irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 120,
|
||||
120, 120));
|
||||
|
||||
const core::vector3df &sun_pos = core::vector3df( 0, 200, 100.0f );
|
||||
m_light = irr_driver->addLight(sun_pos, 10000.0f, 1., 1, 1, 1, true);
|
||||
#ifdef DEBUG
|
||||
m_light->setName("light");
|
||||
#endif
|
||||
|
||||
if (!irr_driver->isGLSL())
|
||||
{
|
||||
((scene::ILightSceneNode *) m_light)->getLightData().DiffuseColor = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
((scene::ILightSceneNode *) m_light)->getLightData().SpecularColor = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
const int unlockedStuffCount = m_unlocked_stuff.size();
|
||||
|
||||
if (unlockedStuffCount == 0) std::cerr << "There is nothing in the unlock chest!!!\n";
|
||||
@ -323,7 +286,8 @@ void FeatureUnlockedCutScene::init()
|
||||
if (m_unlocked_stuff[n].m_unlock_model.size() > 0)
|
||||
{
|
||||
m_unlocked_stuff[n].m_root_gift_node = irr_driver->addMesh( irr_driver->getMesh(m_unlocked_stuff[n].m_unlock_model) );
|
||||
m_unlocked_stuff[n].m_root_gift_node->setScale( core::vector3df(0.5f, 0.5f, 0.5f) );
|
||||
m_unlocked_stuff[n].m_scale = 0.7f;
|
||||
//m_unlocked_stuff[n].m_root_gift_node->setScale(core::vector3df(0.2f, 0.2f, 0.2f));
|
||||
}
|
||||
else if (m_unlocked_stuff[n].m_unlocked_kart != NULL)
|
||||
{
|
||||
@ -331,6 +295,7 @@ void FeatureUnlockedCutScene::init()
|
||||
m_unlocked_stuff[n].m_unlocked_kart->getKartModelCopy();
|
||||
m_all_kart_models.push_back(kart_model);
|
||||
m_unlocked_stuff[n].m_root_gift_node = kart_model->attachModel(true, false);
|
||||
m_unlocked_stuff[n].m_scale = 5.0f;
|
||||
kart_model->setAnimation(KartModel::AF_DEFAULT);
|
||||
float susp[4]={0,0,0,0};
|
||||
kart_model->update(0.0f, 0.0f, 0.0f, susp, 0.0f);
|
||||
@ -363,7 +328,6 @@ void FeatureUnlockedCutScene::init()
|
||||
m.SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
m.GouraudShading = false;
|
||||
m.Shininess = 0;
|
||||
//m.setFlag(video::EMF_TEXTURE_WRAP, false);
|
||||
|
||||
m.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
|
||||
m.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
|
||||
@ -389,29 +353,7 @@ void FeatureUnlockedCutScene::init()
|
||||
void FeatureUnlockedCutScene::tearDown()
|
||||
{
|
||||
Screen::tearDown();
|
||||
irr_driver->removeNode(m_sky);
|
||||
m_sky = NULL;
|
||||
|
||||
irr_driver->removeCameraSceneNode(m_camera);
|
||||
m_camera = NULL;
|
||||
|
||||
irr_driver->removeNode(m_chest);
|
||||
m_chest = NULL;
|
||||
|
||||
irr_driver->removeNode(m_light);
|
||||
m_light = NULL;
|
||||
|
||||
#ifdef USE_IRRLICHT_BUG_WORKAROUND
|
||||
if(m_avoid_irrlicht_bug)
|
||||
irr_driver->removeNode(m_avoid_irrlicht_bug);
|
||||
m_avoid_irrlicht_bug = NULL;
|
||||
#endif
|
||||
|
||||
m_unlocked_stuff.clearAndDeleteAll();
|
||||
m_all_kart_models.clearAndDeleteAll();
|
||||
|
||||
// update point count and the list of locked/unlocked stuff
|
||||
PlayerManager::getCurrentPlayer()->computeActive();
|
||||
((CutsceneWorld*)World::getWorld())->abortCutscene();
|
||||
} // tearDown
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -427,62 +369,31 @@ T keepInRange(T from, T to, T value)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const float ANIM_FROM = 1.0f;
|
||||
const float ANIM_TO = 3.0f;
|
||||
const int GIFT_EXIT_FROM = (int)ANIM_TO;
|
||||
const int GIFT_EXIT_TO = GIFT_EXIT_FROM + 7;
|
||||
|
||||
void FeatureUnlockedCutScene::onUpdate(float dt)
|
||||
{
|
||||
m_global_time += dt;
|
||||
|
||||
m_sky_angle += dt*2;
|
||||
if (m_sky_angle > 360) m_sky_angle -= 360;
|
||||
m_sky->setRotation( core::vector3df(0, m_sky_angle, 0) );
|
||||
|
||||
const int last_image = m_chest->getEndFrame() - 1;
|
||||
|
||||
if (m_global_time < ANIM_FROM)
|
||||
{
|
||||
// progression of the chest rotation between 0 and 1
|
||||
const float rotationProgression =
|
||||
keepInRange( 0.0f, 1.0f, (float)sin(M_PI/2.0f*m_global_time/ANIM_FROM) );
|
||||
const float chest_rotation =
|
||||
keepInRange(80.0f, 160.0f, 80 + rotationProgression * 80);
|
||||
m_chest->setRotation( core::vector3df(0.0f, chest_rotation, 0.0f) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_chest->setRotation( core::vector3df(0.0f, 160.0f, 0.0f) );
|
||||
}
|
||||
|
||||
|
||||
// Make sure it doesn't continue on its own, WE animated it ourselves here
|
||||
m_chest->setAnimationSpeed(0);
|
||||
|
||||
const float current_frame = keepInRange(0.0f, (float)last_image,
|
||||
(float)(m_global_time - ANIM_FROM)
|
||||
/(ANIM_TO - ANIM_FROM) * last_image);
|
||||
m_chest->setCurrentFrame( current_frame );
|
||||
|
||||
const int unlockedStuffCount = m_unlocked_stuff.size();
|
||||
|
||||
if (m_global_time > GIFT_EXIT_FROM && m_global_time < GIFT_EXIT_TO)
|
||||
{
|
||||
float progress_factor = (m_global_time - GIFT_EXIT_FROM) / (GIFT_EXIT_TO - GIFT_EXIT_FROM);
|
||||
float smoothed_progress_factor = sin((progress_factor - 0.5f)*M_PI)/2.0f + 0.5f;
|
||||
|
||||
Log::info("smoothed_progress_factor", "%f", smoothed_progress_factor);
|
||||
|
||||
for (int n=0; n<unlockedStuffCount; n++)
|
||||
{
|
||||
if (m_unlocked_stuff[n].m_root_gift_node == NULL) continue;
|
||||
|
||||
core::vector3df pos = m_unlocked_stuff[n].m_root_gift_node->getPosition();
|
||||
pos.Y = sin( (float)((m_global_time-GIFT_EXIT_FROM)*M_PI*1.2/GIFT_EXIT_TO) )*30.0f;
|
||||
pos.Y = sin(smoothed_progress_factor*2.5f)*10.0f;
|
||||
|
||||
// when there are more than 1 unlocked items, make sure they each
|
||||
// have their own path when they move
|
||||
if (unlockedStuffCount > 1)
|
||||
{
|
||||
if (n == 1) pos.X -= 6.2f*dt*float( int((n + 1)/2) );
|
||||
else if (n > 1) pos.X += 6.2f*dt*(n - 1.0f);
|
||||
if (n == 1) pos.X -= 1.0f*dt*float( int((n + 1)/2) );
|
||||
else if (n > 1) pos.X += 1.0f*dt*(n - 0.3f);
|
||||
|
||||
//else pos.X += 6.2f*dt*float( int((n + 1)/2) );
|
||||
//std::cout << "Object " << n << " moving by " <<
|
||||
@ -493,30 +404,15 @@ void FeatureUnlockedCutScene::onUpdate(float dt)
|
||||
//pos.X -= 2.0f*dt;
|
||||
}
|
||||
|
||||
if (m_global_time > GIFT_EXIT_FROM + 2.0f) pos.Z += 6.0f*dt;
|
||||
//if (m_global_time > GIFT_EXIT_FROM + 2.0f) pos.Z -= 2.0f*dt;
|
||||
|
||||
pos.Z = smoothed_progress_factor * -4.0f;
|
||||
|
||||
m_unlocked_stuff[n].m_root_gift_node->setPosition(pos);
|
||||
|
||||
core::vector3df scale =
|
||||
m_unlocked_stuff[n].m_root_gift_node->getScale();
|
||||
scale.X += 0.9f*dt;
|
||||
scale.Y += 0.9f*dt;
|
||||
scale.Z += 0.9f*dt;
|
||||
m_unlocked_stuff[n].m_root_gift_node->setScale(scale);
|
||||
}
|
||||
|
||||
core::vector3df campos = m_camera->getPosition();
|
||||
campos.X -= 8.0f*dt;
|
||||
campos.Y += 5.0f*dt;
|
||||
campos.Z += 5.0f*dt;
|
||||
|
||||
m_camera->setPosition(campos);
|
||||
}
|
||||
else if (m_global_time < GIFT_EXIT_FROM)
|
||||
{
|
||||
m_camera->setPosition( core::vector3df(cos((1.0f-m_key_angle)*M_PI/4 + M_PI/4)*70.0f,
|
||||
30.0f,
|
||||
sin((1.0f-m_key_angle)*M_PI/8 + M_PI/4)*70.0f) );
|
||||
}
|
||||
|
||||
for (int n=0; n<unlockedStuffCount; n++)
|
||||
@ -554,20 +450,16 @@ void FeatureUnlockedCutScene::onUpdate(float dt)
|
||||
} // textureID != previousTextureID
|
||||
} // if pictureCount>1
|
||||
} // if !m_unlocked_stuff[n].m_pictures.empty()
|
||||
|
||||
float scale = m_unlocked_stuff[n].m_scale;
|
||||
if (m_global_time <= GIFT_EXIT_FROM)
|
||||
scale *= 0.1f;
|
||||
else if (m_global_time > GIFT_EXIT_FROM && m_global_time < GIFT_EXIT_TO)
|
||||
scale *= ((m_global_time - GIFT_EXIT_FROM) / (GIFT_EXIT_TO - GIFT_EXIT_FROM));
|
||||
m_unlocked_stuff[n].m_root_gift_node->setScale(core::vector3df(scale, scale, scale));
|
||||
} // for n<unlockedStuffCount
|
||||
|
||||
assert(m_unlocked_stuff.size() > 0);
|
||||
if (m_unlocked_stuff[0].m_root_gift_node != NULL)
|
||||
{
|
||||
m_camera->setTarget( m_unlocked_stuff[0].m_root_gift_node->getPosition() +
|
||||
core::vector3df(0.0f, 10.0f, 0.0f) );
|
||||
m_camera->updateAbsolutePosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_camera->setTarget( core::vector3df(0, 10, 0.0f) );
|
||||
m_camera->updateAbsolutePosition();
|
||||
}
|
||||
|
||||
static const int w = irr_driver->getFrameSize().Width;
|
||||
static const int h = irr_driver->getFrameSize().Height;
|
||||
@ -654,6 +546,7 @@ void FeatureUnlockedCutScene::addUnlockedGP(const GrandPrixData* gp)
|
||||
|
||||
bool FeatureUnlockedCutScene::onEscapePressed()
|
||||
{
|
||||
((CutsceneWorld*)World::getWorld())->abortCutscene();
|
||||
continueButtonPressed();
|
||||
return false; // continueButtonPressed already pop'ed the menu
|
||||
} // onEscapePressed
|
||||
|
@ -36,7 +36,7 @@ class ChallengeData;
|
||||
* \brief Screen shown when a feature has been unlocked
|
||||
* \ingroup states_screens
|
||||
*/
|
||||
class FeatureUnlockedCutScene : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<FeatureUnlockedCutScene>
|
||||
class FeatureUnlockedCutScene : public GUIEngine::CutsceneScreen, public GUIEngine::ScreenSingleton<FeatureUnlockedCutScene>
|
||||
{
|
||||
friend class GUIEngine::ScreenSingleton<FeatureUnlockedCutScene>;
|
||||
|
||||
@ -60,6 +60,8 @@ class FeatureUnlockedCutScene : public GUIEngine::Screen, public GUIEngine::Scre
|
||||
/** Contains whatever is in the chest */
|
||||
scene::ISceneNode* m_root_gift_node;
|
||||
|
||||
float m_scale;
|
||||
|
||||
irr::core::stringw m_unlock_message;
|
||||
|
||||
UnlockedThing(std::string model, irr::core::stringw msg);
|
||||
@ -91,9 +93,6 @@ class FeatureUnlockedCutScene : public GUIEngine::Screen, public GUIEngine::Scre
|
||||
/** To store the copy of the KartModel for each unlocked kart. */
|
||||
PtrVector<KartModel> m_all_kart_models;
|
||||
|
||||
/** sky angle, 0-360 */
|
||||
float m_sky_angle;
|
||||
|
||||
/** Global evolution of time */
|
||||
double m_global_time;
|
||||
|
||||
@ -103,20 +102,6 @@ class FeatureUnlockedCutScene : public GUIEngine::Screen, public GUIEngine::Scre
|
||||
/** Angle of the key (from 0 to 1, simply traces progression) */
|
||||
float m_key_angle;
|
||||
|
||||
/** The scene node for the sky box. */
|
||||
irr::scene::ISceneNode *m_sky;
|
||||
|
||||
/** The scene node for the camera. */
|
||||
irr::scene::ICameraSceneNode *m_camera;
|
||||
|
||||
/** The scene node for the animated mesh. */
|
||||
irr::scene::IAnimatedMeshSceneNode *m_chest;
|
||||
|
||||
/** The scene node for the light. */
|
||||
irr::scene::ISceneNode* m_light;
|
||||
|
||||
//#define USE_IRRLICHT_BUG_WORKAROUND
|
||||
|
||||
#ifdef USE_IRRLICHT_BUG_WORKAROUND
|
||||
scene::IMeshSceneNode *m_avoid_irrlicht_bug;
|
||||
#endif
|
||||
@ -125,6 +110,8 @@ class FeatureUnlockedCutScene : public GUIEngine::Screen, public GUIEngine::Scre
|
||||
|
||||
public:
|
||||
|
||||
virtual void onCutsceneEnd() OVERRIDE;
|
||||
|
||||
/** \brief implement optional callback from parent class GUIEngine::Screen */
|
||||
void onUpdate(float dt) OVERRIDE;
|
||||
|
||||
|
@ -82,15 +82,76 @@ DEFINE_SCREEN_SINGLETON( GrandPrixLose );
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
GrandPrixLose::GrandPrixLose() : Screen("grand_prix_lose.stkgui", false /* pause race */)
|
||||
GrandPrixLose::GrandPrixLose() : CutsceneScreen("grand_prix_lose.stkgui")
|
||||
{
|
||||
setNeeds3D(true);
|
||||
|
||||
m_throttle_FPS = false;
|
||||
} // GrandPrixLose
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
void GrandPrixLose::onCutsceneEnd()
|
||||
{
|
||||
TrackObjectManager* tobjman = World::getWorld()->getTrack()->getTrackObjectManager();
|
||||
if (m_kart_node[0] != NULL)
|
||||
m_kart_node[0]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
|
||||
if (m_kart_node[1] != NULL)
|
||||
m_kart_node[1]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
|
||||
if (m_kart_node[2] != NULL)
|
||||
m_kart_node[2]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
|
||||
if (m_kart_node[3] != NULL)
|
||||
m_kart_node[3]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
|
||||
|
||||
for (unsigned int i = 0; i<m_all_kart_models.size(); i++)
|
||||
delete m_all_kart_models[i];
|
||||
|
||||
m_all_kart_models.clear();
|
||||
|
||||
m_kart_node[0] = NULL;
|
||||
m_kart_node[1] = NULL;
|
||||
m_kart_node[2] = NULL;
|
||||
m_kart_node[3] = NULL;
|
||||
|
||||
// un-set the GP mode so that after unlocking, it doesn't try to continue the GP
|
||||
race_manager->setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
|
||||
|
||||
std::vector<const ChallengeData*> unlocked =
|
||||
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
|
||||
if (unlocked.size() > 0)
|
||||
{
|
||||
|
||||
FeatureUnlockedCutScene* scene =
|
||||
FeatureUnlockedCutScene::getInstance();
|
||||
|
||||
scene->addTrophy(race_manager->getDifficulty());
|
||||
scene->findWhatWasUnlocked(race_manager->getDifficulty());
|
||||
|
||||
StateManager::get()->replaceTopMostScreen(scene);
|
||||
PlayerManager::getCurrentPlayer()->clearUnlocked();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (race_manager->raceWasStartedFromOverworld())
|
||||
{
|
||||
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
|
||||
OverWorld::enterOverWorld();
|
||||
}
|
||||
else
|
||||
{
|
||||
// we assume the main menu was pushed before showing this menu
|
||||
StateManager::get()->popMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
bool GrandPrixLose::onEscapePressed()
|
||||
{
|
||||
((CutsceneWorld*)World::getWorld())->abortCutscene();
|
||||
return false;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
void GrandPrixLose::loadedFromFile()
|
||||
{
|
||||
m_kart_node[0] = NULL;
|
||||
@ -121,17 +182,6 @@ void GrandPrixLose::init()
|
||||
void GrandPrixLose::tearDown()
|
||||
{
|
||||
Screen::tearDown();
|
||||
((CutsceneWorld*)World::getWorld())->abortCutscene();
|
||||
|
||||
for (unsigned int i=0; i<m_all_kart_models.size(); i++)
|
||||
delete m_all_kart_models[i];
|
||||
|
||||
m_all_kart_models.clear();
|
||||
|
||||
m_kart_node[0] = NULL;
|
||||
m_kart_node[1] = NULL;
|
||||
m_kart_node[2] = NULL;
|
||||
m_kart_node[3] = NULL;
|
||||
} // tearDown
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
@ -181,36 +231,7 @@ void GrandPrixLose::eventCallback(GUIEngine::Widget* widget,
|
||||
{
|
||||
if (name == "continue")
|
||||
{
|
||||
// un-set the GP mode so that after unlocking, it doesn't try to continue the GP
|
||||
race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
|
||||
|
||||
std::vector<const ChallengeData*> unlocked =
|
||||
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
|
||||
if (unlocked.size() > 0)
|
||||
{
|
||||
|
||||
FeatureUnlockedCutScene* scene =
|
||||
FeatureUnlockedCutScene::getInstance();
|
||||
|
||||
scene->addTrophy(race_manager->getDifficulty());
|
||||
scene->findWhatWasUnlocked(race_manager->getDifficulty());
|
||||
|
||||
StateManager::get()->replaceTopMostScreen(scene);
|
||||
PlayerManager::getCurrentPlayer()->clearUnlocked();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (race_manager->raceWasStartedFromOverworld())
|
||||
{
|
||||
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
|
||||
OverWorld::enterOverWorld();
|
||||
}
|
||||
else
|
||||
{
|
||||
// we assume the main menu was pushed before showing this menu
|
||||
StateManager::get()->popMenu();
|
||||
}
|
||||
}
|
||||
((CutsceneWorld*)World::getWorld())->abortCutscene();
|
||||
}
|
||||
} // eventCallback
|
||||
|
||||
|
@ -33,7 +33,7 @@ class TrackObject;
|
||||
* \brief Screen shown at the end of a Grand Prix
|
||||
* \ingroup states_screens
|
||||
*/
|
||||
class GrandPrixLose : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<GrandPrixLose>
|
||||
class GrandPrixLose : public GUIEngine::CutsceneScreen, public GUIEngine::ScreenSingleton<GrandPrixLose>
|
||||
{
|
||||
friend class GUIEngine::ScreenSingleton<GrandPrixLose>;
|
||||
|
||||
@ -53,6 +53,10 @@ class GrandPrixLose : public GUIEngine::Screen, public GUIEngine::ScreenSingleto
|
||||
|
||||
public:
|
||||
|
||||
virtual void onCutsceneEnd() OVERRIDE;
|
||||
|
||||
virtual bool onEscapePressed() OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void loadedFromFile() OVERRIDE;
|
||||
|
||||
|
@ -53,24 +53,21 @@ using namespace irr::core;
|
||||
using namespace irr::gui;
|
||||
using namespace irr::video;
|
||||
|
||||
const float KARTS_X = -0.62f;
|
||||
const float KARTS_DELTA_X = 0.815f;
|
||||
const float KARTS_X = -0.95f;
|
||||
const float KARTS_DELTA_X = 1.9f;
|
||||
const float KARTS_DELTA_Y = -0.55f;
|
||||
const float KARTS_DEST_Z = 1.2f;
|
||||
const float KARTS_INITIAL_Z = -10.0f;
|
||||
const float KARTS_DEST_Z = -1.8f;
|
||||
const float INITIAL_Y = 0.0f;
|
||||
const float INITIAL_PODIUM_Y = -0.89f;
|
||||
const float PODIUM_HEIGHT[3] = { 0.325f, 0.5f, 0.15f };
|
||||
const float INITIAL_PODIUM_Y = -1.27f;
|
||||
const float PODIUM_HEIGHT[3] = { 0.650f, 1.0f, 0.30f };
|
||||
|
||||
DEFINE_SCREEN_SINGLETON( GrandPrixWin );
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
GrandPrixWin::GrandPrixWin() : Screen("grand_prix_win.stkgui", false /* pause race */)
|
||||
GrandPrixWin::GrandPrixWin() : CutsceneScreen("grand_prix_win.stkgui")
|
||||
{
|
||||
setNeeds3D(true);
|
||||
|
||||
m_throttle_FPS = false;
|
||||
|
||||
m_kart_node[0] = NULL;
|
||||
m_kart_node[1] = NULL;
|
||||
m_kart_node[2] = NULL;
|
||||
@ -83,6 +80,70 @@ GrandPrixWin::GrandPrixWin() : Screen("grand_prix_win.stkgui", false /* pause ra
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
GrandPrixWin::~GrandPrixWin()
|
||||
{
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
void GrandPrixWin::onCutsceneEnd()
|
||||
{
|
||||
for (unsigned int i = 0; i<m_all_kart_models.size(); i++)
|
||||
delete m_all_kart_models[i];
|
||||
m_all_kart_models.clear();
|
||||
|
||||
if (m_unlocked_label != NULL)
|
||||
{
|
||||
manualRemoveWidget(m_unlocked_label);
|
||||
delete m_unlocked_label;
|
||||
m_unlocked_label = NULL;
|
||||
}
|
||||
|
||||
TrackObjectManager* tobjman = World::getWorld()->getTrack()->getTrackObjectManager();
|
||||
if (m_kart_node[0] != NULL)
|
||||
m_kart_node[0]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
|
||||
if (m_kart_node[1] != NULL)
|
||||
m_kart_node[1]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
|
||||
if (m_kart_node[2] != NULL)
|
||||
m_kart_node[2]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
|
||||
|
||||
m_kart_node[0] = NULL;
|
||||
m_kart_node[1] = NULL;
|
||||
m_kart_node[2] = NULL;
|
||||
|
||||
m_podium_steps[0] = NULL;
|
||||
m_podium_steps[1] = NULL;
|
||||
m_podium_steps[2] = NULL;
|
||||
|
||||
|
||||
|
||||
// un-set the GP mode so that after unlocking, it doesn't try to continue the GP
|
||||
race_manager->setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
|
||||
|
||||
if (PlayerManager::getCurrentPlayer()
|
||||
->getRecentlyCompletedChallenges().size() > 0)
|
||||
{
|
||||
std::vector<const ChallengeData*> unlocked =
|
||||
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
|
||||
PlayerManager::getCurrentPlayer()->clearUnlocked();
|
||||
|
||||
FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance();
|
||||
|
||||
assert(unlocked.size() > 0);
|
||||
scene->addTrophy(race_manager->getDifficulty());
|
||||
scene->findWhatWasUnlocked(race_manager->getDifficulty());
|
||||
|
||||
StateManager::get()->replaceTopMostScreen(scene);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we assume the main menu was pushed before showing this menu
|
||||
StateManager::get()->popMenu();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
void GrandPrixWin::loadedFromFile()
|
||||
{
|
||||
} // loadedFromFile
|
||||
@ -160,29 +221,17 @@ void GrandPrixWin::init()
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
bool GrandPrixWin::onEscapePressed()
|
||||
{
|
||||
((CutsceneWorld*)World::getWorld())->abortCutscene();
|
||||
return false;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
void GrandPrixWin::tearDown()
|
||||
{
|
||||
Screen::tearDown();
|
||||
((CutsceneWorld*)World::getWorld())->abortCutscene();
|
||||
|
||||
for (unsigned int i = 0; i<m_all_kart_models.size(); i++)
|
||||
delete m_all_kart_models[i];
|
||||
m_all_kart_models.clear();
|
||||
|
||||
if (m_unlocked_label != NULL)
|
||||
{
|
||||
manualRemoveWidget(m_unlocked_label);
|
||||
delete m_unlocked_label;
|
||||
m_unlocked_label = NULL;
|
||||
}
|
||||
|
||||
m_kart_node[0] = NULL;
|
||||
m_kart_node[1] = NULL;
|
||||
m_kart_node[2] = NULL;
|
||||
|
||||
m_podium_steps[0] = NULL;
|
||||
m_podium_steps[1] = NULL;
|
||||
m_podium_steps[2] = NULL;
|
||||
} // tearDown
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
@ -221,7 +270,7 @@ void GrandPrixWin::onUpdate(float dt)
|
||||
|
||||
core::vector3df kart_pos(m_kart_x[k], m_kart_y[k], m_kart_z[k]);
|
||||
core::vector3df kart_rot(0, m_kart_rotation[k], 0);
|
||||
core::vector3df kart_scale(0.5f, 0.5f, 0.5f);
|
||||
core::vector3df kart_scale(1.0f, 1.0f, 1.0f);
|
||||
m_kart_node[k]->move(kart_pos, kart_rot, kart_scale, false);
|
||||
}
|
||||
} // end for
|
||||
@ -246,7 +295,7 @@ void GrandPrixWin::onUpdate(float dt)
|
||||
|
||||
core::vector3df kart_pos(m_kart_x[k], m_kart_y[k], m_kart_z[k]);
|
||||
core::vector3df kart_rot(0, m_kart_rotation[k], 0);
|
||||
core::vector3df kart_scale(0.5f, 0.5f, 0.5f);
|
||||
core::vector3df kart_scale(1.0f, 1.0f, 1.0f);
|
||||
m_kart_node[k]->move(kart_pos, kart_rot, kart_scale, false);
|
||||
|
||||
core::vector3df podium_pos = m_podium_steps[k]->getInitXYZ();
|
||||
@ -274,7 +323,7 @@ void GrandPrixWin::onUpdate(float dt)
|
||||
m_kart_y[k] += dt*(PODIUM_HEIGHT[k]);
|
||||
core::vector3df kart_pos(m_kart_x[k], m_kart_y[k], m_kart_z[k]);
|
||||
core::vector3df kart_rot(0, m_kart_rotation[k], 0);
|
||||
core::vector3df kart_scale(0.5f, 0.5f, 0.5f);
|
||||
core::vector3df kart_scale(1.0f, 1.0f, 1.0f);
|
||||
m_kart_node[k]->move(kart_pos, kart_rot, kart_scale, false);
|
||||
|
||||
|
||||
@ -310,29 +359,7 @@ void GrandPrixWin::eventCallback(GUIEngine::Widget* widget,
|
||||
{
|
||||
if (name == "continue")
|
||||
{
|
||||
// un-set the GP mode so that after unlocking, it doesn't try to continue the GP
|
||||
race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
|
||||
|
||||
if (PlayerManager::getCurrentPlayer()
|
||||
->getRecentlyCompletedChallenges().size() > 0)
|
||||
{
|
||||
std::vector<const ChallengeData*> unlocked =
|
||||
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
|
||||
PlayerManager::getCurrentPlayer()->clearUnlocked();
|
||||
|
||||
FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance();
|
||||
|
||||
assert(unlocked.size() > 0);
|
||||
scene->addTrophy(race_manager->getDifficulty());
|
||||
scene->findWhatWasUnlocked(race_manager->getDifficulty());
|
||||
|
||||
StateManager::get()->replaceTopMostScreen(scene);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we assume the main menu was pushed before showing this menu
|
||||
StateManager::get()->popMenu();
|
||||
}
|
||||
((CutsceneWorld*)World::getWorld())->abortCutscene();
|
||||
}
|
||||
} // eventCallback
|
||||
|
||||
@ -359,12 +386,12 @@ void GrandPrixWin::setKarts(const std::string idents_arg[3])
|
||||
|
||||
m_kart_x[i] = KARTS_X + i*KARTS_DELTA_X;
|
||||
m_kart_y[i] = INITIAL_Y + KARTS_DELTA_Y;
|
||||
m_kart_z[i] = -4; // to 1.2
|
||||
m_kart_z[i] = KARTS_INITIAL_Z;
|
||||
m_kart_rotation[i] = 0.0f;
|
||||
|
||||
core::vector3df kart_pos(m_kart_x[i], m_kart_y[i], m_kart_z[i]);
|
||||
core::vector3df kart_rot(0, 0, 0);
|
||||
core::vector3df kart_scale(0.5, 0.5, 0.5);
|
||||
core::vector3df kart_scale(1.0f, 1.0f, 1.0f);
|
||||
|
||||
//FIXME: it's not ideal that both the track object and the presentation know the initial coordinates of the object
|
||||
TrackObjectPresentationSceneNode* presentation = new TrackObjectPresentationSceneNode(
|
||||
|
@ -32,12 +32,14 @@ class TrackObject;
|
||||
* \brief Screen shown at the end of a Grand Prix
|
||||
* \ingroup states_screens
|
||||
*/
|
||||
class GrandPrixWin : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<GrandPrixWin>
|
||||
class GrandPrixWin : public GUIEngine::CutsceneScreen, public GUIEngine::ScreenSingleton<GrandPrixWin>
|
||||
{
|
||||
friend class GUIEngine::ScreenSingleton<GrandPrixWin>;
|
||||
|
||||
GrandPrixWin();
|
||||
|
||||
virtual ~GrandPrixWin();
|
||||
|
||||
/** Global evolution of time */
|
||||
double m_global_time;
|
||||
|
||||
@ -61,6 +63,10 @@ class GrandPrixWin : public GUIEngine::Screen, public GUIEngine::ScreenSingleton
|
||||
|
||||
public:
|
||||
|
||||
virtual void onCutsceneEnd() OVERRIDE;
|
||||
|
||||
virtual bool onEscapePressed() OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void loadedFromFile() OVERRIDE;
|
||||
|
||||
|
@ -67,7 +67,7 @@ void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const i
|
||||
|
||||
// Create player and associate player with keyboard
|
||||
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
|
||||
device, NULL);
|
||||
device);
|
||||
|
||||
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
|
||||
{
|
||||
|
@ -682,10 +682,9 @@ void PlayerKartWidget::onUpdate(float delta)
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Event callback */
|
||||
GUIEngine::EventPropagation PlayerKartWidget::transmitEvent(
|
||||
Widget* w,
|
||||
const std::string& originator,
|
||||
const int m_player_id)
|
||||
GUIEngine::EventPropagation PlayerKartWidget::transmitEvent(Widget* w,
|
||||
const std::string& originator,
|
||||
const int m_player_id )
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
// if it's declared ready, there is really nothing to process
|
||||
@ -1012,7 +1011,7 @@ void KartSelectionScreen::init()
|
||||
else */
|
||||
// For now this is what will happen
|
||||
{
|
||||
playerJoin( input_manager->getDeviceList()->getLatestUsedDevice(),
|
||||
joinPlayer( input_manager->getDeviceList()->getLatestUsedDevice(),
|
||||
true );
|
||||
w->updateItemDisplay();
|
||||
}
|
||||
@ -1057,7 +1056,7 @@ void KartSelectionScreen::tearDown()
|
||||
m_kart_widgets.clearAndDeleteAll();
|
||||
|
||||
if (m_must_delete_on_back)
|
||||
GUIEngine::removeScreen(this->getName().c_str());
|
||||
GUIEngine::removeScreen(getName().c_str());
|
||||
} // tearDown
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -1070,24 +1069,24 @@ void KartSelectionScreen::unloaded()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Return true if event was handled successfully
|
||||
bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
|
||||
bool KartSelectionScreen::joinPlayer(InputDevice* device, bool first_player)
|
||||
{
|
||||
if (UserConfigParams::logGUI())
|
||||
Log::info("[KartSelectionScreen]", "playerJoin() invoked");
|
||||
if (!m_multiplayer && !firstPlayer) return false;
|
||||
Log::info("[KartSelectionScreen]", "joinPlayer() invoked");
|
||||
if (!m_multiplayer && !first_player) return false;
|
||||
|
||||
assert (g_dispatcher != NULL);
|
||||
|
||||
DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts");
|
||||
if (w == NULL)
|
||||
{
|
||||
Log::error("[KartSelectionScreen]", "playerJoin(): Called outside of "
|
||||
Log::error("[KartSelectionScreen]", "joinPlayer(): Called outside of "
|
||||
"kart selection screen.");
|
||||
return false;
|
||||
}
|
||||
else if (device == NULL)
|
||||
{
|
||||
Log::error("[KartSelectionScreen]", "playerJoin(): Received null "
|
||||
Log::error("[KartSelectionScreen]", "joinPlayer(): Received null "
|
||||
"device pointer");
|
||||
return false;
|
||||
}
|
||||
@ -1100,32 +1099,19 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---- Get available area for karts
|
||||
// make a copy of the area, ands move it to be outside the screen
|
||||
Widget* kartsAreaWidget = getWidget("playerskarts");
|
||||
// start at the rightmost of the screen
|
||||
const int shift = irr_driver->getFrameSize().Width;
|
||||
core::recti kartsArea(kartsAreaWidget->m_x + shift,
|
||||
kartsAreaWidget->m_y,
|
||||
kartsAreaWidget->m_x + shift + kartsAreaWidget->m_w,
|
||||
kartsAreaWidget->m_y + kartsAreaWidget->m_h);
|
||||
|
||||
// ---- Create new active player
|
||||
PlayerProfile* profile_to_use = PlayerManager::getCurrentPlayer();
|
||||
|
||||
if (!firstPlayer)
|
||||
// Make sure enough guest character exists. At this stage this player has
|
||||
// not been added, so the number of guests requested for the first player
|
||||
// is 0 --> forcing at least one real player.
|
||||
PlayerManager::get()->createGuestPlayers(
|
||||
StateManager::get()->activePlayerCount());
|
||||
if (!first_player)
|
||||
{
|
||||
const int player_profile_count = PlayerManager::get()->getNumPlayers();
|
||||
for (int i=0; i<player_profile_count; i++)
|
||||
{
|
||||
PlayerProfile *player = PlayerManager::get()->getPlayer(i);
|
||||
if (player->isGuestAccount())
|
||||
{
|
||||
profile_to_use = player;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Give each player a different start profile
|
||||
const int num_active_players = StateManager::get()->activePlayerCount();
|
||||
profile_to_use = PlayerManager::get()->getPlayer(num_active_players);
|
||||
|
||||
// Remove multiplayer message
|
||||
if (m_multiplayer_message != NULL)
|
||||
@ -1139,7 +1125,7 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
|
||||
}
|
||||
|
||||
const int new_player_id =
|
||||
StateManager::get()->createActivePlayer( profile_to_use, device, NULL );
|
||||
StateManager::get()->createActivePlayer( profile_to_use, device);
|
||||
StateManager::ActivePlayer* aplayer =
|
||||
StateManager::get()->getActivePlayer(new_player_id);
|
||||
|
||||
@ -1149,6 +1135,16 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
|
||||
std::string selected_kart_group =
|
||||
tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
// ---- Get available area for karts
|
||||
// make a copy of the area, ands move it to be outside the screen
|
||||
Widget* kartsAreaWidget = getWidget("playerskarts");
|
||||
// start at the rightmost of the screen
|
||||
const int shift = irr_driver->getFrameSize().Width;
|
||||
core::recti kartsArea(kartsAreaWidget->m_x + shift,
|
||||
kartsAreaWidget->m_y,
|
||||
kartsAreaWidget->m_x + shift + kartsAreaWidget->m_w,
|
||||
kartsAreaWidget->m_y + kartsAreaWidget->m_h);
|
||||
|
||||
// ---- Create player/kart widget
|
||||
PlayerKartWidget* newPlayerWidget =
|
||||
new PlayerKartWidget(this, aplayer, NULL, kartsArea, m_kart_widgets.size(),
|
||||
@ -1164,7 +1160,7 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
|
||||
Widget* fullarea = getWidget("playerskarts");
|
||||
|
||||
// in this special case, leave room for a message on the right
|
||||
if (m_multiplayer && firstPlayer)
|
||||
if (m_multiplayer && first_player)
|
||||
{
|
||||
const int splitWidth = fullarea->m_w / 2;
|
||||
|
||||
@ -1196,7 +1192,7 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
|
||||
}
|
||||
|
||||
|
||||
if (!firstPlayer)
|
||||
if (!first_player)
|
||||
{
|
||||
// select something (anything) in the ribbon; by default, only the
|
||||
// game master has something selected. Thus, when a new player joins,
|
||||
@ -1204,17 +1200,17 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
|
||||
w->setSelection(new_player_id, new_player_id, true);
|
||||
|
||||
newPlayerWidget->m_player_ident_spinner
|
||||
->setFocusForPlayer(new_player_id);
|
||||
->setFocusForPlayer(new_player_id);
|
||||
}
|
||||
|
||||
if (!m_multiplayer)
|
||||
{
|
||||
input_manager->getDeviceList()->setSinglePlayer( StateManager::get()
|
||||
->getActivePlayer(0));
|
||||
->getActivePlayer(0));
|
||||
}
|
||||
|
||||
return true;
|
||||
} // playerJoin
|
||||
} // joinPlayer
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@ -1560,7 +1556,7 @@ void KartSelectionScreen::eventCallback(Widget* widget,
|
||||
|
||||
setKartsFromCurrentGroup();
|
||||
|
||||
const std::string selected_kart_group =
|
||||
const std::string &selected_kart_group =
|
||||
tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
UserConfigParams::m_last_used_kart_group = selected_kart_group;
|
||||
@ -2010,7 +2006,7 @@ void KartSelectionScreen::setKartsFromCurrentGroup()
|
||||
// selected kart group is removed. In this case, select the
|
||||
// 'standard' group
|
||||
if (selected_kart_group != ALL_KART_GROUPS_ID &&
|
||||
!kart_properties_manager->getKartsInGroup(selected_kart_group).size())
|
||||
!kart_properties_manager->getKartsInGroup(selected_kart_group).size())
|
||||
{
|
||||
selected_kart_group = DEFAULT_GROUP_NAME;
|
||||
}
|
||||
@ -2018,69 +2014,43 @@ void KartSelectionScreen::setKartsFromCurrentGroup()
|
||||
DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts");
|
||||
w->clearItems();
|
||||
|
||||
int usableKartCount = 0;
|
||||
int usable_kart_count = 0;
|
||||
PtrVector<const KartProperties, REF> karts;
|
||||
|
||||
if (selected_kart_group == ALL_KART_GROUPS_ID)
|
||||
for(unsigned int i=0; i<kart_properties_manager->getNumberOfKarts(); i++)
|
||||
{
|
||||
const int kart_amount = kart_properties_manager->getNumberOfKarts();
|
||||
|
||||
for (int n=0; n<kart_amount; n++)
|
||||
{
|
||||
const KartProperties* prop =
|
||||
kart_properties_manager->getKartById(n);
|
||||
if (PlayerManager::getCurrentPlayer()->isLocked(prop->getIdent()))
|
||||
{
|
||||
w->addItem(
|
||||
_("Locked : solve active challenges to gain access "
|
||||
"to more!"),
|
||||
ID_LOCKED+prop->getIdent(),
|
||||
prop->getAbsoluteIconFile(), LOCKED_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
w->addItem(translations->fribidize(prop->getName()),
|
||||
prop->getIdent(),
|
||||
prop->getAbsoluteIconFile(), 0,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
usableKartCount++;
|
||||
}
|
||||
}
|
||||
const KartProperties* prop = kart_properties_manager->getKartById(i);
|
||||
// Ignore karts that are not in the selected group
|
||||
if(selected_kart_group != ALL_KART_GROUPS_ID &&
|
||||
!prop->isInGroup(selected_kart_group))
|
||||
continue;
|
||||
karts.push_back(prop);
|
||||
}
|
||||
else if (selected_kart_group != RibbonWidget::NO_ITEM_ID)
|
||||
karts.insertionSort();
|
||||
|
||||
for(unsigned int i=0; i<karts.size(); i++)
|
||||
{
|
||||
std::vector<int> group =
|
||||
kart_properties_manager->getKartsInGroup(selected_kart_group);
|
||||
const int kart_amount = group.size();
|
||||
|
||||
|
||||
for (int n=0; n<kart_amount; n++)
|
||||
const KartProperties* prop = karts.get(i);
|
||||
if (PlayerManager::getCurrentPlayer()->isLocked(prop->getIdent()))
|
||||
{
|
||||
const KartProperties* prop =
|
||||
kart_properties_manager->getKartById(group[n]);
|
||||
const std::string &icon_path = prop->getAbsoluteIconFile();
|
||||
|
||||
if (PlayerManager::getCurrentPlayer()->isLocked(prop->getIdent()))
|
||||
{
|
||||
w->addItem(
|
||||
_("Locked : solve active challenges to gain access "
|
||||
"to more!"),
|
||||
ID_LOCKED+prop->getIdent(), icon_path, LOCKED_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
w->addItem(translations->fribidize(prop->getName()),
|
||||
prop->getIdent(),
|
||||
icon_path, 0,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
usableKartCount++;
|
||||
}
|
||||
w->addItem(_("Locked : solve active challenges to gain access "
|
||||
"to more!"),
|
||||
ID_LOCKED + prop->getIdent(),
|
||||
prop->getAbsoluteIconFile(), LOCKED_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
w->addItem(translations->fribidize(prop->getName()),
|
||||
prop->getIdent(),
|
||||
prop->getAbsoluteIconFile(), 0,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
usable_kart_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// add random
|
||||
if (usableKartCount > 1)
|
||||
if (usable_kart_count > 1)
|
||||
{
|
||||
w->addItem(_("Random Kart"), RANDOM_KART_ID, "/gui/random_kart.png");
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ public:
|
||||
|
||||
/** \brief Called when a player hits 'fire'/'select' on his device to
|
||||
* join the game */
|
||||
bool playerJoin(InputDevice* device, bool firstPlayer);
|
||||
bool joinPlayer(InputDevice* device, bool first_player);
|
||||
|
||||
/**
|
||||
* \brief Called when a player hits 'rescue'/'cancel' on his device
|
||||
|
@ -358,7 +358,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
|
||||
// Create player and associate player with keyboard
|
||||
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
|
||||
device, NULL);
|
||||
device);
|
||||
|
||||
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
|
||||
{
|
||||
|
@ -344,7 +344,10 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
|
||||
{
|
||||
race_manager->exitRace();
|
||||
race_manager->setAIKartOverride("");
|
||||
NetworkKartSelectionScreen::getInstance()->tearDown(); // be sure to delete the kart selection screen
|
||||
// FIXME: why is this call necessary here? tearDown should be
|
||||
// automatically called when the screen is left. Note that the
|
||||
// NetworkKartSelectionScreen::getInstance()->tearDown(); caused #1347
|
||||
KartSelectionScreen::getRunningInstance()->tearDown();
|
||||
Screen* newStack[] = {MainMenuScreen::getInstance(),
|
||||
RaceSetupScreen::getInstance(),
|
||||
NULL};
|
||||
@ -358,7 +361,10 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
|
||||
{
|
||||
race_manager->exitRace();
|
||||
race_manager->setAIKartOverride("");
|
||||
NetworkKartSelectionScreen::getInstance()->tearDown(); // be sure to delete the kart selection screen
|
||||
// FIXME: why is this call necessary here? tearDown should be
|
||||
// automatically called when the screen is left. Note that the
|
||||
// NetworkKartSelectionScreen::getInstance()->tearDown(); caused #1347
|
||||
KartSelectionScreen::getRunningInstance()->tearDown();
|
||||
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
|
||||
|
||||
if (race_manager->raceWasStartedFromOverworld())
|
||||
|
@ -102,12 +102,11 @@ void StateManager::updateActivePlayerIDs()
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int StateManager::createActivePlayer(PlayerProfile *profile,
|
||||
InputDevice *device,
|
||||
Online::OnlineProfile* user)
|
||||
InputDevice *device)
|
||||
{
|
||||
ActivePlayer *p;
|
||||
int i;
|
||||
p = new ActivePlayer(profile, device, user);
|
||||
p = new ActivePlayer(profile, device);
|
||||
i = m_active_players.size();
|
||||
m_active_players.push_back(p);
|
||||
|
||||
@ -254,8 +253,7 @@ void StateManager::onStackEmptied()
|
||||
#endif
|
||||
|
||||
StateManager::ActivePlayer::ActivePlayer(PlayerProfile* player,
|
||||
InputDevice *device,
|
||||
Online::OnlineProfile* user)
|
||||
InputDevice *device)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
m_magic_number = 0xAC1EF1AE;
|
||||
@ -264,7 +262,6 @@ StateManager::ActivePlayer::ActivePlayer(PlayerProfile* player,
|
||||
m_player = player;
|
||||
m_device = NULL;
|
||||
m_kart = NULL;
|
||||
m_online_user = user;
|
||||
setDevice(device);
|
||||
} // ActivePlayer
|
||||
|
||||
|
@ -76,7 +76,6 @@ public:
|
||||
{
|
||||
friend class StateManager;
|
||||
|
||||
Online::OnlineProfile *m_online_user;
|
||||
PlayerProfile *m_player;
|
||||
InputDevice *m_device;
|
||||
|
||||
@ -86,8 +85,7 @@ public:
|
||||
/** ID of this player within the list of active players */
|
||||
int m_id;
|
||||
|
||||
ActivePlayer(PlayerProfile* player, InputDevice* device,
|
||||
Online::OnlineProfile* user);
|
||||
ActivePlayer(PlayerProfile* player, InputDevice* device);
|
||||
|
||||
#ifdef DEBUG
|
||||
unsigned int m_magic_number;
|
||||
@ -128,19 +126,6 @@ public:
|
||||
* selecting his identity) */
|
||||
void setPlayerProfile(PlayerProfile* player);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
Online::OnlineProfile* getOnlineUser()
|
||||
{
|
||||
return m_online_user;
|
||||
} // getOnlineUser
|
||||
// --------------------------------------------------------------------
|
||||
/** Call to change the identity of this player (useful when player is
|
||||
* selecting his identity) */
|
||||
void setOnlineUser(Online::OnlineProfile* user)
|
||||
{
|
||||
m_online_user = user;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** ID of this player within the list of active players */
|
||||
int getID() const
|
||||
@ -197,8 +182,7 @@ public:
|
||||
*/
|
||||
const PlayerProfile* getActivePlayerProfile(const int id);
|
||||
|
||||
int createActivePlayer(PlayerProfile *profile, InputDevice *device,
|
||||
Online::OnlineProfile* use);
|
||||
int createActivePlayer(PlayerProfile *profile, InputDevice *device);
|
||||
void removeActivePlayer(int id);
|
||||
|
||||
unsigned int activePlayerCount();
|
||||
|
@ -46,20 +46,8 @@ DEFINE_SCREEN_SINGLETON( TracksScreen );
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TracksScreen::TracksScreen() : Screen("tracks.stkgui")
|
||||
{
|
||||
} // TracksScreen
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TracksScreen::loadedFromFile()
|
||||
{
|
||||
} // loadedFromFile
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void TracksScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
const int playerID )
|
||||
const int playerID)
|
||||
{
|
||||
// -- track selection screen
|
||||
if (name == "tracks")
|
||||
@ -87,8 +75,8 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
std::string track = m_random_track_list.front();
|
||||
m_random_track_list.pop_front();
|
||||
m_random_track_list.push_back(track);
|
||||
Track* clicked_track = track_manager->getTrack(track);
|
||||
|
||||
Track* clicked_track = track_manager->getTrack(track);
|
||||
|
||||
if (clicked_track)
|
||||
{
|
||||
@ -129,29 +117,17 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
else if (name == "gps")
|
||||
{
|
||||
DynamicRibbonWidget* gps_widget = dynamic_cast<DynamicRibbonWidget*>(widget);
|
||||
if (gps_widget)
|
||||
{
|
||||
const std::string &selection =
|
||||
const std::string &selection =
|
||||
gps_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
if (selection == "locked")
|
||||
{
|
||||
unlock_manager->playLockSound();
|
||||
}
|
||||
else
|
||||
{
|
||||
new GPInfoDialog( selection, 0.8f, 0.7f );
|
||||
}
|
||||
}
|
||||
if (selection == "locked")
|
||||
unlock_manager->playLockSound();
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
} // name=="gps"
|
||||
new GPInfoDialog(selection, 0.8f, 0.7f);
|
||||
}
|
||||
else if (name == "trackgroups")
|
||||
{
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs );
|
||||
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
|
||||
UserConfigParams::m_last_used_track_group = tabs->getSelectionIDString(0);
|
||||
buildTrackList();
|
||||
}
|
||||
@ -166,10 +142,7 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
void TracksScreen::beforeAddingWidget()
|
||||
{
|
||||
Screen::init();
|
||||
// Dynamically add tabs
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs );
|
||||
|
||||
tabs->clearAllChildren();
|
||||
|
||||
const std::vector<std::string>& groups = track_manager->getAllTrackGroups();
|
||||
@ -188,15 +161,11 @@ void TracksScreen::beforeAddingWidget()
|
||||
//I18N: track group name
|
||||
FOR_GETTEXT_ONLY( _("Add-Ons") )
|
||||
|
||||
// add others after
|
||||
// add behind the other categories
|
||||
for (int n=0; n<group_amount; n++)
|
||||
{
|
||||
// try to translate the group name
|
||||
tabs->addTextChild( _(groups[n].c_str()), groups[n] );
|
||||
}
|
||||
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget );
|
||||
tracks_widget->setItemCountHint( track_manager->getNumberOfTracks()+1 );
|
||||
} // beforeAddingWidget
|
||||
|
||||
@ -204,69 +173,60 @@ void TracksScreen::beforeAddingWidget()
|
||||
|
||||
void TracksScreen::init()
|
||||
{
|
||||
DynamicRibbonWidget* gps_widget = getWidget<DynamicRibbonWidget>("gps");
|
||||
assert( gps_widget );
|
||||
|
||||
DynamicRibbonWidget* gps_widget = getWidget<DynamicRibbonWidget>("gps");
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget );
|
||||
assert(tracks_widget != NULL);
|
||||
|
||||
// Reset GP list everytime (accounts for locking changes, etc.)
|
||||
gps_widget->clearItems();
|
||||
|
||||
// Ensure that no GP and no track is NULL
|
||||
grand_prix_manager->checkConsistency();
|
||||
|
||||
// Build GP list
|
||||
const int gpAmount = grand_prix_manager->getNumberOfGrandPrix();
|
||||
for (int n=0; n<gpAmount; n++)
|
||||
{
|
||||
const GrandPrixData* gp = grand_prix_manager->getGrandPrix(n);
|
||||
|
||||
const std::vector<std::string> tracks = gp->getTrackNames(true);
|
||||
|
||||
std::vector<std::string> sshot_files;
|
||||
std::vector<std::string> screenshots;
|
||||
for (unsigned int t=0; t<tracks.size(); t++)
|
||||
{
|
||||
Track* curr = track_manager->getTrack(tracks[t]);
|
||||
if (!curr )
|
||||
{
|
||||
Log::warn("TracksScreen", "Grand Prix '%s' refers to track '%s',"
|
||||
"which does not exist.",
|
||||
gp->getId().c_str(), tracks[t].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
sshot_files.push_back(curr->getScreenshotFile());
|
||||
}
|
||||
}
|
||||
if (sshot_files.size() == 0)
|
||||
{
|
||||
Log::warn("TracksScreen",
|
||||
"Grand Prix '%s' does not contain any valid track.",
|
||||
gp->getId().c_str());
|
||||
sshot_files.push_back("gui/main_help.png");
|
||||
const Track* curr = track_manager->getTrack(tracks[t]);
|
||||
screenshots.push_back(curr->getScreenshotFile());
|
||||
}
|
||||
assert(screenshots.size() > 0);
|
||||
|
||||
if (PlayerManager::getCurrentPlayer()->isLocked(gp->getId()))
|
||||
{
|
||||
gps_widget->addAnimatedItem(_("Locked!"),
|
||||
"locked", sshot_files, 1.5f,
|
||||
gps_widget->addAnimatedItem(_("Locked!"), "locked",
|
||||
screenshots, 1.5f,
|
||||
LOCKED_BADGE | TROPHY_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gps_widget->addAnimatedItem(translations->fribidize(gp->getName()),
|
||||
gp->getId(),
|
||||
sshot_files, 1.5f, TROPHY_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
|
||||
gp->getId(), screenshots, 1.5f,
|
||||
TROPHY_BADGE,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
}
|
||||
}
|
||||
|
||||
/*// Random GP - not finished yet
|
||||
std::vector<std::string> screenshots;
|
||||
screenshots.push_back("gui/main_help.png");
|
||||
gps_widget->addAnimatedItem(translations->fribidize("Random"), "Random",
|
||||
screenshots, 1.5f, 0,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);*/
|
||||
|
||||
gps_widget->updateItemDisplay();
|
||||
|
||||
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs );
|
||||
tabs->select(UserConfigParams::m_last_used_track_group, PLAYER_ID_GAME_MASTER);
|
||||
|
||||
|
||||
buildTrackList();
|
||||
|
||||
// select old track for the game master (if found)
|
||||
@ -287,11 +247,8 @@ void TracksScreen::init()
|
||||
*/
|
||||
void TracksScreen::buildTrackList()
|
||||
{
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget);
|
||||
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("trackgroups");
|
||||
assert( tabs );
|
||||
DynamicRibbonWidget* tracks_widget = this->getWidget<DynamicRibbonWidget>("tracks");
|
||||
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
|
||||
|
||||
// Reset track list everytime (accounts for locking changes, etc.)
|
||||
tracks_widget->clearItems();
|
||||
@ -338,8 +295,8 @@ void TracksScreen::buildTrackList()
|
||||
}
|
||||
}
|
||||
|
||||
tracks_widget->addItem(_("Random Track"), "random_track",
|
||||
"/gui/track_random.png", 0 /* no badge */,
|
||||
tracks_widget->addItem(_("Random Track"), "random_track",
|
||||
"/gui/track_random.png", 0 /* no badge */,
|
||||
IconButtonWidget::ICON_PATH_TYPE_RELATIVE);
|
||||
|
||||
tracks_widget->updateItemDisplay();
|
||||
@ -350,8 +307,7 @@ void TracksScreen::buildTrackList()
|
||||
|
||||
void TracksScreen::setFocusOnTrack(const std::string& trackName)
|
||||
{
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert( tracks_widget);
|
||||
DynamicRibbonWidget* tracks_widget = this->getWidget<DynamicRibbonWidget>("tracks");
|
||||
|
||||
// only the game master can select tracks,
|
||||
// so it's safe to use 'PLAYER_ID_GAME_MASTER'
|
||||
@ -363,7 +319,6 @@ void TracksScreen::setFocusOnTrack(const std::string& trackName)
|
||||
void TracksScreen::setFocusOnGP(const std::string& gpName)
|
||||
{
|
||||
DynamicRibbonWidget* gps_widget = getWidget<DynamicRibbonWidget>("gps");
|
||||
assert( gps_widget );
|
||||
|
||||
// only the game master can select tracks/GPs,
|
||||
// so it's safe to use 'PLAYER_ID_GAME_MASTER'
|
||||
|
@ -27,11 +27,12 @@ namespace GUIEngine { class Widget; }
|
||||
* \brief screen where the user can select a track
|
||||
* \ingroup states_screens
|
||||
*/
|
||||
class TracksScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<TracksScreen>
|
||||
class TracksScreen : public GUIEngine::Screen,
|
||||
public GUIEngine::ScreenSingleton<TracksScreen>
|
||||
{
|
||||
friend class GUIEngine::ScreenSingleton<TracksScreen>;
|
||||
|
||||
TracksScreen();
|
||||
TracksScreen() : Screen("tracks.stkgui") {}
|
||||
|
||||
/** adds the tracks from the current track group into the tracks ribbon */
|
||||
void buildTrackList();
|
||||
@ -41,10 +42,11 @@ class TracksScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingleton
|
||||
public:
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void loadedFromFile() OVERRIDE;
|
||||
virtual void loadedFromFile() OVERRIDE {};
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name,
|
||||
virtual void eventCallback(GUIEngine::Widget* widget,
|
||||
const std::string& name,
|
||||
const int playerID) OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
|
@ -74,7 +74,7 @@ void BaseUserScreen::init()
|
||||
assert(m_info_widget);
|
||||
|
||||
getWidget<CheckBoxWidget>("remember-user")
|
||||
->setState(UserConfigParams::m_always_show_login_screen);
|
||||
->setState(UserConfigParams::m_remember_user);
|
||||
m_sign_out_name = "";
|
||||
m_sign_in_name = "";
|
||||
|
||||
@ -111,6 +111,10 @@ void BaseUserScreen::init()
|
||||
PlayerProfile *player = PlayerManager::getCurrentPlayer();
|
||||
const stringw &online_name = player->getLastOnlineName();
|
||||
m_username_tb->setText(online_name);
|
||||
if(online_name.size()>0)
|
||||
m_username_tb->setDeactivated();
|
||||
else
|
||||
m_username_tb->setActivated();
|
||||
// Select 'online
|
||||
m_online_cb->setState(player->wasOnlineLastTime() ||
|
||||
player->isLoggedIn() );
|
||||
@ -284,6 +288,10 @@ void BaseUserScreen::eventCallback(Widget* widget,
|
||||
deletePlayer();
|
||||
}
|
||||
} // options
|
||||
else if (name == "back")
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@ -440,6 +448,7 @@ void BaseUserScreen::loginError(const irr::core::stringw & error_message)
|
||||
// which allows the player to enter a new password.
|
||||
if(player && player->hasSavedSession())
|
||||
player->clearSession();
|
||||
player->setLastOnlineName("");
|
||||
makeEntryFieldsVisible();
|
||||
sfx_manager->quickSound("anvil");
|
||||
m_info_widget->setErrorColor();
|
||||
|
@ -209,11 +209,8 @@ core::stringw Track::getSortName() const
|
||||
*/
|
||||
bool Track::isInGroup(const std::string &group_name)
|
||||
{
|
||||
for(unsigned int i=0; i<m_groups.size(); i++)
|
||||
{
|
||||
if(m_groups[i]==group_name) return true;
|
||||
}
|
||||
return false;
|
||||
return std::find(m_groups.begin(), m_groups.end(), group_name)
|
||||
!= m_groups.end();
|
||||
} // isInGroup
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -433,9 +433,7 @@ public:
|
||||
void itemCommand(const XMLNode *node);
|
||||
core::stringw getName() const;
|
||||
core::stringw getSortName() const;
|
||||
// ------------------------------------------------------------------------
|
||||
bool isInGroup(const std::string &group_name);
|
||||
// ------------------------------------------------------------------------
|
||||
const core::vector3df& getSunRotation();
|
||||
/** Sets the current ambient color for a kart with index k. */
|
||||
void setAmbientColor(const video::SColor &color,
|
||||
|
79
src/utils/can_be_deleted.hpp
Executable file
79
src/utils/can_be_deleted.hpp
Executable file
@ -0,0 +1,79 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010-2013 Joerg Henrichs
|
||||
//
|
||||
// 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_CAN_BE_DELETED
|
||||
#define HEADER_CAN_BE_DELETED
|
||||
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
/** A simple class that a adds a function to wait with a timeout for a
|
||||
* class to be ready to be deleted. It is used for objects with their
|
||||
* own threads (e.g. RequestManager) to make sure they can be deleted.
|
||||
* For example, the RequestManager might be executing a download request.
|
||||
* So we have to signal libcurl to abort the download request, then
|
||||
* potentially handle a high priority sign-out request before the thread
|
||||
* can be deleted. With this object the main thread can wait for a given
|
||||
* amount of time (in case that of a bad internet hickup) before deleting
|
||||
* the RequestManager.
|
||||
*/
|
||||
class CanBeDeleted
|
||||
{
|
||||
private:
|
||||
Synchronised<bool> m_can_be_deleted;
|
||||
public:
|
||||
/** Set this instance to be not ready to be deleted. */
|
||||
CanBeDeleted() { m_can_be_deleted.setAtomic(false); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets this instance to be ready to be deleted. */
|
||||
void setCanBeDeleted() {m_can_be_deleted.setAtomic(true); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Waits at most t seconds for this class to be ready to be deleted.
|
||||
* \return true if the class is ready, false in case of a time out.
|
||||
*/
|
||||
bool waitForReadyToDeleted(float waiting_time)
|
||||
{
|
||||
if (m_can_be_deleted.getAtomic()) return true;
|
||||
double start = StkTime::getRealTime();
|
||||
Log::verbose("Thread", "Start waiting %lf", start);
|
||||
while(1)
|
||||
{
|
||||
if(m_can_be_deleted.getAtomic())
|
||||
{
|
||||
Log::verbose("Thread",
|
||||
"Waited %lf seconds for thread to become deleteable.",
|
||||
StkTime::getRealTime()-start);
|
||||
Log::verbose("Thread", "Stop waiting %lf", StkTime::getRealTime());
|
||||
return true;
|
||||
}
|
||||
StkTime::sleep(10);
|
||||
if(StkTime::getRealTime() - start > waiting_time)
|
||||
{
|
||||
Log::verbose("Thread", "Stop waiting %lf", StkTime::getRealTime());
|
||||
Log::verbose("Thread", "Waited for more than %f seconds for "
|
||||
"thread to become deleteable",
|
||||
waiting_time);
|
||||
return false;
|
||||
}
|
||||
} // while 1
|
||||
} // waitForReadyToDeleted
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
}; // CanBeDeleted
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user