Merge remote branch 'origin/master' into new_login

This commit is contained in:
hiker 2014-05-14 14:06:06 +10:00
commit d9daf928e5
55 changed files with 1303 additions and 597 deletions

View File

@ -17,6 +17,7 @@ option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
if(UNIX)
option(USE_CPP2011 "Activate C++ 2011 mode (GCC only)" OFF)
option(USE_XRANDR "Use xrandr instead of vidmode" OFF)
endif()
if(MSVC)
# Normally hide the option to build wiiuse on VS, since it depends
@ -117,6 +118,11 @@ if(USE_FRIBIDI)
endif()
endif()
# Xrandr
if(UNIX AND USE_XRANDR)
find_package(Xrandr REQUIRED)
endif()
if(UNIX)
if(USE_CPP2011)
add_definitions("-std=c++0x")
@ -278,6 +284,11 @@ if(USE_WIIUSE)
endif()
# Xrandr
if(UNIX AND USE_XRANDR)
target_link_libraries(supertuxkart ${XRANDR_LIBRARIES})
endif()
if(MSVC)
target_link_libraries(supertuxkart iphlpapi.lib)
add_custom_command(TARGET supertuxkart POST_BUILD

18
cmake/FindXrandr.cmake Normal file
View File

@ -0,0 +1,18 @@
find_path(XRANDR_INCLUDE_DIR NAMES X11/extensions/Xrandr.h
PATH_SUFFIXES X11/extensions
DOC "The XRANDR include directory"
)
find_library(XRANDR_LIBRARY NAMES Xrandr
DOC "The XRANDR library"
)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(XRANDR DEFAULT_MSG XRANDR_LIBRARY XRANDR_INCLUDE_DIR)
if(XRANDR_FOUND)
set( XRANDR_LIBRARIES ${XRANDR_LIBRARY} )
set( XRANDR_INCLUDE_DIRS ${XRANDR_INCLUDE_DIR} )
endif()
mark_as_advanced(XRANDR_INCLUDE_DIR XRANDR_LIBRARY)

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<particles emitter="point">
<particles emitter="box" box_x="12.0" box_y="0.5" box_z="12.0">
<spreading angle="24" />
@ -10,21 +10,23 @@
<material file="waterparticles.png" />
<!-- Amount of particles emitted per second -->
<rate min="10"
max="30" />
<rate min="5"
max="20" />
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
<lifetime min="500"
max="1000" />
<lifetime min="1000"
max="4000" />
<!-- Size of the particles -->
<size min="0.6"
max="6.2" />
<size min="5.0"
max="10.0"
x-increase-factor="2.6"
y-increase-factor="2.6" />
<color min="255 255 255"
max="255 255 255" />
<fadeout time="300" />
<fadeout time="5000" />
</particles>

View File

@ -131,6 +131,25 @@
<label text="Depth of field" I18N="Video settings"/>
</div>
</div>
<spacer height="4" width="10" />
<div layout="horizontal-row" width="100%" height="fit">
<div layout="horizontal-row" proportion="1" height="fit">
<checkbox id="hd-textures"/>
<spacer width="10" height="10"/>
<label text="Use high definition textures" I18N="Video settings"/>
</div>
<spacer height="4" width="10" />
<!--
<div layout="horizontal-row" proportion="1" height="fit">
<checkbox id="anim_gfx"/>
<spacer width="10" height="10"/>
<label text="Animated Scenery" I18N="Video settings"/>
</div>
-->
</div>
<spacer height="20" width="10" />

View File

@ -12,5 +12,5 @@ varying vec2 uv;
void main(void)
{
vec4 color = texture(tex, uv);
FragColor = vec4(color.rgb * color.a, color.a);
FragColor = vec4(color.rgb, color.a);
}

View File

@ -21,62 +21,58 @@ void main()
vec2 offset = 10. / screen;
vec4 col = texture2D(tex, uv);
vec4 col = texture(tex, uv);
vec4 colOriginal = col;
// Weight from here http://artmartinsh.blogspot.fr/2010/02/glsl-lens-blur-filter-with-bokeh.html
col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.15, 0.37) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.29,0.29) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.37,0.15) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.37, -0.15) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.15, -0.37) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.15, 0.37) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.37, 0.15) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.37, -0.15) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.15, -0.37) * offset) * blur);
col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur);
col += texture(tex, uv + (vec2(0.15, 0.37) * offset) * blur);
col += texture(tex, uv + (vec2(0.29,0.29) * offset) * blur);
col += texture(tex, uv + (vec2(-0.37,0.15) * offset) * blur);
col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur);
col += texture(tex, uv + (vec2(0.37, -0.15) * offset) * blur);
col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur);
col += texture(tex, uv + (vec2(-0.15, -0.37) * offset) * blur);
col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur);
col += texture(tex, uv + (vec2(-0.15, 0.37) * offset) * blur);
col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur);
col += texture(tex, uv + (vec2(0.37, 0.15) * offset) * blur);
col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur);
col += texture(tex, uv + (vec2(-0.37, -0.15) * offset) * blur);
col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur);
col += texture(tex, uv + (vec2(0.15, -0.37) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.15, 0.37) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(-0.37, 0.15) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(0.37, -0.15) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(-0.15, -0.37) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(-0.15, 0.37) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(0.37, 0.15) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(-0.37, -0.15) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(0.15, -0.37) * offset) * blur * 0.9);
col += texture(tex, uv + (vec2(0.15, 0.37) * offset) * blur * 0.9);
col += texture(tex, uv + (vec2(-0.37, 0.15) * offset) * blur * 0.9);
col += texture(tex, uv + (vec2(0.37, -0.15) * offset) * blur * 0.9);
col += texture(tex, uv + (vec2(-0.15, -0.37) * offset) * blur * 0.9);
col += texture(tex, uv + (vec2(-0.15, 0.37) * offset) * blur * 0.9);
col += texture(tex, uv + (vec2(0.37, 0.15) * offset) * blur * 0.9);
col += texture(tex, uv + (vec2(-0.37, -0.15) * offset) * blur * 0.9);
col += texture(tex, uv + (vec2(0.15, -0.37) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur *0.7);
col += texture(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.7);
col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.7);
col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.7);
col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.7);
col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.7);
col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.7);
col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.7);
col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur *0.7);
col += texture2D(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur * 0.4);
col += texture(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.4);
col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.4);
col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.4);
col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.4);
col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.4);
col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.4);
col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.4);
col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur * 0.4);
col = vec4(col.rgb / 41.0, col.a);
depth = clamp((FragPos.z/280), 0., 1.);
depth = (1 - depth);
vec3 final = colOriginal.rgb * depth + col.rgb * (1 - depth);
/*
FragColor.xyz = vec3(depth);
FragColor.a = 1.0;
*/
FragColor = vec4(final, 1.);
}

View File

@ -0,0 +1,31 @@
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
uniform sampler2D tex;
uniform vec2 pixel;
uniform float sigma = 5.;
in vec2 uv;
out vec4 FragColor;
void main()
{
float X = uv.x;
float Y = uv.y;
float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma));
g2 = g1 * g1;
vec4 sum = texture(tex, vec2(X, Y)) * g0;
g0 *= g1;
g1 *= g2;
for (int i = 1; i < 9; i++) {
sum += texture(tex, vec2(X - i * pixel.x, Y)) * g0;
sum += texture(tex, vec2(X + i * pixel.x, Y)) * g0;
g0 *= g1;
g1 *= g2;
}
FragColor = sum;
}

View File

@ -0,0 +1,32 @@
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
uniform sampler2D tex;
uniform vec2 pixel;
uniform float sigma = 5.;
in vec2 uv;
out vec4 FragColor;
void main()
{
float X = uv.x;
float Y = uv.y;
float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma));
g2 = g1 * g1;
vec4 sum = texture(tex, vec2(X, Y)) * g0;
g0 *= g1;
g1 *= g2;
for (int i = 1; i < 9; i++) {
sum += texture(tex, vec2(X, Y - i * pixel.y)) * g0;
sum += texture(tex, vec2(X, Y + i * pixel.y)) * g0;
g0 *= g1;
g1 *= g2;
}
FragColor = sum;
}

View File

@ -0,0 +1,13 @@
uniform sampler2D tex;
uniform float zn;
uniform float zf;
in vec2 uv;
out float Depth;
void main()
{
float d = texture(tex, uv).x;
float c0 = zn * zf, c1 = zn - zf, c2 = zf;
Depth = c0 / (d * c1 + c2);
}

View File

@ -20,6 +20,5 @@ void main(void)
EnvPos /= EnvPos.w;
float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
vec4 color = texture(tex, tc) * vec4(pc, 1.0);
color.a *= alpha * smoothstep(1., 0.8, lf);
FragColor = vec4(color.rgb * color.a, color.a);
FragColor = color * alpha * smoothstep(1., 0.8, lf);
}

View File

@ -22,6 +22,7 @@ layout (std140) uniform MatrixesData
flat in vec3 center;
flat in float energy;
flat in vec3 col;
flat in float radius;
out vec4 Diffuse;
out vec4 Specular;
@ -46,8 +47,7 @@ void main()
vec3 light_col = col.xyz;
float d = distance(light_pos, xpos.xyz);
float att = energy * 20. / (1. + d * d);
float max_d = 5. * energy;
att *= (max_d - d) / max_d;
att *= (radius - d) / radius;
if (att <= 0.) discard;
// Light Direction

View File

