Revert "Revert "Merge sources.cmake change""

This reverts commit 0290564310ee3014561abd8ffb2f99f04a23e113.
This commit is contained in:
Sachith Hasaranga Seneviratne 2014-06-05 12:38:38 +05:30
parent 0290564310
commit 795a6022e5
99 changed files with 12418 additions and 12295 deletions

View File

@ -9,7 +9,7 @@
<spacer height="15" width="10"/> <spacer height="15" width="10"/>
<scrollable_ribbon id="players" height="120" y="10" x="10" width="98%" align="center" label_location="each" <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"/> <spacer height="15" width="10"/>
<div width="80%" align="center" layout="vertical-row" height="fit"> <div width="80%" align="center" layout="vertical-row" height="fit">

View File

@ -18,7 +18,7 @@
<spacer height="15" width="10"/> <spacer height="15" width="10"/>
<scrollable_ribbon id="players" height="120" y="10" x="10" width="98%" align="center" label_location="each" <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"/> <spacer height="15" width="10"/>
<div width="80%" align="center" layout="vertical-row" height="fit"> <div width="80%" align="center" layout="vertical-row" height="fit">

View File

@ -1,22 +1,16 @@
uniform sampler2D tex; uniform sampler2D tex;
uniform float low; uniform float low;
#if __VERSION__ >= 130
in vec2 uv;
out vec4 FragColor; out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
vec3 getCIEYxy(vec3 rgbColor); vec3 getCIEYxy(vec3 rgbColor);
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy / 512;
vec3 col = texture(tex, uv).xyz; vec3 col = texture(tex, uv).xyz;
float luma = getCIEYxy(col).x; float luma = getCIEYxy(col).x;
col *= smoothstep(1., 10., luma); col *= smoothstep(1., 10., luma);
FragColor = vec4(col, 1.0); FragColor = vec4(col, 1.0);
} }

View File

@ -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; out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
void main() void main()
{ {
vec4 col = texture(tex, uv); vec2 uv = gl_FragCoord.xy / screen;
vec4 col = .125 * texture(tex_128, uv);
col.xyz *= 10.0 * col.a; col += .25 * texture(tex_256, uv);
col += .5 * texture(tex_512, uv);
FragColor = vec4(col.xyz, 1.); FragColor = vec4(col.xyz, 1.);
} }

View File

@ -3,16 +3,17 @@ uniform float greenLmn[9];
uniform float redLmn[9]; uniform float redLmn[9];
uniform sampler2D ntex; uniform sampler2D ntex;
uniform mat4 TransposeViewMatrix; 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 Diff;
out vec4 Spec;
#else
varying vec2 uv;
#define Diff gl_FragData[0]
#define Spec gl_FragData[1]
#endif
vec3 DecodeNormal(vec2 n); vec3 DecodeNormal(vec2 n);
@ -30,6 +31,7 @@ mat4 getMatrix(float L[9])
void main(void) void main(void)
{ {
vec2 uv = gl_FragCoord.xy / screen;
vec3 normal = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); vec3 normal = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
// Convert normal in world space (where SH coordinates were computed) // Convert normal in world space (where SH coordinates were computed)
vec4 extendednormal = TransposeViewMatrix * vec4(normal, 1.); vec4 extendednormal = TransposeViewMatrix * vec4(normal, 1.);
@ -43,5 +45,4 @@ void main(void)
float b = dot(extendednormal, bmat * extendednormal); float b = dot(extendednormal, bmat * extendednormal);
Diff = max(0.25 * vec4(r, g, b, .1), vec4(0.)); Diff = max(0.25 * vec4(r, g, b, .1), vec4(0.));
Spec = vec4(0.);
} }

View File

@ -11,7 +11,6 @@ layout (std140) uniform MatrixesData
vec2 screen; vec2 screen;
}; };
in vec2 uv;
out vec4 FragColor; out vec4 FragColor;
float focalDepth = 10.; float focalDepth = 10.;
@ -20,6 +19,7 @@ float range = 100.;
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy / screen;
float curdepth = texture(dtex, uv).x; float curdepth = texture(dtex, uv).x;
vec4 FragPos = InverseProjectionMatrix * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f); vec4 FragPos = InverseProjectionMatrix * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f);
FragPos /= FragPos.w; FragPos /= FragPos.w;
@ -82,5 +82,5 @@ void main()
depth = (1 - depth); depth = (1 - depth);
vec3 final = colOriginal.rgb * depth + col.rgb * (1 - depth); vec3 final = colOriginal.rgb * depth + col.rgb * (1 - depth);
FragColor = vec4(final, 1.); FragColor = vec4(final, colOriginal.a);
} }

View File

@ -24,7 +24,6 @@ layout (std140) uniform MatrixesData
}; };
#endif #endif
in vec2 uv;
out vec4 FragColor; out vec4 FragColor;
@ -32,6 +31,7 @@ vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy / screen;
float z = texture(tex, uv).x; float z = texture(tex, uv).x;
vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix); vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);

View File

@ -0,0 +1,36 @@
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
uniform layout(size1x16) restrict readonly image2D source;
uniform layout(size1x16) volatile restrict writeonly image2D dest;
uniform float sigma = 5.;
layout (local_size_x = 8, local_size_y = 8) in;
shared float local_src[8 + 2 * 8][8];
void main()
{
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
ivec2 uv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
local_src[x][y] = imageLoad(source, ivec2(uv) - ivec2(8, 0)).x;
local_src[x + 8][y] = imageLoad(source, ivec2(uv)).x;
local_src[x + 16][y] = imageLoad(source, ivec2(uv) + ivec2(8, 0)).x;
barrier();
float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma));
g2 = g1 * g1;
float sum = local_src[x + 8][y] * g0;
g0 *= g1;
g1 *= g2;
for (int j = 1; j < 8; j++) {
sum += local_src[8 + x - j][y] * g0;
sum += local_src[8 + x + j][y] * g0;
g0 *= g1;
g1 *= g2;
}
imageStore(dest, ivec2(uv), vec4(sum));
}

View File

@ -4,15 +4,14 @@ uniform sampler2D tex;
uniform vec2 pixel; uniform vec2 pixel;
uniform float sigma = 5.; uniform float sigma = 5.;
in vec2 uv;
out vec4 FragColor; out vec4 FragColor;
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy * pixel;
float X = uv.x; float X = uv.x;
float Y = uv.y; float Y = uv.y;
float g0, g1, g2; float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma); g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma)); g1 = exp(-0.5 / (sigma * sigma));

View File

@ -4,15 +4,14 @@ uniform sampler2D tex;
uniform vec2 pixel; uniform vec2 pixel;
uniform float sigma = 5.; uniform float sigma = 5.;
in vec2 uv;
out vec4 FragColor; out vec4 FragColor;
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy * pixel;
float X = uv.x; float X = uv.x;
float Y = uv.y; float Y = uv.y;
float g0, g1, g2; float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma); g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma)); g1 = exp(-0.5 / (sigma * sigma));

View File

@ -3,16 +3,11 @@ uniform vec2 pixel;
// Gaussian separated blur with radius 3. // Gaussian separated blur with radius 3.
#if __VERSION__ >= 130
in vec2 uv;
out vec4 FragColor; out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy * pixel;
vec4 sum = vec4(0.0); vec4 sum = vec4(0.0);
float X = uv.x; float X = uv.x;
float Y = uv.y; float Y = uv.y;

View File

@ -3,16 +3,11 @@ uniform vec2 pixel;
// Gaussian separated blur with radius 3. // Gaussian separated blur with radius 3.
#if __VERSION__ >= 130
in vec2 uv;
out vec4 FragColor; out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy * pixel;
vec4 sum = vec4(0.0); vec4 sum = vec4(0.0);
float X = uv.x; float X = uv.x;
float Y = uv.y; float Y = uv.y;

View File

@ -3,16 +3,11 @@ uniform vec2 pixel;
// Gaussian separated blur with radius 6. // Gaussian separated blur with radius 6.
#if __VERSION__ >= 130
in vec2 uv;
out vec4 FragColor; out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy * pixel;
vec4 sum = vec4(0.0); vec4 sum = vec4(0.0);
float X = uv.x; float X = uv.x;
float Y = uv.y; float Y = uv.y;

View File

@ -3,16 +3,11 @@ uniform vec2 pixel;
// Gaussian separated blur with radius 6. // Gaussian separated blur with radius 6.
#if __VERSION__ >= 130
in vec2 uv;
out vec4 FragColor; out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy * pixel;
vec4 sum = vec4(0.0); vec4 sum = vec4(0.0);
float X = uv.x; float X = uv.x;
float Y = uv.y; float Y = uv.y;

View File

@ -0,0 +1,36 @@
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
uniform layout(size1x16) restrict readonly image2D source;
uniform layout(size1x16) volatile restrict writeonly image2D dest;
uniform float sigma = 5.;
layout (local_size_x = 8, local_size_y = 8) in;
shared float local_src[8][8 + 2 * 8];
void main()
{
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
ivec2 uv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
local_src[x][y] = imageLoad(source, ivec2(uv) - ivec2(0, 8)).x;
local_src[x][y + 8] = imageLoad(source, ivec2(uv)).x;
local_src[x][y + 16] = imageLoad(source, ivec2(uv) + ivec2(0, 8)).x;
barrier();
float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma));
g2 = g1 * g1;
float sum = local_src[x][y + 8] * g0;
g0 *= g1;
g1 *= g2;
for (int j = 1; j < 8; j++) {
sum += local_src[x][y + 8 + j] * g0;
sum += local_src[x][y + 8 - j] * g0;
g0 *= g1;
g1 *= g2;
}
imageStore(dest, ivec2(uv), vec4(sum));
}

View File

@ -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)); return vec3 (dot(Y,sh_r), dot(Y,sh_g), dot(Y,sh_b));
} }
in vec2 uv; out vec4 Diffuse;
layout (location = 0) out vec4 Diffuse;
layout (location = 1) out vec4 Specular;
vec3 DecodeNormal(vec2 n); vec3 DecodeNormal(vec2 n);
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
@ -49,6 +47,7 @@ vec3 resolution = vec3(32, 16, 32);
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy / screen;
vec3 GI = vec3(0.); vec3 GI = vec3(0.);
float depth = texture2D(dtex, uv).x; float depth = texture2D(dtex, uv).x;
@ -97,5 +96,4 @@ void main()
GI /= 4; GI /= 4;
Diffuse = max(16. * vec4(GI, 1.), vec4(0.)); Diffuse = max(16. * vec4(GI, 1.), vec4(0.));
Specular = vec4(0.);
} }

View File

@ -2,11 +2,21 @@ uniform sampler2D tex;
uniform float zn; uniform float zn;
uniform float zf; 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; out float Depth;
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy / screen;
float d = texture(tex, uv).x; float d = texture(tex, uv).x;
float c0 = zn * zf, c1 = zn - zf, c2 = zf; float c0 = zn * zf, c1 = zn - zf, c2 = zf;
Depth = c0 / (d * c1 + c2); Depth = c0 / (d * c1 + c2);

View File

@ -1,7 +1,15 @@
uniform sampler2D edgesMap; uniform sampler2D edgesMap;
uniform sampler2D areaMap; uniform sampler2D areaMap;
uniform vec2 PIXEL_SIZE; layout (std140) uniform MatrixesData
{
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
vec2 screen;
};
#define MAX_SEARCH_STEPS 8.0 #define MAX_SEARCH_STEPS 8.0
#define MAX_DISTANCE 33.0 #define MAX_DISTANCE 33.0
@ -16,7 +24,7 @@ out vec4 FragColor;
* bit. * bit.
*/ */
vec4 tex2Doffset(sampler2D map, vec2 texcoord, vec2 offset) { vec4 tex2Doffset(sampler2D map, vec2 texcoord, vec2 offset) {
return textureLod(map, texcoord + PIXEL_SIZE * offset, 0.0); return textureLod(map, texcoord + offset / screen, 0.0);
} }
float SearchXLeft(vec2 texcoord) { float SearchXLeft(vec2 texcoord) {
@ -87,7 +95,7 @@ void main() {
// Now fetch the crossing edges. Instead of sampling between edgels, we // Now fetch the crossing edges. Instead of sampling between edgels, we
// sample at 0.25, to be able to discern what value has each edgel: // sample at 0.25, to be able to discern what value has each edgel:
vec4 coords = vec4(d.x, 0.25, d.y + 1.0, 0.25) * PIXEL_SIZE.xyxy + uv.xyxy; vec4 coords = vec4(d.x, 0.25, d.y + 1.0, 0.25) / screen.xyxy + uv.xyxy;
float e1 = textureLod(edgesMap, coords.xy, 0.0).r; float e1 = textureLod(edgesMap, coords.xy, 0.0).r;
float e2 = textureLod(edgesMap, coords.zw, 0.0).r; float e2 = textureLod(edgesMap, coords.zw, 0.0).r;
@ -102,7 +110,7 @@ void main() {
vec2 d = vec2(SearchYUp(uv), SearchYDown(uv)); vec2 d = vec2(SearchYUp(uv), SearchYDown(uv));
// Now fetch the crossing edges (yet again): // Now fetch the crossing edges (yet again):
vec4 coords = vec4(-0.25, d.x, -0.25, d.y - 1.0) * PIXEL_SIZE.xyxy + uv.xyxy; vec4 coords = vec4(-0.25, d.x, -0.25, d.y - 1.0) / screen.xyxy + uv.xyxy;
float e1 = textureLod(edgesMap, coords.xy, 0.0).g; float e1 = textureLod(edgesMap, coords.xy, 0.0).g;
float e2 = textureLod(edgesMap, coords.zw, 0.0).g; float e2 = textureLod(edgesMap, coords.zw, 0.0).g;

View File

@ -1,4 +1,12 @@
uniform vec2 PIXEL_SIZE; layout (std140) uniform MatrixesData
{
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
vec2 screen;
};
in vec2 Position; in vec2 Position;
in vec2 Texcoord; in vec2 Texcoord;
@ -12,6 +20,6 @@ void main() {
// invy.y = 1.0 - invy.y; // invy.y = 1.0 - invy.y;
uv = invy.st; uv = invy.st;
offset[0] = invy.xyxy + PIXEL_SIZE.xyxy * vec4(-1.0, 0.0, 0.0, 1.0); offset[0] = invy.xyxy + vec4(-1.0, 0.0, 0.0, 1.0) / screen.xyxy;
offset[1] = invy.xyxy + PIXEL_SIZE.xyxy * vec4( 1.0, 0.0, 0.0, -1.0); offset[1] = invy.xyxy + vec4( 1.0, 0.0, 0.0, -1.0) / screen.xyxy;
} }

View File

@ -40,20 +40,24 @@ uniform float mask_radius;
// Maximum height of texture used // Maximum height of texture used
uniform float max_tex_height; uniform float max_tex_height;
#if __VERSION__ >= 130 layout (std140) uniform MatrixesData
in vec2 uv; {
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
vec2 screen;
};
out vec4 FragColor; out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
// Number of samples used for blurring // Number of samples used for blurring
#define NB_SAMPLES 8 #define NB_SAMPLES 8
void main() void main()
{ {
vec2 texcoords = uv; vec2 texcoords = gl_FragCoord.xy / screen;
// Sample the color buffer // Sample the color buffer
vec3 color = texture(color_buffer, texcoords).rgb; vec3 color = texture(color_buffer, texcoords).rgb;

View File

@ -34,7 +34,6 @@ vec4 DirToSh(vec3 dir, float flux)
void main(void) void main(void)
{ {
vec3 normalizedRHCenter = 2. * vec3(gl_FragCoord.xy, slice) / resolution - 1.; vec3 normalizedRHCenter = 2. * vec3(gl_FragCoord.xy, slice) / resolution - 1.;
vec3 RHcenter = (RHMatrix * vec4(normalizedRHCenter * extents, 1.)).xyz; vec3 RHcenter = (RHMatrix * vec4(normalizedRHCenter * extents, 1.)).xyz;

View File

@ -22,7 +22,6 @@ layout (std140) uniform MatrixesData
}; };
#endif #endif
in vec2 uv;
out float AO; out float AO;
const float sigma = 1.; const float sigma = 1.;
@ -46,6 +45,7 @@ vec3 getXcYcZc(int x, int y, float zC)
void main(void) void main(void)
{ {
vec2 uv = gl_FragCoord.xy / screen;
float lineardepth = textureLod(dtex, uv, 0.).x; float lineardepth = textureLod(dtex, uv, 0.).x;
int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y); int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y);
vec3 FragPos = getXcYcZc(x, y, lineardepth); vec3 FragPos = getXcYcZc(x, y, lineardepth);

View File

@ -21,25 +21,19 @@ layout (std140) uniform MatrixesData
mat4 InverseViewMatrix; mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix; mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4]; mat4 ShadowViewProjMatrixes[4];
vec2 screen;
}; };
#endif #endif
#if __VERSION__ >= 130
in vec2 uv;
out vec4 Diff; out vec4 Diff;
out vec4 Spec; out vec4 Spec;
#else
varying vec2 uv;
#define Diff gl_FragData[0]
#define Spec gl_FragData[1]
#endif
vec3 DecodeNormal(vec2 n); vec3 DecodeNormal(vec2 n);
vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness); vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
void main() { void main() {
vec2 uv = gl_FragCoord.xy / screen;
float z = texture(dtex, uv).x; float z = texture(dtex, uv).x;
vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix); vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);

View File

@ -24,6 +24,7 @@ layout (std140) uniform MatrixesData
mat4 InverseViewMatrix; mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix; mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4]; mat4 ShadowViewProjMatrixes[4];
vec2 screen;
}; };
#endif #endif
@ -68,6 +69,7 @@ float getShadowFactor(vec3 pos, float bias, int index)
} }
void main() { void main() {
vec2 uv = gl_FragCoord.xy / screen;
float z = texture(dtex, uv).x; float z = texture(dtex, uv).x;
vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix); vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);