@ -17,10 +17,12 @@ layout (std140) uniform MatrixesData
in vec3 Position;
in float Energy;
in vec3 Color;
in float Radius;
flat out vec3 center;
flat out float energy;
flat out vec3 col;
flat out float radius;
const float zNear = 1.;
@ -86,12 +88,11 @@ vec4 ComputeClipRegion(vec3 lightPosView, float lightRadius)
void main(void)
{
float radius = 5. * Energy;
vec4 Center = ViewMatrix * vec4(Position, 1.);
Center /= Center.w;
vec2 ProjectedCornerPosition;
vec4 clip = ComputeClipRegion(Center.xyz, radius);
vec4 clip = ComputeClipRegion(Center.xyz, Radius);
switch (gl_VertexID)
{
case 0:
@ -110,7 +111,7 @@ void main(void)
// Work out nearest depth for quad Z
// Clamp to near plane in case this light intersects the near plane... don't want our quad to be clipped
float quadDepth = max(zNear, Center.z - radius);
float quadDepth = max(zNear, Center.z - Radius);
// Project quad depth into clip space
vec4 quadClip = ProjectionMatrix * vec4(0., 0., quadDepth, 1.0f);
@ -119,4 +120,5 @@ void main(void)
col = Color;
center = Position;
energy = Energy;
radius = Radius;
}

View File

@ -1,78 +1,80 @@
uniform sampler2D ntex;
uniform sampler2D dtex;
uniform sampler2D noise_texture;
uniform vec4 samplePoints[16];
#ifdef UBO_DISABLED
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 InverseViewMatrix;
uniform mat4 InverseProjectionMatrix;
#else
layout (std140) uniform MatrixesData
{
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
};
#endif
in vec2 uv;
out float AO;
const float strengh = 5.;
const float radius = 1.f;
#define SAMPLES 16
const float invSamples = strengh / SAMPLES;
vec3 rand(vec2 co)
{
float noiseX = clamp(fract(sin(dot(co ,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0;
float noiseY = clamp(fract(sin(dot(co ,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0;
return vec3(noiseX, noiseY, length(texture(noise_texture, co * pow(3.14159265359, 2.)).xyz));
}
vec3 DecodeNormal(vec2 n);
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
void main(void)
{
vec4 cur = texture(ntex, uv);
float curdepth = texture(dtex, uv).x;
vec4 FragPos = getPosFromUVDepth(vec3(uv, curdepth), InverseProjectionMatrix);
// get the normal of current fragment
vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
// Workaround for nvidia and skyboxes
float len = dot(vec3(1.0), abs(cur.xyz));
if (len < 0.2 || curdepth > 0.9955) discard;
// Make a tangent as random as possible
vec3 randvect = rand(uv);
vec3 tangent = normalize(cross(norm, randvect));
vec3 bitangent = cross(norm, tangent);
float bl = 0.0;
for(int i = 0; i < SAMPLES; ++i) {
vec3 sampleDir = samplePoints[i].x * tangent + samplePoints[i].y * bitangent + samplePoints[i].z * norm;
sampleDir *= samplePoints[i].w;
vec4 samplePos = FragPos + radius * vec4(sampleDir, 0.0);
vec4 sampleProj = ProjectionMatrix * samplePos;
sampleProj /= sampleProj.w;
bool isInsideTexture = (sampleProj.x > -1.) && (sampleProj.x < 1.) && (sampleProj.y > -1.) && (sampleProj.y < 1.);
// get the depth of the occluder fragment
float occluderFragmentDepth = texture(dtex, (sampleProj.xy * 0.5) + 0.5).x;
// Position of the occluder fragment in worldSpace
vec4 occluderPos = getPosFromUVDepth(vec3((sampleProj.xy * 0.5) + 0.5, occluderFragmentDepth), InverseProjectionMatrix);
bool isOccluded = isInsideTexture && (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius);
bl += isOccluded ? samplePoints[i].z * smoothstep(5 * radius, 0, distance(samplePos, FragPos)) : 0.;
}
AO = max(1.0 - bl * invSamples, 0.);
}
// From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/
// and improvements here http://graphics.cs.williams.edu/papers/SAOHPG12/
uniform sampler2D dtex;
uniform vec4 samplePoints[16];
uniform vec2 screen;
#ifdef UBO_DISABLED
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 InverseViewMatrix;
uniform mat4 InverseProjectionMatrix;
#else
layout (std140) uniform MatrixesData
{
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
};
#endif
in vec2 uv;
out float AO;
const float sigma = 1.;
const float tau = 7.;
const float beta = 0.001;
const float epsilon = .00001;
const float radius = 1.;
const float k = 1.5;
#define SAMPLES 16
const float invSamples = 1. / SAMPLES;
vec3 getXcYcZc(int x, int y, float zC)
{
// We use perspective symetric projection matrix hence P(0,2) = P(1, 2) = 0
float xC= (1. - 2 * (float(x) + 0.5) / screen.x) * zC / ProjectionMatrix[0][0];
float yC= (1. + 2 * (float(y) + 0.5) / screen.y) * zC / ProjectionMatrix[1][1];
return vec3(xC, yC, zC);
}
void main(void)
{
float lineardepth = textureLod(dtex, uv, 0.).x;
int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y);
vec3 FragPos = getXcYcZc(x, y, lineardepth);
// get the normal of current fragment
vec3 ddx = dFdx(FragPos);
vec3 ddy = dFdy(FragPos);
vec3 norm = -normalize(cross(ddy, ddx));
float r = radius / FragPos.z;
float phi = 30. * (x ^ y) + 10. * x * y;
float bl = 0.0;
for(int i = 0; i < SAMPLES; ++i) {
float alpha = (i + .5) * invSamples;
float theta = 2. * 3.14 * tau * alpha + phi;
float h = r * alpha;
vec2 offset = h * vec2(cos(theta), sin(theta)) * screen;
float m = round(log2(h) + 6);
ivec2 ioccluder_uv = ivec2(x, y) + ivec2(offset);
if (ioccluder_uv.x < 0 || ioccluder_uv.x > screen.x || ioccluder_uv.y < 0 || ioccluder_uv.y > screen.y) continue;
float LinearoccluderFragmentDepth = textureLod(dtex, vec2(ioccluder_uv) / screen, m).x;
vec3 OccluderPos = getXcYcZc(ioccluder_uv.x, ioccluder_uv.y, LinearoccluderFragmentDepth);
vec3 vi = OccluderPos - FragPos;
bl += max(0, dot(vi, norm) - FragPos.z * beta) / (dot(vi, vi) + epsilon);
}
AO = max(pow(1.0 - 2. * sigma * bl * invSamples, k), 0.);
}

View File

@ -21,6 +21,12 @@ else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include")
endif()
# Xrandr
if(UNIX AND USE_XRANDR)
add_definitions(-DNO_IRR_LINUX_X11_VIDMODE_)
add_definitions(-D_IRR_LINUX_X11_RANDR_)
endif()
set(IRRLICHT_SOURCES
source/Irrlicht/CTRStencilShadow.cpp
source/Irrlicht/CGUIListBox.cpp

View File

@ -12,6 +12,7 @@
namespace irr
{
namespace video { class ITexture; }
namespace gui
{
class IGUIFont;
@ -564,6 +565,10 @@ namespace gui
//! get the type of this skin
virtual EGUI_SKIN_TYPE getType() const { return EGST_UNKNOWN; }
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
const video::SColor* const colors, bool useAlphaChannelOfTexture) = 0;
};

View File

@ -544,12 +544,12 @@ B3D, MS3D or X meshes */
#endif
//! Define _IRR_COMPILE_WITH_BMP_WRITER_ if you want to write .bmp files
//#define _IRR_COMPILE_WITH_BMP_WRITER_
#define _IRR_COMPILE_WITH_BMP_WRITER_
#ifdef NO_IRR_COMPILE_WITH_BMP_WRITER_
#undef _IRR_COMPILE_WITH_BMP_WRITER_
#endif
//! Define _IRR_COMPILE_WITH_JPG_WRITER_ if you want to write .jpg files
//#define _IRR_COMPILE_WITH_JPG_WRITER_
#define _IRR_COMPILE_WITH_JPG_WRITER_
#ifdef NO_IRR_COMPILE_WITH_JPG_WRITER_
#undef _IRR_COMPILE_WITH_JPG_WRITER_
#endif

View File

@ -249,11 +249,16 @@ void CGUIButton::draw()
pos.X -= ImageRect.getWidth() / 2;
pos.Y -= ImageRect.getHeight() / 2;
driver->draw2DImage(Image,
ScaleImage? AbsoluteRect :
core::recti(pos, ImageRect.getSize()),
ImageRect, &AbsoluteClippingRect,
0, UseAlphaChannel);
skin->draw2DImage(Image,
ScaleImage ? AbsoluteRect :
core::recti(pos, ImageRect.getSize()),
ImageRect, &AbsoluteClippingRect,
0, UseAlphaChannel);
//driver->draw2DImage(Image,
// ScaleImage? AbsoluteRect :
// core::recti(pos, ImageRect.getSize()),
// ImageRect, &AbsoluteClippingRect,
// 0, UseAlphaChannel);
}
}
else

View File

@ -179,6 +179,13 @@ CGUISkin::~CGUISkin()
}
void CGUISkin::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
const video::SColor* const colors, bool useAlphaChannelOfTexture)
{
Driver->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture);
}
//! returns default color
video::SColor CGUISkin::getColor(EGUI_DEFAULT_COLOR color) const
{

View File

@ -224,6 +224,10 @@ namespace gui
//! scripting languages, editors, debuggers or xml deserialization purposes.
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0);
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
const video::SColor* const colors, bool useAlphaChannelOfTexture);
private:
video::SColor Colors[EGDC_COUNT];

View File

@ -264,6 +264,7 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
// enumerate video modes
s32 modeCount;
XF86VidModeModeInfo** modes;
float refresh_rate;
XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes);
@ -271,13 +272,37 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
for (s32 i = 0; i<modeCount; ++i)
{
if (bestMode==-1 && modes[i]->hdisplay >= Width && modes[i]->vdisplay >= Height)
{
float pixels_per_second = modes[i]->dotclock * 1000.0;
float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal;
refresh_rate = pixels_per_second / pixels_per_frame;
bestMode = i;
}
else if (bestMode!=-1 &&
modes[i]->hdisplay == modes[bestMode]->hdisplay &&
modes[i]->vdisplay == modes[bestMode]->vdisplay)
{
float pixels_per_second = modes[i]->dotclock * 1000.0;
float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal;
float refresh_rate_tmp = pixels_per_second / pixels_per_frame;
if (refresh_rate_tmp > refresh_rate)
{
refresh_rate = refresh_rate_tmp;
bestMode = i;
}
}
else if (bestMode!=-1 &&
modes[i]->hdisplay >= Width &&
modes[i]->vdisplay >= Height &&
modes[i]->hdisplay <= modes[bestMode]->hdisplay &&
modes[i]->vdisplay <= modes[bestMode]->vdisplay)
{
float pixels_per_second = modes[i]->dotclock * 1000.0;
float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal;
refresh_rate = pixels_per_second / pixels_per_frame;
bestMode = i;
}
}
if (bestMode != -1)
{

View File

@ -443,6 +443,9 @@ namespace UserConfigParams
PARAM_PREFIX BoolUserConfigParam m_texture_compression
PARAM_DEFAULT(BoolUserConfigParam(true, "enable_texture_compression",
&m_video_group, "Enable Texture Compression"));
PARAM_PREFIX BoolUserConfigParam m_high_definition_textures
PARAM_DEFAULT(BoolUserConfigParam(true, "enable_high_definition_textures",
&m_video_group, "Enable high definition textures"));
PARAM_PREFIX BoolUserConfigParam m_ubo_disabled
PARAM_DEFAULT(BoolUserConfigParam(false, "disable_ubo_support",
&m_video_group, "Disable UBO support"));

View File

@ -69,6 +69,8 @@ PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
PFNGLBLENDCOLORPROC glBlendColor;
PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
#endif
static bool is_gl_init = false;
@ -216,6 +218,8 @@ void initGL()
glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformBlockIndex");
glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)IRR_OGL_LOAD_EXTENSION("glUniformBlockBinding");
glBlendColor = (PFNGLBLENDCOLORPROC)IRR_OGL_LOAD_EXTENSION("glBlendColor");
glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D");
glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)IRR_OGL_LOAD_EXTENSION("glGetCompressedTexImage");
#ifdef DEBUG
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB");
#endif
@ -306,28 +310,56 @@ GLuint getDepthTexture(irr::video::ITexture *tex)
}
std::set<irr::video::ITexture *> AlreadyTransformedTexture;
void resetTextureTable()
{
AlreadyTransformedTexture.clear();
}
void compressTexture(irr::video::ITexture *tex, bool srgb)
void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha)
{
if (AlreadyTransformedTexture.find(tex) != AlreadyTransformedTexture.end())
return;
AlreadyTransformedTexture.insert(tex);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex));
std::string cached_file;
if (UserConfigParams::m_texture_compression)
{
// Try to retrieve the compressed texture in cache
std::string tex_name = irr_driver->getTextureName(tex);
if (!tex_name.empty()) {
cached_file = file_manager->getTextureCacheLocation(tex_name) + ".gltz";
if (!file_manager->fileIsNewer(tex_name, cached_file)) {
if (loadCompressedTexture(cached_file))
return;
}
}
}
size_t w = tex->getSize().Width, h = tex->getSize().Height;
char *data = new char[w * h * 4];
unsigned char *data = new unsigned char[w * h * 4];
memcpy(data, tex->lock(), w * h * 4);
tex->unlock();
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex));
unsigned internalFormat, Format;
if (tex->hasAlpha())
Format = GL_BGRA;
else
Format = GL_BGR;
if (premul_alpha)
{
for (unsigned i = 0; i < w * h; i++)
{
float alpha = data[4 * i + 3];
if (alpha > 0.)
alpha = pow(alpha / 255., 1. / 2.2);
data[4 * i] *= alpha;
data[4 * i + 1] *= alpha;
data[4 * i + 2] *= alpha;
}
}
if (!UserConfigParams::m_texture_compression)
{
if (srgb)
@ -338,13 +370,94 @@ void compressTexture(irr::video::ITexture *tex, bool srgb)
else
{
if (srgb)
internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_SRGB_ALPHA : GL_COMPRESSED_SRGB;
internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
else
internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_RGBA : GL_COMPRESSED_RGB;
internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_RGBA_S3TC_DXT5_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
}
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, Format, GL_UNSIGNED_BYTE, (GLvoid *)data);
glGenerateMipmap(GL_TEXTURE_2D);
delete[] data;
if (UserConfigParams::m_texture_compression && !cached_file.empty())
{
// Save the compressed texture in the cache for later use.
saveCompressedTexture(cached_file);
}
}
//-----------------------------------------------------------------------------
/** Try to load a compressed texture from the given file name.
* Data in the specified file need to have a specific format. See the
* saveCompressedTexture() function for a description of the format.
* \return true if the loading succeeded, false otherwise.
* \see saveCompressedTexture
*/
bool loadCompressedTexture(const std::string& compressed_tex)
{
std::ifstream ifs(compressed_tex.c_str(), std::ios::in | std::ios::binary);
if (!ifs.is_open())
return false;
int internal_format;
int w, h;
int size = -1;
ifs.read((char*)&internal_format, sizeof(int));
ifs.read((char*)&w, sizeof(int));
ifs.read((char*)&h, sizeof(int));
ifs.read((char*)&size, sizeof(int));
if (ifs.fail() || size == -1)
return false;
char *data = new char[size];
ifs.read(data, size);
if (!ifs.fail())
{
glCompressedTexImage2D(GL_TEXTURE_2D, 0, internal_format,
w, h, 0, size, (GLvoid*)data);
glGenerateMipmap(GL_TEXTURE_2D);
delete[] data;
ifs.close();
return true;
}
delete[] data;
return false;
}
//-----------------------------------------------------------------------------
/** Try to save the last texture sent to glTexImage2D in a file of the given
* file name. This function should only be used for textures sent to
* glTexImage2D with a compressed internal format as argument.<br>
* \note The following format is used to save the compressed texture:<br>
* <internal-format><width><height><size><data> <br>
* The first four elements are integers and the last one is stored
* on \c size bytes.
* \see loadCompressedTexture
*/
void saveCompressedTexture(const std::string& compressed_tex)
{
int internal_format, width, height, size, compressionSuccessful;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&internal_format);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint *)&width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint *)&height);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, (GLint *)&compressionSuccessful);
if (!compressionSuccessful)
return;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint *)&size);
char *data = new char[size];
glGetCompressedTexImage(GL_TEXTURE_2D, 0, (GLvoid*)data);
std::ofstream ofs(compressed_tex.c_str(), std::ios::out | std::ios::binary);
if (ofs.is_open())
{
ofs.write((char*)&internal_format, sizeof(int));
ofs.write((char*)&width, sizeof(int));
ofs.write((char*)&height, sizeof(int));
ofs.write((char*)&size, sizeof(int));
ofs.write(data, size);
ofs.close();
}
delete[] data;
}
void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF)
@ -377,6 +490,7 @@ ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer)
if (!UserConfigParams::m_profiler_enabled) return;
if (profiler.isFrozen()) return;
#ifdef GL_TIME_ELAPSED
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
if (!timer.initialised)
{
@ -384,14 +498,17 @@ ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer)
timer.initialised = true;
}
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, timer.query);
#endif
}
ScopedGPUTimer::~ScopedGPUTimer()
{
if (!UserConfigParams::m_profiler_enabled) return;
if (profiler.isFrozen()) return;
#ifdef GL_TIME_ELAPSED
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
#endif
}
GPUTimer::GPUTimer() : initialised(false)
@ -408,6 +525,30 @@ unsigned GPUTimer::elapsedTimeus()
return result / 1000;
}
void draw3DLine(const core::vector3df& start,
const core::vector3df& end, irr::video::SColor color)
{
if (!irr_driver->isGLSL()) {
irr_driver->getVideoDriver()->draw3DLine(start, end, color);
return;
}
float vertex[6] = {
start.X, start.Y, start.Z,
end.X, end.Y, end.Z
};
glBindVertexArray(UtilShader::ColoredLine::vao);
glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(float), vertex);
glUseProgram(UtilShader::ColoredLine::Program);
UtilShader::ColoredLine::setUniforms(color);
glDrawArrays(GL_LINES, 0, 2);
glGetError();
}
static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height,
float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y,
float tex_width, float tex_height)