View File

@ -5,7 +5,16 @@ uniform sampler2D logluminancetex;
uniform float exposure = .09; uniform float exposure = .09;
uniform float Lwhite = 1.; 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; out vec4 FragColor;
vec3 getCIEYxy(vec3 rgbColor); vec3 getCIEYxy(vec3 rgbColor);
@ -17,6 +26,7 @@ float saturation = 1.;
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy / screen;
vec4 col = texture(tex, uv); vec4 col = texture(tex, uv);
float avgLw = textureLod(logluminancetex, uv, 10.).x; float avgLw = textureLod(logluminancetex, uv, 10.).x;
avgLw = max(exp(avgLw) - delta, delta); avgLw = max(exp(avgLw) - delta, delta);
@ -33,6 +43,5 @@ void main()
// Uncharted2 tonemap with Auria's custom coefficients // Uncharted2 tonemap with Auria's custom coefficients
vec4 perChannel = (col * (6.9 * col + .5)) / (col * (5.2 * col + 1.7) + 0.06); vec4 perChannel = (col * (6.9 * col + .5)) / (col * (5.2 * col + 1.7) + 0.06);
perChannel = pow(perChannel, vec4(2.2)); perChannel = pow(perChannel, vec4(2.2));
FragColor = vec4(perChannel.xyz, 1.); FragColor = vec4(perChannel.xyz, col.a);
} }

View File

@ -237,8 +237,10 @@ when the border that intersect at this corner are enabled.
<!-- Text field color --> <!-- Text field color -->
<color type="text_field" state="background" a="255" r="200" g="200" b="200" /> <color type="text_field" state="background" a="255" r="200" g="200" b="200" />
<color type="text_field" state="background_focused" a="255" r="223" g="238" b="248" /> <color type="text_field" state="background_focused" a="255" r="223" g="238" b="248" />
<color type="text_field" state="background_deactivated" a="255" r="200" g="200" b="200" />
<color type="text_field" state="neutral" a="255" r="138" g="138" b="138" /> <color type="text_field" state="neutral" a="255" r="138" g="138" b="138" />
<color type="text_field" state="focused" a="255" r="42" g="169" b="211" /> <color type="text_field" state="focused" a="255" r="42" g="169" b="211" />
<color type="text_field" state="deactivated" a="255" r="138" g="138" b="138" />
<!-- Rating star image --> <!-- Rating star image -->
<element type="rating" state="neutral" image="ocean/rating_star.png" /> <element type="rating" state="neutral" image="ocean/rating_star.png" />

View File

@ -235,8 +235,10 @@ when the border that intersect at this corner are enabled.
<!-- Text field color --> <!-- Text field color -->
<color type="text_field" state="background" a="255" r="200" g="200" b="200" /> <color type="text_field" state="background" a="255" r="200" g="200" b="200" />
<color type="text_field" state="background_focused" a="255" r="236" g="226" b="201" /> <color type="text_field" state="background_focused" a="255" r="236" g="226" b="201" />
<color type="text_field" state="background_deactivated" a="255" r="200" g="200" b="200" />
<color type="text_field" state="neutral" a="255" r="138" g="138" b="138" /> <color type="text_field" state="neutral" a="255" r="138" g="138" b="138" />
<color type="text_field" state="focused" a="255" r="243" g="164" b="80" /> <color type="text_field" state="focused" a="255" r="243" g="164" b="80" />
<color type="text_field" state="deactivated" a="255" r="138" g="138" b="138" />
<!-- Rating star image --> <!-- Rating star image -->
<element type="rating" state="neutral" image="peach/rating_star.png" /> <element type="rating" state="neutral" image="peach/rating_star.png" />

File diff suppressed because it is too large Load Diff

View File

@ -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_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp") 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/*")

View File

@ -49,9 +49,10 @@ NewsManager::~NewsManager()
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** This function initialises the data for the news manager. It starts a /** This function initialises the data for the news manager. It starts a
* separate thread to execute downloadNews() - which (if necessary) the * separate thread to execute downloadNews() - which (if necessary) downaloads
* news.xml file and updating the list of news messages. It also initialises * the news.xml file and updates the list of news messages. It also
* the addons manager (which can trigger another download of news.xml). * initialises the addons manager (which can trigger another download of
* news.xml).
* \param force_refresh Re-download news.xml, even if * \param force_refresh Re-download news.xml, even if
*/ */
void NewsManager::init(bool force_refresh) void NewsManager::init(bool force_refresh)
@ -194,6 +195,10 @@ void* NewsManager::downloadNews(void *obj)
delete xml; 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); pthread_exit(NULL);
return 0; // prevent warning return 0; // prevent warning
} // downloadNews } // downloadNews

View File

@ -25,6 +25,7 @@
#include <irrString.h> #include <irrString.h>
using namespace irr; using namespace irr;
#include "utils/can_be_deleted.hpp"
#include "utils/synchronised.hpp" #include "utils/synchronised.hpp"
class XMLNode; class XMLNode;
@ -32,7 +33,7 @@ class XMLNode;
/** /**
* \ingroup addonsgroup * \ingroup addonsgroup
*/ */
class NewsManager class NewsManager : public CanBeDeleted
{ {
private: private:
static NewsManager *m_news_manager; static NewsManager *m_news_manager;

View File

@ -262,6 +262,8 @@ void DisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int)
void DisplaceProvider::update() void DisplaceProvider::update()
{ {
if (World::getWorld() == NULL) return;
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
const float speed = World::getWorld()->getTrack()->getDisplacementSpeed(); const float speed = World::getWorld()->getTrack()->getDisplacementSpeed();

View File

@ -74,6 +74,8 @@ PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
PFNGLTEXSTORAGE1DPROC glTexStorage1D; PFNGLTEXSTORAGE1DPROC glTexStorage1D;
PFNGLTEXSTORAGE2DPROC glTexStorage2D; PFNGLTEXSTORAGE2DPROC glTexStorage2D;
PFNGLTEXSTORAGE3DPROC glTexStorage3D; PFNGLTEXSTORAGE3DPROC glTexStorage3D;
PFNGLBINDIMAGETEXTUREPROC glBindImageTexture;
PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
#endif #endif
static bool is_gl_init = false; static bool is_gl_init = false;
@ -226,6 +228,8 @@ void initGL()
glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage1D"); glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage1D");
glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage2D"); glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage2D");
glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage3D"); glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage3D");
glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glBindImageTexture");
glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)IRR_OGL_LOAD_EXTENSION("glDispatchCompute");
#ifdef DEBUG #ifdef DEBUG
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB"); glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB");
#endif #endif
@ -648,14 +652,15 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol
glGetError(); glGetError();
} }
void drawTexQuad(const video::ITexture *texture, float width, float height, static
void drawTexQuad(GLuint texture, float width, float height,
float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y,
float tex_width, float tex_height) float tex_width, float tex_height)
{ {
glUseProgram(UIShader::TextureRectShader::Program); glUseProgram(UIShader::TextureRectShader::Program);
glBindVertexArray(UIShader::TextureRectShader::vao); glBindVertexArray(UIShader::TextureRectShader::vao);
setTexture(0, static_cast<const irr::video::COpenGLTexture*>(texture)->getOpenGLTextureName(), GL_LINEAR, GL_LINEAR); setTexture(0, texture, GL_LINEAR, GL_LINEAR);
UIShader::TextureRectShader::setUniforms(center_pos_x, center_pos_y, width, height, tex_center_pos_x, tex_center_pos_y, tex_width, tex_height, 0); UIShader::TextureRectShader::setUniforms(center_pos_x, center_pos_y, width, height, tex_center_pos_x, tex_center_pos_y, tex_width, tex_height, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -666,7 +671,8 @@ void drawTexQuad(const video::ITexture *texture, float width, float height,
} }
static void static void
getSize(const video::ITexture* texture, const core::rect<s32>& destRect, getSize(unsigned texture_width, unsigned texture_height, bool textureisRTT,
const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>& sourceRect,
float &width, float &height, float &width, float &height,
float &center_pos_x, float &center_pos_y, float &center_pos_x, float &center_pos_y,
@ -689,23 +695,20 @@ getSize(const video::ITexture* texture, const core::rect<s32>& destRect,
height = float(destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y); height = float(destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y);
height /= screen_h; height /= screen_h;
const core::dimension2d<u32>& ss = texture->getOriginalSize();
tex_center_pos_x = float(sourceRect.UpperLeftCorner.X + sourceRect.LowerRightCorner.X); tex_center_pos_x = float(sourceRect.UpperLeftCorner.X + sourceRect.LowerRightCorner.X);
tex_center_pos_x /= ss.Width * 2.f; tex_center_pos_x /= texture_width * 2.f;
tex_center_pos_y = float(sourceRect.UpperLeftCorner.Y + sourceRect.LowerRightCorner.Y); tex_center_pos_y = float(sourceRect.UpperLeftCorner.Y + sourceRect.LowerRightCorner.Y);
tex_center_pos_y /= ss.Height * 2.f; tex_center_pos_y /= texture_height * 2.f;
tex_width = float(sourceRect.LowerRightCorner.X - sourceRect.UpperLeftCorner.X); tex_width = float(sourceRect.LowerRightCorner.X - sourceRect.UpperLeftCorner.X);
tex_width /= ss.Width * 2.f; tex_width /= texture_width * 2.f;
tex_height = float(sourceRect.LowerRightCorner.Y - sourceRect.UpperLeftCorner.Y); tex_height = float(sourceRect.LowerRightCorner.Y - sourceRect.UpperLeftCorner.Y);
tex_height /= ss.Height * 2.f; tex_height /= texture_height * 2.f;
if (texture->isRenderTarget()) if (textureisRTT)
{
tex_height = -tex_height; tex_height = -tex_height;
}
const f32 invW = 1.f / static_cast<f32>(ss.Width); const f32 invW = 1.f / static_cast<f32>(texture_width);
const f32 invH = 1.f / static_cast<f32>(ss.Height); const f32 invH = 1.f / static_cast<f32>(texture_height);
const core::rect<f32> tcoords( const core::rect<f32> tcoords(
sourceRect.UpperLeftCorner.X * invW, sourceRect.UpperLeftCorner.X * invW,
sourceRect.UpperLeftCorner.Y * invH, sourceRect.UpperLeftCorner.Y * invH,
@ -730,7 +733,8 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
tex_width, tex_height, tex_width, tex_height,
tex_center_pos_x, tex_center_pos_y; tex_center_pos_x, tex_center_pos_y;
getSize(texture, destRect, sourceRect, width, height, center_pos_x, center_pos_y, getSize(texture->getOriginalSize().Width, texture->getOriginalSize().Height, texture->isRenderTarget(),
destRect, sourceRect, width, height, center_pos_x, center_pos_y,
tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); tex_width, tex_height, tex_center_pos_x, tex_center_pos_y);
if (useAlphaChannelOfTexture) if (useAlphaChannelOfTexture)
@ -769,6 +773,25 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
glGetError(); glGetError();
} }
void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h,
const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
bool useAlphaChannelOfTexture)
{
glEnable(GL_BLEND);
float width, height,
center_pos_x, center_pos_y,
tex_width, tex_height,
tex_center_pos_x, tex_center_pos_y;
getSize(texture_w, texture_h, true,
destRect, sourceRect, width, height, center_pos_x, center_pos_y,
tex_width, tex_height, tex_center_pos_x, tex_center_pos_y);
drawTexQuad(texture, width, height, center_pos_x, center_pos_y,
tex_center_pos_x, tex_center_pos_y, tex_width, tex_height);
}
void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect, void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
const video::SColor* const colors, bool useAlphaChannelOfTexture) const video::SColor* const colors, bool useAlphaChannelOfTexture)
@ -784,7 +807,8 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
tex_width, tex_height, tex_width, tex_height,
tex_center_pos_x, tex_center_pos_y; tex_center_pos_x, tex_center_pos_y;
getSize(texture, destRect, sourceRect, width, height, center_pos_x, center_pos_y, getSize(texture->getOriginalSize().Width, texture->getOriginalSize().Height, texture->isRenderTarget(),
destRect, sourceRect, width, height, center_pos_x, center_pos_y,
tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); tex_width, tex_height, tex_center_pos_x, tex_center_pos_y);
if (useAlphaChannelOfTexture) if (useAlphaChannelOfTexture)
@ -810,7 +834,7 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
drawTexColoredQuad(texture, colors, width, height, center_pos_x, center_pos_y, drawTexColoredQuad(texture, colors, width, height, center_pos_x, center_pos_y,
tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); tex_center_pos_x, tex_center_pos_y, tex_width, tex_height);
else else
drawTexQuad(texture, width, height, center_pos_x, center_pos_y, drawTexQuad(static_cast<const irr::video::COpenGLTexture*>(texture)->getOpenGLTextureName(), width, height, center_pos_x, center_pos_y,
tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); tex_center_pos_x, tex_center_pos_y, tex_width, tex_height);
if (clipRect) if (clipRect)
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);

View File

@ -97,6 +97,8 @@ extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
extern PFNGLTEXSTORAGE1DPROC glTexStorage1D; extern PFNGLTEXSTORAGE1DPROC glTexStorage1D;
extern PFNGLTEXSTORAGE2DPROC glTexStorage2D; extern PFNGLTEXSTORAGE2DPROC glTexStorage2D;
extern PFNGLTEXSTORAGE3DPROC glTexStorage3D; extern PFNGLTEXSTORAGE3DPROC glTexStorage3D;
extern PFNGLBINDIMAGETEXTUREPROC glBindImageTexture;
extern PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
#ifdef DEBUG #ifdef DEBUG
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB; extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
#endif #endif
@ -219,6 +221,11 @@ void saveCompressedTexture(const std::string& compressed_tex);
void draw3DLine(const core::vector3df& start, void draw3DLine(const core::vector3df& start,
const core::vector3df& end, irr::video::SColor color); const core::vector3df& end, irr::video::SColor color);
void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h,
const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
bool useAlphaChannelOfTexture);
void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect<s32>& destRect, void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect<s32>& destRect,
const irr::core::rect<s32>& sourceRect, const irr::core::rect<s32>* clipRect, const irr::core::rect<s32>& sourceRect, const irr::core::rect<s32>* clipRect,
const irr::video::SColor &color, bool useAlphaChannelOfTexture); const irr::video::SColor &color, bool useAlphaChannelOfTexture);

View File