View File

@ -5,6 +5,12 @@
# include <OpenGL/gl.h>
# include <OpenGL/gl3.h>
# define OGL32CTX
# ifdef GL_ARB_instanced_arrays
# define glVertexAttribDivisor glVertexAttribDivisorARB
# endif
# ifndef GL_TEXTURE_SWIZZLE_RGBA
# define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
# endif
#elif defined(ANDROID)
# include <GLES/gl.h>
#elif defined(WIN32)
@ -85,6 +91,8 @@ extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
extern PFNGLBLENDCOLORPROC glBlendColor;
extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
#ifdef DEBUG
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
#endif
@ -179,9 +187,14 @@ public:
GLuint getTextureGLuint(irr::video::ITexture *tex);
GLuint getDepthTexture(irr::video::ITexture *tex);
void resetTextureTable();
void compressTexture(irr::video::ITexture *tex, bool srgb);
void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = false);
bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(const std::string& compressed_tex);
void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height);
void draw3DLine(const core::vector3df& start,
const core::vector3df& end, irr::video::SColor color);
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::video::SColor &color, bool useAlphaChannelOfTexture);

View File

@ -360,7 +360,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter)
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
video::ITexture *tex = getMaterial(0).getTexture(0);
compressTexture(tex, true);
compressTexture(tex, true, true);
texture = getTextureGLuint(getMaterial(0).getTexture(0));
}

View File

@ -444,7 +444,7 @@ void IrrDriver::initDevice()
// Parse extensions
hasVSLayer = false;
const GLubyte *extensions = glGetString(GL_EXTENSIONS);
if (strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL)
if (extensions && strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL)
hasVSLayer = true;
@ -1254,6 +1254,74 @@ void IrrDriver::unsetTextureErrorMessage()
m_texture_error_message = "";
} // unsetTextureErrorMessage
// ----------------------------------------------------------------------------
/** Retrieve all textures in the specified directory, generate a smaller
* version for each of them and save them in the cache. Smaller textures are
* generated only if they do not already exist or if their original version
* is newer than the cached one.
* \param dir Directory from where textures will be retrieved.
* Must end with '/'.
* \return Directory where smaller textures were cached.
*/
std::string IrrDriver::generateSmallerTextures(const std::string& dir)
{
std::set<std::string> files;
file_manager->listFiles(files, dir, true);
std::set<std::string>::const_iterator it;
for (it = files.begin(); it != files.end(); ++it)
{
std::string ext = StringUtils::toLowerCase(StringUtils::getExtension(*it));
if (ext == "png" || ext == "jpg" || ext == "jpeg" || ext == "bmp")
{
getSmallerTexture(*it);
}
} // for it in files
return file_manager->getTextureCacheLocation(dir);
} // generateSmallerTextures
// ----------------------------------------------------------------------------
/** Return the filename for the cached smaller version of the texture. Also,
* generate the smaller version of the texture if it does not already
* exist or if the original version is newer than the cached one.
* \param filename File name of the original texture.
* \return File name of the cached texture.
*/
std::string IrrDriver::getSmallerTexture(const std::string& filename)
{
// Retrieve the filename of the cached texture
std::string cached_file = file_manager->getTextureCacheLocation(filename);
// If the cached texture does not exist, we generate it.
if (!file_manager->fileExists(cached_file) ||
file_manager->fileIsNewer(filename, cached_file))
{
video::IVideoDriver* video_driver = irr_driver->getVideoDriver();
video::IImage* img =
video_driver->createImageFromFile(filename.c_str());
if (img != NULL)
{
core::dimension2d<u32> dim = img->getDimension();
core::dimension2d<u32> new_dim; // Dimension of the cached texture
const int scale_factor = 2;
// Resize the texture only if it can be done properly
if (dim.Width < scale_factor || dim.Height < scale_factor)
new_dim = dim;
else
new_dim = dim / scale_factor;
video::IImage* scaled =
video_driver->createImage(img->getColorFormat(), new_dim);
img->copyToScaling(scaled);
video_driver->writeImageToFile(scaled, cached_file.c_str());
} // if img != NULL
} // if !file_manager->fileExists(cached_file)
return cached_file;
} // getSmallerTexture
// ----------------------------------------------------------------------------
/** Loads a texture from a file and returns the texture object. This is just
* a convenient wrapper which loads the texture from a STK asset directory.
@ -1365,9 +1433,34 @@ video::ITexture *IrrDriver::getTexture(const std::string &filename,
Log::error("irr_driver", "Texture '%s' not found.", filename.c_str());
}
m_texturesFileName[out] = filename;
return out;
} // getTexture
// ----------------------------------------------------------------------------
/** Clear the texture-filename reminder.
*/
void IrrDriver::clearTexturesFileName()
{
m_texturesFileName.clear();
} // clearTexturesFileName
// ----------------------------------------------------------------------------
/** Get the texture file name using a texture pointer.
* \param tex Pointer on the texture for which we want to find the file name.
* \return Filename of the texture if found, or an empty string otherwise.
*/
std::string IrrDriver::getTextureName(video::ITexture* tex)
{
std::map<video::ITexture*, std::string>::iterator it;
it = m_texturesFileName.find(tex);
if (it != m_texturesFileName.end())
return it->second;
else
return "";
} // getTextureName
// ----------------------------------------------------------------------------
/** Appends a pointer to each texture used in this mesh to the vector.
* \param mesh The mesh from which the textures are being determined.
@ -1534,7 +1627,7 @@ void IrrDriver::displayFPS()
if (UserConfigParams::m_artist_debug_mode)
{
sprintf(buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) KTris - LightDst : ~%d",
sprintf(buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) - LightDst : ~%d",
min, fps, max, object_count[SOLID_NORMAL_AND_DEPTH_PASS], object_count[SOLID_NORMAL_AND_DEPTH_PASS], object_count[TRANSPARENT_PASS], m_last_light_bucket_distance);
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
@ -1858,6 +1951,16 @@ void IrrDriver::update(float dt)
else
renderFixed(dt);
if (world != NULL && world->getPhysics() != NULL)
{
IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer();
if (debug_drawer != NULL && debug_drawer->debugEnabled())
{
debug_drawer->beginNextFrame();
}
}
if (m_request_screenshot) doScreenShot();
// Enable this next print statement to get render information printed
@ -2202,7 +2305,7 @@ void IrrDriver::applyObjectPassShader()
// ----------------------------------------------------------------------------
scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy,
scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, float radius,
float r, float g, float b, bool sun, scene::ISceneNode* parent)
{
if (m_glsl)
@ -2211,7 +2314,7 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy,
LightNode *light = NULL;
if (!sun)
light = new LightNode(m_scene_manager, parent, energy, r, g, b);
light = new LightNode(m_scene_manager, parent, energy, radius, r, g, b);
else
light = new SunNode(m_scene_manager, parent, r, g, b);

View File

@ -77,9 +77,17 @@ enum STKRenderingPass
enum QueryPerf
{
Q_SOLID_PASS1,
Q_SOLID_PASS2,
Q_LIGHT,
Q_SHADOWS,
Q_LIGHT,
Q_SSAO,
Q_SOLID_PASS2,
Q_TRANSPARENT,
Q_PARTICLES,
Q_DISPLACEMENT,
Q_GODRAYS,
Q_BLOOM,
Q_TONEMAP,
Q_MOTIONBLUR,
Q_LAST
};
@ -134,6 +142,8 @@ private:
float greenSHCoeff[9];
float redSHCoeff[9];
/** Keep a trace of the origin file name of a texture. */
std::map<video::ITexture*, std::string> m_texturesFileName;
/** Flag to indicate if a resolution change is pending (which will be
* acted upon in the next update). None means no change, yes means
@ -269,7 +279,8 @@ private:
void computeCameraMatrix(scene::ICameraSceneNode * const camnode);
void renderShadows();
void renderGlow(std::vector<GlowData>& glows);
void renderLights(float dt);
void renderSSAO();
void renderLights(scene::ICameraSceneNode * const camnode, float dt);
void renderDisplacement();
void doScreenShot();
public:
@ -296,6 +307,8 @@ public:
void displayFPS();
bool OnEvent(const irr::SEvent &event);
void setAmbientLight(const video::SColor &light);
std::string generateSmallerTextures(const std::string& dir);
std::string getSmallerTexture(const std::string& texture);
video::ITexture *getTexture(FileManager::AssetType type,
const std::string &filename,
bool is_premul=false,
@ -305,6 +318,8 @@ public:
bool is_premul=false,
bool is_prediv=false,
bool complain_if_not_found=true);
void clearTexturesFileName();
std::string getTextureName(video::ITexture* tex);
void grabAllTextures(const scene::IMesh *mesh);
void dropAllTextures(const scene::IMesh *mesh);
scene::IMesh *createQuadMesh(const video::SMaterial *material=NULL,
@ -548,8 +563,8 @@ public:
void applyObjectPassShader();
void applyObjectPassShader(scene::ISceneNode * const node, bool rimlit = false);
// ------------------------------------------------------------------------
scene::ISceneNode *addLight(const core::vector3df &pos, float energy = 1., float r = 1.0f,
float g = 1.0f, float b = 1.0f, bool sun = false, scene::ISceneNode* parent = NULL);
scene::ISceneNode *addLight(const core::vector3df &pos, float energy, float radius, float r,
float g, float b, bool sun = false, scene::ISceneNode* parent = NULL);
// ------------------------------------------------------------------------
void clearLights();
// ------------------------------------------------------------------------

View File

@ -34,10 +34,11 @@ using namespace core;
aabbox3df LightNode::box;
LightNode::LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float e, float r, float g, float b):
LightNode::LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float e, float d, float r, float g, float b):
ISceneNode(parent == NULL ? mgr->getRootSceneNode() : parent, mgr, -1)
{
m_energy = e;
m_radius = d;
m_energy_multiplier = 1.0f;
m_color[0] = r;
m_color[1] = g;

View File

@ -40,7 +40,7 @@ class LightNode: public scene::ISceneNode
#endif
public:
LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float energy, float r, float g, float b);
LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float energy, float d, float r, float g, float b);
virtual ~LightNode();
virtual void render() OVERRIDE;
@ -55,7 +55,7 @@ public:
virtual u32 getMaterialCount() const OVERRIDE { return 1; }
virtual bool isPointLight() { return true; }
//float getRadius() const { return m_radius; }
float getRadius() const { return m_radius; }
float getEnergy() const { return m_energy; }
float getEffectiveEnergy() const { return m_energy_multiplier * m_energy; }
core::vector3df getColor() const { return core::vector3df(m_color[0], m_color[1], m_color[2]); }
@ -66,7 +66,7 @@ public:
protected:
static core::aabbox3df box;
//float m_radius;
float m_radius;
float m_color[3];
float m_energy;

View File

@ -383,6 +383,39 @@ void PostProcessing::renderGaussian6Blur(GLuint in_fbo, GLuint in_tex, GLuint tm
}
}
void PostProcessing::renderGaussian17TapBlur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t width, size_t height)
{
float inv_width = 1.f / width, inv_height = 1.f / height;
{
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fbo);
glUseProgram(FullScreenShader::Gaussian17TapHShader::Program);
glBindVertexArray(FullScreenShader::Gaussian17TapHShader::vao);
glUniform2f(FullScreenShader::Gaussian17TapHShader::uniform_pixel, inv_width, inv_height);
setTexture(0, in_tex, GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian17TapHShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
{
glBindFramebuffer(GL_FRAMEBUFFER, in_fbo);
glUseProgram(FullScreenShader::Gaussian17TapVShader::Program);
glBindVertexArray(FullScreenShader::Gaussian17TapVShader::vao);
glUniform2f(FullScreenShader::Gaussian17TapVShader::uniform_pixel, inv_width, inv_height);
setTexture(0, tmp_tex, GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian17TapVShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
}
void PostProcessing::renderPassThrough(GLuint tex)
{
@ -418,16 +451,26 @@ void PostProcessing::renderSSAO()
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
// Generate linear depth buffer
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_LINEAR_DEPTH));
glUseProgram(FullScreenShader::LinearizeDepthShader::Program);
glBindVertexArray(FullScreenShader::LinearizeDepthShader::vao);
setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
FullScreenShader::LinearizeDepthShader::setUniforms(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue(), 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_SSAO));
if (!noise_tex)
noise_tex = irr_driver->getTexture(file_manager->getAsset("textures/noise.png").c_str());
glUseProgram(FullScreenShader::SSAOShader::Program);
glBindVertexArray(FullScreenShader::SSAOShader::vao);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_LINEAR, GL_LINEAR);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
setTexture(2, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR);
FullScreenShader::SSAOShader::setUniforms(0, 1, 2);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR);
FullScreenShader::SSAOShader::setUniforms(core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0, 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
@ -624,10 +667,8 @@ void PostProcessing::applyMLAA()
// ----------------------------------------------------------------------------
/** Render the post-processed scene */
void PostProcessing::render()
void PostProcessing::render(scene::ICameraSceneNode * const camnode)
{
if (!irr_driver->isGLSL()) return;
IVideoDriver * const drv = irr_driver->getVideoDriver();
MotionBlurProvider * const mocb = (MotionBlurProvider *) irr_driver->
@ -635,29 +676,25 @@ void PostProcessing::render()
GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver->
getCallback(ES_GAUSSIAN3H);
const u32 cams = Camera::getNumCameras();
for(u32 cam = 0; cam < cams; cam++)
GLuint in_rtt = irr_driver->getRenderTargetTexture(RTT_COLOR), in_fbo = irr_driver->getFBO(FBO_COLORS);
GLuint out_rtt = irr_driver->getRenderTargetTexture(RTT_TMP1), out_fbo = irr_driver->getFBO(FBO_TMP1_WITH_DS);
// Each effect uses these as named, and sets them up for the next effect.
// This allows chaining effects where some may be disabled.
// As the original color shouldn't be touched, the first effect can't be disabled.
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
if (UserConfigParams::m_dof)
{
scene::ICameraSceneNode * const camnode =
Camera::getCamera(cam)->getCameraSceneNode();
mocb->setCurrentCamera(cam);
GLuint in_rtt = irr_driver->getRenderTargetTexture(RTT_COLOR), in_fbo = irr_driver->getFBO(FBO_COLORS);
GLuint out_rtt = irr_driver->getRenderTargetTexture(RTT_TMP1), out_fbo = irr_driver->getFBO(FBO_TMP1_WITH_DS);
// Each effect uses these as named, and sets them up for the next effect.
// This allows chaining effects where some may be disabled.
// As the original color shouldn't be touched, the first effect can't be disabled.
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
if (UserConfigParams::m_dof)
{
renderDoF(out_fbo, in_rtt);
std::swap(in_rtt, out_rtt);
std::swap(in_fbo, out_fbo);
}
renderDoF(out_fbo, in_rtt);
std::swap(in_rtt, out_rtt);
std::swap(in_fbo, out_fbo);
}
{
PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_GODRAYS));
const bool hasgodrays = World::getWorld()->getTrack()->hasGodRays();
if (UserConfigParams::m_light_shaft && m_sunpixels > 30 && hasgodrays)
{
@ -665,7 +702,7 @@ void PostProcessing::render()
// Grab the sky
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
glClear(GL_COLOR_BUFFER_BIT);
// irr_driver->renderSkybox();
irr_driver->renderSkybox(camnode);
// Set the sun's color
const SColor col = World::getWorld()->getTrack()->getSunColor();
@ -700,8 +737,8 @@ void PostProcessing::render()
trans.transformVect(ndc, pos);
const float texh = m_vertices[cam].v1.TCoords.Y - m_vertices[cam].v0.TCoords.Y;
const float texw = m_vertices[cam].v3.TCoords.X - m_vertices[cam].v0.TCoords.X;
const float texh = m_vertices[0].v1.TCoords.Y - m_vertices[0].v0.TCoords.Y;
const float texw = m_vertices[0].v3.TCoords.X - m_vertices[0].v0.TCoords.X;
const float sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw;
const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh;
@ -727,10 +764,13 @@ void PostProcessing::render()
glDisable(GL_BLEND);
}
PROFILER_POP_CPU_MARKER();
}
// Simulate camera defects from there
// Simulate camera defects from there
{
PROFILER_PUSH_CPU_MARKER("- Bloom", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_BLOOM));
if (UserConfigParams::m_bloom)
{
glClear(GL_STENCIL_BUFFER_BIT);
@ -785,52 +825,60 @@ void PostProcessing::render()
glDisable(GL_BLEND);
} // end if bloom
PROFILER_POP_CPU_MARKER();
}
computeLogLuminance(in_rtt);
//computeLogLuminance(in_rtt);
{
PROFILER_PUSH_CPU_MARKER("- Tonemap", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TONEMAP));
toneMap(out_fbo, in_rtt);
std::swap(in_rtt, out_rtt);
std::swap(in_fbo, out_fbo);
PROFILER_POP_CPU_MARKER();
}
{
PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MOTIONBLUR));
if (UserConfigParams::m_motionblur && m_any_boost) // motion blur
{
PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00);
renderMotionBlur(cam, in_rtt, out_fbo);
renderMotionBlur(0, in_rtt, out_fbo);
std::swap(in_fbo, out_fbo);
std::swap(in_rtt, out_rtt);
PROFILER_POP_CPU_MARKER();
}
PROFILER_POP_CPU_MARKER();
}
if (irr_driver->getNormals())
{
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH));
glDisable(GL_FRAMEBUFFER_SRGB);
}
else if (irr_driver->getSSAOViz())
{
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_SSAO));
glDisable(GL_FRAMEBUFFER_SRGB);
}
else if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
{
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_MLAA_COLORS));
renderPassThrough(in_rtt);
glDisable(GL_FRAMEBUFFER_SRGB);
applyMLAA();
blitFBO(irr_driver->getFBO(FBO_MLAA_COLORS), 0, UserConfigParams::m_width, UserConfigParams::m_height);
PROFILER_POP_CPU_MARKER();
}
else
{
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
renderPassThrough(in_rtt);
glDisable(GL_FRAMEBUFFER_SRGB);
}
if (irr_driver->getNormals())
{
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH));
glDisable(GL_FRAMEBUFFER_SRGB);
}
else if (irr_driver->getSSAOViz())
{
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_SSAO));
glDisable(GL_FRAMEBUFFER_SRGB);
}
else if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
{
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_MLAA_COLORS));
renderPassThrough(in_rtt);
glDisable(GL_FRAMEBUFFER_SRGB);
applyMLAA();
blitFBO(irr_driver->getFBO(FBO_MLAA_COLORS), 0, UserConfigParams::m_width, UserConfigParams::m_height);
PROFILER_POP_CPU_MARKER();
}
else
{
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
renderPassThrough(in_rtt);
glDisable(GL_FRAMEBUFFER_SRGB);
}
} // render

View File

@ -21,6 +21,7 @@
#include "IShaderConstantSetCallBack.h"
#include "S3DVertex.h"
#include "SMaterial.h"
#include "graphics/camera.hpp"
#include <vector>
@ -83,6 +84,7 @@ public:
/** Blur the in texture */
void renderGaussian3Blur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t inv_width, size_t inv_height);
void renderGaussian6Blur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t width, size_t height);
void renderGaussian17TapBlur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t width, size_t height);
/** Render tex. Used for blit/texture resize */
void renderPassThrough(unsigned tex);
@ -92,7 +94,7 @@ public:
void renderGlow(unsigned tex);
/** Render the post-processed scene */
void render();
void render(scene::ICameraSceneNode * const camnode);
/** Use motion blur for a short time */
void giveBoost(unsigned int cam_index);

View File