@ -211,7 +211,10 @@ Window get_toplevel_parent(Display* display, Window window)
#endif #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() void IrrDriver::updateConfigIfRelevant()
{ {
if (!UserConfigParams::m_fullscreen && if (!UserConfigParams::m_fullscreen &&
@ -241,7 +244,6 @@ void IrrDriver::updateConfigIfRelevant()
{ {
UserConfigParams::m_window_x = x; UserConfigParams::m_window_x = x;
UserConfigParams::m_window_y = y; UserConfigParams::m_window_y = y;
user_config->saveConfig();
} }
} }
else else
@ -265,11 +267,10 @@ void IrrDriver::updateConfigIfRelevant()
{ {
UserConfigParams::m_window_x = wx; UserConfigParams::m_window_x = wx;
UserConfigParams::m_window_y = wy; UserConfigParams::m_window_y = wy;
user_config->saveConfig();
} }
#endif #endif
} }
} } // updateConfigIfRelevant
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Gets a list of supported video modes from the irrlicht device. This data /** Gets a list of supported video modes from the irrlicht device. This data
@ -1556,6 +1557,11 @@ video::ITexture* IrrDriver::applyMask(video::ITexture* texture,
return t; return t;
} // applyMask } // applyMask
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void IrrDriver::setRTT(RTT* rtt)
{
m_rtts = rtt;
}
// ----------------------------------------------------------------------------
void IrrDriver::onLoadWorld() void IrrDriver::onLoadWorld()
{ {
if (m_glsl) if (m_glsl)
@ -1570,6 +1576,8 @@ void IrrDriver::onUnloadWorld()
{ {
delete m_rtts; delete m_rtts;
m_rtts = NULL; m_rtts = NULL;
suppressSkyBox();
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Sets the ambient light. /** Sets the ambient light.
@ -1913,6 +1921,8 @@ void IrrDriver::update(float dt)
// ================================= // =================================
if (!m_device->run()) if (!m_device->run())
{ {
GUIEngine::cleanUp();
GUIEngine::deallocate();
main_loop->abort(); main_loop->abort();
return; return;
} }
@ -2402,3 +2412,4 @@ GLuint IrrDriver::getDepthStencilTexture()
{ {
return m_rtts->getDepthStencilTexture(); return m_rtts->getDepthStencilTexture();
} }

View File

@ -108,7 +108,11 @@ enum QueryPerf
{ {
Q_SOLID_PASS1, Q_SOLID_PASS1,
Q_SHADOWS, Q_SHADOWS,
Q_LIGHT, Q_RH,
Q_GI,
Q_ENVMAP,
Q_SUN,
Q_POINTLIGHTS,
Q_SSAO, Q_SSAO,
Q_SOLID_PASS2, Q_SOLID_PASS2,
Q_TRANSPARENT, Q_TRANSPARENT,
@ -290,6 +294,11 @@ public:
m_lwhite = v; m_lwhite = v;
} }
struct GlowData {
scene::ISceneNode * node;
float r, g, b;
};
private: private:
std::vector<VideoMode> m_modes; std::vector<VideoMode> m_modes;
@ -327,11 +336,6 @@ private:
scene::CLensFlareSceneNode *m_lensflare; scene::CLensFlareSceneNode *m_lensflare;
scene::ICameraSceneNode *m_suncam; scene::ICameraSceneNode *m_suncam;
struct GlowData {
scene::ISceneNode * node;
float r, g, b;
};
std::vector<GlowData> m_glowing; std::vector<GlowData> m_glowing;
std::vector<LightNode *> m_lights; std::vector<LightNode *> m_lights;
@ -361,12 +365,9 @@ private:
void renderTransparent(); void renderTransparent();
void renderParticles(); void renderParticles();
void computeSunVisibility(); void computeSunVisibility();
void renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadows);
void computeCameraMatrix(scene::ICameraSceneNode * const camnode, size_t width, size_t height);
void renderShadows(); void renderShadows();
void renderGlow(std::vector<GlowData>& glows); void renderGlow(std::vector<GlowData>& glows);
void renderSSAO(); void renderSSAO();
unsigned UpdateLightsInfo(scene::ICameraSceneNode * const camnode, float dt);
void renderLights(unsigned pointlightCount); void renderLights(unsigned pointlightCount);
void renderDisplacement(); void renderDisplacement();
void doScreenShot(); void doScreenShot();
@ -525,7 +526,10 @@ public:
{ {
return m_texture_error_message; return m_texture_error_message;
} // getTextureErrorMessage } // getTextureErrorMessage
// ------------------------------------------------------------------------
void setRTT(RTT* rtt);
// ------------------------------------------------------------------------
RTT* getRTT() { return m_rtts; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a list of all video modes supports by the graphics card. */ /** Returns a list of all video modes supports by the graphics card. */
const std::vector<VideoMode>& getVideoModes() const { return m_modes; } const std::vector<VideoMode>& getVideoModes() const { return m_modes; }
@ -696,6 +700,10 @@ public:
void onLoadWorld(); void onLoadWorld();
void onUnloadWorld(); void onUnloadWorld();
void renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadows, bool forceRTT);
unsigned UpdateLightsInfo(scene::ICameraSceneNode * const camnode, float dt);
void computeCameraMatrix(scene::ICameraSceneNode * const camnode, size_t width, size_t height);
// --------------------- RTT -------------------- // --------------------- RTT --------------------
/** /**
* Class that provides RTT (currently, only when no other 3D rendering * Class that provides RTT (currently, only when no other 3D rendering

View File

@ -207,36 +207,17 @@ void PostProcessing::update(float dt)
static static
void renderBloom(GLuint in) void renderBloom(GLuint in)
{ {
const float threshold = World::getWorld()->getTrack()->getBloomThreshold(); float threshold = 1.0f;
if (World::getWorld() != NULL)
threshold = World::getWorld()->getTrack()->getBloomThreshold();
glUseProgram(FullScreenShader::BloomShader::Program); glUseProgram(FullScreenShader::BloomShader::Program);
glBindVertexArray(FullScreenShader::BloomShader::vao); glBindVertexArray(FullScreenShader::BloomShader::vao);
setTexture(0, in, GL_NEAREST, GL_NEAREST); setTexture(0, in, GL_NEAREST, GL_NEAREST);
FullScreenShader::BloomShader::setUniforms(0); FullScreenShader::BloomShader::setUniforms(0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
}
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);
} }
void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff) void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff)
@ -253,7 +234,7 @@ void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSH
core::matrix4 TVM = irr_driver->getViewMatrix().getTransposed(); core::matrix4 TVM = irr_driver->getViewMatrix().getTransposed();
FullScreenShader::DiffuseEnvMapShader::setUniforms(TVM, bSHCoeff, gSHCoeff, rSHCoeff, 0); FullScreenShader::DiffuseEnvMapShader::setUniforms(TVM, bSHCoeff, gSHCoeff, rSHCoeff, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@ -287,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(3, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
setTexture(4, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST); setTexture(4, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
FullScreenShader::GlobalIlluminationReconstructionShader::setUniforms(RHMatrix, rh_extend, 3, 4, 0, 1, 2); 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() void PostProcessing::renderSunlight()
@ -304,7 +285,7 @@ void PostProcessing::renderSunlight()
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST); setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getDepthStencilTexture(), 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); 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); glBindVertexArray(0);
} }
@ -341,7 +322,7 @@ void PostProcessing::renderShadowedSunlight(const std::vector<core::matrix4> &su
glBindVertexArray(FullScreenShader::ShadowedSunLightShader::vao); glBindVertexArray(FullScreenShader::ShadowedSunLightShader::vao);
FullScreenShader::ShadowedSunLightShader::setUniforms(cb->getPosition(), cb->getRed(), cb->getGreen(), cb->getBlue(), 0, 1, 2); 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); glBindVertexArray(0);
} }
@ -362,7 +343,7 @@ void PostProcessing::renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian3VBlurShader::uniform_tex, 0); glUniform1i(FullScreenShader::Gaussian3VBlurShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
} }
{ {
in_fbo.Bind(); in_fbo.Bind();
@ -376,7 +357,7 @@ void PostProcessing::renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian3HBlurShader::uniform_tex, 0); glUniform1i(FullScreenShader::Gaussian3HBlurShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
} }
} }
@ -396,7 +377,7 @@ void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian6VBlurShader::uniform_tex, 0); glUniform1i(FullScreenShader::Gaussian6VBlurShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
} }
{ {
in_fbo.Bind(); in_fbo.Bind();
@ -410,7 +391,7 @@ void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian6HBlurShader::uniform_tex, 0); glUniform1i(FullScreenShader::Gaussian6HBlurShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
} }
} }
@ -418,6 +399,8 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
{ {
assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight()); assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight());
float inv_width = 1.0f / in_fbo.getWidth(), inv_height = 1.0f / in_fbo.getHeight(); float inv_width = 1.0f / in_fbo.getWidth(), inv_height = 1.0f / in_fbo.getHeight();
{
if (irr_driver->getGLSLVersion() < 430)
{ {
auxiliary.Bind(); auxiliary.Bind();
glUseProgram(FullScreenShader::Gaussian17TapHShader::Program); glUseProgram(FullScreenShader::Gaussian17TapHShader::Program);
@ -430,8 +413,20 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian17TapHShader::uniform_tex, 0); glUniform1i(FullScreenShader::Gaussian17TapHShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
} }
else
{
glUseProgram(FullScreenShader::ComputeGaussian17TapHShader::Program);
glBindImageTexture(0, in_fbo.getRTT()[0], 0, false, 0, GL_READ_ONLY, GL_R16F);
glBindImageTexture(1, auxiliary.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R16F);
glUniform1i(FullScreenShader::ComputeGaussian17TapHShader::uniform_source, 0);
glUniform1i(FullScreenShader::ComputeGaussian17TapHShader::uniform_dest, 1);
glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1);
}
}
{
if (irr_driver->getGLSLVersion() < 430)
{ {
in_fbo.Bind(); in_fbo.Bind();
glUseProgram(FullScreenShader::Gaussian17TapVShader::Program); glUseProgram(FullScreenShader::Gaussian17TapVShader::Program);
@ -444,7 +439,17 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian17TapVShader::uniform_tex, 0); glUniform1i(FullScreenShader::Gaussian17TapVShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
}
else
{
glUseProgram(FullScreenShader::ComputeGaussian17TapVShader::Program);
glBindImageTexture(0, auxiliary.getRTT()[0], 0, false, 0, GL_READ_ONLY, GL_R16F);
glBindImageTexture(1, in_fbo.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R16F);
glUniform1i(FullScreenShader::ComputeGaussian17TapVShader::uniform_source, 0);
glUniform1i(FullScreenShader::ComputeGaussian17TapVShader::uniform_dest, 1);
glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1);
}
} }
} }
@ -489,7 +494,7 @@ void PostProcessing::renderSSAO()
glBindVertexArray(FullScreenShader::LinearizeDepthShader::vao); glBindVertexArray(FullScreenShader::LinearizeDepthShader::vao);
setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR); setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
FullScreenShader::LinearizeDepthShader::setUniforms(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue(), 0); 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(); irr_driver->getFBO(FBO_SSAO).Bind();
if (!noise_tex) if (!noise_tex)
@ -498,7 +503,7 @@ void PostProcessing::renderSSAO()
glUseProgram(FullScreenShader::SSAOShader::Program); glUseProgram(FullScreenShader::SSAOShader::Program);
glBindVertexArray(FullScreenShader::SSAOShader::vao); 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); glGenerateMipmap(GL_TEXTURE_2D);
setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR); setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR);
@ -506,7 +511,7 @@ void PostProcessing::renderSSAO()
float(UserConfigParams::m_height)), float(UserConfigParams::m_height)),
0, 1); 0, 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
} }
void PostProcessing::renderFog() void PostProcessing::renderFog()
@ -536,7 +541,7 @@ void PostProcessing::renderFog()
setTexture(0, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST); setTexture(0, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
FullScreenShader::FogShader::setUniforms(fogmax, startH, endH, start, end, col, 0); FullScreenShader::FogShader::setUniforms(fogmax, startH, endH, start, end, col, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@ -576,7 +581,7 @@ void PostProcessing::renderMotionBlur(unsigned cam, FrameBuffer &in_fbo, FrameBu
cb->getDirection(cam), 0.15f, cb->getDirection(cam), 0.15f,
cb->getMaxHeight(cam) * 0.7f, 0); 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) static void renderGodFade(GLuint tex, const SColor &col)
@ -608,7 +613,7 @@ static void toneMap(FrameBuffer &fbo, GLuint rtt)
setTexture(1, irr_driver->getRenderTargetTexture(RTT_LOG_LUMINANCE), GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST); 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); 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) static void renderDoF(FrameBuffer &fbo, GLuint rtt)
@ -620,7 +625,7 @@ static void renderDoF(FrameBuffer &fbo, GLuint rtt)
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST); setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
FullScreenShader::DepthOfFieldShader::setUniforms(0, 1); FullScreenShader::DepthOfFieldShader::setUniforms(0, 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLES, 0, 3);
} }
static void averageTexture(GLuint tex) static void averageTexture(GLuint tex)
@ -630,19 +635,6 @@ static void averageTexture(GLuint tex)
glGenerateMipmap(GL_TEXTURE_2D); 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() void PostProcessing::applyMLAA()
{ {
const core::vector2df &PIXEL_SIZE = core::vector2df(1.0f / UserConfigParams::m_width, 1.0f / UserConfigParams::m_height); const core::vector2df &PIXEL_SIZE = core::vector2df(1.0f / UserConfigParams::m_width, 1.0f / UserConfigParams::m_height);
@ -728,7 +720,10 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode)
{ {
PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_GODRAYS)); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_GODRAYS));
const bool hasgodrays = World::getWorld()->getTrack()->hasGodRays(); bool hasgodrays = false;
if (World::getWorld() != NULL)
hasgodrays = World::getWorld()->getTrack()->hasGodRays();
if (UserConfigParams::m_light_shaft && m_sunpixels > 30 && hasgodrays) if (UserConfigParams::m_light_shaft && m_sunpixels > 30 && hasgodrays)
{ {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
@ -798,6 +793,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode)
if (UserConfigParams::m_bloom) if (UserConfigParams::m_bloom)
{ {
glClear(GL_STENCIL_BUFFER_BIT); glClear(GL_STENCIL_BUFFER_BIT);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
FrameBuffer::Blit(*in_fbo, irr_driver->getFBO(FBO_BLOOM_1024), GL_COLOR_BUFFER_BIT, GL_LINEAR); FrameBuffer::Blit(*in_fbo, irr_driver->getFBO(FBO_BLOOM_1024), GL_COLOR_BUFFER_BIT, GL_LINEAR);
@ -818,15 +814,18 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode)
// Additively blend on top of tmp1 // Additively blend on top of tmp1
in_fbo->Bind(); in_fbo->Bind();
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_CONSTANT_COLOR, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD); glBlendEquation(GL_FUNC_ADD);
glBlendColor(.125, .125, .125, .125); setTexture(0, irr_driver->getRenderTargetTexture(RTT_BLOOM_128), GL_LINEAR, GL_LINEAR);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_128)); setTexture(1, irr_driver->getRenderTargetTexture(RTT_BLOOM_256), GL_LINEAR, GL_LINEAR);
glBlendColor(.25, .25, .25, .25); setTexture(2, irr_driver->getRenderTargetTexture(RTT_BLOOM_512), GL_LINEAR, GL_LINEAR);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_256)); glUseProgram(FullScreenShader::BloomBlendShader::Program);
glBlendColor(.5, .5, .5, .5); FullScreenShader::BloomBlendShader::setUniforms(0, 1, 2);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_512)); glBindVertexArray(FullScreenShader::BloomBlendShader::vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
} // end if bloom } // end if bloom
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} }
@ -843,7 +842,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode)
{ {
PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MOTIONBLUR)); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MOTIONBLUR));
if (UserConfigParams::m_motionblur && m_any_boost) // motion blur if (UserConfigParams::m_motionblur && m_any_boost && World::getWorld() != NULL) // motion blur
{ {
renderMotionBlur(0, *in_fbo, *out_fbo); renderMotionBlur(0, *in_fbo, *out_fbo);
std::swap(in_fbo, out_fbo); std::swap(in_fbo, out_fbo);

View File

@ -131,12 +131,10 @@ void IrrDriver::renderGLSL(float dt)
Camera * const camera = Camera::getCamera(cam); Camera * const camera = Camera::getCamera(cam);
scene::ICameraSceneNode * const camnode = camera->getCameraSceneNode(); scene::ICameraSceneNode * const camnode = camera->getCameraSceneNode();
#ifdef ENABLE_PROFILER
std::ostringstream oss; std::ostringstream oss;
oss << "drawAll() for kart " << cam << std::flush; oss << "drawAll() for kart " << cam;
PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), (cam+1)*60, PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), (cam+1)*60,
0x00, 0x00); 0x00, 0x00);
#endif
camera->activate(); camera->activate();
rg->preRenderCallback(camera); // adjusts start referee rg->preRenderCallback(camera); // adjusts start referee
m_scene_manager->setActiveCamera(camnode); m_scene_manager->setActiveCamera(camnode);
@ -145,7 +143,7 @@ void IrrDriver::renderGLSL(float dt)
unsigned plc = UpdateLightsInfo(camnode, dt); unsigned plc = UpdateLightsInfo(camnode, dt);
computeCameraMatrix(camnode, viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); computeCameraMatrix(camnode, viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
renderScene(camnode, plc, glows, dt, track->hasShadows()); renderScene(camnode, plc, glows, dt, track->hasShadows(), false);
// Debug physic // Debug physic
// Note that drawAll must be called before rendering // Note that drawAll must be called before rendering
@ -228,10 +226,10 @@ void IrrDriver::renderGLSL(float dt)
for(unsigned int i=0; i<Camera::getNumCameras(); i++) for(unsigned int i=0; i<Camera::getNumCameras(); i++)
{ {
Camera *camera = Camera::getCamera(i); Camera *camera = Camera::getCamera(i);
char marker_name[100]; std::ostringstream oss;
sprintf(marker_name, "renderPlayerView() for kart %d", i); oss << "renderPlayerView() for kart " << i;
PROFILER_PUSH_CPU_MARKER(marker_name, 0x00, 0x00, (i+1)*60); PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), 0x00, 0x00, (i+1)*60);
rg->renderPlayerView(camera, dt); rg->renderPlayerView(camera, dt);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
@ -261,7 +259,7 @@ void IrrDriver::renderGLSL(float dt)
getPostProcessing()->update(dt); getPostProcessing()->update(dt);
} }
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow) 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); glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
@ -287,7 +285,6 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
// Lights // Lights
{ {
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT));
renderLights(pointlightcount); renderLights(pointlightcount);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} }
@ -302,7 +299,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
} }
PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF); PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF);
if (!UserConfigParams::m_dynamic_lights) if (!UserConfigParams::m_dynamic_lights && ! forceRTT)
{ {
glEnable(GL_FRAMEBUFFER_SRGB); glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -312,7 +309,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
renderSolidSecondPass(); renderSolidSecondPass();
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
if (UserConfigParams::m_dynamic_lights && World::getWorld()->isFogEnabled()) if (UserConfigParams::m_dynamic_lights && World::getWorld() != NULL &&
World::getWorld()->isFogEnabled())
{ {
PROFILER_PUSH_CPU_MARKER("- Fog", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- Fog", 0xFF, 0x00, 0x00);
m_post_processing->renderFog(); m_post_processing->renderFog();
@ -374,7 +372,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
renderParticles(); renderParticles();
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} }
if (!UserConfigParams::m_dynamic_lights) if (!UserConfigParams::m_dynamic_lights && !forceRTT)
return; return;
// Render displacement // Render displacement
@ -407,12 +405,10 @@ void IrrDriver::renderFixed(float dt)
{ {
Camera *camera = Camera::getCamera(i); Camera *camera = Camera::getCamera(i);
#ifdef ENABLE_PROFILER
std::ostringstream oss; std::ostringstream oss;
oss << "drawAll() for kart " << i << std::flush; oss << "drawAll() for kart " << i;
PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), (i+1)*60, PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), (i+1)*60,
0x00, 0x00); 0x00, 0x00);
#endif
camera->activate(); camera->activate();
rg->preRenderCallback(camera); // adjusts start referee rg->preRenderCallback(camera); // adjusts start referee
@ -437,10 +433,10 @@ void IrrDriver::renderFixed(float dt)
for(unsigned int i=0; i<Camera::getNumCameras(); i++) for(unsigned int i=0; i<Camera::getNumCameras(); i++)
{ {
Camera *camera = Camera::getCamera(i); Camera *camera = Camera::getCamera(i);
char marker_name[100]; std::ostringstream oss;
sprintf(marker_name, "renderPlayerView() for kart %d", i); oss << "renderPlayerView() for kart " << i;
PROFILER_PUSH_CPU_MARKER(marker_name, 0x00, 0x00, (i+1)*60); PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), 0x00, 0x00, (i+1)*60);
rg->renderPlayerView(camera, dt); rg->renderPlayerView(camera, dt);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
@ -467,8 +463,15 @@ void IrrDriver::renderFixed(float dt)
void IrrDriver::computeSunVisibility() void IrrDriver::computeSunVisibility()
{ {
// Is the lens flare enabled & visible? Check last frame's query. // Is the lens flare enabled & visible? Check last frame's query.
const bool hasflare = World::getWorld()->getTrack()->hasLensFlare(); bool hasflare = false;
const bool hasgodrays = World::getWorld()->getTrack()->hasGodRays(); bool hasgodrays = false;
if (World::getWorld() != NULL)
{
hasflare = World::getWorld()->getTrack()->hasLensFlare();
hasgodrays = World::getWorld()->getTrack()->hasGodRays();
}
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver(); irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
if (UserConfigParams::m_light_shaft && hasgodrays)//hasflare || hasgodrays) if (UserConfigParams::m_light_shaft && hasgodrays)//hasflare || hasgodrays)
{ {
@ -567,7 +570,10 @@ void IrrDriver::renderSolidFirstPass()
void IrrDriver::renderSolidSecondPass() void IrrDriver::renderSolidSecondPass()
{ {
SColor clearColor = World::getWorld()->getClearColor(); SColor clearColor(0., 150, 150, 150);
if (World::getWorld() != NULL)
clearColor = World::getWorld()->getClearColor();
glClearColor(clearColor.getRed() / 255.f, clearColor.getGreen() / 255.f, glClearColor(clearColor.getRed() / 255.f, clearColor.getGreen() / 255.f,
clearColor.getBlue() / 255.f, clearColor.getAlpha() / 255.f); clearColor.getBlue() / 255.f, clearColor.getAlpha() / 255.f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
@ -666,9 +672,6 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW)); irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
irr_driver->genProjViewMatrix(); irr_driver->genProjViewMatrix();
const Vec3 *vmin, *vmax;
World::getWorld()->getTrack()->getAABB(&vmin, &vmax);
const float oldfar = camnode->getFarValue(); const float oldfar = camnode->getFarValue();
const float oldnear = camnode->getNearValue(); const float oldnear = camnode->getNearValue();
float FarValues[] = float FarValues[] =
@ -686,9 +689,21 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
50., 50.,
}; };
float *tmp = new float[18 * 8];
memcpy(tmp, irr_driver->getViewMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[16], irr_driver->getProjMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[32], irr_driver->getInvViewMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float));
const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix(); const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix();
sun_ortho_matrix.clear(); sun_ortho_matrix.clear();
if (World::getWorld() && World::getWorld()->getTrack())
{
const Vec3 *vmin, *vmax;
World::getWorld()->getTrack()->getAABB(&vmin, &vmax);
// Build the 3 ortho projection (for the 3 shadow resolution levels) // Build the 3 ortho projection (for the 3 shadow resolution levels)
for (unsigned i = 0; i < 4; i++) for (unsigned i = 0; i < 4; i++)
{ {
@ -700,7 +715,6 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
core::aabbox3df trackbox(vmin->toIrrVector(), vmax->toIrrVector() - core::aabbox3df trackbox(vmin->toIrrVector(), vmax->toIrrVector() -
core::vector3df(0, 30, 0)); core::vector3df(0, 30, 0));
// Set up a nice ortho projection that contains our camera frustum // Set up a nice ortho projection that contains our camera frustum
core::aabbox3df box = smallcambox; core::aabbox3df box = smallcambox;
box = box.intersect(trackbox); box = box.intersect(trackbox);
@ -709,7 +723,7 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
SunCamViewMatrix.transformBoxEx(trackbox); SunCamViewMatrix.transformBoxEx(trackbox);
SunCamViewMatrix.transformBoxEx(box); SunCamViewMatrix.transformBoxEx(box);
core::vector3df extent = trackbox.getExtent(); core::vector3df extent = box.getExtent();
const float w = fabsf(extent.X); const float w = fabsf(extent.X);
const float h = fabsf(extent.Y); const float h = fabsf(extent.Y);
float z = box.MaxEdge.Z; float z = box.MaxEdge.Z;
@ -748,19 +762,16 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
core::vector3df translation(8 * floor(campos.X / 8), 8 * floor(campos.Y / 8), 8 * floor(campos.Z / 8)); core::vector3df translation(8 * floor(campos.X / 8), 8 * floor(campos.Y / 8), 8 * floor(campos.Z / 8));
rh_matrix.setTranslation(translation); rh_matrix.setTranslation(translation);
assert(sun_ortho_matrix.size() == 4); assert(sun_ortho_matrix.size() == 4);
camnode->setNearValue(oldnear); camnode->setNearValue(oldnear);
camnode->setFarValue(oldfar); camnode->setFarValue(oldfar);
float *tmp = new float[18 * 8];
memcpy(tmp, irr_driver->getViewMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[16], irr_driver->getProjMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[32], irr_driver->getInvViewMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float));
size_t size = irr_driver->getShadowViewProj().size(); size_t size = irr_driver->getShadowViewProj().size();
for (unsigned i = 0; i < size; i++) for (unsigned i = 0; i < size; i++)
memcpy(&tmp[16 * i + 64], irr_driver->getShadowViewProj()[i].pointer(), 16 * sizeof(float)); memcpy(&tmp[16 * i + 64], irr_driver->getShadowViewProj()[i].pointer(), 16 * sizeof(float));
}
tmp[128] = float(width); tmp[128] = float(width);
tmp[129] = float(height); tmp[129] = float(height);
@ -974,6 +985,7 @@ void IrrDriver::renderLights(unsigned pointlightcount)
//RH //RH
if (UserConfigParams::m_gi) if (UserConfigParams::m_gi)
{ {
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH));
glDisable(GL_BLEND); glDisable(GL_BLEND);
m_rtts->getRH().Bind(); m_rtts->getRH().Bind();
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program); glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program);
@ -994,25 +1006,36 @@ void IrrDriver::renderLights(unsigned pointlightcount)
if (!UserConfigParams::m_dynamic_lights) if (!UserConfigParams::m_dynamic_lights)
return; return;
m_rtts->getFBO(FBO_TMP1_WITH_DS).Bind();
if (UserConfigParams::m_gi) if (UserConfigParams::m_gi)
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI));
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]); 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) if (SkyboxCubeMap)
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP));
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
}
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && SkyboxCubeMap && UserConfigParams::m_gi)
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0)); irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
// Render sunlight if and only if track supports shadow // Render sunlight if and only if track supports shadow
if (World::getWorld()->getTrack()->hasShadows()) if (!World::getWorld() || World::getWorld()->getTrack()->hasShadows())
{ {
if (UserConfigParams::m_shadows) ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_SUN));
if (World::getWorld() && UserConfigParams::m_shadows)
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex()); m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
else else
m_post_processing->renderSunlight(); m_post_processing->renderSunlight();
} }
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_POINTLIGHTS));
renderPointLights(MIN2(pointlightcount, MAXLIGHT)); renderPointLights(MIN2(pointlightcount, MAXLIGHT));
if (SkyboxCubeMap) }
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
} }
void IrrDriver::renderSSAO() void IrrDriver::renderSSAO()

View File

@ -22,6 +22,18 @@
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
static GLuint generateRTT3D(GLenum target, size_t w, size_t h, size_t d, GLint internalFormat, GLint format, GLint type)
{
GLuint result;
glGenTextures(1, &result);
glBindTexture(target, result);
if (irr_driver->getGLSLVersion() < 420)
glTexImage3D(target, 0, internalFormat, w, h, d, 0, format, type, 0);
else
glTexStorage3D(target, 1, internalFormat, w, h, d);
return result;
}
static GLuint generateRTT(const core::dimension2du &res, GLint internalFormat, GLint format, GLint type, unsigned mipmaplevel = 1) static GLuint generateRTT(const core::dimension2du &res, GLint internalFormat, GLint format, GLint type, unsigned mipmaplevel = 1)
{ {
GLuint result; GLuint result;
@ -57,6 +69,7 @@ static GLuint generateFBO(GLuint ColorAttachement, GLuint DepthAttachement)
RTT::RTT(size_t width, size_t height) RTT::RTT(size_t width, size_t height)
{ {
m_shadow_FBO = NULL; m_shadow_FBO = NULL;
m_RH_FBO = NULL;
m_RSM = NULL; m_RSM = NULL;
m_RH_FBO = NULL; m_RH_FBO = NULL;
using namespace video; using namespace video;
@ -79,9 +92,7 @@ RTT::RTT(size_t width, size_t height)
unsigned linear_depth_mip_levels = ceil(log2(max_(res.Width, res.Height))); unsigned linear_depth_mip_levels = ceil(log2(max_(res.Width, res.Height)));
glGenTextures(1, &DepthStencilTexture); DepthStencilTexture = generateRTT(res, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
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);
// All RTTs are currently RGBA16F mostly with stencil. The four tmp RTTs are the same size // All RTTs are currently RGBA16F mostly with stencil. The four tmp RTTs are the same size
// as the screen, for use in post-processing. // as the screen, for use in post-processing.
@ -93,7 +104,7 @@ RTT::RTT(size_t width, size_t height)
RenderTargetTextures[RTT_LINEAR_DEPTH] = generateRTT(res, GL_R32F, GL_RED, GL_FLOAT, linear_depth_mip_levels); 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_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGBA16F, GL_RGBA, GL_FLOAT);
RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT); RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB, GL_BGR, 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_SSAO] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT); RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
@ -195,12 +206,8 @@ RTT::RTT(size_t width, size_t height)
if (UserConfigParams::m_shadows) if (UserConfigParams::m_shadows)
{ {
glGenTextures(1, &shadowColorTex); shadowColorTex = generateRTT3D(GL_TEXTURE_2D_ARRAY, 1024, 1024, 4, GL_R8, GL_RED, GL_UNSIGNED_BYTE);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowColorTex); shadowDepthTex = generateRTT3D(GL_TEXTURE_2D_ARRAY, 1024, 1024, 4, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8, 1024, 1024, 4, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
glGenTextures(1, &shadowDepthTex);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowDepthTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_STENCIL, 1024, 1024, 4, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
somevector.clear(); somevector.clear();
somevector.push_back(shadowColorTex); somevector.push_back(shadowColorTex);
@ -210,30 +217,18 @@ RTT::RTT(size_t width, size_t height)
if (UserConfigParams::m_gi) if (UserConfigParams::m_gi)
{ {
//Todo : use "normal" shadowtex //Todo : use "normal" shadowtex
glGenTextures(1, &RSM_Color); RSM_Color = generateRTT(shadowsize0, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE);
glBindTexture(GL_TEXTURE_2D, RSM_Color); RSM_Normal = generateRTT(shadowsize0, GL_RGB16F, GL_RGB, GL_FLOAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); RSM_Depth = generateRTT(shadowsize0, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
glGenTextures(1, &RSM_Normal);
glBindTexture(GL_TEXTURE_2D, RSM_Normal);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, 0);
glGenTextures(1, &RSM_Depth);
glBindTexture(GL_TEXTURE_2D, RSM_Depth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, 1024, 1024, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
somevector.clear(); somevector.clear();
somevector.push_back(RSM_Color); somevector.push_back(RSM_Color);
somevector.push_back(RSM_Normal); somevector.push_back(RSM_Normal);
m_RSM = new FrameBuffer(somevector, RSM_Depth, 1024, 1024, true); m_RSM = new FrameBuffer(somevector, RSM_Depth, 1024, 1024, true);
glGenTextures(1, &RH_Red); RH_Red = generateRTT3D(GL_TEXTURE_3D, 32, 16, 32, GL_RGBA16F, GL_RGBA, GL_FLOAT);
glBindTexture(GL_TEXTURE_3D, RH_Red); RH_Green = generateRTT3D(GL_TEXTURE_3D, 32, 16, 32, GL_RGBA16F, GL_RGBA, GL_FLOAT);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, 32, 16, 32, 0, GL_RGBA, GL_FLOAT, 0); RH_Blue = generateRTT3D(GL_TEXTURE_3D, 32, 16, 32, GL_RGBA16F, GL_RGBA, GL_FLOAT);
glGenTextures(1, &RH_Green);
glBindTexture(GL_TEXTURE_3D, RH_Green);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, 32, 16, 32, 0, GL_RGBA, GL_FLOAT, 0);
glGenTextures(1, &RH_Blue);
glBindTexture(GL_TEXTURE_3D, RH_Blue);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, 32, 16, 32, 0, GL_RGBA, GL_FLOAT, 0);
somevector.clear(); somevector.clear();
somevector.push_back(RH_Red); somevector.push_back(RH_Red);

View File

@ -50,7 +50,7 @@ Shaders::Shaders()
loadShaders(); loadShaders();
} }
GLuint quad_vbo; GLuint quad_vbo, tri_vbo;
static void initQuadVBO() static void initQuadVBO()
{ {
@ -64,6 +64,16 @@ static void initQuadVBO()
glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); glBindBuffer(GL_ARRAY_BUFFER, quad_vbo);
glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); 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... // It should be possible to merge it with previous one...
@ -265,12 +275,13 @@ void Shaders::loadShaders()
FullScreenShader::BloomBlendShader::init(); FullScreenShader::BloomBlendShader::init();
FullScreenShader::BloomShader::init(); FullScreenShader::BloomShader::init();
FullScreenShader::DepthOfFieldShader::init(); FullScreenShader::DepthOfFieldShader::init();
FullScreenShader::ColorLevelShader::init();
FullScreenShader::FogShader::init(); FullScreenShader::FogShader::init();
FullScreenShader::Gaussian17TapHShader::init(); FullScreenShader::Gaussian17TapHShader::init();
FullScreenShader::ComputeGaussian17TapHShader::init();
FullScreenShader::Gaussian3HBlurShader::init(); FullScreenShader::Gaussian3HBlurShader::init();
FullScreenShader::Gaussian3VBlurShader::init(); FullScreenShader::Gaussian3VBlurShader::init();
FullScreenShader::Gaussian17TapVShader::init(); FullScreenShader::Gaussian17TapVShader::init();
FullScreenShader::ComputeGaussian17TapVShader::init();
FullScreenShader::Gaussian6HBlurShader::init(); FullScreenShader::Gaussian6HBlurShader::init();
FullScreenShader::Gaussian6VBlurShader::init(); FullScreenShader::Gaussian6VBlurShader::init();
FullScreenShader::GlowShader::init(); FullScreenShader::GlowShader::init();
@ -287,7 +298,6 @@ void Shaders::loadShaders()
FullScreenShader::MotionBlurShader::init(); FullScreenShader::MotionBlurShader::init();
FullScreenShader::GodFadeShader::init(); FullScreenShader::GodFadeShader::init();
FullScreenShader::GodRayShader::init(); FullScreenShader::GodRayShader::init();
FullScreenShader::LogLuminanceShader::init();
FullScreenShader::ToneMapShader::init(); FullScreenShader::ToneMapShader::init();
FullScreenShader::MLAAColorEdgeDetectionSHader::init(); FullScreenShader::MLAAColorEdgeDetectionSHader::init();
FullScreenShader::MLAABlendWeightSHader::init(); FullScreenShader::MLAABlendWeightSHader::init();
@ -2031,6 +2041,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) static GLuint createVAO(GLuint Program)
{ {
GLuint vao; GLuint vao;
@ -2059,7 +2082,7 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getCIEXYZ.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getCIEXYZ.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/bloom.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/bloom.frag").c_str());
uniform_texture = glGetUniformLocation(Program, "tex"); uniform_texture = glGetUniformLocation(Program, "tex");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
} }
void BloomShader::setUniforms(unsigned TU_tex) void BloomShader::setUniforms(unsigned TU_tex)
@ -2068,20 +2091,27 @@ namespace FullScreenShader
} }
GLuint BloomBlendShader::Program; 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; GLuint BloomBlendShader::vao;
void BloomBlendShader::init() void BloomBlendShader::init()
{ {
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/bloomblend.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/bloomblend.frag").c_str());
uniform_texture = glGetUniformLocation(Program, "tex"); uniform_tex_128 = glGetUniformLocation(Program, "tex_128");
vao = createVAO(Program); 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; GLuint ToneMapShader::Program;
@ -2102,7 +2132,7 @@ namespace FullScreenShader
uniform_logluminancetex = glGetUniformLocation(Program, "logluminancetex"); uniform_logluminancetex = glGetUniformLocation(Program, "logluminancetex");
uniform_exposure = glGetUniformLocation(Program, "exposure"); uniform_exposure = glGetUniformLocation(Program, "exposure");
uniform_lwhite = glGetUniformLocation(Program, "Lwhite"); uniform_lwhite = glGetUniformLocation(Program, "Lwhite");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
} }
void ToneMapShader::setUniforms(float exposure, float Lwhite, unsigned TU_tex, unsigned TU_loglum) void ToneMapShader::setUniforms(float exposure, float Lwhite, unsigned TU_tex, unsigned TU_loglum)
@ -2125,7 +2155,7 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/dof.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/dof.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex"); uniform_tex = glGetUniformLocation(Program, "tex");
uniform_depth = glGetUniformLocation(Program, "dtex"); uniform_depth = glGetUniformLocation(Program, "dtex");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
} }
@ -2136,28 +2166,6 @@ namespace FullScreenShader
glUniform1i(uniform_depth, TU_dtex); 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::Program;
GLuint SunLightShader::uniform_ntex; GLuint SunLightShader::uniform_ntex;
GLuint SunLightShader::uniform_dtex; GLuint SunLightShader::uniform_dtex;
@ -2177,7 +2185,7 @@ namespace FullScreenShader
uniform_dtex = glGetUniformLocation(Program, "dtex"); uniform_dtex = glGetUniformLocation(Program, "dtex");
uniform_direction = glGetUniformLocation(Program, "direction"); uniform_direction = glGetUniformLocation(Program, "direction");
uniform_col = glGetUniformLocation(Program, "col"); uniform_col = glGetUniformLocation(Program, "col");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
if (!UserConfigParams::m_ubo_disabled) if (!UserConfigParams::m_ubo_disabled)
{ {
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@ -2214,7 +2222,7 @@ namespace FullScreenShader
uniform_greenLmn = glGetUniformLocation(Program, "greenLmn[0]"); uniform_greenLmn = glGetUniformLocation(Program, "greenLmn[0]");
uniform_redLmn = glGetUniformLocation(Program, "redLmn[0]"); uniform_redLmn = glGetUniformLocation(Program, "redLmn[0]");
uniform_TVM = glGetUniformLocation(Program, "TransposeViewMatrix"); 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) void DiffuseEnvMapShader::setUniforms(const core::matrix4 &TransposeViewMatrix, const float *blueSHCoeff, const float *greenSHCoeff, const float *redSHCoeff, unsigned TU_ntex)
@ -2247,7 +2255,7 @@ namespace FullScreenShader
uniform_shadowtex = glGetUniformLocation(Program, "shadowtex"); uniform_shadowtex = glGetUniformLocation(Program, "shadowtex");
uniform_direction = glGetUniformLocation(Program, "direction"); uniform_direction = glGetUniformLocation(Program, "direction");
uniform_col = glGetUniformLocation(Program, "col"); uniform_col = glGetUniformLocation(Program, "col");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
if (!UserConfigParams::m_ubo_disabled) if (!UserConfigParams::m_ubo_disabled)
{ {
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@ -2336,7 +2344,7 @@ namespace FullScreenShader
uniform_extents = glGetUniformLocation(Program, "extents"); uniform_extents = glGetUniformLocation(Program, "extents");
uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix"); uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix");
uniform_RSMMatrix = glGetUniformLocation(Program, "RSMMatrix"); 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) 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 +2411,7 @@ namespace FullScreenShader
uniform_SHB = glGetUniformLocation(Program, "SHB"); uniform_SHB = glGetUniformLocation(Program, "SHB");
uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix"); uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix");
uniform_extents = glGetUniformLocation(Program, "extents"); uniform_extents = glGetUniformLocation(Program, "extents");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
} }
@ -2430,7 +2438,18 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian17taph.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian17taph.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex"); uniform_tex = glGetUniformLocation(Program, "tex");
uniform_pixel = glGetUniformLocation(Program, "pixel"); uniform_pixel = glGetUniformLocation(Program, "pixel");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
}
GLuint ComputeGaussian17TapHShader::Program;
GLuint ComputeGaussian17TapHShader::uniform_source;
GLuint ComputeGaussian17TapHShader::uniform_dest;
void ComputeGaussian17TapHShader::init()
{
Program = LoadProgram(
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/gaussian.comp").c_str());
uniform_source = glGetUniformLocation(Program, "source");
uniform_dest = glGetUniformLocation(Program, "dest");
} }
GLuint Gaussian6HBlurShader::Program; GLuint Gaussian6HBlurShader::Program;
@ -2444,7 +2463,7 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian6h.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian6h.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex"); uniform_tex = glGetUniformLocation(Program, "tex");
uniform_pixel = glGetUniformLocation(Program, "pixel"); uniform_pixel = glGetUniformLocation(Program, "pixel");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
} }
GLuint Gaussian3HBlurShader::Program; GLuint Gaussian3HBlurShader::Program;
@ -2458,7 +2477,7 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian3h.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian3h.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex"); uniform_tex = glGetUniformLocation(Program, "tex");
uniform_pixel = glGetUniformLocation(Program, "pixel"); uniform_pixel = glGetUniformLocation(Program, "pixel");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
} }
GLuint Gaussian17TapVShader::Program; GLuint Gaussian17TapVShader::Program;
@ -2472,7 +2491,18 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian17tapv.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian17tapv.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex"); uniform_tex = glGetUniformLocation(Program, "tex");
uniform_pixel = glGetUniformLocation(Program, "pixel"); uniform_pixel = glGetUniformLocation(Program, "pixel");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
}
GLuint ComputeGaussian17TapVShader::Program;
GLuint ComputeGaussian17TapVShader::uniform_source;
GLuint ComputeGaussian17TapVShader::uniform_dest;
void ComputeGaussian17TapVShader::init()
{
Program = LoadProgram(
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/gaussianv.comp").c_str());
uniform_source = glGetUniformLocation(Program, "source");
uniform_dest = glGetUniformLocation(Program, "dest");
} }
GLuint Gaussian6VBlurShader::Program; GLuint Gaussian6VBlurShader::Program;
@ -2486,7 +2516,7 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian6v.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian6v.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex"); uniform_tex = glGetUniformLocation(Program, "tex");
uniform_pixel = glGetUniformLocation(Program, "pixel"); uniform_pixel = glGetUniformLocation(Program, "pixel");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
} }
GLuint Gaussian3VBlurShader::Program; GLuint Gaussian3VBlurShader::Program;
@ -2500,7 +2530,7 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian3v.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian3v.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex"); uniform_tex = glGetUniformLocation(Program, "tex");
uniform_pixel = glGetUniformLocation(Program, "pixel"); uniform_pixel = glGetUniformLocation(Program, "pixel");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
} }
GLuint PassThroughShader::Program; GLuint PassThroughShader::Program;
@ -2528,7 +2558,7 @@ namespace FullScreenShader
uniform_texture = glGetUniformLocation(Program, "texture"); uniform_texture = glGetUniformLocation(Program, "texture");
uniform_zf = glGetUniformLocation(Program, "zf"); uniform_zf = glGetUniformLocation(Program, "zf");
uniform_zn = glGetUniformLocation(Program, "zn"); uniform_zn = glGetUniformLocation(Program, "zn");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
} }
void LinearizeDepthShader::setUniforms(float zn, float zf, unsigned TU_tex) void LinearizeDepthShader::setUniforms(float zn, float zf, unsigned TU_tex)
@ -2569,7 +2599,7 @@ namespace FullScreenShader
uniform_dtex = glGetUniformLocation(Program, "dtex"); uniform_dtex = glGetUniformLocation(Program, "dtex");
uniform_noise_texture = glGetUniformLocation(Program, "noise_texture"); uniform_noise_texture = glGetUniformLocation(Program, "noise_texture");
uniform_samplePoints = glGetUniformLocation(Program, "samplePoints[0]"); uniform_samplePoints = glGetUniformLocation(Program, "samplePoints[0]");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
if (!UserConfigParams::m_ubo_disabled) if (!UserConfigParams::m_ubo_disabled)
{ {
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@ -2723,7 +2753,7 @@ namespace FullScreenShader
uniform_start = glGetUniformLocation(Program, "start"); uniform_start = glGetUniformLocation(Program, "start");
uniform_end = glGetUniformLocation(Program, "end"); uniform_end = glGetUniformLocation(Program, "end");
uniform_col = glGetUniformLocation(Program, "col"); uniform_col = glGetUniformLocation(Program, "col");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
if (!UserConfigParams::m_ubo_disabled) if (!UserConfigParams::m_ubo_disabled)
{ {
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@ -2764,7 +2794,7 @@ namespace FullScreenShader
uniform_direction = glGetUniformLocation(Program, "direction"); uniform_direction = glGetUniformLocation(Program, "direction");
uniform_mask_radius = glGetUniformLocation(Program, "mask_radius"); uniform_mask_radius = glGetUniformLocation(Program, "mask_radius");
uniform_max_tex_height = glGetUniformLocation(Program, "max_tex_height"); uniform_max_tex_height = glGetUniformLocation(Program, "max_tex_height");
vao = createVAO(Program); vao = createFullScreenVAO(Program);
} }
void MotionBlurShader::setUniforms(float boost_amount, const core::vector2df &center, const core::vector2df &direction, float mask_radius, float max_tex_height, unsigned TU_cb) void MotionBlurShader::setUniforms(float boost_amount, const core::vector2df &center, const core::vector2df &direction, float mask_radius, float max_tex_height, unsigned TU_cb)
@ -2819,24 +2849,6 @@ namespace FullScreenShader
glUniform1i(uniform_tex, TU_tex); 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::Program;
GLuint MLAAColorEdgeDetectionSHader::uniform_colorMapG; GLuint MLAAColorEdgeDetectionSHader::uniform_colorMapG;
GLuint MLAAColorEdgeDetectionSHader::uniform_PIXEL_SIZE; GLuint MLAAColorEdgeDetectionSHader::uniform_PIXEL_SIZE;

View File

@ -526,11 +526,11 @@ class BloomBlendShader
{ {
public: public:
static GLuint Program; static GLuint Program;
static GLuint uniform_texture; static GLuint uniform_tex_128, uniform_tex_256, uniform_tex_512;
static GLuint vao; static GLuint vao;
static void init(); 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 class ToneMapShader
@ -555,16 +555,6 @@ public:
static void setUniforms(unsigned TU_tex, unsigned TU_depth); 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 class SunLightShader
{ {
public: public:
@ -651,6 +641,15 @@ public:
static void init(); static void init();
}; };
class ComputeGaussian17TapHShader
{
public:
static GLuint Program;
static GLuint uniform_source, uniform_dest;
static void init();
};
class Gaussian6HBlurShader class Gaussian6HBlurShader
{ {
public: public:
@ -681,6 +680,16 @@ public:
static void init(); static void init();
}; };
class ComputeGaussian17TapVShader
{
public:
static GLuint Program;
static GLuint uniform_source, uniform_dest;
static void init();
};
class Gaussian6VBlurShader class Gaussian6VBlurShader
{ {
public: public:
@ -788,17 +797,6 @@ public:
static void setUniforms(const core::vector2df &sunpos, unsigned TU_tex); 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 class MLAAColorEdgeDetectionSHader
{ {
public: public:

View File

@ -230,7 +230,7 @@ void STKAnimatedMesh::render()
for_in(mesh, TransparentMesh[TM_BUBBLE]) for_in(mesh, TransparentMesh[TM_BUBBLE])
drawBubble(*mesh, ModelViewProjectionMatrix); drawBubble(*mesh, ModelViewProjectionMatrix);
if (World::getWorld()->isFogEnabled()) if (World::getWorld() != NULL && World::getWorld()->isFogEnabled())
{ {
if (!TransparentMesh[TM_DEFAULT].empty() || !TransparentMesh[TM_ADDITIVE].empty()) if (!TransparentMesh[TM_DEFAULT].empty() || !TransparentMesh[TM_ADDITIVE].empty())
glUseProgram(MeshShader::TransparentFogShader::Program); glUseProgram(MeshShader::TransparentFogShader::Program);

View File

@ -740,7 +740,7 @@ void initvaostate(GLMesh &mesh, TransparentMaterial TranspMat)
break; break;
case TM_DEFAULT: case TM_DEFAULT:
case TM_ADDITIVE: case TM_ADDITIVE:
if (World::getWorld()->isFogEnabled()) if (World::getWorld() != NULL && World::getWorld()->isFogEnabled())
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::TransparentFogShader::attrib_position, MeshShader::TransparentFogShader::attrib_texcoord, -1, -1, -1, -1, MeshShader::TransparentFogShader::attrib_color, mesh.Stride); MeshShader::TransparentFogShader::attrib_position, MeshShader::TransparentFogShader::attrib_texcoord, -1, -1, -1, -1, MeshShader::TransparentFogShader::attrib_color, mesh.Stride);
else else

View File

@ -691,7 +691,6 @@ X##_yflip.LowerRightCorner.Y = w->m_skin_dest_y + \
void Skin::drawButton(Widget* w, const core::recti &rect, void Skin::drawButton(Widget* w, const core::recti &rect,
const bool pressed, const bool focused) const bool pressed, const bool focused)
{ {
// if within an appearing dialog, grow // if within an appearing dialog, grow
if (m_dialog && m_dialog_size < 1.0f && w->m_parent != NULL && if (m_dialog && m_dialog_size < 1.0f && w->m_parent != NULL &&
w->m_parent->getType() == gui::EGUIET_WINDOW) w->m_parent->getType() == gui::EGUIET_WINDOW)
@ -1916,6 +1915,16 @@ void Skin::process3DPane(IGUIElement *element, const core::recti &rect,
if (!widget->m_event_handler->m_deactivated) if (!widget->m_event_handler->m_deactivated)
drawSpinnerChild(rect, widget, pressed, focused); drawSpinnerChild(rect, widget, pressed, focused);
} }
else if (type == WTYPE_MODEL_VIEW)
{
ModelViewWidget* mvw = dynamic_cast<ModelViewWidget*>(widget);
FrameBuffer* fb = mvw->getFrameBuffer();
if (fb != NULL && fb->getRTT().size() > 0)
{
draw2DImageFromRTT(fb->getRTT()[0], 512, 512,
rect, core::rect<s32>(0, 0, 512, 512), NULL, true);
}
}
else if (type == WTYPE_ICON_BUTTON || type == WTYPE_MODEL_VIEW) else if (type == WTYPE_ICON_BUTTON || type == WTYPE_MODEL_VIEW)
{ {
drawIconButton(rect, widget, pressed, focused); drawIconButton(rect, widget, pressed, focused);
@ -2101,8 +2110,10 @@ void Skin::draw3DSunkenPane (IGUIElement *element, video::SColor bgcolor,
{ {
SColor& bg_color = SkinConfig::m_colors["text_field::background"]; SColor& bg_color = SkinConfig::m_colors["text_field::background"];
SColor& bg_color_focused = SkinConfig::m_colors["text_field::background_focused"]; SColor& bg_color_focused = SkinConfig::m_colors["text_field::background_focused"];
SColor& bg_color_deactivated = SkinConfig::m_colors["text_field::background_deactivated"];
SColor& border_color = SkinConfig::m_colors["text_field::neutral"]; SColor& border_color = SkinConfig::m_colors["text_field::neutral"];
SColor& border_color_focus = SkinConfig::m_colors["text_field::focused"]; SColor& border_color_focus = SkinConfig::m_colors["text_field::focused"];
SColor& border_color_deactivated = SkinConfig::m_colors["text_field::deactivated"];
core::recti borderArea = rect; core::recti borderArea = rect;
//borderArea.UpperLeftCorner -= position2d< s32 >( 2, 2 ); //borderArea.UpperLeftCorner -= position2d< s32 >( 2, 2 );
@ -2128,12 +2139,22 @@ void Skin::draw3DSunkenPane (IGUIElement *element, video::SColor bgcolor,
center.Y + (int)(((int)rect.LowerRightCorner.Y center.Y + (int)(((int)rect.LowerRightCorner.Y
- (int)center.Y)*texture_size); - (int)center.Y)*texture_size);
} }
GL32_draw2DRectangle(focused ? border_color_focus : border_color, borderArea); if(widget->m_deactivated)
GL32_draw2DRectangle(border_color_deactivated, borderArea);
else if(focused)
GL32_draw2DRectangle(border_color_focus, borderArea);
else
GL32_draw2DRectangle(border_color, borderArea);
core::recti innerArea = borderArea; core::recti innerArea = borderArea;
innerArea.UpperLeftCorner += position2d< s32 >( 3, 3 ); innerArea.UpperLeftCorner += position2d< s32 >( 3, 3 );
innerArea.LowerRightCorner -= position2d< s32 >( 3, 3 ); innerArea.LowerRightCorner -= position2d< s32 >( 3, 3 );
GL32_draw2DRectangle(focused ? bg_color_focused : bg_color, innerArea); if(widget->m_deactivated)
GL32_draw2DRectangle(bg_color_deactivated, innerArea);
else if(focused)
GL32_draw2DRectangle(bg_color_focused, innerArea);
else
GL32_draw2DRectangle(bg_color, innerArea);
return; return;
} }
else if (type == WTYPE_LIST) else if (type == WTYPE_LIST)

View File

@ -15,9 +15,19 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config/user_config.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/widgets/model_view_widget.hpp" #include "guiengine/widgets/model_view_widget.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/post_processing.hpp"
#include "graphics/rtts.hpp"
#include <algorithm> #include <algorithm>
#include <IAnimatedMesh.h>
#include <IAnimatedMeshSceneNode.h>
#include <ICameraSceneNode.h>
#include <ILightSceneNode.h>
#include <ISceneManager.h>
using namespace GUIEngine; using namespace GUIEngine;
using namespace irr::core; using namespace irr::core;
using namespace irr::gui; using namespace irr::gui;
@ -25,7 +35,10 @@ using namespace irr::gui;
ModelViewWidget::ModelViewWidget() : ModelViewWidget::ModelViewWidget() :
IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO, false, false) IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO, false, false)
{ {
//FIXME: find nicer way than overriding what IconButtonWidget's constructor already set... m_frame_buffer = NULL;
m_rtt_main_node = NULL;
m_camera = NULL;
m_light = NULL;
m_type = WTYPE_MODEL_VIEW; m_type = WTYPE_MODEL_VIEW;
m_rtt_provider = NULL; m_rtt_provider = NULL;
m_rotation_mode = ROTATE_OFF; m_rotation_mode = ROTATE_OFF;
@ -70,10 +83,17 @@ void ModelViewWidget::clearModels()
m_model_scale.clear(); m_model_scale.clear();
m_model_frames.clear(); m_model_frames.clear();
delete m_rtt_provider; if (m_rtt_main_node != NULL) m_rtt_main_node->remove();
m_rtt_provider = NULL; if (m_light != NULL) m_light->remove();
if (m_camera != NULL) m_camera->remove();
m_rtt_main_node = NULL;
m_camera = NULL;
m_light = NULL;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void ModelViewWidget::addModel(irr::scene::IMesh* mesh, const Vec3& location, void ModelViewWidget::addModel(irr::scene::IMesh* mesh, const Vec3& location,
const Vec3& scale, const int frame) const Vec3& scale, const int frame)
{ {
@ -83,20 +103,8 @@ void ModelViewWidget::addModel(irr::scene::IMesh* mesh, const Vec3& location,
m_model_location.push_back(location); m_model_location.push_back(location);
m_model_scale.push_back(scale); m_model_scale.push_back(scale);
m_model_frames.push_back(frame); m_model_frames.push_back(frame);
/*
((IGUIMeshViewer*)m_element)->setMesh( mesh );
video::SMaterial mat = mesh->getMeshBuffer(0)->getMaterial(); //mesh_view->getMaterial();
mat.setFlag(EMF_LIGHTING , false);
//mat.setFlag(EMF_GOURAUD_SHADING, false);
//mat.setFlag(EMF_NORMALIZE_NORMALS, true);
((IGUIMeshViewer*)m_element)->setMaterial(mat);
*/
delete m_rtt_provider;
m_rtt_provider = NULL;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void ModelViewWidget::update(float delta) void ModelViewWidget::update(float delta)
{ {
@ -146,27 +154,144 @@ void ModelViewWidget::update(float delta)
if (fabsf(angle - m_rotation_target) < 2.0f) m_rotation_mode = ROTATE_OFF; if (fabsf(angle - m_rotation_target) < 2.0f) m_rotation_mode = ROTATE_OFF;
} }
if (!irr_driver->isGLSL())
return;
if (m_rtt_provider == NULL) if (m_rtt_provider == NULL)
{ {
std::string name = "model view "; std::string name = "model view ";
name += m_properties[PROP_ID].c_str(); name += m_properties[PROP_ID].c_str();
m_rtt_provider = new IrrDriver::RTTProvider(core::dimension2d< u32 >(512, 512), name, false);
m_rtt_provider->setupRTTScene(m_models, m_model_location, m_model_scale, m_model_frames); m_rtt_provider = new RTT(512, 512);
} }
m_texture = m_rtt_provider->renderToTexture(angle); if (m_rtt_main_node == NULL)
if (m_texture != NULL)
{ {
setImage(m_texture); setupRTTScene(m_models, m_model_location, m_model_scale, m_model_frames);
}
m_rtt_main_node->setRotation(core::vector3df(0.0f, angle, 0.0f));
m_rtt_main_node->setVisible(true);
irr_driver->setRTT(m_rtt_provider);
irr_driver->getSceneManager()->setActiveCamera(m_camera);
std::vector<IrrDriver::GlowData> glows;
irr_driver->computeCameraMatrix(m_camera, 512, 512);
unsigned plc = irr_driver->UpdateLightsInfo(m_camera, GUIEngine::getLatestDt());
irr_driver->renderScene(m_camera, plc, glows, GUIEngine::getLatestDt(), false, true);
m_frame_buffer = irr_driver->getPostProcessing()->render(m_camera);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
irr_driver->setRTT(NULL);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
irr_driver->getSceneManager()->setActiveCamera(NULL);
m_rtt_main_node->setVisible(false);
}
void ModelViewWidget::setupRTTScene(PtrVector<scene::IMesh, REF>& mesh,
AlignedArray<Vec3>& mesh_location,
AlignedArray<Vec3>& mesh_scale,
const std::vector<int>& model_frames)
{
irr_driver->suppressSkyBox();
if (m_rtt_main_node != NULL) m_rtt_main_node->remove();
if (m_light != NULL) m_light->remove();
if (m_camera != NULL) m_camera->remove();
m_rtt_main_node = NULL;
m_camera = NULL;
m_light = NULL;
irr_driver->clearLights();
if (model_frames[0] == -1)
{
scene::ISceneNode* node = irr_driver->addMesh(mesh.get(0), NULL);
node->setPosition(mesh_location[0].toIrrVector());
node->setScale(mesh_scale[0].toIrrVector());
node->setMaterialFlag(video::EMF_FOG_ENABLE, false);
m_rtt_main_node = node;
} }
else else
{ {
m_rtt_unsupported = true; scene::IAnimatedMeshSceneNode* node =
} irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)mesh.get(0), NULL);
//getIrrlichtElement<IGUIButton>()->setImage(m_texture); node->setPosition(mesh_location[0].toIrrVector());
//getIrrlichtElement<IGUIButton>()->setPressedImage(m_texture); node->setFrameLoop(model_frames[0], model_frames[0]);
} node->setAnimationSpeed(0);
node->setScale(mesh_scale[0].toIrrVector());
node->setMaterialFlag(video::EMF_FOG_ENABLE, false);
m_rtt_main_node = node;
}
assert(m_rtt_main_node != NULL);
assert(mesh.size() == mesh_location.size());
assert(mesh.size() == model_frames.size());
const int mesh_amount = mesh.size();
for (int n = 1; n<mesh_amount; n++)
{
if (model_frames[n] == -1)
{
scene::ISceneNode* node =
irr_driver->addMesh(mesh.get(n), m_rtt_main_node);
node->setPosition(mesh_location[n].toIrrVector());
node->updateAbsolutePosition();
node->setScale(mesh_scale[n].toIrrVector());
}
else
{
scene::IAnimatedMeshSceneNode* node =
irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)mesh.get(n),
m_rtt_main_node);
node->setPosition(mesh_location[n].toIrrVector());
node->setFrameLoop(model_frames[n], model_frames[n]);
node->setAnimationSpeed(0);
node->updateAbsolutePosition();
node->setScale(mesh_scale[n].toIrrVector());
//std::cout << "(((( set frame " << model_frames[n] << " ))))\n";
}
}
irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 35, 35, 35));
const core::vector3df &spot_pos = core::vector3df(0, 30, 40);
m_light = irr_driver->addLight(spot_pos, 0.3f /* energy */, 10 /* distance */, 1.0f /* r */, 1.0f /* g */, 1.0f /* g*/, true, NULL);
m_rtt_main_node->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);
m_rtt_main_node->setMaterialFlag(video::EMF_LIGHTING, true);
const int materials = m_rtt_main_node->getMaterialCount();
for (int n = 0; n<materials; n++)
{
m_rtt_main_node->getMaterial(n).setFlag(video::EMF_LIGHTING, true);
// set size of specular highlights
m_rtt_main_node->getMaterial(n).Shininess = 100.0f;
m_rtt_main_node->getMaterial(n).SpecularColor.set(255, 50, 50, 50);
m_rtt_main_node->getMaterial(n).DiffuseColor.set(255, 150, 150, 150);
m_rtt_main_node->getMaterial(n).setFlag(video::EMF_GOURAUD_SHADING,
true);
}
m_camera = irr_driver->getSceneManager()->addCameraSceneNode();
m_camera->setAspectRatio(1.0f);
m_camera->setPosition(core::vector3df(0.0, 20.0f, 70.0f));
if (irr_driver->isGLSL())
m_camera->setUpVector(core::vector3df(0.0, 1.0, 0.0));
else
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();
}
void ModelViewWidget::setRotateOff() void ModelViewWidget::setRotateOff()
{ {

View File

@ -52,12 +52,20 @@ namespace GUIEngine
video::ITexture* m_texture; video::ITexture* m_texture;
IrrDriver::RTTProvider* m_rtt_provider; RTT* m_rtt_provider;
float angle; float angle;
bool m_rtt_unsupported; bool m_rtt_unsupported;
scene::ISceneNode *m_rtt_main_node;
scene::ICameraSceneNode *m_camera;
scene::ISceneNode *m_light;
FrameBuffer *m_frame_buffer;
public: public:
LEAK_CHECK() LEAK_CHECK()
@ -89,6 +97,13 @@ namespace GUIEngine
bool isRotating(); bool isRotating();
void clearRttProvider(); void clearRttProvider();
void setupRTTScene(PtrVector<scene::IMesh, REF>& mesh,
AlignedArray<Vec3>& mesh_location,
AlignedArray<Vec3>& mesh_scale,
const std::vector<int>& model_frames);
FrameBuffer* getFrameBuffer() { return m_frame_buffer; }
}; };
} }

View File

@ -94,6 +94,9 @@ void TextBoxWidget::add()
(m_parent ? m_parent : GUIEngine::getGUIEnv()->getRootGUIElement()), (m_parent ? m_parent : GUIEngine::getGUIEnv()->getRootGUIElement()),
getNewID(), widget_size); getNewID(), widget_size);
if (m_deactivated)
m_element->setEnabled(false);
//m_element = GUIEngine::getGUIEnv()->addEditBox(text.c_str(), widget_size, //m_element = GUIEngine::getGUIEnv()->addEditBox(text.c_str(), widget_size,
// true /* border */, m_parent, getNewID()); // true /* border */, m_parent, getNewID());
m_id = m_element->getID(); m_id = m_element->getID();
@ -168,3 +171,33 @@ void TextBoxWidget::elementRemoved()
m_element->drop(); m_element->drop();
Widget::elementRemoved(); 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);
}
}
// -----------------------------------------------------------------------------

View File

@ -71,6 +71,12 @@ namespace GUIEngine
void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*'); void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*');
virtual void elementRemoved(); virtual void elementRemoved();
/** Override method from base class Widget */
virtual void setActivated();
/** Override method from base class Widget */
virtual void setDeactivated();
}; };
} }

View File

@ -78,7 +78,7 @@ void AbstractKart::reset()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Returns a name to be displayed for this kart. */ /** 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(); return m_kart_properties->getName();
} // getName; } // getName;

View File

@ -83,6 +83,7 @@ public:
int world_kart_id, int world_kart_id,
int position, const btTransform& init_transform); int position, const btTransform& init_transform);
virtual ~AbstractKart(); virtual ~AbstractKart();
virtual core::stringw getName() const;
virtual void reset(); virtual void reset();
virtual void init(RaceManager::KartType type) = 0; virtual void init(RaceManager::KartType type) = 0;
// ======================================================================== // ========================================================================
@ -109,8 +110,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Sets the kart properties. */ /** Sets the kart properties. */
void setKartProperties(const KartProperties *kp) { m_kart_properties=kp; } 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 /** Returns a unique identifier for this kart (name of the directory the
* kart was loaded from). */ * kart was loaded from). */