@ -52,6 +52,9 @@
STKInstancedSceneNode *InstancedBox = 0;
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
void IrrDriver::renderGLSL(float dt)
{
World *world = World::getWorld(); // Never NULL.
@ -139,27 +142,56 @@ void IrrDriver::renderGLSL(float dt)
#endif
camera->activate();
rg->preRenderCallback(camera); // adjusts start referee
m_scene_manager->setActiveCamera(camnode);
renderScene(camnode, glows, dt, track->hasShadows());
PROFILER_POP_CPU_MARKER();
// Debug physic
// Note that drawAll must be called before rendering
// the bullet debug view, since otherwise the camera
// is not set up properly. This is only used for
// the bullet debug view.
if (UserConfigParams::m_artist_debug_mode)
World::getWorld()->getPhysics()->draw();
if (world != NULL && world->getPhysics() != NULL)
{
IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer();
if (debug_drawer != NULL && debug_drawer->debugEnabled())
{
const std::map<video::SColor, std::vector<float> >& lines = debug_drawer->getLines();
std::map<video::SColor, std::vector<float> >::const_iterator it;
glUseProgram(UtilShader::ColoredLine::Program);
glBindVertexArray(UtilShader::ColoredLine::vao);
glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::vbo);
for (it = lines.begin(); it != lines.end(); it++)
{
UtilShader::ColoredLine::setUniforms(it->first);
const std::vector<float> &vertex = it->second;
const float *tmp = vertex.data();
for (int i = 0; i < vertex.size(); i += 1024 * 6)
{
unsigned count = MIN2(vertex.size() - i, 1024 * 6);
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]);
glDrawArrays(GL_LINES, 0, count / 3);
}
}
glUseProgram(0);
glBindVertexArray(0);
}
}
// Render the post-processed scene
if (UserConfigParams::m_dynamic_lights)
m_post_processing->render(camnode);
else
glDisable(GL_FRAMEBUFFER_SRGB);
PROFILER_POP_CPU_MARKER();
} // for i<world->getNumKarts()
PROFILER_PUSH_CPU_MARKER("Postprocessing", 0xFF, 0xFF, 0x00);
// Render the post-processed scene
if (UserConfigParams::m_dynamic_lights)
m_post_processing->render();
else
glDisable(GL_FRAMEBUFFER_SRGB);
PROFILER_POP_CPU_MARKER();
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@ -198,6 +230,7 @@ void IrrDriver::renderGLSL(float dt)
drawDebugMeshes();
#endif
PROFILER_PUSH_CPU_MARKER("EndSccene", 0x45, 0x75, 0x45);
m_video_driver->endScene();
PROFILER_POP_CPU_MARKER();
@ -216,20 +249,35 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox();
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
// Shadows
if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights &&
UserConfigParams::m_shadows && hasShadow)
{
renderShadows();
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS));
// To avoid wrong culling, use the largest view possible
m_scene_manager->setActiveCamera(m_suncam);
if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights &&
UserConfigParams::m_shadows && hasShadow)
renderShadows();
m_scene_manager->setActiveCamera(camnode);
PROFILER_POP_CPU_MARKER();
}
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
// Lights
renderLights(dt);
PROFILER_POP_CPU_MARKER();
{
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT));
renderLights(camnode, dt);
PROFILER_POP_CPU_MARKER();
}
// Handle SSAO
{
PROFILER_PUSH_CPU_MARKER("- SSAO", 0xFF, 0xFF, 0x00);
ScopedGPUTimer Timer(getGPUTimer(Q_SSAO));
if (UserConfigParams::m_ssao)
renderSSAO();
PROFILER_POP_CPU_MARKER();
}
PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF);
if (!UserConfigParams::m_dynamic_lights)
@ -268,18 +316,33 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
computeSunVisibility();
PROFILER_POP_CPU_MARKER();
// We need to re-render camera due to the per-cam-node hack.
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
renderTransparent();
PROFILER_POP_CPU_MARKER();
// Render transparent
{
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(getGPUTimer(Q_TRANSPARENT));
renderTransparent();
PROFILER_POP_CPU_MARKER();
}
PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00);
renderParticles();
PROFILER_POP_CPU_MARKER();
// Render particles
{
PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00);
ScopedGPUTimer Timer(getGPUTimer(Q_PARTICLES));
renderParticles();
PROFILER_POP_CPU_MARKER();
}
if (!UserConfigParams::m_dynamic_lights)
return;
PROFILER_PUSH_CPU_MARKER("- Displacement", 0x00, 0x00, 0xFF);
renderDisplacement();
PROFILER_POP_CPU_MARKER();
// Render displacement
{
PROFILER_PUSH_CPU_MARKER("- Displacement", 0x00, 0x00, 0xFF);
ScopedGPUTimer Timer(getGPUTimer(Q_DISPLACEMENT));
renderDisplacement();
PROFILER_POP_CPU_MARKER();
}
// Ensure that no object will be drawn after that by using invalid pass
irr_driver->setPhase(PASS_COUNT);
}
// --------------------------------------------
@ -591,11 +654,18 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode)
core::matrix4 tmp_matrix;
// Prevent Matrix without extend
if (left == right || up == down)
{
Log::error("Shadows", "Shadows Near/Far plane have a 0 area");
sun_ortho_matrix.push_back(tmp_matrix);
continue;
}
tmp_matrix.buildProjectionMatrixOrthoLH(left, right,
up, down,
30, z);
m_suncam->setProjectionMatrix(tmp_matrix, true);
m_scene_manager->setActiveCamera(m_suncam);
m_suncam->render();
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
@ -603,7 +673,6 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode)
assert(sun_ortho_matrix.size() == 4);
camnode->setNearValue(oldnear);
camnode->setFarValue(oldfar);
// camnode->render();
float *tmp = new float[16 * 8];
@ -632,13 +701,9 @@ void IrrDriver::renderShadows()
glDrawBuffer(GL_NONE);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
{
ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS));
m_scene_manager->drawAll(scene::ESNRP_SOLID);
}
m_scene_manager->drawAll(scene::ESNRP_SOLID);
glDisable(GL_POLYGON_OFFSET_FILL);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
}
@ -708,8 +773,7 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
}
// ----------------------------------------------------------------------------
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
static LightShader::PointLightInfo PointLightsInfo[MAXLIGHT];
static void renderPointLights(unsigned count)
@ -729,13 +793,13 @@ static void renderPointLights(unsigned count)
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
LightShader::PointLightShader
::setUniforms(core::vector2df(float(UserConfigParams::m_width),
float(UserConfigParams::m_height) ),
float(UserConfigParams::m_height) ),
200, 0, 1);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
}
void IrrDriver::renderLights(float dt)
void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
{
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
@ -757,92 +821,90 @@ void IrrDriver::renderLights(float dt)
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
const u32 lightcount = m_lights.size();
const core::vector3df &campos =
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
const core::vector3df &campos = camnode->getAbsolutePosition();
std::vector<LightNode *> BucketedLN[15];
for (unsigned int i = 0; i < lightcount; i++)
{
ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT));
std::vector<LightNode *> BucketedLN[15];
for (unsigned int i = 0; i < lightcount; i++)
if (!m_lights[i]->isPointLight())
{
if (!m_lights[i]->isPointLight())
{
m_lights[i]->render();
if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows())
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
else
m_post_processing->renderSunlight();
continue;
}
const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
unsigned idx = (unsigned)(lightpos.getLength() / 10);
if (idx > 14)
idx = 14;
BucketedLN[idx].push_back(m_lights[i]);
m_lights[i]->render();
if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows())
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
else
m_post_processing->renderSunlight();
continue;
}
unsigned lightnum = 0;
for (unsigned i = 0; i < 15; i++)
{
for (unsigned j = 0; j < BucketedLN[i].size(); j++)
{
if (++lightnum >= MAXLIGHT)
{
LightNode* light_node = BucketedLN[i].at(j);
light_node->setEnergyMultiplier(0.0f);
}
else
{
LightNode* light_node = BucketedLN[i].at(j);
float em = light_node->getEnergyMultiplier();
if (em < 1.0f)
{
light_node->setEnergyMultiplier(std::min(1.0f, em + dt));
}
const core::vector3df &pos = light_node->getAbsolutePosition();
PointLightsInfo[lightnum].posX = pos.X;
PointLightsInfo[lightnum].posY = pos.Y;
PointLightsInfo[lightnum].posZ = pos.Z;
PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy();
const core::vector3df &col = light_node->getColor();
PointLightsInfo[lightnum].red = col.X;
PointLightsInfo[lightnum].green = col.Y;
PointLightsInfo[lightnum].blue = col.Z;
}
}
if (lightnum > MAXLIGHT)
{
irr_driver->setLastLightBucketDistance(i * 10);
break;
}
}
lightnum++;
renderPointLights(MIN2(lightnum, MAXLIGHT));
if (SkyboxCubeMap)
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
unsigned idx = (unsigned)(lightpos.getLength() / 10);
if (idx > 14)
idx = 14;
BucketedLN[idx].push_back(m_lights[i]);
}
unsigned lightnum = 0;
for (unsigned i = 0; i < 15; i++)
{
for (unsigned j = 0; j < BucketedLN[i].size(); j++)
{
if (++lightnum >= MAXLIGHT)
{
LightNode* light_node = BucketedLN[i].at(j);
light_node->setEnergyMultiplier(0.0f);
}
else
{
LightNode* light_node = BucketedLN[i].at(j);
float em = light_node->getEnergyMultiplier();
if (em < 1.0f)
{
light_node->setEnergyMultiplier(std::min(1.0f, em + dt));
}
const core::vector3df &pos = light_node->getAbsolutePosition();
PointLightsInfo[lightnum].posX = pos.X;
PointLightsInfo[lightnum].posY = pos.Y;
PointLightsInfo[lightnum].posZ = pos.Z;
PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy();
const core::vector3df &col = light_node->getColor();
PointLightsInfo[lightnum].red = col.X;
PointLightsInfo[lightnum].green = col.Y;
PointLightsInfo[lightnum].blue = col.Z;
// Light radius
PointLightsInfo[lightnum].radius = light_node->getRadius();
}
}
if (lightnum > MAXLIGHT)
{
irr_driver->setLastLightBucketDistance(i * 10);
break;
}
}
lightnum++;
renderPointLights(MIN2(lightnum, MAXLIGHT));
if (SkyboxCubeMap)
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
gl_driver->extGlDrawBuffers(1, bufs);
// Handle SSAO
if (UserConfigParams::m_ssao)
{
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_SSAO));
glClearColor(1., 1., 1., 1.);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
m_post_processing->renderSSAO();
// Blur it to reduce noise.
m_post_processing->renderGaussian6Blur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO),
irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
}
}
void IrrDriver::renderSSAO()
{
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_SSAO));
glClearColor(1., 1., 1., 1.);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
m_post_processing->renderSSAO();
// Blur it to reduce noise.
m_post_processing->renderGaussian17TapBlur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO),
irr_driver->getFBO(FBO_TMP4), irr_driver->getRenderTargetTexture(RTT_TMP4), UserConfigParams::m_width, UserConfigParams::m_height );
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
}
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)

View File

@ -83,10 +83,11 @@ RTT::RTT()
RenderTargetTextures[RTT_TMP2] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_TMP3] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_TMP4] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_LINEAR_DEPTH] = generateRTT(res, GL_R32F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGBA16F, GL_RGBA, GL_FLOAT);
RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_SSAO] = generateRTT(half, 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_HALF1] = generateRTT(half, GL_RGBA16F, GL_BGRA, GL_FLOAT);
@ -118,6 +119,7 @@ RTT::RTT()
FrameBuffers[FBO_TMP1_WITH_DS] = generateFBO(RenderTargetTextures[RTT_TMP1], DepthStencilTexture);
FrameBuffers[FBO_TMP2_WITH_DS] = generateFBO(RenderTargetTextures[RTT_TMP2], DepthStencilTexture);
FrameBuffers[FBO_TMP4] = generateFBO(RenderTargetTextures[RTT_TMP4], DepthStencilTexture);
FrameBuffers[FBO_LINEAR_DEPTH] = generateFBO(RenderTargetTextures[RTT_LINEAR_DEPTH]);
FrameBuffers[FBO_DISPLACE] = generateFBO(RenderTargetTextures[RTT_DISPLACE], DepthStencilTexture);
FrameBuffers[FBO_HALF1] = generateFBO(RenderTargetTextures[RTT_HALF1]);
FrameBuffers[FBO_HALF2] = generateFBO(RenderTargetTextures[RTT_HALF2]);

View File

@ -31,6 +31,7 @@ enum TypeRTT
RTT_TMP2,
RTT_TMP3,
RTT_TMP4,
RTT_LINEAR_DEPTH,
RTT_NORMAL_AND_DEPTH,
RTT_COLOR,
RTT_LOG_LUMINANCE,
@ -87,6 +88,7 @@ enum TypeFBO
FBO_TMP1_WITH_DS,
FBO_TMP2_WITH_DS,
FBO_TMP4,
FBO_LINEAR_DEPTH,
FBO_HALF1,
FBO_HALF2,
FBO_QUARTER1,

View File

@ -301,14 +301,17 @@ void Shaders::loadShaders()
FullScreenShader::DepthOfFieldShader::init();
FullScreenShader::ColorLevelShader::init();
FullScreenShader::FogShader::init();
FullScreenShader::Gaussian17TapHShader::init();
FullScreenShader::Gaussian3HBlurShader::init();
FullScreenShader::Gaussian3VBlurShader::init();
FullScreenShader::Gaussian17TapVShader::init();
FullScreenShader::Gaussian6HBlurShader::init();
FullScreenShader::Gaussian6VBlurShader::init();
FullScreenShader::PenumbraHShader::init();
FullScreenShader::PenumbraVShader::init();
FullScreenShader::GlowShader::init();
FullScreenShader::PassThroughShader::init();
FullScreenShader::LinearizeDepthShader::init();
FullScreenShader::SSAOShader::init();
FullScreenShader::SunLightShader::init();
FullScreenShader::DiffuseEnvMapShader::init();
@ -364,6 +367,7 @@ void Shaders::loadShaders()
UIShader::ColoredTextureRectShader::init();
UIShader::TextureRectShader::init();
UIShader::UniformColoredTextureRectShader::init();
UtilShader::ColoredLine::init();
}
Shaders::~Shaders()
@ -404,6 +408,38 @@ static void bypassUBO(GLint Program)
glUniformMatrix4fv(IPM, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer());
}
namespace UtilShader
{
GLuint ColoredLine::Program;
GLuint ColoredLine::uniform_color;
GLuint ColoredLine::vao;
GLuint ColoredLine::vbo;
void ColoredLine::init()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/coloredquad.frag").c_str());
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 6 * 1024 * sizeof(float), 0, GL_DYNAMIC_DRAW);
GLuint attrib_position = glGetAttribLocation(Program, "Position");
glEnableVertexAttribArray(attrib_position);
glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
uniform_color = glGetUniformLocation(Program, "color");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
void ColoredLine::setUniforms(const irr::video::SColor &col)
{
glUniform4i(uniform_color, col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha());
glUniformMatrix4fv(glGetUniformLocation(Program, "ModelMatrix"), 1, GL_FALSE, core::IdentityMatrix.pointer());
}
}
namespace MeshShader
{
@ -1792,6 +1828,7 @@ namespace LightShader
GLuint PointLightShader::attrib_Position;
GLuint PointLightShader::attrib_Color;
GLuint PointLightShader::attrib_Energy;
GLuint PointLightShader::attrib_Radius;
GLuint PointLightShader::uniform_ntex;
GLuint PointLightShader::uniform_dtex;
GLuint PointLightShader::uniform_spec;
@ -1810,6 +1847,7 @@ namespace LightShader
attrib_Position = glGetAttribLocation(Program, "Position");
attrib_Color = glGetAttribLocation(Program, "Color");
attrib_Energy = glGetAttribLocation(Program, "Energy");
attrib_Radius = glGetAttribLocation(Program, "Radius");
uniform_ntex = glGetUniformLocation(Program, "ntex");
uniform_dtex = glGetUniformLocation(Program, "dtex");
uniform_spec = glGetUniformLocation(Program, "spec");
@ -1828,10 +1866,13 @@ namespace LightShader
glVertexAttribPointer(attrib_Energy, 1, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(3 * sizeof(float)));
glEnableVertexAttribArray(attrib_Color);
glVertexAttribPointer(attrib_Color, 3, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(4 * sizeof(float)));
glEnableVertexAttribArray(attrib_Radius);
glVertexAttribPointer(attrib_Radius, 1, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(7 * sizeof(float)));
glVertexAttribDivisor(attrib_Position, 1);
glVertexAttribDivisor(attrib_Energy, 1);
glVertexAttribDivisor(attrib_Color, 1);
glVertexAttribDivisor(attrib_Radius, 1);
}
void PointLightShader::setUniforms(const core::vector2df &screen, unsigned spec, unsigned TU_ntex, unsigned TU_dtex)
@ -2311,6 +2352,20 @@ namespace FullScreenShader
glUniform1i(uniform_shadowtex, TU_shadowtex);
}
GLuint Gaussian17TapHShader::Program;
GLuint Gaussian17TapHShader::uniform_tex;
GLuint Gaussian17TapHShader::uniform_pixel;
GLuint Gaussian17TapHShader::vao;
void Gaussian17TapHShader::init()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian17taph.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_pixel = glGetUniformLocation(Program, "pixel");
vao = createVAO(Program);
}
GLuint Gaussian6HBlurShader::Program;
GLuint Gaussian6HBlurShader::uniform_tex;
GLuint Gaussian6HBlurShader::uniform_pixel;
@ -2339,6 +2394,20 @@ namespace FullScreenShader
vao = createVAO(Program);
}
GLuint Gaussian17TapVShader::Program;
GLuint Gaussian17TapVShader::uniform_tex;
GLuint Gaussian17TapVShader::uniform_pixel;
GLuint Gaussian17TapVShader::vao;
void Gaussian17TapVShader::init()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian17tapv.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_pixel = glGetUniformLocation(Program, "pixel");
vao = createVAO(Program);
}
GLuint Gaussian6VBlurShader::Program;
GLuint Gaussian6VBlurShader::uniform_tex;
GLuint Gaussian6VBlurShader::uniform_pixel;
@ -2442,6 +2511,29 @@ namespace FullScreenShader
vao = createVAO(Program);
}
GLuint LinearizeDepthShader::Program;
GLuint LinearizeDepthShader::uniform_zn;
GLuint LinearizeDepthShader::uniform_zf;
GLuint LinearizeDepthShader::uniform_texture;
GLuint LinearizeDepthShader::vao;
void LinearizeDepthShader::init()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/linearizedepth.frag").c_str());
uniform_texture = glGetUniformLocation(Program, "texture");
uniform_zf = glGetUniformLocation(Program, "zf");
uniform_zn = glGetUniformLocation(Program, "zn");
vao = createVAO(Program);
}
void LinearizeDepthShader::setUniforms(float zn, float zf, unsigned TU_tex)
{
glUniform1f(uniform_zn, zn);
glUniform1f(uniform_zf, zf);
glUniform1i(uniform_texture, TU_tex);
}
GLuint GlowShader::Program;
GLuint GlowShader::uniform_tex;
GLuint GlowShader::vao;
@ -2459,6 +2551,7 @@ namespace FullScreenShader
GLuint SSAOShader::uniform_dtex;
GLuint SSAOShader::uniform_noise_texture;
GLuint SSAOShader::uniform_samplePoints;
GLuint SSAOShader::uniform_screen;
GLuint SSAOShader::vao;
float SSAOShader::SSAOSamples[64];
@ -2473,6 +2566,7 @@ namespace FullScreenShader
uniform_dtex = glGetUniformLocation(Program, "dtex");
uniform_noise_texture = glGetUniformLocation(Program, "noise_texture");
uniform_samplePoints = glGetUniformLocation(Program, "samplePoints[0]");
uniform_screen = glGetUniformLocation(Program, "screen");
vao = createVAO(Program);
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
@ -2591,15 +2685,15 @@ namespace FullScreenShader
}*/
}
void SSAOShader::setUniforms(unsigned TU_ntex, unsigned TU_dtex, unsigned TU_noise)
void SSAOShader::setUniforms(const core::vector2df &screen, unsigned TU_dtex, unsigned TU_noise)
{
if (UserConfigParams::m_ubo_disabled)
bypassUBO(Program);
glUniform4fv(FullScreenShader::SSAOShader::uniform_samplePoints, 16, FullScreenShader::SSAOShader::SSAOSamples);
glUniform4fv(uniform_samplePoints, 16, SSAOSamples);
glUniform2f(uniform_screen, screen.X, screen.Y);
glUniform1i(FullScreenShader::SSAOShader::uniform_ntex, TU_ntex);
glUniform1i(FullScreenShader::SSAOShader::uniform_dtex, TU_dtex);
glUniform1i(FullScreenShader::SSAOShader::uniform_noise_texture, TU_noise);
glUniform1i(uniform_dtex, TU_dtex);
glUniform1i(uniform_noise_texture, TU_noise);
}
GLuint FogShader::Program;

View File