View File

@ -20,6 +20,7 @@
#include "addons/addon.hpp" #include "addons/addon.hpp"
#include "config/stk_config.hpp" #include "config/stk_config.hpp"
#include "config/player_manager.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
@ -732,6 +733,28 @@ void KartProperties::checkAllSet(const std::string &filename)
m_ai_properties[i]->checkAllSet(filename); m_ai_properties[i]->checkAllSet(filename);
} // checkAllSet } // 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 /** 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 * through m_startup_times to find the appropriate slot, and returns the

View File

@ -387,6 +387,8 @@ public:
void getAllData (const XMLNode * root); void getAllData (const XMLNode * root);
void checkAllSet (const std::string &filename); void checkAllSet (const std::string &filename);
float getStartupBoost () const; 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. /** Returns the (maximum) speed for a given turn radius.
@ -431,9 +433,9 @@ public:
/** Returns the name of this kart. /** Returns the name of this kart.
\note Pass it through fridibi as needed, this is the LTR name \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()));
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -1375,13 +1375,6 @@ int main(int argc, char *argv[] )
/* Program closing...*/ /* 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 #ifdef ENABLE_WIIUSE
if(wiimote_manager) if(wiimote_manager)
delete wiimote_manager; delete wiimote_manager;
@ -1433,27 +1426,15 @@ static void cleanSuperTuxKart()
delete main_loop; delete main_loop;
irr_driver->updateConfigIfRelevant();
if(Online::RequestManager::isRunning()) if(Online::RequestManager::isRunning())
Online::RequestManager::get()->stopNetworkThread(); Online::RequestManager::get()->stopNetworkThread();
//delete in reverse order of what they were created in. irr_driver->updateConfigIfRelevant();
//see InitTuxkart()
Online::RequestManager::deallocate();
Online::ServersManager::deallocate();
Online::ProfileManager::destroy();
GUIEngine::DialogQueue::deallocate();
AchievementsManager::destroy(); AchievementsManager::destroy();
Referee::cleanup(); Referee::cleanup();
if(ReplayPlay::get()) ReplayPlay::destroy(); if(ReplayPlay::get()) ReplayPlay::destroy();
if(race_manager) delete race_manager; if(race_manager) delete race_manager;
NewsManager::deallocate();
if(addons_manager) delete addons_manager; if(addons_manager) delete addons_manager;
NetworkManager::kill();
if(grand_prix_manager) delete grand_prix_manager; if(grand_prix_manager) delete grand_prix_manager;
if(highscore_manager) delete highscore_manager; if(highscore_manager) delete highscore_manager;
if(attachment_manager) delete attachment_manager; if(attachment_manager) delete attachment_manager;
@ -1470,6 +1451,33 @@ static void cleanSuperTuxKart()
delete ParticleKindManager::get(); delete ParticleKindManager::get();
PlayerManager::destroy(); PlayerManager::destroy();
if(unlock_manager) delete unlock_manager; 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(); cleanUserConfig();
@ -1485,7 +1493,14 @@ static void cleanUserConfig()
{ {
if(stk_config) delete stk_config; if(stk_config) delete stk_config;
if(translations) delete translations; 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(file_manager) delete file_manager;
if(irr_driver) delete irr_driver; if(irr_driver) delete irr_driver;
} }

View File

@ -29,6 +29,7 @@
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp" #include "karts/kart_properties_manager.hpp"
#include "karts/rescue_animation.hpp" #include "karts/rescue_animation.hpp"
#include "physics/btKart.hpp"
#include "physics/physics.hpp" #include "physics/physics.hpp"
#include "states_screens/dialogs/select_challenge.hpp" #include "states_screens/dialogs/select_challenge.hpp"
#include "states_screens/offline_kart_selection.hpp" #include "states_screens/offline_kart_selection.hpp"
@ -54,7 +55,6 @@ OverWorld::~OverWorld()
/** Function to simplify the start process */ /** Function to simplify the start process */
void OverWorld::enterOverWorld() void OverWorld::enterOverWorld()
{ {
race_manager->setNumLocalPlayers(1); race_manager->setNumLocalPlayers(1);
race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE); race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
race_manager->setMinorMode (RaceManager::MINOR_MODE_OVERWORLD); race_manager->setMinorMode (RaceManager::MINOR_MODE_OVERWORLD);
@ -231,6 +231,7 @@ void OverWorld::onMouseClick(int x, int y)
// be the location of the challenge bubble. // be the location of the challenge bubble.
AbstractKart* kart = getKart(0); AbstractKart* kart = getKart(0);
kart->setXYZ(challenge->m_position); kart->setXYZ(challenge->m_position);
kart->getVehicle()->capSpeed(0);
unsigned int index = getRescuePositionIndex(kart); unsigned int index = getRescuePositionIndex(kart);
btTransform s = getRescueTransform(index); btTransform s = getRescueTransform(index);

View File

@ -468,10 +468,10 @@ void ThreeStrikesBattle::getKartsDisplayInfo(
break; break;
} }
char lives[4]; std::ostringstream oss;
sprintf(lives, "%i", m_kart_info[i].m_lives); oss << m_kart_info[i].m_lives;
rank_info.m_text = lives; rank_info.m_text = oss.str().c_str();
} }
} // getKartsDisplayInfo } // getKartsDisplayInfo

View File

@ -322,7 +322,8 @@ namespace Online
// Check if we are asked to abort the download. If so, signal this // Check if we are asked to abort the download. If so, signal this
// back to libcurl by returning a non-zero status. // 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 // Indicates to abort the current download, which means that this
// thread will go back to the mainloop and handle the next request. // thread will go back to the mainloop and handle the next request.

View File

@ -240,6 +240,7 @@ namespace Online
m_player->setUserDetails(this, m_player->setUserDetails(this,
UserConfigParams::m_remember_user ? "client-quit" UserConfigParams::m_remember_user ? "client-quit"
:"disconnect"); :"disconnect");
setAbortable(false);
} // SignOutRequest } // SignOutRequest
}; // SignOutRequest }; // SignOutRequest
// ---------------------------------------------------------------- // ----------------------------------------------------------------

View File

@ -44,6 +44,7 @@ namespace Online
{ {
m_cancel.setAtomic(false); m_cancel.setAtomic(false);
m_state.setAtomic(S_PREPARING); m_state.setAtomic(S_PREPARING);
m_is_abortable.setAtomic(true);
} // Request } // Request
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -105,6 +105,12 @@ namespace Online
/** Cancel this request if it is active. */ /** Cancel this request if it is active. */
Synchronised<bool> m_cancel; 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 /** Set to though if the reply of the request is in and callbacks are
* executed */ * executed */
Synchronised<State> m_state; Synchronised<State> m_state;
@ -156,6 +162,12 @@ namespace Online
/** Returns if this request is to be canceled. */ /** Returns if this request is to be canceled. */
bool isCancelled() const { return m_cancel.getAtomic(); } 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. */ /** Sets the request state to busy. */
void setBusy() void setBusy()
{ {

View File

@ -1,7 +1,7 @@
// //
// SuperTuxKart - a fun racing game with go-kart // SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2014 Lucas Baudin // Copyright (C) 2010-2014 Lucas Baudin
// 2011-201 Joerg Henrichs // 2011-2014 Joerg Henrichs
// 2013-2014 Glenn De Jonghe // 2013-2014 Glenn De Jonghe
// //
// This program is free software; you can redistribute it and/or // This program is free software; you can redistribute it and/or
@ -83,7 +83,7 @@ namespace Online
pthread_cond_init(&m_cond_request, NULL); pthread_cond_init(&m_cond_request, NULL);
m_abort.setAtomic(false); m_abort.setAtomic(false);
m_time_since_poll = MENU_POLLING_INTERVAL * 0.9; m_time_since_poll = MENU_POLLING_INTERVAL * 0.9;
} } // RequestManager
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
RequestManager::~RequestManager() RequestManager::~RequestManager()
@ -94,8 +94,7 @@ namespace Online
m_thread_id.unlock(); m_thread_id.unlock();
pthread_cond_destroy(&m_cond_request); pthread_cond_destroy(&m_cond_request);
curl_global_cleanup(); curl_global_cleanup();
} } // ~RequestManager
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Start the actual network thread. This can not be done as part of /** Start the actual network thread. This can not be done as part of
@ -147,28 +146,26 @@ namespace Online
*/ */
void RequestManager::stopNetworkThread() void RequestManager::stopNetworkThread()
{ {
// If a download should be active (which means it was cancelled by the // This will queue a sign-out or client-quit request
// 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
PlayerManager::onSTKQuit(); PlayerManager::onSTKQuit();
addRequest(new Request(true, HTTP_MAX_PRIORITY, Request::RT_QUIT));
} // stopNetworkThread
// ------------------------------------------------------------------------ // Put in a high priortity quit request in. It has the same priority
/** Signals to the progress function to request any ongoing download to be // as a sign-out request (so the sign-out will be executed before the
* cancelled. This function can also be called if there is actually no // quit request).
* download atm. The function progressDownload checks m_abort and will Request *quit = new Request(true, HTTP_MAX_PRIORITY, Request::RT_QUIT);
* return a non-zero value which causes libcurl to abort. */ quit->setAbortable(false);
void RequestManager::cancelAllDownloads() 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); m_abort.setAtomic(true);
// FIXME doesn't get called at the moment. When using this again, } // stopNetworkThread
// be sure that HTTP_MAX_PRIORITY requests still get executed.
} // cancelAllDownloads
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Inserts a request into the queue of all requests. The request will be /** Inserts a request into the queue of all requests. The request will be
@ -222,6 +219,11 @@ namespace Online
me->m_request_queue.lock(); me->m_request_queue.lock();
} // while } // 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 // At this stage we have the lock for m_request_queue
while(!me->m_request_queue.getData().empty()) while(!me->m_request_queue.getData().empty())
{ {

View File

@ -23,6 +23,7 @@
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "online/request.hpp" #include "online/request.hpp"
#include "utils/can_be_deleted.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
#include "utils/synchronised.hpp" #include "utils/synchronised.hpp"
@ -42,11 +43,41 @@
namespace Online namespace Online
{ {
/** /** A class to execute requests in a separate thread. Typically the
* \brief Class to connect with a server over HTTP(S) * 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 * \ingroup online
*/ */
class RequestManager class RequestManager : public CanBeDeleted
{ {
public: public:
/** If stk has permission to access the internet (for news /** If stk has permission to access the internet (for news
@ -102,7 +133,6 @@ namespace Online
static bool isRunning(); static bool isRunning();
void addRequest(Online::Request *request); void addRequest(Online::Request *request);
void cancelAllDownloads();
void startNetworkThread(); void startNetworkThread();
void stopNetworkThread(); void stopNetworkThread();

View File

@ -975,8 +975,11 @@ void btKart::capSpeed(float max_speed)
{ {
const btVector3 &velocity = m_chassisBody->getLinearVelocity(); const btVector3 &velocity = m_chassisBody->getLinearVelocity();
float speed = velocity.length(); float speed = velocity.length();
const float velocity_ratio = max_speed/speed; if(speed!=0)
m_chassisBody->setLinearVelocity( velocity * velocity_ratio); {
const float velocity_ratio = max_speed / speed;
m_chassisBody->setLinearVelocity(velocity * velocity_ratio);
}
} // capSpeed } // capSpeed
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -365,7 +365,7 @@ void GrandPrixData::addTrack(Track* track, unsigned int laps, bool reverse,
int n = getNumberOfTracks(true); int n = getNumberOfTracks(true);
assert (track != NULL); assert (track != NULL);
assert (laps > 0); assert (laps > 0);
assert (-1 < position && position < n); assert (-1 <= position && position < n);
if (position < 0 || position == (n - 1) || m_tracks.empty()) if (position < 0 || position == (n - 1) || m_tracks.empty())
{ {

View File

@ -184,12 +184,16 @@ void EditTrackScreen::loadTrackList()
{ {
Track* t = track_manager->getTrack(i); Track* t = track_manager->getTrack(i);
const std::vector<std::string>& groups = t->getGroups(); const std::vector<std::string>& groups = t->getGroups();
belongsToGroup = (m_track_group.empty() || m_track_group == ALL_TRACKS_GROUP_ID || belongsToGroup = (m_track_group.empty() ||
std::find(groups.begin(), groups.end(), m_track_group) != groups.end()); m_track_group == ALL_TRACKS_GROUP_ID ||
if (!t->isArena() && !t->isSoccer() && !t->isInternal() && belongsToGroup) t->isInGroup(m_track_group) );
if (!t->isArena() && !t->isSoccer() &&
!t->isInternal() && belongsToGroup )
{ {
tracks_widget->addItem(translations->fribidize(t->getName()), t->getIdent(), tracks_widget->addItem(translations->fribidize(t->getName()),
t->getScreenshotFile(), 0, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE ); t->getIdent(),
t->getScreenshotFile(), 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
} }
} }

View File

@ -29,6 +29,7 @@
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp" #include "karts/kart_properties_manager.hpp"
#include "modes/cutscene_world.hpp"
#include "modes/overworld.hpp" #include "modes/overworld.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "race/grand_prix_manager.hpp" #include "race/grand_prix_manager.hpp"
@ -50,6 +51,10 @@ using namespace irr::core;
using namespace irr::gui; using namespace irr::gui;
using namespace irr::video; 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 ); DEFINE_SCREEN_SINGLETON( FeatureUnlockedCutScene );
@ -66,6 +71,7 @@ FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(std::string model,
m_unlock_message = msg; m_unlock_message = msg;
m_unlock_model = model; m_unlock_model = model;
m_curr_image = -1; m_curr_image = -1;
m_scale = 1.0f;
} }
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
@ -77,6 +83,7 @@ FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(KartProperties* kart,
m_unlocked_kart = kart; m_unlocked_kart = kart;
m_unlock_message = msg; m_unlock_message = msg;
m_curr_image = -1; m_curr_image = -1;
m_scale = 1.0f;
} // UnlockedThing::UnlockedThing } // UnlockedThing::UnlockedThing
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
@ -91,6 +98,7 @@ FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(irr::video::ITexture* pict
m_h = h; m_h = h;
m_unlock_message = msg; m_unlock_message = msg;
m_curr_image = -1; m_curr_image = -1;
m_scale = 1.0f;
} // UnlockedThing::UnlockedThing } // UnlockedThing::UnlockedThing
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -105,6 +113,7 @@ FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(std::vector<irr::video::IT
m_h = h; m_h = h;
m_unlock_message = msg; m_unlock_message = msg;
m_curr_image = 0; m_curr_image = 0;
m_scale = 1.0f;
} // UnlockedThing::UnlockedThing } // UnlockedThing::UnlockedThing
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -123,12 +132,10 @@ FeatureUnlockedCutScene::UnlockedThing::~UnlockedThing()
#endif #endif
FeatureUnlockedCutScene::FeatureUnlockedCutScene() FeatureUnlockedCutScene::FeatureUnlockedCutScene()
: Screen("feature_unlocked.stkgui") : CutsceneScreen("feature_unlocked.stkgui")
{ {
m_key_angle = 0; m_key_angle = 0;
setNeeds3D(true);
m_throttle_FPS = false;
#ifdef USE_IRRLICHT_BUG_WORKAROUND #ifdef USE_IRRLICHT_BUG_WORKAROUND
m_avoid_irrlicht_bug = NULL; m_avoid_irrlicht_bug = NULL;
#endif #endif
@ -140,6 +147,23 @@ void FeatureUnlockedCutScene::loadedFromFile()
{ {
} // 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) 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() void FeatureUnlockedCutScene::init()
{ {
m_sky_angle = 0.0f;
m_global_time = 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(); const int unlockedStuffCount = m_unlocked_stuff.size();
if (unlockedStuffCount == 0) std::cerr << "There is nothing in the unlock chest!!!\n"; 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) 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 = 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) 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_unlocked_stuff[n].m_unlocked_kart->getKartModelCopy();
m_all_kart_models.push_back(kart_model); 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_root_gift_node = kart_model->attachModel(true, false);
m_unlocked_stuff[n].m_scale = 5.0f;
kart_model->setAnimation(KartModel::AF_DEFAULT); kart_model->setAnimation(KartModel::AF_DEFAULT);
float susp[4]={0,0,0,0}; float susp[4]={0,0,0,0};
kart_model->update(0.0f, 0.0f, 0.0f, susp, 0.0f); 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.SpecularColor = video::SColor(255, 255, 255, 255);
m.GouraudShading = false; m.GouraudShading = false;
m.Shininess = 0; m.Shininess = 0;
//m.setFlag(video::EMF_TEXTURE_WRAP, false);
m.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; m.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
m.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; m.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
@ -389,29 +353,7 @@ void FeatureUnlockedCutScene::init()
void FeatureUnlockedCutScene::tearDown() void FeatureUnlockedCutScene::tearDown()
{ {
Screen::tearDown(); Screen::tearDown();
irr_driver->removeNode(m_sky); ((CutsceneWorld*)World::getWorld())->abortCutscene();
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();
} // tearDown } // 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) void FeatureUnlockedCutScene::onUpdate(float dt)
{ {
m_global_time += 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(); const int unlockedStuffCount = m_unlocked_stuff.size();
if (m_global_time > GIFT_EXIT_FROM && m_global_time < GIFT_EXIT_TO) 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++) for (int n=0; n<unlockedStuffCount; n++)
{ {
if (m_unlocked_stuff[n].m_root_gift_node == NULL) continue; if (m_unlocked_stuff[n].m_root_gift_node == NULL) continue;
core::vector3df pos = m_unlocked_stuff[n].m_root_gift_node->getPosition(); 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 // when there are more than 1 unlocked items, make sure they each
// have their own path when they move // have their own path when they move
if (unlockedStuffCount > 1) if (unlockedStuffCount > 1)
{ {
if (n == 1) pos.X -= 6.2f*dt*float( int((n + 1)/2) ); if (n == 1) pos.X -= 1.0f*dt*float( int((n + 1)/2) );
else if (n > 1) pos.X += 6.2f*dt*(n - 1.0f); else if (n > 1) pos.X += 1.0f*dt*(n - 0.3f);
//else pos.X += 6.2f*dt*float( int((n + 1)/2) ); //else pos.X += 6.2f*dt*float( int((n + 1)/2) );
//std::cout << "Object " << n << " moving by " << //std::cout << "Object " << n << " moving by " <<
@ -493,30 +404,15 @@ void FeatureUnlockedCutScene::onUpdate(float dt)
//pos.X -= 2.0f*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); 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) 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++) for (int n=0; n<unlockedStuffCount; n++)
@ -554,20 +450,16 @@ void FeatureUnlockedCutScene::onUpdate(float dt)
} // textureID != previousTextureID } // textureID != previousTextureID
} // if pictureCount>1 } // if pictureCount>1
} // if !m_unlocked_stuff[n].m_pictures.empty() } // 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 } // for n<unlockedStuffCount
assert(m_unlocked_stuff.size() > 0); 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 w = irr_driver->getFrameSize().Width;
static const int h = irr_driver->getFrameSize().Height; static const int h = irr_driver->getFrameSize().Height;
@ -654,6 +546,7 @@ void FeatureUnlockedCutScene::addUnlockedGP(const GrandPrixData* gp)
bool FeatureUnlockedCutScene::onEscapePressed() bool FeatureUnlockedCutScene::onEscapePressed()
{ {
((CutsceneWorld*)World::getWorld())->abortCutscene();
continueButtonPressed(); continueButtonPressed();
return false; // continueButtonPressed already pop'ed the menu return false; // continueButtonPressed already pop'ed the menu
} // onEscapePressed } // onEscapePressed

View File

@ -36,7 +36,7 @@ class ChallengeData;
* \brief Screen shown when a feature has been unlocked * \brief Screen shown when a feature has been unlocked
* \ingroup states_screens * \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>; friend class GUIEngine::ScreenSingleton<FeatureUnlockedCutScene>;
@ -60,6 +60,8 @@ class FeatureUnlockedCutScene : public GUIEngine::Screen, public GUIEngine::Scre
/** Contains whatever is in the chest */ /** Contains whatever is in the chest */
scene::ISceneNode* m_root_gift_node; scene::ISceneNode* m_root_gift_node;
float m_scale;
irr::core::stringw m_unlock_message; irr::core::stringw m_unlock_message;
UnlockedThing(std::string model, irr::core::stringw msg); 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. */ /** To store the copy of the KartModel for each unlocked kart. */
PtrVector<KartModel> m_all_kart_models; PtrVector<KartModel> m_all_kart_models;
/** sky angle, 0-360 */
float m_sky_angle;
/** Global evolution of time */ /** Global evolution of time */
double m_global_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) */ /** Angle of the key (from 0 to 1, simply traces progression) */
float m_key_angle; 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 #ifdef USE_IRRLICHT_BUG_WORKAROUND
scene::IMeshSceneNode *m_avoid_irrlicht_bug; scene::IMeshSceneNode *m_avoid_irrlicht_bug;
#endif #endif
@ -125,6 +110,8 @@ class FeatureUnlockedCutScene : public GUIEngine::Screen, public GUIEngine::Scre
public: public:
virtual void onCutsceneEnd() OVERRIDE;
/** \brief implement optional callback from parent class GUIEngine::Screen */ /** \brief implement optional callback from parent class GUIEngine::Screen */
void onUpdate(float dt) OVERRIDE; void onUpdate(float dt) OVERRIDE;

View File

@ -321,8 +321,15 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
const KartModel &kart_model = props->getMasterKartModel(); const KartModel &kart_model = props->getMasterKartModel();
float scale = 35.0f;
if (kart_model.getLength() > 1.45f)
{
// if kart is too long, size it down a bit so that it fits
scale = 30.0f;
}
m_model_view->addModel( kart_model.getModel(), Vec3(0,0,0), m_model_view->addModel( kart_model.getModel(), Vec3(0,0,0),
Vec3(35.0f, 35.0f, 35.0f), Vec3(scale, scale, scale),
kart_model.getBaseFrame() ); kart_model.getBaseFrame() );
m_model_view->addModel( kart_model.getWheelModel(0), m_model_view->addModel( kart_model.getWheelModel(0),
kart_model.getWheelGraphicsPosition(0) ); kart_model.getWheelGraphicsPosition(0) );
@ -675,10 +682,9 @@ void PlayerKartWidget::onUpdate(float delta)
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** Event callback */ /** Event callback */
GUIEngine::EventPropagation PlayerKartWidget::transmitEvent( GUIEngine::EventPropagation PlayerKartWidget::transmitEvent(Widget* w,
Widget* w,
const std::string& originator, const std::string& originator,
const int m_player_id) const int m_player_id )
{ {
assert(m_magic_number == 0x33445566); assert(m_magic_number == 0x33445566);
// if it's declared ready, there is really nothing to process // if it's declared ready, there is really nothing to process
@ -1050,7 +1056,7 @@ void KartSelectionScreen::tearDown()
m_kart_widgets.clearAndDeleteAll(); m_kart_widgets.clearAndDeleteAll();
if (m_must_delete_on_back) if (m_must_delete_on_back)
GUIEngine::removeScreen(this->getName().c_str()); GUIEngine::removeScreen(getName().c_str());
} // tearDown } // tearDown
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -1462,6 +1468,7 @@ void KartSelectionScreen::updateKartWidgetModel(uint8_t widget_id,
// Random kart // Random kart
scene::IMesh* model = scene::IMesh* model =
ItemManager::getItemModel(Item::ITEM_BONUS_BOX); ItemManager::getItemModel(Item::ITEM_BONUS_BOX);
w3->clearModels(); w3->clearModels();
w3->addModel( model, Vec3(0.0f, -12.0f, 0.0f), w3->addModel( model, Vec3(0.0f, -12.0f, 0.0f),
Vec3(35.0f, 35.0f, 35.0f) ); Vec3(35.0f, 35.0f, 35.0f) );
@ -1498,9 +1505,16 @@ void KartSelectionScreen::updateKartWidgetModel(uint8_t widget_id,
{ {
const KartModel &kart_model = kp->getMasterKartModel(); const KartModel &kart_model = kp->getMasterKartModel();
float scale = 35.0f;
if (kart_model.getLength() > 1.45f)
{
// if kart is too long, size it down a bit so that it fits
scale = 30.0f;
}
w3->clearModels(); w3->clearModels();
w3->addModel( kart_model.getModel(), Vec3(0,0,0), w3->addModel( kart_model.getModel(), Vec3(0,0,0),
Vec3(35.0f, 35.0f, 35.0f), Vec3(scale, scale, scale),
kart_model.getBaseFrame() ); kart_model.getBaseFrame() );
w3->addModel( kart_model.getWheelModel(0), w3->addModel( kart_model.getWheelModel(0),
kart_model.getWheelGraphicsPosition(0) ); kart_model.getWheelGraphicsPosition(0) );
@ -1542,7 +1556,7 @@ void KartSelectionScreen::eventCallback(Widget* widget,
setKartsFromCurrentGroup(); setKartsFromCurrentGroup();
const std::string selected_kart_group = const std::string &selected_kart_group =
tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER); tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER);
UserConfigParams::m_last_used_kart_group = selected_kart_group; UserConfigParams::m_last_used_kart_group = selected_kart_group;
@ -2000,22 +2014,28 @@ void KartSelectionScreen::setKartsFromCurrentGroup()
DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts"); DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts");
w->clearItems(); 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(); 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);
}
karts.insertionSort();
for (int n=0; n<kart_amount; n++) for(unsigned int i=0; i<karts.size(); i++)
{ {
const KartProperties* prop = const KartProperties* prop = karts.get(i);
kart_properties_manager->getKartById(n);
if (PlayerManager::getCurrentPlayer()->isLocked(prop->getIdent())) if (PlayerManager::getCurrentPlayer()->isLocked(prop->getIdent()))
{ {
w->addItem( w->addItem(_("Locked : solve active challenges to gain access "
_("Locked : solve active challenges to gain access "
"to more!"), "to more!"),
ID_LOCKED+prop->getIdent(), ID_LOCKED + prop->getIdent(),
prop->getAbsoluteIconFile(), LOCKED_BADGE, prop->getAbsoluteIconFile(), LOCKED_BADGE,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
} }
@ -2025,44 +2045,12 @@ void KartSelectionScreen::setKartsFromCurrentGroup()
prop->getIdent(), prop->getIdent(),
prop->getAbsoluteIconFile(), 0, prop->getAbsoluteIconFile(), 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
usableKartCount++; usable_kart_count++;
}
}
}
else if (selected_kart_group != RibbonWidget::NO_ITEM_ID)
{
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 =
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++;
}
} }
} }
// add random // add random
if (usableKartCount > 1) if (usable_kart_count > 1)
{ {
w->addItem(_("Random Kart"), RANDOM_KART_ID, "/gui/random_kart.png"); w->addItem(_("Random Kart"), RANDOM_KART_ID, "/gui/random_kart.png");
} }