@ -32,6 +32,21 @@ public:
static GLuint cubevbo, cubeindexes;
static GLuint ViewProjectionMatrixesUBO;
};
namespace UtilShader
{
class ColoredLine
{
public:
static GLuint Program;
static GLuint uniform_color;
static GLuint vao, vbo;
static void init();
static void setUniforms(const irr::video::SColor &);
};
}
namespace MeshShader
{
class ObjectPass1Shader
@ -425,7 +440,7 @@ namespace LightShader
float red;
float green;
float blue;
float padding;
float radius;
};
@ -433,7 +448,7 @@ namespace LightShader
{
public:
static GLuint Program;
static GLuint attrib_Position, attrib_Energy, attrib_Color;
static GLuint attrib_Position, attrib_Energy, attrib_Color, attrib_Radius;
static GLuint uniform_ntex, uniform_dtex, uniform_spec, uniform_screen;
static GLuint vbo;
static GLuint vao;
@ -595,6 +610,16 @@ public:
static void setUniforms(const core::vector3df &direction, float r, float g, float b, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_shadowtex);
};
class Gaussian17TapHShader
{
public:
static GLuint Program;
static GLuint uniform_tex, uniform_pixel;
static GLuint vao;
static void init();
};
class Gaussian6HBlurShader
{
public:
@ -615,6 +640,16 @@ public:
static void init();
};
class Gaussian17TapVShader
{
public:
static GLuint Program;
static GLuint uniform_tex, uniform_pixel;
static GLuint vao;
static void init();
};
class Gaussian6VBlurShader
{
public:
@ -678,6 +713,17 @@ public:
static void init();
};
class LinearizeDepthShader
{
public:
static GLuint Program;
static GLuint uniform_zn, uniform_zf, uniform_texture;
static GLuint vao;
static void init();
static void setUniforms(float zn, float zf, unsigned TU_tex);
};
class GlowShader
{
public:
@ -692,12 +738,12 @@ class SSAOShader
{
public:
static GLuint Program;
static GLuint uniform_ntex, uniform_dtex, uniform_noise_texture, uniform_samplePoints;
static GLuint uniform_ntex, uniform_dtex, uniform_noise_texture, uniform_samplePoints, uniform_screen;
static GLuint vao;
static float SSAOSamples[64];
static void init();
static void setUniforms(unsigned TU_ntex, unsigned TU_dtex, unsigned TU_noise);
static void setUniforms(const core::vector2df &screen, unsigned TU_dtex, unsigned TU_noise);
};
class FogShader

View File

@ -35,7 +35,7 @@ void STKBillboard::render()
core::vector3df pos = getAbsolutePosition();
glBindVertexArray(billboardvao);
video::ITexture *tex = Material.getTexture(0);
compressTexture(tex, true);
compressTexture(tex, true, true);
GLuint texid = getTextureGLuint(tex);
setTexture(0, texid, GL_LINEAR, GL_LINEAR);
glUseProgram(MeshShader::BillboardShader::Program);

View File

@ -35,7 +35,7 @@ using namespace scene;
using namespace core;
SunNode::SunNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float r, float g, float b):
LightNode(mgr, parent, 0., r, g, b)
LightNode(mgr, parent, 0., 0., r, g, b)
{
m_color[0] = r;
m_color[1] = g;

View File

@ -1048,7 +1048,12 @@ namespace GUIEngine
const int screen_width = irr_driver->getFrameSize().Width;
const int screen_height = irr_driver->getFrameSize().Height;
float scale = std::max(0, screen_width - 640)/564.0f;
if (screen_height < 700) scale = std::min(scale, 0.25f); // attempt to compensate for small screens
// attempt to compensate for small screens
if (screen_width < 1200) scale = std::max(0, screen_width - 640) / 750.0f;
if (screen_width < 900 || screen_height < 700) scale = std::min(scale, 0.05f);
Log::info("GUIEngine", "scale: %f", scale);
float normal_text_scale = 0.7f + 0.2f*scale;
float title_text_scale = 0.2f + 0.2f*scale;

View File

@ -159,8 +159,12 @@ bool EventHandler::OnEvent (const SEvent &event)
event.EventType == EET_JOYSTICK_INPUT_EVENT)
{
// Remember the mouse position
m_mouse_pos.X = event.MouseInput.X;
m_mouse_pos.Y = event.MouseInput.Y;
if (event.EventType == EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event == EMIE_MOUSE_MOVED)
{
m_mouse_pos.X = event.MouseInput.X;
m_mouse_pos.Y = event.MouseInput.Y;
}
// Notify the profiler of mouse events
if(UserConfigParams::m_profiler_enabled &&

View File

@ -2267,6 +2267,15 @@ void Skin::drawIcon (IGUIElement *element, EGUI_DEFAULT_ICON icon,
// -----------------------------------------------------------------------------
void Skin::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
const video::SColor* const colors, bool useAlphaChannelOfTexture)
{
::draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture);
}
// -----------------------------------------------------------------------------
video::SColor Skin::getColor (EGUI_DEFAULT_COLOR color) const
{
/*

View File

@ -381,6 +381,11 @@ namespace GUIEngine
const core::rect< s32 > &rect,
const core::rect< s32 > *clip,
core::rect<s32>* checkClientArea=0);
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
const video::SColor* const colors, bool useAlphaChannelOfTexture);
virtual void drawIcon (gui::IGUIElement *element,
gui::EGUI_DEFAULT_ICON icon,
const core::position2di position,

View File

@ -192,6 +192,7 @@ FileManager::FileManager()
checkAndCreateConfigDir();
checkAndCreateAddonsDir();
checkAndCreateScreenshotDir();
checkAndCreateCachedTexturesDir();
checkAndCreateGPDir();
#ifdef WIN32
@ -596,6 +597,14 @@ std::string FileManager::getScreenshotDir() const
return m_screenshot_dir;
} // getScreenshotDir
//-----------------------------------------------------------------------------
/** Returns the directory in which resized textures should be cached.
*/
std::string FileManager::getCachedTexturesDir() const
{
return m_cached_textures_dir;
} // getCachedTexturesDir
//-----------------------------------------------------------------------------
/** Returns the directory in which user-defined grand prix should be stored.
*/
@ -852,6 +861,31 @@ void FileManager::checkAndCreateScreenshotDir()
} // checkAndCreateScreenshotDir
// ----------------------------------------------------------------------------
/** Creates the directories for cached textures. This will set
* m_cached_textures_dir with the appropriate path.
*/
void FileManager::checkAndCreateCachedTexturesDir()
{
#if defined(WIN32) || defined(__CYGWIN__)
m_cached_textures_dir = m_user_config_dir + "cached-textures/";
#elif defined(__APPLE__)
m_cached_textures_dir = getenv("HOME");
m_cached_textures_dir += "/Library/Application Support/SuperTuxKart/CachedTextures/";
#else
m_cached_textures_dir = checkAndCreateLinuxDir("XDG_CACHE_HOME", "supertuxkart", ".cache/", ".");
m_cached_textures_dir += "cached-textures/";
#endif
if (!checkAndCreateDirectory(m_cached_textures_dir))
{
Log::error("FileManager", "Can not create cached textures directory '%s', "
"falling back to '.'.", m_cached_textures_dir.c_str());
m_cached_textures_dir = ".";
}
} // checkAndCreateCachedTexturesDir
// ----------------------------------------------------------------------------
/** Creates the directories for user-defined grand prix. This will set m_gp_dir
* with the appropriate path.
@ -976,6 +1010,35 @@ void FileManager::redirectOutput()
Log::openOutputFiles(logoutfile);
} // redirectOutput
//-----------------------------------------------------------------------------
/** Returns the theoretical location of the cached version of a texture
* depending of the current config. (This function also works for directories:
* in this case the returned directory will be the cache location for all
* textures that you will find in the specified directory. The specified
* directory must end with '/')
* \note The returned location is where the cached data should be read or
* written but the file itseft does not necessarity exist. However, the
* directory structure is automatically created if it does not exist.
*/
std::string FileManager::getTextureCacheLocation(const std::string& filename)
{
std::string file = StringUtils::getBasename(filename);
std::string parent_dir = StringUtils::getPath(filename);
if (StringUtils::hasSuffix(parent_dir, "/"))
parent_dir = parent_dir.substr(0, parent_dir.size() - 1);
parent_dir = StringUtils::getBasename(parent_dir);
std::string cache_subdir = UserConfigParams::m_high_definition_textures
? "hd/"
: "resized/";
std::string cached_file =
getCachedTexturesDir() + cache_subdir + parent_dir + "/";
checkAndCreateDirectoryP(cached_file);
cached_file += file;
return cached_file;
} // getTextureCacheLocation
//-----------------------------------------------------------------------------
/** Returns the directory for addon files. */
const std::string &FileManager::getAddonsDir() const
@ -1150,3 +1213,17 @@ bool FileManager::removeDirectory(const std::string &name) const
#endif
} // remove directory
// ----------------------------------------------------------------------------
/** Returns true if the first file is newer than the second. The comparison is
* based on the modification time of the two files.
*/
bool FileManager::fileIsNewer(const std::string& f1, const std::string& f2) const
{
struct stat stat1;
struct stat stat2;
stat(f1.c_str(), &stat1);
stat(f2.c_str(), &stat2);
return stat1.st_mtime > stat2.st_mtime;
} // fileIsNewer

View File