View File

@ -717,10 +717,10 @@ void RaceGUI::drawSpeedAndEnergy(const AbstractKart* kart,
font = GUIEngine::getSmallFont(); font = GUIEngine::getSmallFont();
static video::SColor color = video::SColor(255, 255, 255, 255); static video::SColor color = video::SColor(255, 255, 255, 255);
char str[256]; std::ostringstream oss;
sprintf(str, "%d", (int)(speed*10)); oss << (int)(speed*10);
font->draw(core::stringw(str).c_str(), pos, color); font->draw(oss.str().c_str(), pos, color);
} }

View File

@ -18,6 +18,7 @@
#include "states_screens/register_screen.hpp" #include "states_screens/register_screen.hpp"
#include "config/player_manager.hpp" #include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "audio/sfx_manager.hpp" #include "audio/sfx_manager.hpp"
#include "guiengine/widgets/check_box_widget.hpp" #include "guiengine/widgets/check_box_widget.hpp"
#include "guiengine/widgets/label_widget.hpp" #include "guiengine/widgets/label_widget.hpp"
@ -78,12 +79,27 @@ void RegisterScreen::init()
m_info_widget = getWidget<LabelWidget>("info"); m_info_widget = getWidget<LabelWidget>("info");
assert(m_info_widget); assert(m_info_widget);
m_info_widget->setDefaultColor();
m_info_widget->setText("", false);
m_options_widget = getWidget<RibbonWidget>("options"); m_options_widget = getWidget<RibbonWidget>("options");
assert(m_options_widget); assert(m_options_widget);
m_signup_request = NULL; m_signup_request = NULL;
m_info_message_shown = false; m_info_message_shown = false;
getWidget<CheckBoxWidget>("online")->setVisible(true);
getWidget<LabelWidget>("label_online")->setVisible(true);
// Check if online is allowed
if (UserConfigParams::m_internet_status != Online::RequestManager::IPERM_NOT_ALLOWED)
{
getWidget<CheckBoxWidget>("online")->setState(true);
makeEntryFieldsVisible(true); makeEntryFieldsVisible(true);
}
else
{
getWidget<CheckBoxWidget>("online")->setState(false);
makeEntryFieldsVisible(false);
}
} // init } // init
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -303,6 +319,13 @@ void RegisterScreen::eventCallback(Widget* widget, const std::string& name,
{ {
if (name == "online") if (name == "online")
{ {
if (UserConfigParams::m_internet_status == Online::RequestManager::IPERM_NOT_ALLOWED)
{
m_info_widget->setErrorColor();
m_info_widget->setText(_("Internet access is disabled, please enable it in the options"), false);
getWidget<CheckBoxWidget>("online")->setState(false);
}
else
makeEntryFieldsVisible(getWidget<CheckBoxWidget>("online")->getState()); makeEntryFieldsVisible(getWidget<CheckBoxWidget>("online")->getState());
} }
else if (name=="options") else if (name=="options")

View File

@ -74,7 +74,7 @@ void BaseUserScreen::init()
assert(m_info_widget); assert(m_info_widget);
getWidget<CheckBoxWidget>("remember-user") getWidget<CheckBoxWidget>("remember-user")
->setState(UserConfigParams::m_always_show_login_screen); ->setState(UserConfigParams::m_remember_user);
m_sign_out_name = ""; m_sign_out_name = "";
m_sign_in_name = ""; m_sign_in_name = "";
@ -115,6 +115,12 @@ void BaseUserScreen::init()
m_online_cb->setState(player->wasOnlineLastTime() || m_online_cb->setState(player->wasOnlineLastTime() ||
player->isLoggedIn() ); player->isLoggedIn() );
makeEntryFieldsVisible(); makeEntryFieldsVisible();
// We have to deactivate after make visible (since make visible
// automatically activates widgets).
if(online_name.size()>0)
m_username_tb->setDeactivated();
else
m_username_tb->setActivated();
} }
else // no current player found else // no current player found
{ {
@ -247,7 +253,7 @@ void BaseUserScreen::eventCallback(Widget* widget,
Online::RequestManager::IPERM_NOT_ALLOWED) Online::RequestManager::IPERM_NOT_ALLOWED)
{ {
m_info_widget->setText( m_info_widget->setText(
"Internet access is disabled, please enable it in the options", _("Internet access is disabled, please enable it in the options"),
true); true);
sfx_manager->quickSound( "anvil" ); sfx_manager->quickSound( "anvil" );
m_online_cb->setState(false); m_online_cb->setState(false);
@ -444,6 +450,7 @@ void BaseUserScreen::loginError(const irr::core::stringw & error_message)
// which allows the player to enter a new password. // which allows the player to enter a new password.
if(player && player->hasSavedSession()) if(player && player->hasSavedSession())
player->clearSession(); player->clearSession();
player->setLastOnlineName("");
makeEntryFieldsVisible(); makeEntryFieldsVisible();
sfx_manager->quickSound("anvil"); sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor(); m_info_widget->setErrorColor();

View File

@ -209,11 +209,8 @@ core::stringw Track::getSortName() const
*/ */
bool Track::isInGroup(const std::string &group_name) bool Track::isInGroup(const std::string &group_name)
{ {
for(unsigned int i=0; i<m_groups.size(); i++) return std::find(m_groups.begin(), m_groups.end(), group_name)
{ != m_groups.end();
if(m_groups[i]==group_name) return true;
}
return false;
} // isInGroup } // isInGroup
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -433,9 +433,7 @@ public:
void itemCommand(const XMLNode *node); void itemCommand(const XMLNode *node);
core::stringw getName() const; core::stringw getName() const;
core::stringw getSortName() const; core::stringw getSortName() const;
// ------------------------------------------------------------------------
bool isInGroup(const std::string &group_name); bool isInGroup(const std::string &group_name);
// ------------------------------------------------------------------------
const core::vector3df& getSunRotation(); const core::vector3df& getSunRotation();
/** Sets the current ambient color for a kart with index k. */ /** Sets the current ambient color for a kart with index k. */
void setAmbientColor(const video::SColor &color, void setAmbientColor(const video::SColor &color,

79
src/utils/can_be_deleted.hpp Executable file
View 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

View File

@ -393,7 +393,11 @@ void Profiler::draw()
{ {
"Solid Pass 1", "Solid Pass 1",
"Shadows", "Shadows",
"Lights", "RH",
"GI",
"Env Map",
"SunLight",
"PointLights",
"SSAO", "SSAO",
"Solid Pass 2", "Solid Pass 2",
"Transparent", "Transparent",

View File

@ -6,7 +6,7 @@ cd data/gui
l="" l=""
for i in $(find . -iname "*.stkgui"); do for i in $(find . -iname "*.stkgui"); do
s=$(basename $i) s=$(basename $i)
x=$(find ../../src/states_screens -exec grep -H $s \{} \; | wc -l) x=$(find ../../src/states_screens -type f -exec grep -H $s \{} \; | wc -l)
echo -n "." echo -n "."
if [ $x == "0" ]; then if [ $x == "0" ]; then
l="$l $i" l="$l $i"

View File

@ -39,7 +39,9 @@ def main():
if statistics: if statistics:
lines_total += len(lines) lines_total += len(lines)
modified = False
for i in range(len(lines)): for i in range(len(lines)):
oldLine = lines[i]
# replacing tabs with four spaces # replacing tabs with four spaces
lines[i] = lines[i].replace("\t", " ") lines[i] = lines[i].replace("\t", " ")
@ -48,9 +50,12 @@ def main():
if statistics: if statistics:
if lines[i].lstrip().startswith("//"): if lines[i].lstrip().startswith("//"):
lines_code += 1 lines_code += 1
if not modified and oldLine != lines[i]:
modified = True
src_file.close() src_file.close()
# writing back # writing back
if modified:
src_file = open(dirpath + "/" + filename, "w") src_file = open(dirpath + "/" + filename, "w")
src_file.write("".join(lines)) src_file.write("".join(lines))
src_file.close() src_file.close()