@ -72,6 +72,9 @@ private:
/** Directory to store screenshots in. */
std::string m_screenshot_dir;
/** Directory where resized textures are cached. */
std::string m_cached_textures_dir;
/** Directory where user-defined grand prix are stored. */
std::string m_gp_dir;
@ -91,6 +94,7 @@ private:
bool isDirectory(const std::string &path) const;
void checkAndCreateAddonsDir();
void checkAndCreateScreenshotDir();
void checkAndCreateCachedTexturesDir();
void checkAndCreateGPDir();
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__APPLE__)
std::string checkAndCreateLinuxDir(const char *env_name,
@ -110,7 +114,9 @@ public:
XMLNode *createXMLTreeFromString(const std::string & content);
std::string getScreenshotDir() const;
std::string getCachedTexturesDir() const;
std::string getGPDir() const;
std::string getTextureCacheLocation(const std::string& filename);
bool checkAndCreateDirectoryP(const std::string &path);
const std::string &getAddonsDir() const;
std::string getAddonsFile(const std::string &name);
@ -137,6 +143,9 @@ public:
void popModelSearchPath();
void popMusicSearchPath();
void redirectOutput();
bool fileIsNewer(const std::string& f1, const std::string& f2) const;
// ------------------------------------------------------------------------
/** Adds a directory to the music search path (or stack).
*/

View File

@ -621,8 +621,14 @@ void World::resetAllKarts()
// Stil wait will all karts are in rest (and handle the case that a kart
// fell through the ground, which can happen if a kart falls for a long
// time, therefore having a high speed when hitting the ground.
int count = 0;
while(!all_finished)
{
if (count++ > 100)
{
Log::error("World", "Infitine loop waiting for all_finished?");
break;
}
m_physics->update(1.f/60.f);
all_finished=true;
for ( KartList::iterator i=m_karts.begin(); i!=m_karts.end(); i++)

View File

@ -153,7 +153,7 @@ void ConnectToServer::asynchronousUpdate()
if (m_server_address.ip == 0 || m_server_address.port == 0)
{ // server data not correct, hide address and stop
m_state = HIDING_ADDRESS;
Log::error("ConnectToServer", "Server address is "ADDRESS_FORMAT, ADDRESS_ARGS(m_server_address.ip, m_server_address.port));
Log::error("ConnectToServer", "Server address is " ADDRESS_FORMAT, ADDRESS_ARGS(m_server_address.ip, m_server_address.port));
m_current_protocol_id = m_listener->requestStart(new HidePublicAddress());
return;
}

View File

@ -22,7 +22,9 @@
#include "karts/abstract_kart.hpp"
#include "modes/world.hpp"
#include <ISceneManager.h>
#include <ISceneNode.h>
#include <ICameraSceneNode.h>
IrrDebugDrawer::IrrDebugDrawer()
{
@ -58,8 +60,32 @@ void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
{
video::SColor c(255, (int)(color.getX()*255), (int)(color.getY()*255),
(int)(color.getZ()*255) );
irr_driver->getVideoDriver()->draw3DLine((const core::vector3df&)from,
(const core::vector3df&)to, c);
//World::getWorld()->getCa
if (from.distance2(m_camera_pos) > 10000) return;
std::vector<float>& v = m_lines[c];
v.push_back(from.getX());
v.push_back(from.getY());
v.push_back(from.getZ());
v.push_back(to.getX());
v.push_back(to.getY());
v.push_back(to.getZ());
//draw3DLine((const core::vector3df&)from, (const core::vector3df&)to, c);
}
// -----------------------------------------------------------------------------
void IrrDebugDrawer::beginNextFrame()
{
for (std::map<video::SColor, std::vector<float> >::iterator it = m_lines.begin(); it != m_lines.end(); it++)
{
it->second.clear();
}
scene::ICameraSceneNode* camera = irr_driver->getSceneManager()->getActiveCamera();
m_camera_pos = camera->getPosition();
}
/* EOF */

View File

@ -20,8 +20,11 @@
#define HEADER_IRR_DEBUG_DRAWER_HPP
#include "btBulletDynamicsCommon.h"
#include "graphics/glwrap.hpp"
#include "utils/vec3.hpp"
#include <map>
#include <vector>
/**
* \ingroup physics
@ -38,6 +41,11 @@ public:
DM_NO_KARTS_GRAPHICS = 0x02
};
DebugModeType m_debug_mode;
std::map<video::SColor, std::vector<float> > m_lines;
Vec3 m_camera_pos;
protected:
virtual void setDebugMode(int debug_mode) {}
/** Callback for bullet: if debug drawing should be done or not.
@ -65,6 +73,9 @@ public:
bool debugEnabled() const {return m_debug_mode!=0;}
void nextDebugMode();
void setDebugMode(DebugModeType mode);
void beginNextFrame();
const std::map<video::SColor, std::vector<float> >& getLines() const { return m_lines; }
}; // IrrDebugDrawer
#endif

View File

@ -165,6 +165,7 @@ public:
void setDebugMode(IrrDebugDrawer::DebugModeType mode) { m_debug_drawer->setDebugMode(mode); }
/** Returns true if the debug drawer is enabled. */
bool isDebug() const {return m_debug_drawer->debugEnabled(); }
IrrDebugDrawer* getDebugDrawer() { return m_debug_drawer; }
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
btPersistentManifold** manifold,int numManifolds,
btTypedConstraint** constraints,int numConstraints,

View File

@ -53,6 +53,7 @@ void CustomVideoSettingsDialog::beforeAddingWidgets()
getWidget<CheckBoxWidget>("weather_gfx")->setState( UserConfigParams::m_weather_effects );
getWidget<CheckBoxWidget>("ubo")->setState(!UserConfigParams::m_ubo_disabled);
getWidget<CheckBoxWidget>("dof")->setState(UserConfigParams::m_dof);
getWidget<CheckBoxWidget>("hd-textures")->setState(UserConfigParams::m_high_definition_textures);
SpinnerWidget* kart_anim = getWidget<SpinnerWidget>("steering_animations");
kart_anim->addLabel( _("Disabled") ); // 0
@ -107,10 +108,12 @@ GUIEngine::EventPropagation CustomVideoSettingsDialog::processEvent(const std::s
getWidget<CheckBoxWidget>("anim_gfx")->getState();
UserConfigParams::m_weather_effects =
getWidget<CheckBoxWidget>("weather_gfx")->getState();
UserConfigParams::m_ubo_disabled =
UserConfigParams::m_ubo_disabled =
!getWidget<CheckBoxWidget>("ubo")->getState();
UserConfigParams::m_dof =
getWidget<CheckBoxWidget>("dof")->getState();
UserConfigParams::m_high_definition_textures =
getWidget<CheckBoxWidget>("hd-textures")->getState();
UserConfigParams::m_motionblur =
getWidget<CheckBoxWidget>("motionblur")->getState();

View File

@ -302,7 +302,7 @@ void FeatureUnlockedCutScene::init()
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);
m_light = irr_driver->addLight(sun_pos, 10000.0f, 1., 1, 1, 1, true);
#ifdef DEBUG
m_light->setName("light");
#endif

View File

@ -1,212 +0,0 @@
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 1) // SuperTuxKart - a fun racing game with go-kart
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 2) // Copyright (C) 2013 Glenn De Jonghe
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 3) //
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 4) // This program is free software; you can redistribute it and/or
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 5) // modify it under the terms of the GNU General Public License
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 6) // as published by the Free Software Foundation; either version 3
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 7) // of the License, or (at your option) any later version.
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 8) //
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 9) // This program is distributed in the hope that it will be useful,
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 10) // but WITHOUT ANY WARRANTY; without even the implied warranty of
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 11) // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 12) // GNU General Public License for more details.
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 13) //
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 14) // You should have received a copy of the GNU General Public License
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 15) // along with this program; if not, write to the Free Software
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 16) // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 17)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 18) #include "states_screens/dialogs/recovery_dialog.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 19)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 20) #include "audio/sfx_manager.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 21) #include "guiengine/engine.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 22) #include "states_screens/state_manager.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 23) #include "utils/translation.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 24) #include "utils/string_utils.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 25) #include "online/messages.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 26)
4d6b110e (hiker 2014-02-26 12:52:16 +1100 27) #include <IGUIEnvironment.h>
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 28)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 29) using namespace GUIEngine;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 30) using namespace irr;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 31) using namespace irr::gui;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 32) using namespace Online;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 33)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 34) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 35) /** Constructor for the recovery dialog.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 36) */
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 37) RecoveryDialog::RecoveryDialog() : ModalDialog(0.8f,0.8f)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 38) {
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 39) m_recovery_request = NULL;
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 40) m_self_destroy = false;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 41) m_show_recovery_input = true;
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 42) m_show_recovery_info = false;
8e8f02a1 (hiker 2014-04-06 01:27:04 +1100 43) doInit();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 44) showRecoveryInput();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 45) } // RecoveryDialog
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 46)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 47) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 48) /** Destructor, destroys the recovery request.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 49) */
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 50) RecoveryDialog::~RecoveryDialog()
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 51) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 52) delete m_recovery_request;
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 53) } //~RecoverDialog
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 54)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 55) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 56) /** Shows the input screen to get the account name and email address.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 57) */
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 58) void RecoveryDialog::showRecoveryInput()
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 59) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 60) m_show_recovery_input = false;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 61) clearWindow();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 62) m_phase = Input;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 63) loadFromFile("online/recovery_input.stkgui");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 64)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 65) m_username_widget = getWidget<TextBoxWidget>("username");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 66) assert(m_username_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 67) m_username_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 68)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 69) m_email_widget = getWidget<TextBoxWidget>("email");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 70) assert(m_email_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 71)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 72) m_info_widget = getWidget<LabelWidget>("info");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 73) assert(m_info_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 74)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 75) m_options_widget = getWidget<RibbonWidget>("options");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 76) assert(m_options_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 77) m_submit_widget = getWidget<IconButtonWidget>("submit");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 78) assert(m_submit_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 79) m_cancel_widget = getWidget<IconButtonWidget>("cancel");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 80) assert(m_cancel_widget != NULL);
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 81) } // showRecoveryInput
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 82)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 83) // -----------------------------------------------------------------------------
7cc83e14 (konstin 2014-03-29 11:33:43 +0100 84) /** Informs the user that an email will be sent.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 85) */
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 86) void RecoveryDialog::showRecoveryInfo()
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 87) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 88) m_show_recovery_info = false;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 89) clearWindow();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 90) m_phase = Info;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 91) loadFromFile("online/recovery_info.stkgui");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 92)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 93) m_info_widget = getWidget<LabelWidget>("info");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 94) assert(m_info_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 95)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 96) m_options_widget = getWidget<RibbonWidget>("options");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 97) assert(m_options_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 98) m_cancel_widget = getWidget<IconButtonWidget>("cancel");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 99) assert(m_cancel_widget != NULL);
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 100) } // showRecoveryInfo
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 101)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 102) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 103) /** Let esc act as cancel.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 104) */
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 105) bool RecoveryDialog::onEscapePressed()
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 106) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 107) return m_cancel_widget->isActivated();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 108) } // onEscapePressed
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 109)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 110) // -----------------------------------------------------------------------------
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 111)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 112) void RecoveryDialog::processInput()
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 113) {
4d6b110e (hiker 2014-02-26 12:52:16 +1100 114) const core::stringw username = m_username_widget->getText().trim();
4d6b110e (hiker 2014-02-26 12:52:16 +1100 115) const core::stringw email = m_email_widget->getText().trim();
7cc83e14 (konstin 2014-03-29 11:33:43 +0100 116) if (username.size() < 4 || username.size() > 30 ||
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 117) email.size() < 4 || email.size() > 50 )
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 118) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 119) sfx_manager->quickSound("anvil");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 120) m_info_widget->setErrorColor();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 121) m_info_widget->setText(_("Username and/or email address invalid."),
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 122) false);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 123) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 124) else
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 125) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 126) m_info_widget->setDefaultColor();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 127) m_options_widget->setDeactivated();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 128) m_recovery_request = new XMLRequest();
cb959acb (hiker 2014-04-07 08:25:48 +1000 129) // This function also works when the current user is not logged in
cb959acb (hiker 2014-04-07 08:25:48 +1000 130) CurrentUser::setUserDetails(m_recovery_request, "recovery");
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 131) m_recovery_request->addParameter("username", username);
cb959acb (hiker 2014-04-07 08:25:48 +1000 132) m_recovery_request->addParameter("email", email );
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 133) m_recovery_request->queue();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 134) }
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 135) } // processInput
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 136)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 137) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 138) /** Handle a user event.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 139) */
7cc83e14 (konstin 2014-03-29 11:33:43 +0100 140) GUIEngine::EventPropagation
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 141) RecoveryDialog::processEvent(const std::string& eventSource)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 142) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 143) std::string selection;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 144) if (eventSource == m_options_widget->m_properties[PROP_ID])
7cc83e14 (konstin 2014-03-29 11:33:43 +0100 145) selection =
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 146) m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 147) else
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 148) selection = eventSource;
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 149)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 150) if (selection == m_cancel_widget->m_properties[PROP_ID])
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 151) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 152) m_self_destroy = true;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 153) return GUIEngine::EVENT_BLOCK;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 154) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 155) else if (selection == m_submit_widget->m_properties[PROP_ID])
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 156) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 157) processInput();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 158) return GUIEngine::EVENT_BLOCK;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 159) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 160) return GUIEngine::EVENT_LET;
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 161) } // processEvent
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 162)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 163) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 164) /** Called when the user pressed enter.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 165) */
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 166) void RecoveryDialog::onEnterPressedInternal()
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 167) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 168)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 169) if (GUIEngine::isFocusedForPlayer(m_options_widget, PLAYER_ID_GAME_MASTER))
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 170) return;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 171) if (m_submit_widget->isActivated())
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 172) processInput();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 173) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 174)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 175) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 176) /** This is called every frame and checks if an outstanding recovery request
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 177) * was finished. If so, it displays the results.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 178) * \param dt Time step size.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 179) */
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 180) void RecoveryDialog::onUpdate(float dt)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 181) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 182) if(m_recovery_request != NULL)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 183) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 184) if(m_recovery_request->isDone())
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 185) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 186) if(m_recovery_request->isSuccess())
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 187) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 188) m_show_recovery_info = true;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 189) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 190) else
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 191) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 192) sfx_manager->quickSound( "anvil" );
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 193) m_info_widget->setErrorColor();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 194) m_info_widget->setText(m_recovery_request->getInfo(), false);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 195) m_options_widget->setActivated();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 196) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 197) delete m_recovery_request;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 198) m_recovery_request = NULL;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 199) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 200) else
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 201) {
99e7b565 (unitraxx 2013-09-14 01:07:22 +0000 202) m_info_widget->setText(Messages::validatingInfo(), false);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 203) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 204) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 205) // It's unsafe to delete from inside the event handler so we do it here
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 206) if (m_self_destroy)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 207) ModalDialog::dismiss();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 208) else if (m_show_recovery_input)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 209) showRecoveryInput();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 210) else if (m_show_recovery_info)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 211) showRecoveryInfo();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 212) } // onUpdates

View File

@ -207,8 +207,10 @@ void Track::cleanup()
ItemManager::destroy();
ParticleKindManager::get()->cleanUpTrackSpecificGfx();
// Clear remainder of transformed textures
// Clear reminder of transformed textures
resetTextureTable();
// Clear reminder of the link between textures and file names.
irr_driver->clearTexturesFileName();
for(unsigned int i=0; i<m_animated_textures.size(); i++)
{
@ -832,7 +834,31 @@ bool Track::loadMainTrack(const XMLNode &root)
std::string model_name;
track_node->get("model", &model_name);
std::string full_path = m_root+model_name;
scene::IMesh *mesh = irr_driver->getMesh(full_path);
scene::IMesh *mesh;
// If the hd texture option is disabled, we generate smaller textures
// and configure the path to them before loading the mesh.
if (!UserConfigParams::m_high_definition_textures)
{
std::string cached_textures_dir =
irr_driver->generateSmallerTextures(m_root);
irr::io::IAttributes* scene_params =
irr_driver->getSceneManager()->getParameters();
// Before changing the texture path, we retrieve the older one to restore it later
std::string texture_default_path =
scene_params->getAttributeAsString(scene::B3D_TEXTURE_PATH).c_str();
scene_params->setAttribute(scene::B3D_TEXTURE_PATH, cached_textures_dir.c_str());
mesh = irr_driver->getMesh(full_path);
scene_params->setAttribute(scene::B3D_TEXTURE_PATH, texture_default_path.c_str());
}
else // Load mesh with default (hd) textures
{
mesh = irr_driver->getMesh(full_path);
}
if(!mesh)
{
Log::fatal("track",
@ -1474,6 +1500,15 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
file_manager->pushTextureSearchPath(m_root);
file_manager->pushModelSearchPath (m_root);
// If the hd texture option is disabled, we generate smaller textures
// and we also add the cache directory to the texture search path
if (!UserConfigParams::m_high_definition_textures)
{
std::string cached_textures_dir =
irr_driver->generateSmallerTextures(m_root);
file_manager->pushTextureSearchPath(cached_textures_dir);
}
// First read the temporary materials.xml file if it exists
try
{
@ -1666,7 +1701,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
World::getWorld()->setClearbackBufferColor(m_sky_color);
}
if (!UserConfigParams::m_high_definition_textures)
{
file_manager->popTextureSearchPath();
}
file_manager->popTextureSearchPath();
file_manager->popModelSearchPath ();
@ -1681,7 +1719,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
}
const video::SColorf tmpf(m_sun_diffuse_color);
m_sun = irr_driver->addLight(m_sun_position, 0., tmpf.r, tmpf.g, tmpf.b, true);
m_sun = irr_driver->addLight(m_sun_position, 0., 0., tmpf.r, tmpf.g, tmpf.b, true);
if (!irr_driver->isGLSL())
{

View File

@ -675,15 +675,15 @@ TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_no
xml_node.get("color", &m_color);
const video::SColorf colorf(m_color);
//m_distance = 25.0f;
//xml_node.get("distance", &m_distance);
m_energy = 1.0f;
xml_node.get("energy", &m_energy);
m_distance = 20. * m_energy;
xml_node.get("distance", &m_distance);
if (irr_driver->isGLSL())
{
m_node = irr_driver->addLight(m_init_xyz, m_energy, colorf.r, colorf.g, colorf.b, false, parent);
m_node = irr_driver->addLight(m_init_xyz, m_energy, m_distance, colorf.r, colorf.g, colorf.b, false, parent);
}
else
{

View File

@ -307,7 +307,7 @@ class TrackObjectPresentationLight : public TrackObjectPresentationSceneNode
{
private:
video::SColor m_color;
//float m_distance;
float m_distance;
float m_energy;
public:

View File

@ -389,8 +389,23 @@ void Profiler::draw()
if (hovered_gpu_marker != Q_LAST)
{
static const char *Phase[Q_LAST] =
{
"Solid Pass 1",
"Shadows",
"Lights",
"SSAO",
"Solid Pass 2",
"Transparent",
"Particles",
"Displacement",
"Godrays",
"Bloom",
"Tonemap",
"Motion Blur"
};
std::ostringstream oss;
oss << "GPU marker " << hovered_gpu_marker << " : " << hovered_gpu_marker_elapsed << " us";
oss << Phase[hovered_gpu_marker] << " : " << hovered_gpu_marker_elapsed << " us";
font->draw(oss.str().c_str(), GPU_MARKERS_NAMES_POS, video::SColor(0xFF, 0xFF, 0x00, 0x00));
}
}