Merge branch 'origin/master' into fixes

This commit is contained in:
Flakebi 2015-03-08 01:16:51 +01:00
commit e5abf4cec3
160 changed files with 2204 additions and 1943 deletions

6
.gitignore vendored
View File

@ -1,12 +1,14 @@
bld*/
build*/
cmake_build/
cmake_build*/
dependencies/
CMakeFiles/
stk-editor/
.config/
supertuxkart-64
make*.bat
data/editor
data/karts
@ -16,6 +18,7 @@ data/music
data/sfx
data/textures
data/tracks
data/wip-tracks
data/.svn
# Ignore doxygen output
@ -41,6 +44,9 @@ src/html
*~
*.swp
# Ignore QtCreator project file
CMakeLists.txt.user
packets_log.txt
history.dat
README.dependencies

View File

@ -184,6 +184,9 @@ find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
if(UNIX AND NOT APPLE)
find_package(X11 REQUIRED)
include_directories(${X11_INCLUDE_DIR})
if(USE_XRANDR)
find_package(Xrandr REQUIRED)
if(NOT XRANDR_FOUND)
@ -275,7 +278,7 @@ else()
if(MSVC)
set(PTHREAD_NAMES pthreadVC2)
elseif(MINGW)
set(PTHREAD_NAMES "winpthread-1" pthreadGC2)
set(PTHREAD_NAMES "winpthread-1" "libwinpthread-1" "pthreadGC2")
endif()
find_library(PTHREAD_LIBRARY NAMES pthread ${PTHREAD_NAMES} PATHS ${PROJECT_SOURCE_DIR}/dependencies/lib)
mark_as_advanced(PTHREAD_LIBRARY)
@ -321,6 +324,7 @@ target_link_libraries(supertuxkart
)
if(UNIX AND NOT APPLE)
target_link_libraries(supertuxkart ${X11_LIBRARIES})
if(USE_XRANDR)
target_link_libraries(supertuxkart ${XRANDR_LIBRARIES})
else()
@ -375,6 +379,25 @@ if(MSVC OR MINGW)
add_custom_target(stkshaders SOURCES ${STK_SHADERS})
endif()
if(MINGW)
find_library(LIBGCC NAMES "libgcc_s_dw2-1.dll" "libgcc_s_sjlj-1.dll" PATHS ${CMAKE_FIND_ROOT_PATH})
if(LIBGCC)
file(COPY ${LIBGCC} DESTINATION ${CMAKE_BINARY_DIR}/bin/)
endif()
find_library(LIBSTDCPP NAMES "libstdc++-6.dll" PATHS ${CMAKE_FIND_ROOT_PATH})
if(LIBSTDCPP)
file(COPY ${LIBSTDCPP} DESTINATION ${CMAKE_BINARY_DIR}/bin/)
endif()
find_library(LIBOPENMP NAMES "libgomp-1.dll" PATHS ${CMAKE_FIND_ROOT_PATH})
if(LIBOPENMP)
file(COPY ${LIBOPENMP} DESTINATION ${CMAKE_BINARY_DIR}/bin/)
endif()
find_library(LIBPTHREAD NAMES "winpthread-1.dll" "libwinpthread-1.dll" "pthreadGC2.dll" PATHS ${CMAKE_FIND_ROOT_PATH})
if(LIBPTHREAD)
file(COPY ${LIBPTHREAD} DESTINATION ${CMAKE_BINARY_DIR}/bin/)
endif()
endif()
# Optional tools
add_subdirectory(tools/font_tool)
@ -437,3 +460,8 @@ install(FILES data/supertuxkart_32.png DESTINATION share/icons/hicolor/32x32/app
install(FILES data/supertuxkart_128.png DESTINATION share/icons/hicolor/128x128/apps RENAME supertuxkart.png)
install(FILES data/supertuxkart_32.png data/supertuxkart_128.png DESTINATION share/pixmaps)
install(FILES data/supertuxkart.appdata.xml DESTINATION share/appdata)
if(MINGW)
install(DIRECTORY ${CMAKE_BINARY_DIR}/bin/ DESTINATION ${STK_INSTALL_BINARY_DIR}
FILES_MATCHING PATTERN "*.dll")
endif()

View File

@ -7,11 +7,11 @@ SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++-posix)
SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32 ${PROJECT_SOURCE_DIR}/dependencies)
SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32 /usr/lib/gcc/i686-w64-mingw32/4.9-posix ${PROJECT_SOURCE_DIR}/dependencies)
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ALWAYS)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -10,10 +10,10 @@
</hard>
<medium>
<karts number="4"/>
<requirements time="220"/>
<requirements time="225"/>
</medium>
<easy>
<karts number="4"/>
<requirements time="250"/>
<requirements time="290"/>
</easy>
</challenge>

View File

@ -2,6 +2,8 @@
<graphical-restrictions>
<card is="Intel(R) HD Graphics 3000" os="windows" disable="UniformBufferObject"/>
<card is="Intel(R) HD Graphics 3000" os="windows" disable="AdvancedPipeline"/>
<card is="Intel(R) HD Graphics 3000" os="windows" disable="FramebufferSRGBWorking"/>
<card contains="Intel" os="osx" disable="GI"/>
<card contains="Intel" disable="TextureCompressionS3TC"/>
<card contains="Intel" os="windows" disable="HighDefinitionTextures"/>
<card contains="NVIDIA" os="windows" version="<344.65" disable="BufferStorage"/>

View File

@ -25,9 +25,20 @@
<div layout="horizontal-row" width="100%" proportion="1">
<spacer width="70" height="10" />
<label text="Shadows" I18N="Video settings"/>
<spacer width="10" height="10"/>
<gauge id="shadows" min_value="0" max_value="2" width="50%"/>
<div layout="horizontal-row" proportion="1" height="fit">
<label text="Shadows" I18N="Video settings"/>
<spacer width="10" height="10"/>
<gauge id="shadows" min_value="0" max_value="2" proportion="1"/>
</div>
<spacer height="4" width="10" />
<div layout="horizontal-row" proportion="1" height="fit">
<checkbox id="ibl"/>
<spacer width="10" height="10"/>
<label text="Image-based lighting" I18N="Video settings"/>
</div>
</div>
<spacer height="4" width="10" />

View File

@ -18,7 +18,7 @@
<div width="90%" align="center" layout="vertical-row" height="80%">
<div width="100%" height="12%" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left"
I18N="In the registration dialog" text="Name"/>
I18N="In the registration dialog" text="Local Name"/>
<textbox id="local_username" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>

View File

@ -7,7 +7,7 @@
<spacer height="25" width="50"/>
<box proportion="5" width="90%" align="center" layout="vertical-row" padding="8">
<list id="terms" x="0" y="0" width="100%" height="100%"/>
<label word_wrap="true" id="terms" x="0" y="0" width="100%" height="100%"/>
</box>
<div align="center" width="fit" height="fit" layout="horizontal-row" >

View File

@ -58,7 +58,7 @@
<div layout="horizontal-row" proportion="1" height="fit">
<checkbox id="perPlayerDifficulty"/>
<spacer width="20" height="100%" />
<label height="100%" I18N="In the ui settings" text="Enable handicapped users"/>
<label height="100%" I18N="In the ui settings" text="Enable per-player handicaps"/>
</div>
</div>

2
data/po/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
transifex
tx.exe

View File

@ -1,31 +0,0 @@
msgfmt ca.po -o ca/LC_MESSAGES/supertuxkart.mo
msgfmt cs.po -o cs/LC_MESSAGES/supertuxkart.mo
msgfmt da.po -o da/LC_MESSAGES/supertuxkart.mo
msgfmt de.po -o de/LC_MESSAGES/supertuxkart.mo
msgfmt es.po -o es/LC_MESSAGES/supertuxkart.mo
msgfmt fi.po -o fi/LC_MESSAGES/supertuxkart.mo
msgfmt fr_CA.po -o fr_CA/LC_MESSAGES/supertuxkart.mo
msgfmt fr.po -o fr/LC_MESSAGES/supertuxkart.mo
msgfmt ga.po -o ga/LC_MESSAGES/supertuxkart.mo
msgfmt gl.po -o gl/LC_MESSAGES/supertuxkart.mo
msgfmt it.po -o it/LC_MESSAGES/supertuxkart.mo
msgfmt nb.po -o nb/LC_MESSAGES/supertuxkart.mo
msgfmt nl.po -o nl/LC_MESSAGES/supertuxkart.mo
msgfmt pl.po -o pl/LC_MESSAGES/supertuxkart.mo
msgfmt pt_BR.po -o pt_BR/LC_MESSAGES/supertuxkart.mo
msgfmt ro.po -o ro/LC_MESSAGES/supertuxkart.mo
msgfmt ru.po -o ru/LC_MESSAGES/supertuxkart.mo
msgfmt sl.po -o sl/LC_MESSAGES/supertuxkart.mo
msgfmt sv.po -o sv/LC_MESSAGES/supertuxkart.mo
msgfmt uk.po -o uk/LC_MESSAGES/supertuxkart.mo
msgfmt zh_CN.po -o zh_CN/LC_MESSAGES/supertuxkart.mo
msgfmt he.po -o he/LC_MESSAGES/supertuxkart.mo
msgfmt ko.po -o ko/LC_MESSAGES/supertuxkart.mo
msgfmt sk.po -o sk/LC_MESSAGES/supertuxkart.mo
msgfmt zh_TW.po -o zh_TW/LC_MESSAGES/supertuxkart.mo
msgfmt tr.po -o tr/LC_MESSAGES/supertuxkart.mo
msgfmt pt.po -o pt/LC_MESSAGES/supertuxkart.mo
msgfmt eu.po -o eu/LC_MESSAGES/supertuxkart.mo
msgfmt is.po -o is/LC_MESSAGES/supertuxkart.mo
msgfmt lt.po -o lt/LC_MESSAGES/supertuxkart.mo
msgfmt hr.po -o hr/LC_MESSAGES/supertuxkart.mo

View File

@ -0,0 +1,26 @@
#!/bin/sh
# Run this script from the root directory to get the latest translations from transifex :
# ./data/po/pull_from_transifex.sh
cd ./data/po
export PATH=$PATH:`pwd`
if [ -d "transifex/translations/supertuxkart.supertuxkartpot" ]; then
cd transifex
else
echo "==== Performing initial checkout ===="
mkdir -p transifex
cd transifex
tx init
tx set --auto-remote http://www.transifex.net/projects/p/supertuxkart/
fi
echo "==== Pulling all translations ===="
tx pull --all
echo "==== Copying files ===="
ls ./translations/supertuxkart.supertuxkartpot/*.po
cp -R ./translations/supertuxkart.supertuxkartpot/*.po ..
echo "==== Done ===="

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ CPP_FILE_LIST="`find ./src \
-name '*.hpp' -or \
-name "*.h" \
`"
XML_FILE_LIST="`find ./data ../stk-assets ../supertuxkart-assets \
XML_FILE_LIST="`find ./data ../stk-assets/tracks ../stk-assets/karts \
-name 'achievements.xml' -or \
-name 'kart.xml' -or \
-name 'track.xml' -or \
@ -36,18 +36,20 @@ python ./data/po/extract_strings_from_XML.py $XML_FILE_LIST
echo "---------------------------"
echo " Generating .pot file..."
# XML Files
xgettext -d supertuxkart -s --keyword=_ --add-comments="I18N:" \
-p ./data/po -o supertuxkart.pot \
--no-location --from-code=UTF-8 ./data/po/gui_strings.h \
--package-name=supertuxkart
# C++ Files
xgettext -d supertuxkart -s --keyword=_ --keyword=N_ --keyword=_LTR \
xgettext -j -d supertuxkart -s --keyword=_ --keyword=N_ --keyword=_LTR \
--keyword=_C:1c,2 --keyword=_P:1,2 \
--keyword=_CP:1c,2,3 --add-comments="I18N:" \
-p ./data/po -o supertuxkart.pot $CPP_FILE_LIST \
--package-name=supertuxkart
# XML Files
xgettext -j -d supertuxkart -s --keyword=_ --add-comments="I18N:" \
-p ./data/po -o supertuxkart.pot \
--from-code=UTF-8 ./data/po/gui_strings.h \
--package-name=supertuxkart
echo " Done"
echo "---------------------------"

View File

@ -49,7 +49,7 @@ void main()
ivec3 lmax3 = ivec3(-1000);
ivec3 lmin3 = ivec3(1000);
vec2 start_xy = gl_LocalInvocationID.xy + gl_WorkGroupID.xy * gl_WorkGroupSize.xy * 8;
vec2 start_xy = gl_LocalInvocationID.xy + gl_WorkGroupID.xy * gl_WorkGroupSize.xy * 8 + vec2(0.5);
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {

View File

@ -15,9 +15,10 @@ void main()
{
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
vec2 uv_m = (iuv - ivec2(8, 0)) * pixel;
vec2 uv = iuv * pixel;
vec2 uv_p = (iuv + ivec2(8, 0)) * pixel;
vec2 guv = gl_GlobalInvocationID.xy + vec2(0.5);
vec2 uv_m = (guv - vec2(8, 0)) * pixel;
vec2 uv = guv * pixel;
vec2 uv_p = (guv + vec2(8, 0)) * pixel;
local_src[x][y] = texture(source, uv_m).x;
local_depth[x][y] = texture(depth, uv_m).x;

View File

@ -15,9 +15,10 @@ void main()
{
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
vec2 uv_m = (iuv - ivec2(0, 8)) * pixel;
vec2 uv = iuv * pixel;
vec2 uv_p = (iuv + ivec2(0, 8)) * pixel;
vec2 guv = gl_GlobalInvocationID.xy + vec2(0.5);
vec2 uv_m = (guv - vec2(0, 8)) * pixel;
vec2 uv = guv * pixel;
vec2 uv_p = (guv + vec2(0, 8)) * pixel;
local_src[x][y] = texture(source, uv_m).x;
local_depth[x][y] = texture(depth, uv_m).x;

View File

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

View File

@ -7,7 +7,7 @@ vec3 getRGBFromCIEXxy(vec3 YxyColor);
void main()
{
vec2 uv = gl_FragCoord.xy / 512;
vec2 uv = gl_FragCoord.xy / 1024;
vec3 col = texture(tex, uv).xyz;
vec3 Yxy = getCIEYxy(col);
vec3 WhiteYxy = getCIEYxy(vec3(1.));

View File

@ -1,14 +0,0 @@
uniform sampler2D tex_128;
uniform sampler2D tex_256;
uniform sampler2D tex_512;
out vec4 FragColor;
void main()
{
vec2 uv = gl_FragCoord.xy / screen;
vec4 col = .125 * texture(tex_128, uv);
col += .25 * texture(tex_256, uv);
col += .5 * texture(tex_512, uv);
FragColor = vec4(col.xyz, 1.);
}

View File

@ -7,5 +7,5 @@ out vec4 FragColor;
void main()
{
vec4 res = texture(tex, uv);
FragColor = vec4(res.xyz * col.xyz, res.a);
FragColor = res * col;
}

View File

@ -0,0 +1,18 @@
uniform sampler2D ntex;
out vec4 Diff;
out vec4 Spec;
vec3 DecodeNormal(vec2 n);
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
vec3 DiffuseIBL(vec3 normal);
vec3 SpecularIBL(vec3 normal, vec3 V, float roughness);
void main(void)
{
vec2 uv = gl_FragCoord.xy / screen;
vec3 normal = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
Diff = vec4(0.25 * DiffuseIBL(normal), 1.);
Spec = vec4(0., 0., 0., 1.);
}

View File

@ -13,9 +13,10 @@ void main()
{
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
vec2 uv_m = (iuv - ivec2(6, 0)) * pixel;
vec2 uv = iuv * pixel;
vec2 uv_p = (iuv + ivec2(6, 0)) * pixel;
vec2 guv = gl_GlobalInvocationID.xy + vec2(0.5);
vec2 uv_m = (guv - vec2(6, 0)) * pixel;
vec2 uv = guv * pixel;
vec2 uv_p = (guv + vec2(6, 0)) * pixel;
local_src[x][y] = texture(source, uv_m);
local_src[x + 6][y] = texture(source, uv);

View File

@ -13,9 +13,10 @@ void main()
{
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
vec2 uv_m = (iuv - ivec2(0, 6)) * pixel;
vec2 uv = iuv * pixel;
vec2 uv_p = (iuv + ivec2(0, 6)) * pixel;
vec2 guv = gl_GlobalInvocationID.xy + vec2(0.5);
vec2 uv_m = (guv - vec2(0, 6)) * pixel;
vec2 uv = guv * pixel;
vec2 uv_p = (guv + vec2(0, 6)) * pixel;
local_src[x][y] = texture(source, uv_m);
local_src[x][y + 6] = texture(source, uv);

View File

@ -1,11 +1,12 @@
uniform sampler2D tex;
uniform vec3 col;
in vec2 uv;
out vec4 FragColor;
void main()
{
// Use quarter resolution
vec2 uv = 4. * gl_FragCoord.xy / screen;
vec4 res = texture(tex, uv);
// Keep the sun fully bright, but fade the sky

View File

@ -5,11 +5,11 @@ uniform vec2 sunpos;
const float decaystep = 0.88;
in vec2 uv;
out vec4 FragColor;
void main()
{
vec2 uv = 4. * gl_FragCoord.xy / screen;
vec2 texc = uv;
vec2 tosun = sunpos - texc;

View File

@ -4,8 +4,6 @@ uniform sampler2D areaMap;
#define MAX_SEARCH_STEPS 8.0
#define MAX_DISTANCE 33.0
in vec2 uv;
out vec4 FragColor;
/**
@ -75,6 +73,7 @@ vec2 Area(vec2 distance, float e1, float e2) {
void main() {
vec4 areas = vec4(0.0);
vec2 uv = gl_FragCoord.xy / screen;
vec2 e = texture(edgesMap, uv).rg;

View File

@ -1,8 +1,5 @@
uniform sampler2D colorMapG;
in vec4 offset[2];
in vec2 uv;
const float threshold = 0.1;
out vec4 FragColor;
@ -10,14 +7,20 @@ out vec4 FragColor;
void main() {
vec3 weights = vec3(0.2126,0.7152, 0.0722); // ITU-R BT. 709
vec2 uv = gl_FragCoord.xy / screen;
vec2 uv_left = uv + vec2(-1., 0.) / screen;
vec2 uv_top = uv + vec2(0., 1.) / screen;
vec2 uv_right = uv + vec2(1., 0.) / screen;
vec2 uv_bottom = uv + vec2(0., -1.) / screen;
/**
* Luma calculation requires gamma-corrected colors:
*/
float L = dot(texture(colorMapG, uv).rgb, weights);
float Lleft = dot(texture(colorMapG, offset[0].xy).rgb, weights);
float Ltop = dot(texture(colorMapG, offset[0].zw).rgb, weights);
float Lright = dot(texture(colorMapG, offset[1].xy).rgb, weights);
float Lbottom = dot(texture(colorMapG, offset[1].zw).rgb, weights);
float Lleft = dot(texture(colorMapG, uv_left).rgb, weights);
float Ltop = dot(texture(colorMapG, uv_top).rgb, weights);
float Lright = dot(texture(colorMapG, uv_right).rgb, weights);
float Lbottom = dot(texture(colorMapG, uv_bottom).rgb, weights);
vec4 delta = abs(vec4(L) - vec4(Lleft, Ltop, Lright, Lbottom));
vec4 edges = step(vec4(threshold), delta);

View File

@ -1,16 +1,19 @@
uniform sampler2D blendMap;
uniform sampler2D colorMap;
in vec4 offset[2];
in vec2 uv;
out vec4 FragColor;
void main() {
vec2 uv = gl_FragCoord.xy / screen;
vec2 uv_left = uv + vec2(-1., 0.) / screen;
vec2 uv_top = uv + vec2(0., 1.) / screen;
vec2 uv_right = uv + vec2(1., 0.) / screen;
vec2 uv_bottom = uv + vec2(0., -1.) / screen;
// Fetch the blending weights for current pixel:
vec4 topLeft = texture(blendMap, uv);
float bottom = texture(blendMap, offset[1].zw).g;
float right = texture(blendMap, offset[1].xy).a;
float bottom = texture(blendMap, uv_bottom).g;
float right = texture(blendMap, uv_right).a;
vec4 a = vec4(topLeft.r, bottom, topLeft.b, right);
// Up to 4 lines can be crossing a pixel (one in each edge). So, we perform
@ -27,10 +30,10 @@ void main() {
// Add the contributions of the possible 4 lines that can cross this pixel:
vec4 C = texture(colorMap, uv);
vec4 Cleft = texture(colorMap, offset[0].xy);
vec4 Ctop = texture(colorMap, offset[0].zw);
vec4 Cright = texture(colorMap, offset[1].xy);
vec4 Cbottom = texture(colorMap, offset[1].zw);
vec4 Cleft = texture(colorMap, uv_left);
vec4 Ctop = texture(colorMap, uv_top);
vec4 Cright = texture(colorMap, uv_right);
vec4 Cbottom = texture(colorMap, uv_bottom);
color = mix(C, Ctop, a.r) * w.r + color;
color = mix(C, Cbottom, a.g) * w.g + color;
color = mix(C, Cleft, a.b) * w.b + color;

View File

@ -1,15 +0,0 @@
in vec2 Position;
in vec2 Texcoord;
out vec4 offset[2];
out vec2 uv;
void main() {
gl_Position = vec4(Position, 0., 1.);
vec4 invy = vec4(Texcoord, Texcoord);
// invy.y = 1.0 - invy.y;
uv = invy.st;
offset[0] = invy.xyxy + vec4(-1.0, 0.0, 0.0, 1.0) / screen.xyxy;
offset[1] = invy.xyxy + vec4( 1.0, 0.0, 0.0, -1.0) / screen.xyxy;
}

View File

@ -0,0 +1,11 @@
uniform sampler2D tex;
uniform int width;
uniform int height;
out vec4 FragColor;
void main()
{
vec2 uv = gl_FragCoord.xy / vec2(width, height);
FragColor = texture(tex, uv);
}

View File

@ -0,0 +1,52 @@
uniform mat4 SunCamMatrix;
layout (local_size_x = 4) in;
struct CascadeBoundingBox
{
int xmin;
int xmax;
int ymin;
int ymax;
int zmin;
int zmax;
};
layout (std430) buffer BoundingBoxes
{
CascadeBoundingBox BB[4];
};
layout (std140) buffer NewMatrixData
{
mat4 ShadowMatrixes[4];
};
mat4 buildProjectionMatrixOrthoLH(float left, float right, float up, float down, float zNear, float zFar)
{
mat4 M;
M[0] = vec4(2. / (right - left), 0., 0., 0.);
M[1] = vec4(0., 2. / (up - down), 0., 0.);
M[2] = vec4(0., 0., 1. / (zFar - zNear), 0.);
M[3].x = - (right + left) / (right - left);
M[3].y = - (up + down) / (up - down);
M[3].z = zNear / (zNear - zFar);
M[3].w = 1.;
return M;
}
void main()
{
if (gl_LocalInvocationIndex > 3)
return;
ShadowMatrixes[gl_LocalInvocationIndex] = buildProjectionMatrixOrthoLH(
BB[gl_LocalInvocationIndex].xmin / 4. - 1., BB[gl_LocalInvocationIndex].xmax / 4. + 1.,
BB[gl_LocalInvocationIndex].ymax / 4. + 1., BB[gl_LocalInvocationIndex].ymin / 4. - 1.,
BB[gl_LocalInvocationIndex].zmin / 4. - 100., BB[gl_LocalInvocationIndex].zmax / 4. + 1.) * SunCamMatrix;
}

View File

@ -68,12 +68,16 @@ when the border that intersect at this corner are enabled.
<!-- Stateless -->
<element type="background" image="ocean/background.jpg" />
<element type="achievement-message" image="ocean/glassbutton.png"
left_border="13" right_border="13" top_border="13" bottom_border="13"
<element type="achievement-message" image="ocean/achievement.png"
left_border="128" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0.3" vborder_out_portion="0"/>
<element type="friend-message" image="ocean/friend.png"
left_border="128" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
<element type="friend-message" image="ocean/glassbutton.png"
left_border="13" right_border="13" top_border="13" bottom_border="13"
<element type="error-message" image="ocean/error.png"
left_border="128" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
<element type="button" state="neutral" image="ocean/glassbutton.png"

View File

@ -76,6 +76,10 @@ when the border that intersect at this corner are enabled.
left_border="128" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
<element type="error-message" image="peach/error.png"
left_border="128" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
<element type="button" state="neutral" image="peach/glassbutton.png"
left_border="13" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>

View File

@ -1,3 +1,7 @@
friend.png, error.png, achievement.png - Licensed under CC-BY-SA 3.0 by Magne Djupvik (notification_backgrounds.xcf),
based on cup_gold.png licensed under CC-BY-SA 3+ from Open Game Art (art by onyum.com, comissionned by Bart Kelsey)
glass_section.png licensed under CC-BY-SA 3.0 Unported and main_about.png licensed under Creative-Commons BY-SA 3, By yeKcim (Anthony Carré)
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send
a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
data/skins/ocean/error.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
data/skins/ocean/friend.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -1,3 +1,7 @@
friend.png, error.png, achievement.png - Licensed under CC-BY-SA 3.0 by Magne Djupvik (notification_backgrounds.xcf),
based on cup_gold.png licensed under CC-BY-SA 3+ from Open Game Art (art by onyum.com, comissionned by Bart Kelsey)
glass_section.png licensed under CC-BY-SA 3.0 Unported and main_about.png licensed under Creative-Commons BY-SA 3, By yeKcim (Anthony Carré)
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send
a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

BIN
data/skins/peach/error.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -686,8 +686,8 @@
time-full-steer ="0:0.15 0.5:0.15 0.5:0.25 1.0:0.25"
time-reset-steer="0.1"/>
<engine power="250 300 350 400" max-speed="15.8 18.8 23.85 30.0" brake-factor="15.0"
max-speed-reverse-ratio="0.3"/>
<engine power="250 300 350 400" max-speed="13 18 21 23.0" brake-factor="15.0"
max-speed-reverse-ratio="0.5"/>
<gear switch-ratio="0.20 0.55 1" power-increase="5 4 3"/>
@ -712,7 +712,7 @@
time-full-steer ="0:0.17 0.5:0.17 0.5:0.28 1.0:0.28"
time-reset-steer="0.1"/>
<engine power="425 500 575 600" max-speed="15 20 23.2 27" brake-factor="11.0"
<engine power="375 450 525 550" max-speed="14 19 22.0 25" brake-factor="11.0"
max-speed-reverse-ratio="0.4"/>
<gear switch-ratio="0.30 0.7 1.0" power-increase="2.2 2.2 2.5"/>
@ -741,7 +741,7 @@
time-full-steer ="0:0.23 0.5:0.23 0.5:0.41 1.0:0.41"
time-reset-steer="0.1"/>
<engine power="600 700 800 900" max-speed="15 20 23 25" brake-factor="10"
<engine power="575 675 775 875" max-speed="15 20 23 25" brake-factor="10"
max-speed-reverse-ratio="0.65"/>
<gear switch-ratio="0.45 0.70 1" power-increase="1.5 1.7 2.5"/>

6
doc/assets_version Normal file
View File

@ -0,0 +1,6 @@
This file keeps track of which svn assets version is used for which stk release.
Atm there is no mechanism in place to verify this.
stk release svn version of assets
---------------------------------------
0.8.2-beta2 needs r15985

View File

@ -72,8 +72,8 @@ namespace video
//! Destructor
~SMaterialLayer()
{
MatrixAllocator.destruct(TextureMatrix);
MatrixAllocator.deallocate(TextureMatrix);
MatrixAllocator.destruct(TextureMatrix);
MatrixAllocator.deallocate(TextureMatrix);
}
//! Assignment operator
@ -219,6 +219,7 @@ namespace video
//! Texture Matrix
/** Do not access this element directly as the internal
ressource management has to cope with Null pointers etc. */
public:
core::matrix4* TextureMatrix;
};

View File

@ -865,9 +865,9 @@ namespace core
// Deal with the 0 rotation case first
// Prior to Irrlicht 1.6, we always returned this value.
if(core::iszero(M[1]) && core::iszero(M[2]) &&
core::iszero(M[4]) && core::iszero(M[6]) &&
core::iszero(M[8]) && core::iszero(M[9]))
if (M[1] == 0 && M[2] == 0 &&
M[4] == 0 && M[6] == 0 &&
M[8] == 0 && M[9] == 0)
return vector3d<T>(M[0], M[5], M[10]);
// We have to do the full calculation.

View File

@ -50,6 +50,7 @@
- (void)windowWillClose:(id)sender
{
_quit = TRUE;
exit(0); // FIXME: hackish workaround, irrlicht crashes if we attempt clean exit
}
- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize

View File

@ -66,7 +66,7 @@ Addon::Addon(const XMLNode &xml)
std::string designer;
xml.get("name", &name );
m_name = StringUtils::decodeFromHtmlEntities(name);
m_name = StringUtils::xmlDecode(name);
m_dir_name = StringUtils::toLowerCase(name);
xml.get("id", &m_dir_name );
m_id = createAddonId(m_dir_name);
@ -83,8 +83,8 @@ Addon::Addon(const XMLNode &xml)
xml.get("file", &m_zip_file );
xml.get("description", &description );
m_description = StringUtils::decodeFromHtmlEntities(description);
m_designer = StringUtils::decodeFromHtmlEntities(designer);
m_description = StringUtils::xmlDecode(description);
m_designer = StringUtils::xmlDecode(designer);
// resolve XML entities
//m_description = StringUtils::replace(m_description, "&#10;", "\n");
@ -144,10 +144,10 @@ void Addon::writeXML(std::ofstream *out_stream)
// We write m_dir_name as 'id' to stay backwards compatible
(*out_stream) << " <" << m_type
<< " name=\""
<< StringUtils::encodeToHtmlEntities(m_name)
<< StringUtils::xmlEncode(m_name)
<< "\" id=\"" << m_dir_name
<< "\" designer=\""
<< StringUtils::encodeToHtmlEntities(m_designer)
<< StringUtils::xmlEncode(m_designer)
<< "\" status=\"" << m_status
<< "\" date=\"" << m_date
<< "\" installed=\""

View File

@ -34,8 +34,7 @@ public:
virtual bool stopMusic () = 0;
virtual bool pauseMusic () = 0;
virtual bool resumeMusic () = 0;
virtual void volumeMusic (float gain) = 0;
virtual void updateFading(float percent) = 0;
virtual void setVolume (float volume) = 0;
virtual void updateFaster(float percent, float pitch) = 0;
virtual void update () = 0;
virtual bool isPlaying () = 0;

View File

@ -34,8 +34,7 @@ public:
virtual bool stopMusic () { return true; }
virtual bool pauseMusic () { return true; }
virtual bool resumeMusic () { return true; }
virtual void volumeMusic (float gain) {}
virtual void updateFading(float percent) {}
virtual void setVolume (float volume) {}
virtual void updateFaster(float percent, float pitch) {}
virtual void update () {}
virtual bool isPlaying () { return false; }

View File

@ -85,24 +85,21 @@ MusicInformation::MusicInformation(const XMLNode *root,
m_faster_time = 1.0f;
m_max_pitch = 0.1f;
m_gain = 1.0f;
m_adjusted_gain = 1.0f;
// Otherwise read config file
// --------------------------
std::string s;
root->get("title", &s );
m_title = StringUtils::decodeFromHtmlEntities(s);
m_title = StringUtils::xmlDecode(s);
root->get("composer", &s );
m_composer = StringUtils::decodeFromHtmlEntities(s);
m_composer = StringUtils::xmlDecode(s);
root->get("file", &m_normal_filename);
root->get("gain", &m_gain );
root->get("tracks", &m_all_tracks );
root->get("fast", &m_enable_fast );
root->get("fast-filename", &m_fast_filename );
m_adjusted_gain = m_gain;
// Get the path from the filename and add it to the ogg filename
std::string path = StringUtils::getPath(filename);
m_normal_filename = path + "/" + m_normal_filename;
@ -137,6 +134,8 @@ void MusicInformation::addMusicToTracks()
} // addMusicToTracks
//-----------------------------------------------------------------------------
/** Starts the music.
*/
void MusicInformation::startMusic()
{
m_time_since_faster = 0.0f;
@ -153,7 +152,7 @@ void MusicInformation::startMusic()
return;
}
if (m_normal_music != NULL) delete m_normal_music;
if (m_normal_music) delete m_normal_music;
#if HAVE_OGGVORBIS
m_normal_music = new MusicOggStream();
@ -166,16 +165,16 @@ void MusicInformation::startMusic()
delete m_normal_music;
m_normal_music = NULL;
Log::warn("MusicInformation", "Unable to load music %s, "
"not supported or not found.\n",
"not supported or not found.",
m_normal_filename.c_str());
return;
}
m_normal_music->volumeMusic(m_adjusted_gain);
m_normal_music->setVolume(m_gain);
m_normal_music->playMusic();
// Then (if available) load the music for the last track
// -----------------------------------------------------
if (m_fast_music != NULL) delete m_fast_music;
if (m_fast_music) delete m_fast_music;
if (m_fast_filename == "")
{
m_fast_music = NULL;
@ -185,7 +184,7 @@ void MusicInformation::startMusic()
if(StringUtils::getExtension(m_fast_filename)!="ogg")
{
Log::warn(
"Music file %s format not recognized, fast music is ignored\n",
"Music file %s format not recognized, fast music is ignored",
m_fast_filename.c_str());
return;
}
@ -204,7 +203,7 @@ void MusicInformation::startMusic()
"supported or not found.\n", m_fast_filename.c_str());
return;
}
m_fast_music->volumeMusic(m_adjusted_gain);
m_fast_music->setVolume(m_gain);
} // startMusic
//-----------------------------------------------------------------------------
@ -224,8 +223,8 @@ void MusicInformation::update(float dt)
return;
}
float fraction=m_time_since_faster/m_faster_time;
m_normal_music->updateFading(1-fraction);
m_fast_music->updateFading(fraction);
m_normal_music->setVolume(1-fraction);
m_fast_music->setVolume(fraction);
break;
}
case SOUND_FASTER: {
@ -246,14 +245,12 @@ void MusicInformation::update(float dt)
break;
}
case SOUND_NORMAL:
if ( m_normal_music == NULL ) break;
m_normal_music->update();
if ( m_normal_music )
m_normal_music->update();
break;
case SOUND_FAST:
if ( m_fast_music == NULL ) break;
m_fast_music->update();
if ( m_fast_music )
m_fast_music->update();
break;
} // switch
@ -298,19 +295,22 @@ void MusicInformation::resumeMusic()
} // resumeMusic
//-----------------------------------------------------------------------------
void MusicInformation::volumeMusic(float gain)
void MusicInformation::setDefaultVolume()
{
m_adjusted_gain = m_gain * gain;
if (m_normal_music != NULL) m_normal_music->volumeMusic(m_adjusted_gain);
if (m_fast_music != NULL) m_fast_music->volumeMusic(m_adjusted_gain);
} // volumeMusic
if (m_normal_music && m_normal_music->isPlaying())
m_normal_music->setVolume(m_gain);
if (m_fast_music && m_fast_music->isPlaying())
m_fast_music->setVolume(m_gain);
} // setVolume
//-----------------------------------------------------------------------------
void MusicInformation::setTemporaryVolume(float gain)
/** Overwrites the current volume with a temporary value (used e.g. to fade
* from normal music to last lap music).
*/
void MusicInformation::setTemporaryVolume(float volume)
{
if (m_normal_music != NULL) m_normal_music->volumeMusic(gain);
if (m_fast_music != NULL) m_fast_music->volumeMusic(gain);
if (m_normal_music != NULL) m_normal_music->setVolume(volume);
if (m_fast_music != NULL) m_fast_music->setVolume(volume);
}
//-----------------------------------------------------------------------------
@ -322,6 +322,7 @@ void MusicInformation::switchToFastMusic()
{
m_mode = SOUND_FADING;
m_fast_music->playMusic();
m_fast_music->setVolume(0);
}
else
{
@ -334,7 +335,8 @@ void MusicInformation::switchToFastMusic()
bool MusicInformation::isPlaying() const
{
return (m_normal_music != NULL && m_normal_music->isPlaying()) || (m_fast_music != NULL && m_fast_music->isPlaying());
return (m_normal_music != NULL && m_normal_music->isPlaying()) ||
(m_fast_music != NULL && m_fast_music->isPlaying());
}
//-----------------------------------------------------------------------------

View File

@ -57,7 +57,6 @@ private:
bool m_enable_fast;
float m_gain;
float m_adjusted_gain;
/** Either time for fading faster music in, or time to change pitch. */
float m_faster_time;
@ -76,6 +75,26 @@ private:
// The constructor is private so that the
// static create function must be used.
MusicInformation (const XMLNode *root, const std::string &filename);
// Declare the following functions private, but allow the SFXManager
// to access them. This makes sure that only the sfx thread calls
// openal/vorbis etc, and so makes it is all thread safe.
private:
friend class SFXManager;
void update(float dt);
void startMusic();
void stopMusic();
void pauseMusic();
void resumeMusic();
void setDefaultVolume();
void switchToFastMusic();
void setTemporaryVolume(float volume);
// ------------------------------------------------------------------------
/** Sets the music to be waiting, i.e. startMusic still needs to be
* called. Used to pre-load track music during track loading time. */
void setMusicWaiting() { m_music_waiting = true; }
// ------------------------------------------------------------------------
public:
LEAK_CHECK()
@ -84,26 +103,23 @@ public:
#endif
~MusicInformation ();
static MusicInformation *create(const std::string &filename);
const stringw& getComposer () const {return m_composer; }
const stringw& getTitle () const {return m_title; }
const std::string& getNormalFilename() const {return m_normal_filename; }
const std::string& getFastFilename () const {return m_fast_filename; }
//int getNumLoops () const {return m_numLoops; }
float getFasterTime () const {return m_faster_time; }
float getMaxPitch () const {return m_max_pitch; }
void setMusicWaiting () {m_music_waiting = true;}
void addMusicToTracks ();
void update (float dt);
void startMusic ();
void stopMusic ();
void pauseMusic ();
void resumeMusic ();
void volumeMusic (float gain);
void setTemporaryVolume(float gain);
void resetTemporaryVolume() { volumeMusic(m_adjusted_gain); }
void switchToFastMusic();
void addMusicToTracks();
bool isPlaying() const;
// ------------------------------------------------------------------------
/** Returns the composer of the music. */
const stringw& getComposer() const { return m_composer; }
// ------------------------------------------------------------------------
/** Returns the title of the music. */
const stringw& getTitle() const { return m_title; }
// ------------------------------------------------------------------------
/** Returns the filename of the normal speed music. */
const std::string& getNormalFilename() const { return m_normal_filename; }
// ------------------------------------------------------------------------
/** If available, returns the file name of the faster/last-lap music. */
const std::string& getFastFilename() const { return m_fast_filename; }
// ------------------------------------------------------------------------
float getMaxPitch() const { return m_max_pitch; }
}; // MusicInformation
#endif

View File

@ -93,8 +93,6 @@ MusicManager::MusicManager()
//-----------------------------------------------------------------------------
MusicManager::~MusicManager()
{
stopMusic();
for(std::map<std::string,MusicInformation*>::iterator
i=m_all_music.begin(); i!=m_all_music.end(); i++)
{
@ -162,7 +160,21 @@ void MusicManager::addMusicToTracks()
} // addMusicToTracks
//-----------------------------------------------------------------------------
void MusicManager::startMusic(MusicInformation* mi, bool startRightNow)
/** Special shortcut vor overworld (which skips other phases where the music
* would normally be started.
*/
void MusicManager::startMusic()
{
if (m_current_music && UserConfigParams::m_music)
SFXManager::get()->queue(SFXManager::SFX_MUSIC_START, m_current_music);
} // startMusic
//-----------------------------------------------------------------------------
/** Schedules the indicated music to be played next.
* \param mi Music information of the music to be played.
* \param start_right_now
*/
void MusicManager::startMusic(MusicInformation* mi, bool start_right_now)
{
// If this music is already playing, ignore this call.
if (m_current_music != NULL &&
@ -180,18 +192,74 @@ void MusicManager::startMusic(MusicInformation* mi, bool startRightNow)
if(!mi || !UserConfigParams::m_music || !m_initialized) return;
mi->volumeMusic(m_masterGain);
if (startRightNow) mi->startMusic();
else mi->setMusicWaiting();
SFXManager::get()->queue(start_right_now ? SFXManager::SFX_MUSIC_START
: SFXManager::SFX_MUSIC_WAITING,
mi);
} // startMusic
//-----------------------------------------------------------------------------
/** Queues a stop current music event for the audio thread.
*/
void MusicManager::stopMusic()
{
if(m_current_music) m_current_music->stopMusic();
if (m_current_music)
SFXManager::get()->queue(SFXManager::SFX_MUSIC_STOP, m_current_music);
} // stopMusic
//-----------------------------------------------------------------------------
/** Insert a command into the sfx queue to pause the current music.
*/
void MusicManager::pauseMusic()
{
if (m_current_music)
SFXManager::get()->queue(SFXManager::SFX_MUSIC_PAUSE, m_current_music);
} // pauseMusic
//-----------------------------------------------------------------------------
/** Inserts a resume current music event into the queue.
*/
void MusicManager::resumeMusic()
{
if (m_current_music)
SFXManager::get()->queue(SFXManager::SFX_MUSIC_RESUME, m_current_music);
} // resumeMusic
//-----------------------------------------------------------------------------
/** Switches to fast (last lap ) music (if defined for the current music).
*/
void MusicManager::switchToFastMusic()
{
if (m_current_music)
SFXManager::get()->queue(SFXManager::SFX_MUSIC_SWITCH_FAST,
m_current_music);
} // switchToFastMusic
//-----------------------------------------------------------------------------
/** Queues a command to temporarily change the volume. This is used to make
* the music a bit quieter while the 'last lap fanfare' is being played.
* \param gain The temporary volume value.
*/
void MusicManager::setTemporaryVolume(float gain)
{
if (m_current_music)
SFXManager::get()->queue(SFXManager::SFX_MUSIC_SET_TMP_VOLUME,
m_current_music, gain);
} // setTemporaryVolume
//-----------------------------------------------------------------------------
/** Queues a command for the sfx manager to reset a temporary volume change.
*/
void MusicManager::resetTemporaryVolume()
{
if (m_current_music)
SFXManager::get()->queue(SFXManager::SFX_MUSIC_DEFAULT_VOLUME,
m_current_music);
} // resetTemporaryVolume
//-----------------------------------------------------------------------------
/** Sets the master music volume.
* \param gain The volume.
*/
void MusicManager::setMasterMusicVolume(float gain)
{
if(gain > 1.0)
@ -199,15 +267,20 @@ void MusicManager::setMasterMusicVolume(float gain)
if(gain < 0.0f)
gain = 0.0f;
m_masterGain = gain;
if(m_current_music) m_current_music->volumeMusic(m_masterGain);
m_master_gain = gain;
if (m_current_music)
{
// Sets the music volume to m_master_gain
SFXManager::get()->queue(SFXManager::SFX_MUSIC_DEFAULT_VOLUME,
m_current_music);
}
UserConfigParams::m_music_volume = m_masterGain;
UserConfigParams::m_music_volume = m_master_gain;
} // setMasterMusicVolume
//-----------------------------------------------------------------------------
/**
*/
/** @throw runtime_error if the music file could not be found/opened
*/
MusicInformation* MusicManager::getMusicInformation(const std::string& filename)
{
if(filename=="")
@ -223,7 +296,7 @@ MusicInformation* MusicManager::getMusicInformation(const std::string& filename)
MusicInformation *mi = MusicInformation::create(filename);
if(mi)
{
mi->volumeMusic(m_masterGain);
SFXManager::get()->queue(SFXManager::SFX_MUSIC_DEFAULT_VOLUME, mi);
m_all_music[basename] = mi;
}
return mi;

View File

@ -20,14 +20,14 @@
#ifndef HEADER_MUSICMANAGER_HPP
#define HEADER_MUSICMANAGER_HPP
#include <map>
#include <vector>
#include <string>
#include "audio/music.hpp"
#include "audio/music_information.hpp"
#include "utils/no_copy.hpp"
#include <map>
#include <string>
#include <vector>
class Vec3;
/**
@ -42,43 +42,44 @@ private:
/** If the sound could not be initialized, e.g. if the player doesn't has
* a sound card, we want to avoid anything sound related so we crash the
* game. */
bool m_initialized;
std::map<std::string, MusicInformation*>
m_all_music;
bool m_initialized;
void loadMusicInformation();
float m_masterGain;
/** Stores all music information files (read from the .music files). */
std::map<std::string, MusicInformation*>
m_all_music;
float m_master_gain;
void loadMusicInformation();
void loadMusicFromOneDir(const std::string& dir);
public:
MusicManager();
virtual ~MusicManager();
MusicManager();
virtual ~MusicManager();
MusicInformation* getMusicInformation(const std::string& filename);
void addMusicToTracks();
void startMusic(MusicInformation* mi, bool startRightNow=true);
void stopMusic();
bool initialized() const {return m_initialized; }
void update(float dt) {if(m_current_music)
m_current_music->update(dt); }
void pauseMusic() {if(m_current_music)
m_current_music->pauseMusic(); }
void resumeMusic() {if(m_current_music)
m_current_music->resumeMusic(); }
void switchToFastMusic() {if(m_current_music)
m_current_music->switchToFastMusic();}
void setMasterMusicVolume(float gain);
float getMasterMusicVolume() const { return m_masterGain; }
MusicInformation *getCurrentMusic() {return m_current_music; }
/**
* @throw runtime_error if the music file could not be found/opened
*/
MusicInformation *getMusicInformation(const std::string& filename);
void loadMusicFromOneDir(const std::string& dir);
void addMusicToTracks();
void clearCurrentMusic() { m_current_music = NULL; }
void startMusic();
void startMusic(MusicInformation* mi,
bool start_right_now=true);
void stopMusic();
void pauseMusic();
void resumeMusic();
void switchToFastMusic();
void setMasterMusicVolume(float gain);
void resetTemporaryVolume();
void setTemporaryVolume(float gain);
// ------------------------------------------------------------------------
/** Returns the master volume. */
float getMasterMusicVolume() const { return m_master_gain; }
// ------------------------------------------------------------------------
/** Returns if the music system is initialised. */
bool initialized() const { return m_initialized; }
// ------------------------------------------------------------------------
/** Returns the information object of the current music. */
MusicInformation* getCurrentMusic() { return m_current_music; }
// ------------------------------------------------------------------------
/** Stops and removes the current music. */
void clearCurrentMusic() { m_current_music = NULL; }
};
extern MusicManager* music_manager;

View File

@ -45,7 +45,7 @@ MusicOggStream::MusicOggStream()
MusicOggStream::~MusicOggStream()
{
if(stopMusic() == false)
Log::warn("MusicOgg", "problems while stopping music.\n");
Log::warn("MusicOgg", "problems while stopping music.");
} // ~MusicOggStream
//-----------------------------------------------------------------------------
@ -61,12 +61,14 @@ bool MusicOggStream::load(const std::string& filename)
if(!m_oggFile)
{
Log::error("MusicOgg", "Loading Music: %s failed (fopen returned NULL)\n", m_fileName.c_str());
Log::error("MusicOgg", "Loading Music: %s failed (fopen returned NULL)",
m_fileName.c_str());
return false;
}
#if defined( WIN32 ) || defined( WIN64 )
const int result = ov_open_callbacks((void *)m_oggFile, &m_oggStream, NULL, 0, OV_CALLBACKS_DEFAULT);
const int result = ov_open_callbacks((void *)m_oggFile, &m_oggStream, NULL,
0, OV_CALLBACKS_DEFAULT );
#else
const int result = ov_open(m_oggFile, &m_oggStream, NULL, 0);
#endif
@ -98,7 +100,8 @@ bool MusicOggStream::load(const std::string& filename)
errorMessage = "Unknown Error";
}
Log::error("MusicOgg", "Loading Music: %s failed : ov_open returned error code %i (%s)\n",
Log::error("MusicOgg", "Loading Music: %s failed : "
"ov_open returned error code %i (%s)",
m_fileName.c_str(), result, errorMessage);
return false;
}
@ -186,7 +189,7 @@ bool MusicOggStream::playMusic()
alSourcePlay(m_soundSource);
m_pausedMusic = false;
m_playing = true;
check("playMusic");
return true;
} // playMusic
@ -244,20 +247,15 @@ bool MusicOggStream::resumeMusic()
} // resumeMusic
//-----------------------------------------------------------------------------
void MusicOggStream::volumeMusic(float gain)
void MusicOggStream::setVolume(float volume)
{
if (gain > 1.0f) gain = 1.0f;
if (gain < 0.0f) gain = 0.0f;
volume *= music_manager->getMasterMusicVolume();
if (volume > 1.0f) volume = 1.0f;
if (volume < 0.0f) volume = 0.0f;
alSourcef(m_soundSource, AL_GAIN, gain);
} // volumeMusic
//-----------------------------------------------------------------------------
void MusicOggStream::updateFading(float percent)
{
alSourcef(m_soundSource,AL_GAIN,percent);
update();
} // updateFading
alSourcef(m_soundSource, AL_GAIN, volume);
check("volume music"); // clear errors
} // setVolume
//-----------------------------------------------------------------------------
void MusicOggStream::updateFaster(float percent, float max_pitch)
@ -302,13 +300,19 @@ void MusicOggStream::update()
if (active)
{
// For debugging
SFXManager::checkError("before source state");
// we have data, so we should be playing...
ALenum state;
alGetSourcei(m_soundSource, AL_SOURCE_STATE, &state);
if (state != AL_PLAYING)
{
Log::warn("MusicOgg", "Music not playing when it should be. "
"Source state: %d\n", state);
// Prevent flooding
static int count = 0;
count++;
if (count<10)
Log::warn("MusicOgg", "Music not playing when it should be. "
"Source state: %d", state);
alGetSourcei(m_soundSource, AL_BUFFERS_PROCESSED, &processed);
alSourcePlay(m_soundSource);
}
@ -316,7 +320,7 @@ void MusicOggStream::update()
else
{
Log::warn("MusicOgg", "Attempt to stream music into buffer failed "
"twice in a row.\n");
"twice in a row.");
}
} // update
@ -359,7 +363,8 @@ bool MusicOggStream::check(const char* what)
if (error != AL_NO_ERROR)
{
Log::error("MusicOgg", "[MusicOggStream] OpenAL error at %s : %s (%i)\n", what, SFXManager::getErrorString(error).c_str(), error);
Log::error("MusicOgg", "OpenAL error at %s : %s (%i)", what,
SFXManager::getErrorString(error).c_str(), error);
return false;
}

View File

@ -51,7 +51,6 @@ public:
virtual ~MusicOggStream();
virtual void update();
virtual void updateFading(float percent);
virtual void updateFaster(float percent, float max_pitch);
virtual bool load(const std::string& filename);
@ -60,7 +59,7 @@ public:
virtual bool stopMusic();
virtual bool pauseMusic();
virtual bool resumeMusic();
virtual void volumeMusic (float gain);
virtual void setVolume(float volume);
virtual bool isPlaying();
protected:
@ -85,7 +84,9 @@ private:
ALenum nb_channels;
bool m_pausedMusic;
static const int m_buffer_size = 11025*4;//one full second of audio at 44100 samples per second
//one full second of audio at 44100 samples per second
static const int m_buffer_size = 11025*4;
};
#endif

View File

@ -111,7 +111,8 @@ bool SFXBuffer::load()
if (!loadVorbisBuffer(m_file, m_buffer))
{
Log::error("SFXBuffer", "Could not load sound effect %s\n", m_file.c_str());
Log::error("SFXBuffer", "Could not load sound effect %s",
m_file.c_str());
// TODO: free al buffer here?
return false;
}
@ -165,20 +166,22 @@ bool SFXBuffer::loadVorbisBuffer(const std::string &name, ALuint buffer)
if(!file)
{
Log::error("SFXBuffer", "[SFXBuffer] LoadVorbisBuffer() - couldn't open file!\n");
Log::error("SFXBuffer", "LoadVorbisBuffer() - couldn't open file!");
return false;
}
if (ov_open_callbacks(file, &oggFile, NULL, 0, OV_CALLBACKS_NOCLOSE) != 0)
{
fclose(file);
Log::error("SFXBuffer", "[SFXBuffer] LoadVorbisBuffer() - ov_open_callbacks() failed, file isn't vorbis?\n");
Log::error("SFXBuffer", "LoadVorbisBuffer() - ov_open_callbacks() failed, "
"file isn't vorbis?");
return false;
}
info = ov_info(&oggFile, -1);
long len = (long)ov_pcm_total(&oggFile, -1) * info->channels * 2; // always 16 bit data
// always 16 bit data
long len = (long)ov_pcm_total(&oggFile, -1) * info->channels * 2;
char *data = (char *) malloc(len);
if(!data)
@ -213,12 +216,13 @@ bool SFXBuffer::loadVorbisBuffer(const std::string &name, ALuint buffer)
// duration (which is the norm), compute it:
if(m_duration < 0)
{
ALint buffer_size, frequency, bits_per_sample, channels;
alGetBufferi(buffer, AL_SIZE, &buffer_size );
alGetBufferi(buffer, AL_FREQUENCY, &frequency );
alGetBufferi(buffer, AL_CHANNELS, &channels );
alGetBufferi(buffer, AL_BITS, &bits_per_sample);
m_duration = float(buffer_size) / (frequency*channels*(bits_per_sample / 8));
ALint buffer_size, frequency, bits_per_sample, channels;
alGetBufferi(buffer, AL_SIZE, &buffer_size );
alGetBufferi(buffer, AL_FREQUENCY, &frequency );
alGetBufferi(buffer, AL_CHANNELS, &channels );
alGetBufferi(buffer, AL_BITS, &bits_per_sample);
m_duration = float(buffer_size)
/ (frequency*channels*(bits_per_sample / 8));
}
return success;
#else

View File

@ -22,6 +22,7 @@
#include "audio/sfx_buffer.hpp"
#include "config/user_config.hpp"
#include "io/file_manager.hpp"
#include "modes/world.hpp"
#include "race/race_manager.hpp"
#include <pthread.h>
@ -134,16 +135,19 @@ SFXManager::~SFXManager()
}
m_all_sfx.getData().clear();
m_all_sfx.unlock();
m_quick_sounds.lock();
// ---- clear m_quick_sounds
{
std::map<std::string, SFXBase*>::iterator i = m_quick_sounds.begin();
for (; i != m_quick_sounds.end(); i++)
std::map<std::string, SFXBase*>::iterator i = m_quick_sounds.getData().begin();
for (; i != m_quick_sounds.getData().end(); i++)
{
SFXBase* snd = (*i).second;
delete snd;
}
}
m_quick_sounds.clear();
m_quick_sounds.getData().clear();
m_quick_sounds.unlock();
// ---- clear m_all_sfx_types
{
@ -201,6 +205,27 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p)
queueCommand(sfx_command);
} // queue (Vec3)
//----------------------------------------------------------------------------
/** Queues a command for the music manager.
* \param mi The music for which the command is.
*/
void SFXManager::queue(SFXCommands command, MusicInformation *mi)
{
SFXCommand *sfx_command = new SFXCommand(command, mi);
queueCommand(sfx_command);
} // queue(MusicInformation)
//----------------------------------------------------------------------------
/** Queues a command for the music manager that takes a floating point value
* (e.g. setTemporaryVolume).
* \param mi The music for which the command is.
* \param f The floating point parameter.
*/
void SFXManager::queue(SFXCommands command, MusicInformation *mi, float f)
{
SFXCommand *sfx_command = new SFXCommand(command, mi, f);
queueCommand(sfx_command);
} // queue(MusicInformation)
//----------------------------------------------------------------------------
/** Enqueues a command to the sfx queue threadsafe. Then signal the
* sfx manager to wake up.
@ -209,11 +234,12 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p)
void SFXManager::queueCommand(SFXCommand *command)
{
m_sfx_commands.lock();
if(m_sfx_commands.getData().size() > 20*race_manager->getNumberOfKarts()+20 &&
if(World::getWorld() &&
m_sfx_commands.getData().size() > 20*race_manager->getNumberOfKarts()+20 &&
race_manager->getMinorMode() != RaceManager::MINOR_MODE_CUTSCENE)
{
if(command->m_command==SFX_POSITION || command->m_command==SFX_LOOP ||
command->m_command==SFX_PLAY || command->m_command==SFX_SPEED )
command->m_command==SFX_SPEED )
{
delete command;
static int count_messages = 0;
@ -279,38 +305,77 @@ void* SFXManager::mainLoop(void *obj)
break;
}
me->m_sfx_commands.unlock();
switch(current->m_command)
switch (current->m_command)
{
case SFX_PLAY: current->m_sfx->reallyPlayNow(); break;
case SFX_STOP: current->m_sfx->reallyStopNow(); break;
case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break;
case SFX_RESUME: current->m_sfx->reallyResumeNow(); break;
case SFX_PLAY: current->m_sfx->reallyPlayNow(); break;
case SFX_STOP: current->m_sfx->reallyStopNow(); break;
case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break;
case SFX_RESUME: current->m_sfx->reallyResumeNow(); break;
case SFX_SPEED: current->m_sfx->reallySetSpeed(
current->m_parameter.getX()); break;
current->m_parameter.getX()); break;
case SFX_POSITION: current->m_sfx->reallySetPosition(
current->m_parameter); break;
current->m_parameter); break;
case SFX_VOLUME: current->m_sfx->reallySetVolume(
current->m_parameter.getX()); break;
case SFX_MASTER_VOLUME:
current->m_sfx->reallySetMasterVolumeNow(
current->m_parameter.getX()); break;
current->m_parameter.getX()); break;
case SFX_MASTER_VOLUME:
current->m_sfx->reallySetMasterVolumeNow(
current->m_parameter.getX()); break;
case SFX_LOOP: current->m_sfx->reallySetLoop(
current->m_parameter.getX()!=0); break;
case SFX_DELETE: {
me->deleteSFX(current->m_sfx); break;
}
case SFX_PAUSE_ALL: me->reallyPauseAllNow(); break;
case SFX_RESUME_ALL: me->reallyResumeAllNow(); break;
case SFX_LISTENER: me->reallyPositionListenerNow(); break;
case SFX_UPDATE: me->reallyUpdateNow(current); break;
current->m_parameter.getX() != 0); break;
case SFX_DELETE: me->deleteSFX(current->m_sfx); break;
case SFX_PAUSE_ALL: me->reallyPauseAllNow(); break;
case SFX_RESUME_ALL: me->reallyResumeAllNow(); break;
case SFX_LISTENER: me->reallyPositionListenerNow(); break;
case SFX_UPDATE: me->reallyUpdateNow(current); break;
case SFX_MUSIC_START:
{
current->m_music_information->setDefaultVolume();
current->m_music_information->startMusic(); break;
}
case SFX_MUSIC_STOP:
current->m_music_information->stopMusic(); break;
case SFX_MUSIC_PAUSE:
current->m_music_information->pauseMusic(); break;
case SFX_MUSIC_RESUME:
current->m_music_information->resumeMusic();
// This might be necessasary if the volume was changed
// in the in-game menu
current->m_music_information->setDefaultVolume(); break;
case SFX_MUSIC_SWITCH_FAST:
current->m_music_information->switchToFastMusic(); break;
case SFX_MUSIC_SET_TMP_VOLUME:
{
MusicInformation *mi = current->m_music_information;
mi->setTemporaryVolume(current->m_parameter.getX()); break;
}
case SFX_MUSIC_WAITING:
current->m_music_information->setMusicWaiting(); break;
case SFX_MUSIC_DEFAULT_VOLUME:
{
current->m_music_information->setDefaultVolume();
}
default: assert("Not yet supported.");
}
delete current;
current = NULL;
// We access the size without lock, doesn't matter if we
// should get an incorrect value because of concurrent read/writes
if (me->m_sfx_commands.getData().size() == 0)
{
// Wait some time to let other threads run, then queue an
// update event to keep music playing.
StkTime::sleep(1);
me->queue(SFX_UPDATE, (SFXBase*)NULL, 0.01f);
}
me->m_sfx_commands.lock();
} // while
// Signal that the sfx manager can now be deleted.
// We signal this even before cleaning up memory, since there is no
// need to keep the user waiting for STK to exit.
me->setCanBeDeleted();
// Clean up memory to avoid leak detection
while(!me->m_sfx_commands.getData().empty())
{
@ -449,7 +514,8 @@ SFXBuffer* SFXManager::addSingleSfx(const std::string &sfx_name,
const bool load)
{
SFXBuffer* buffer = new SFXBuffer(sfx_file, positional, rolloff, max_width, gain);
SFXBuffer* buffer = new SFXBuffer(sfx_file, positional, rolloff,
max_width, gain);
m_all_sfx_types[sfx_name] = buffer;
@ -551,7 +617,7 @@ SFXBase* SFXManager::createSoundSource(SFXBuffer* buffer,
//----------------------------------------------------------------------------
SFXBase* SFXManager::createSoundSource(const std::string &name,
const bool addToSFXList)
const bool add_to_SFXList)
{
std::map<std::string, SFXBuffer*>::iterator i = m_all_sfx_types.find(name);
if ( i == m_all_sfx_types.end() )
@ -562,7 +628,7 @@ SFXBase* SFXManager::createSoundSource(const std::string &name,
return NULL;
}
return createSoundSource( i->second, addToSFXList );
return createSoundSource( i->second, add_to_SFXList );
} // createSoundSource
//----------------------------------------------------------------------------
@ -597,26 +663,28 @@ void SFXManager::deleteSFXMapping(const std::string &name)
} // deleteSFXMapping
//----------------------------------------------------------------------------
/** Make sures that the sfx thread is started at least one per frame. It also
/** Make sure that the sfx thread is started at least once per frame. It also
* adds an update command for the music manager.
* \param dt Time step size.
*/
void SFXManager::update(float dt)
{
queue(SFX_UPDATE, NULL, dt);
queue(SFX_UPDATE, (SFXBase*)NULL, dt);
// Wake up the sfx thread to handle all queued up audio commands.
pthread_cond_signal(&m_cond_request);
} // update
//----------------------------------------------------------------------------
/** Updates the status of all playing sfx (to test if they are finished).
* This function is executed once per thread (triggered by the
* This function is executed once per frame (triggered by the audio thread).
* \param current The sfx command - used to get timestep information.
*/
void SFXManager::reallyUpdateNow(SFXCommand *current)
{
assert(current->m_command==SFX_UPDATE);
float dt = current->m_parameter.getX();
music_manager->update(dt);
if (music_manager->getCurrentMusic())
music_manager->getCurrentMusic()->update(dt);
m_all_sfx.lock();
for (std::vector<SFXBase*>::iterator i = m_all_sfx.getData().begin();
i != m_all_sfx.getData().end(); i++)
@ -626,6 +694,17 @@ void SFXManager::reallyUpdateNow(SFXCommand *current)
} // for i in m_all_sfx
m_all_sfx.unlock();
// We need to lock the quick sounds during update, since adding more
// quick sounds by another thread could invalidate the iterator.
m_quick_sounds.lock();
std::map<std::string, SFXBase*>::iterator i = m_quick_sounds.getData().begin();
for (; i != m_quick_sounds.getData().end(); i++)
{
if (i->second->getStatus() == SFXBase::SFX_PLAYING)
i->second->updatePlayingSFX(dt);
} // for i in m_all_sfx
m_quick_sounds.unlock();
} // reallyUpdateNow
//----------------------------------------------------------------------------
@ -756,11 +835,13 @@ void SFXManager::setMasterSFXVolume(float gain)
// quick SFX
{
std::map<std::string, SFXBase*>::iterator i = m_quick_sounds.begin();
for (; i != m_quick_sounds.end(); i++)
m_quick_sounds.lock();
std::map<std::string, SFXBase*>::iterator i = m_quick_sounds.getData().begin();
for (; i != m_quick_sounds.getData().end(); i++)
{
(*i).second->setMasterVolume(m_master_gain);
}
m_quick_sounds.unlock();
}
} // setMasterSFXVolume
@ -809,7 +890,7 @@ void SFXManager::positionListener(const Vec3 &position, const Vec3 &front,
void SFXManager::reallyPositionListenerNow()
{
#if HAVE_OGGVORBIS
if (!UserConfigParams::m_sfx || !m_initialized) return;
if (!sfxAllowed()) return;
m_listener_position.lock();
{
@ -844,22 +925,28 @@ void SFXManager::reallyPositionListenerNow()
SFXBase* SFXManager::quickSound(const std::string &sound_type)
{
if (!sfxAllowed()) return NULL;
std::map<std::string, SFXBase*>::iterator sound = m_quick_sounds.find(sound_type);
if (sound == m_quick_sounds.end())
m_quick_sounds.lock();
std::map<std::string, SFXBase*>::iterator sound =
m_quick_sounds.getData().find(sound_type);
if (sound == m_quick_sounds.getData().end())
{
// sound not yet in our local list of quick sounds
SFXBase* newSound = SFXManager::get()->createSoundSource(sound_type, false);
if (newSound == NULL) return NULL;
newSound->play();
m_quick_sounds[sound_type] = newSound;
return newSound;
SFXBase* new_sound = createSoundSource(sound_type, false);
if (new_sound == NULL) return NULL;
new_sound->play();
m_quick_sounds.getData()[sound_type] = new_sound;
m_quick_sounds.unlock();
return new_sound;
}
else
{
(*sound).second->play();
return (*sound).second;
SFXBase *base_sound = sound->second;
base_sound->play();
m_quick_sounds.unlock();
return base_sound;
}
} // quickSound

View File

@ -19,6 +19,7 @@
#ifndef HEADER_SFX_MANAGER_HPP
#define HEADER_SFX_MANAGER_HPP
#include "utils/can_be_deleted.hpp"
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
#include "utils/synchronised.hpp"
@ -38,7 +39,7 @@
typedef unsigned int ALuint;
#endif
class MusicInformation;
class SFXBase;
class SFXBuffer;
class XMLNode;
@ -50,7 +51,7 @@ class XMLNode;
* on of the (shared) buffers from the sound manager.
* \ingroup audio
*/
class SFXManager : public NoCopy
class SFXManager : public NoCopy, public CanBeDeleted
{
private:
/** Singleton pointer. */
@ -76,6 +77,14 @@ public:
SFX_LOOP,
SFX_LISTENER,
SFX_UPDATE,
SFX_MUSIC_START,
SFX_MUSIC_STOP,
SFX_MUSIC_PAUSE,
SFX_MUSIC_RESUME,
SFX_MUSIC_SWITCH_FAST,
SFX_MUSIC_SET_TMP_VOLUME,
SFX_MUSIC_WAITING,
SFX_MUSIC_DEFAULT_VOLUME,
SFX_EXIT,
}; // SFXCommands
@ -108,10 +117,15 @@ private:
LEAK_CHECK()
public:
/** The sound effect for which the command should be executed. */
SFXBase *m_sfx;
SFXBase *m_sfx;
/** Stores music information for music commands. */
MusicInformation *m_music_information;
/** The command to execute. */
SFXCommands m_command;
/** Optional parameter for commands that need more input. */
/** Optional parameter for commands that need more input. Single
* floating point values are stored in the X component. */
Vec3 m_parameter;
// --------------------------------------------------------------------
SFXCommand(SFXCommands command, SFXBase *base)
@ -120,6 +134,22 @@ private:
m_sfx = base;
} // SFXCommand()
// --------------------------------------------------------------------
/** Constructor for music information commands. */
SFXCommand(SFXCommands command, MusicInformation *mi)
{
m_command = command;
m_music_information = mi;
} // SFXCommnd(MusicInformation*)
// --------------------------------------------------------------------
/** Constructor for music information commands that take a floating
* point parameter (which is stored in the X value of m_parameter). */
SFXCommand(SFXCommands command, MusicInformation *mi, float f)
{
m_command = command;
m_parameter.setX(f);
m_music_information = mi;
} // SFXCommnd(MusicInformation *, float)
// --------------------------------------------------------------------
SFXCommand(SFXCommands command, SFXBase *base, float parameter)
{
m_command = command;
@ -157,8 +187,9 @@ private:
/** The list of sound effects to be played in the next update. */
Synchronised< std::vector<SFXCommand*> > m_sfx_commands;
/** To play non-positional sounds without having to create a new object for each */
std::map<std::string, SFXBase*> m_quick_sounds;
/** To play non-positional sounds without having to create a
* new object for each. */
Synchronised<std::map<std::string, SFXBase*> > m_quick_sounds;
/** If the sfx manager has been initialised. */
bool m_initialized;
@ -187,6 +218,8 @@ public:
void queue(SFXCommands command, SFXBase *sfx=NULL);
void queue(SFXCommands command, SFXBase *sfx, float f);
void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p);
void queue(SFXCommands command, MusicInformation *mi);
void queue(SFXCommands command, MusicInformation *mi, float f);
// ------------------------------------------------------------------------
/** Static function to get the singleton sfx manager. */
static SFXManager *get()

View File

@ -38,7 +38,7 @@
#include <stdio.h>
#include <string>
SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain,
SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float volume,
bool owns_buffer)
: SFXBase()
{
@ -46,7 +46,7 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain,
m_sound_source = 0;
m_status = SFX_NOT_INITIALISED;
m_positional = positional;
m_default_gain = gain;
m_default_gain = volume;
m_loop = false;
m_gain = -1.0f;
m_master_gain = 1.0f;
@ -67,7 +67,7 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain,
* buffer. */
SFXOpenAL::~SFXOpenAL()
{
if (m_status!=SFX_UNKNOWN)
if (m_status!=SFX_UNKNOWN && m_status!=SFX_NOT_INITIALISED)
{
alDeleteSources(1, &m_sound_source);
}
@ -174,26 +174,27 @@ void SFXOpenAL::reallySetSpeed(float factor)
factor = 0.5f;
}
alSourcef(m_sound_source,AL_PITCH,factor);
SFXManager::checkError("setting speed");
} // reallySetSpeed
//-----------------------------------------------------------------------------
/** Changes the volume of a sound effect.
* \param gain Volume adjustment between 0.0 (mute) and 1.0 (full volume).
* \param volume Volume adjustment between 0.0 (mute) and 1.0 (full volume).
*/
void SFXOpenAL::setVolume(float gain)
void SFXOpenAL::setVolume(float volume)
{
if(m_status==SFX_UNKNOWN || !SFXManager::get()->sfxAllowed()) return;
assert(!isnan(gain)) ;
SFXManager::get()->queue(SFXManager::SFX_VOLUME, this, gain);
assert(!isnan(volume)) ;
SFXManager::get()->queue(SFXManager::SFX_VOLUME, this, volume);
} // setVolume
//-----------------------------------------------------------------------------
/** Changes the volume of a sound effect.
* \param gain Volume adjustment between 0.0 (mute) and 1.0 (full volume).
* \param volume Volume adjustment between 0.0 (mute) and 1.0 (full volume).
*/
void SFXOpenAL::reallySetVolume(float gain)
void SFXOpenAL::reallySetVolume(float volume)
{
m_gain = m_default_gain * gain;
m_gain = m_default_gain * volume;
if(m_status==SFX_UNKNOWN) return;
@ -209,23 +210,23 @@ void SFXOpenAL::reallySetVolume(float gain)
//-----------------------------------------------------------------------------
/** Schedules setting of the master volume.
* \param gain Gain value.
* \param volume Volume value.
*/
void SFXOpenAL::setMasterVolume(float gain)
void SFXOpenAL::setMasterVolume(float volume)
{
// This needs to be called even if sfx are disabled atm, so only exit
// in case that the sfx could not be loaded in the first place.
if(m_status==SFX_UNKNOWN) return;
SFXManager::get()->queue(SFXManager::SFX_MASTER_VOLUME, this, gain);
SFXManager::get()->queue(SFXManager::SFX_MASTER_VOLUME, this, volume);
} // setMasterVolume
//-----------------------------------------------------------------------------
/** Sets the master volume.
* \param gain Master volume.
* \param volume Master volume.
*/
void SFXOpenAL::reallySetMasterVolumeNow(float gain)
void SFXOpenAL::reallySetMasterVolumeNow(float volume)
{
m_master_gain = gain;
m_master_gain = volume;
if(m_status==SFX_UNKNOWN || m_status == SFX_NOT_INITIALISED) return;
@ -415,7 +416,7 @@ void SFXOpenAL::reallySetPosition(const Vec3 &position)
alSource3f(m_sound_source, AL_POSITION, position.getX(),
position.getY(), -position.getZ());
if (SFXManager::get()->getListenerPos().distance(position)
if (SFXManager::get()->getListenerPos().distance(position)
> m_sound_buffer->getMaxDist())
{
alSourcef(m_sound_source, AL_GAIN, 0);

View File

@ -76,7 +76,7 @@ private:
float m_play_time;
public:
SFXOpenAL(SFXBuffer* buffer, bool positional, float gain,
SFXOpenAL(SFXBuffer* buffer, bool positional, float volume,
bool owns_buffer = false);
virtual ~SFXOpenAL();
@ -97,10 +97,10 @@ public:
virtual void reallySetSpeed(float factor);
virtual void setPosition(const Vec3 &position);
virtual void reallySetPosition(const Vec3 &p);
virtual void setVolume(float gain);
virtual void reallySetVolume(float gain);
virtual void setMasterVolume(float gain);
virtual void reallySetMasterVolumeNow(float gain);
virtual void setVolume(float volume);
virtual void reallySetVolume(float volume);
virtual void setMasterVolume(float volume);
virtual void reallySetMasterVolumeNow(float volue);
virtual void onSoundEnabledBack();
virtual void setRolloff(float rolloff);
// ------------------------------------------------------------------------

View File

@ -214,7 +214,7 @@ void PlayerManager::load()
if(current)
{
stringw name;
current->get("player", &name);
current->getAndDecode("player", &name);
m_current_player = getPlayer(name);
}
@ -269,7 +269,7 @@ void PlayerManager::save()
if(m_current_player)
{
players_file << L" <current player=\""
<< m_current_player->getName() << L"\"/>\n";
<< StringUtils::xmlEncode(m_current_player->getName()) << L"\"/>\n";
}
// Save all non-guest players

View File

@ -78,7 +78,7 @@ PlayerProfile::PlayerProfile(const XMLNode* node)
m_achievements_status = NULL;
m_icon_filename = "";
node->get("name", &m_local_name );
node->getAndDecode("name", &m_local_name);
node->get("guest", &m_is_guest_account );
node->get("use-frequency", &m_use_frequency );
node->get("unique-id", &m_unique_id );
@ -196,7 +196,7 @@ const std::string PlayerProfile::getIconFilename() const
*/
void PlayerProfile::save(UTFWriter &out)
{
out << L" <player name=\"" << m_local_name
out << L" <player name=\"" << StringUtils::xmlEncode(m_local_name)
<< L"\" guest=\"" << m_is_guest_account
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n";

View File

@ -606,6 +606,11 @@ namespace UserConfigParams
PARAM_DEFAULT( IntUserConfigParam(0, "christmas-mode",
&m_graphics_quality, "Christmas hats: 0 use current date, 1 always on, 2 always off") );
// This saves the actual user preference.
PARAM_PREFIX IntUserConfigParam m_easter_ear_mode
PARAM_DEFAULT(IntUserConfigParam(0, "easter-ear-mode",
&m_graphics_quality, "Easter Bunny Ears: 0 use current date, 1 always on, 2 always off"));
PARAM_PREFIX BoolUserConfigParam m_weather_effects
PARAM_DEFAULT( BoolUserConfigParam(true, "weather_gfx",
&m_graphics_quality, "Weather effects") );
@ -649,6 +654,10 @@ namespace UserConfigParams
PARAM_DEFAULT( IntUserConfigParam(0,
"shadows_resoltion", &m_graphics_quality,
"Shadow resolution (0 = disabled") );
PARAM_PREFIX BoolUserConfigParam m_degraded_IBL
PARAM_DEFAULT(BoolUserConfigParam(false,
"Degraded_IBL", &m_graphics_quality,
"Disable specular IBL"));
// ---- Misc
PARAM_PREFIX BoolUserConfigParam m_cache_overworld

View File

@ -65,10 +65,9 @@ float &tex_width, float &tex_height,
float &tex_center_pos_x, float &tex_center_pos_y
)
{
core::dimension2d<u32> frame_size =
irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
core::dimension2d<u32> frame_size = irr_driver->getActualScreenSize();
const int screen_w = frame_size.Width;
const int screen_h = frame_size.Height;
const int screen_h = frame_size.Height;
center_pos_x = float(destRect.UpperLeftCorner.X + destRect.LowerRightCorner.X);
center_pos_x /= screen_w;
center_pos_x -= 1.;
@ -137,7 +136,7 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
return;
glEnable(GL_SCISSOR_TEST);
const core::dimension2d<u32>& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
const core::dimension2d<u32>& renderTargetSize = irr_driver->getActualScreenSize();
glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y,
clipRect->getWidth(), clipRect->getHeight());
}
@ -226,7 +225,7 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
return;
glEnable(GL_SCISSOR_TEST);
const core::dimension2d<u32>& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
const core::dimension2d<u32>& renderTargetSize = irr_driver->getActualScreenSize();
glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y,
clipRect->getWidth(), clipRect->getHeight());
}
@ -287,8 +286,7 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect<s32>& position,
return;
}
core::dimension2d<u32> frame_size =
irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
core::dimension2d<u32> frame_size = irr_driver->getActualScreenSize();
const int screen_w = frame_size.Width;
const int screen_h = frame_size.Height;
float center_pos_x = float(position.UpperLeftCorner.X + position.LowerRightCorner.X);
@ -318,7 +316,7 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect<s32>& position,
return;
glEnable(GL_SCISSOR_TEST);
const core::dimension2d<u32>& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
const core::dimension2d<u32>& renderTargetSize = irr_driver->getActualScreenSize();
glScissor(clip->UpperLeftCorner.X, renderTargetSize.Height - clip->LowerRightCorner.Y,
clip->getWidth(), clip->getHeight());
}

View File

@ -21,7 +21,7 @@
#include <math.h>
#include "audio/music_manager.hpp"
#include "audio/sfx_manager.hpp"
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "io/xml_node.hpp"
@ -164,21 +164,21 @@ void Camera::readEndCamera(const XMLNode &root)
*/
void Camera::setupCamera()
{
m_aspect = (float)(UserConfigParams::m_width)/UserConfigParams::m_height;
m_aspect = (float)(irr_driver->getActualScreenSize().Width)/irr_driver->getActualScreenSize().Height;
switch(race_manager->getNumLocalPlayers())
{
case 1: m_viewport = core::recti(0, 0,
UserConfigParams::m_width,
UserConfigParams::m_height);
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height);
m_scaling = core::vector2df(1.0f, 1.0f);
m_fov = DEGREE_TO_RAD*75.0f;
break;
case 2: m_viewport = core::recti(0,
m_index==0 ? 0
: UserConfigParams::m_height>>1,
UserConfigParams::m_width,
m_index==0 ? UserConfigParams::m_height>>1
: UserConfigParams::m_height);
: irr_driver->getActualScreenSize().Height>>1,
irr_driver->getActualScreenSize().Width,
m_index==0 ? irr_driver->getActualScreenSize().Height>>1
: irr_driver->getActualScreenSize().Height);
m_scaling = core::vector2df(1.0f, 0.5f);
m_aspect *= 2.0f;
m_fov = DEGREE_TO_RAD*65.0f;
@ -188,19 +188,19 @@ void Camera::setupCamera()
if(m_index<2)
{
m_viewport = core::recti(m_index==0 ? 0
: UserConfigParams::m_width>>1,
: irr_driver->getActualScreenSize().Width>>1,
0,
m_index==0 ? UserConfigParams::m_width>>1
: UserConfigParams::m_width,
UserConfigParams::m_height>>1);
m_index==0 ? irr_driver->getActualScreenSize().Width>>1
: irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height>>1);
m_scaling = core::vector2df(0.5f, 0.5f);
m_fov = DEGREE_TO_RAD*50.0f;
}
else
{
m_viewport = core::recti(0, UserConfigParams::m_height>>1,
UserConfigParams::m_width,
UserConfigParams::m_height);
m_viewport = core::recti(0, irr_driver->getActualScreenSize().Height>>1,
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height);
m_scaling = core::vector2df(1.0f, 0.5f);
m_fov = DEGREE_TO_RAD*65.0f;
m_aspect *= 2.0f;
@ -208,10 +208,10 @@ void Camera::setupCamera()
break;*/
case 4:
{ // g++ 4.3 whines about the variables in switch/case if not {}-wrapped (???)
const int x1 = (m_index%2==0 ? 0 : UserConfigParams::m_width>>1);
const int y1 = (m_index<2 ? 0 : UserConfigParams::m_height>>1);
const int x2 = (m_index%2==0 ? UserConfigParams::m_width>>1 : UserConfigParams::m_width);
const int y2 = (m_index<2 ? UserConfigParams::m_height>>1 : UserConfigParams::m_height);
const int x1 = (m_index%2==0 ? 0 : irr_driver->getActualScreenSize().Width>>1);
const int y1 = (m_index<2 ? 0 : irr_driver->getActualScreenSize().Height>>1);
const int x2 = (m_index%2==0 ? irr_driver->getActualScreenSize().Width>>1 : irr_driver->getActualScreenSize().Width);
const int y2 = (m_index<2 ? irr_driver->getActualScreenSize().Height>>1 : irr_driver->getActualScreenSize().Height);
m_viewport = core::recti(x1, y1, x2, y2);
m_scaling = core::vector2df(0.5f, 0.5f);
m_fov = DEGREE_TO_RAD*50.0f;
@ -222,8 +222,8 @@ void Camera::setupCamera()
Log::warn("Camera", "Incorrect number of players: '%d' - assuming 1.",
race_manager->getNumLocalPlayers());
m_viewport = core::recti(0, 0,
UserConfigParams::m_width,
UserConfigParams::m_height);
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height);
m_scaling = core::vector2df(1.0f, 1.0f);
m_fov = DEGREE_TO_RAD*75.0f;
break;

View File

@ -27,6 +27,7 @@ void CentralVideoSettings::init()
hasTextureCompression = false;
hasUBO = false;
hasGS = false;
m_GI_has_artifact = false;
m_need_rh_workaround = false;
m_need_srgb_workaround = false;
@ -140,6 +141,11 @@ void CentralVideoSettings::init()
UserConfigParams::m_high_definition_textures = 0x00;
}
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_GI))
{
m_GI_has_artifact = true;
}
// Specific disablement
if (strstr((const char *)glGetString(GL_VENDOR), "NVIDIA") != NULL)
{
@ -263,7 +269,7 @@ bool CentralVideoSettings::supportsShadows() const
bool CentralVideoSettings::supportsGlobalIllumination() const
{
return isARBGeometryShader4Usable() && isARBUniformBufferObjectUsable();
return isARBGeometryShader4Usable() && isARBUniformBufferObjectUsable() && !m_GI_has_artifact;
}
bool CentralVideoSettings::supportsIndirectInstancingRendering() const

View File

@ -26,6 +26,7 @@ private:
bool m_need_rh_workaround;
bool m_need_srgb_workaround;
bool m_GI_has_artifact;
public:
void init();
bool isGLSL() const;

View File

@ -57,7 +57,9 @@ namespace GraphicsRestrictions
"AMDVertexShaderLayer",
"DriverRecentEnough",
"HighDefinitionTextures",
"AdvancedPipeline"
"AdvancedPipeline",
"FramebufferSRGBWorking",
"GI",
};
} // namespace Private
using namespace Private;
@ -411,6 +413,11 @@ void unitTesting()
assert(Version("3.3 NVIDIA-10.0.19 310.90.10.05b1",
"NVIDIA GeForce GTX 680MX OpenGL Engine")
== Version("310.90.10.5") );
assert(Version("4.1 NVIDIA-10.0.43 310.41.05f01",
"NVIDIA GeForce GTX 780M OpenGL Engine")
== Version("310.41.05"));
assert(Version("3.1 (Core Profile) Mesa 10.3.0",
"Mesa DRI Mobile Intel\u00ae GM45 Express Chipset")
== Version("10.3.0") );

View File

@ -52,6 +52,8 @@ namespace GraphicsRestrictions
GR_DRIVER_RECENT_ENOUGH,
GR_HIGHDEFINITION_TEXTURES,
GR_ADVANCED_PIPELINE,
GR_FRAMEBUFFER_SRGB_WORKING,
GR_GI,
GR_COUNT /** MUST be last entry. */
} ;

View File

@ -478,6 +478,9 @@ void IrrDriver::initDevice()
m_gui_env = m_device->getGUIEnvironment();
m_video_driver = m_device->getVideoDriver();
m_sync = 0;
m_actual_screen_size = m_video_driver->getCurrentRenderTargetSize();
CVS->init();

View File

@ -100,6 +100,7 @@ enum TypeFBO
FBO_DISPLACE,
FBO_BLOOM_1024,
FBO_SCALAR_1024,
FBO_TMP_1024,
FBO_BLOOM_512,
FBO_TMP_512,
FBO_LENS_512,
@ -162,6 +163,7 @@ enum TypeRTT
RTT_BLOOM_1024,
RTT_SCALAR_1024,
RTT_TMP_1024,
RTT_BLOOM_512,
RTT_TMP_512,
RTT_LENS_512,
@ -209,6 +211,7 @@ private:
bool m_rsm_matrix_initialized;
bool m_rsm_map_available;
core::vector2df m_current_screen_size;
core::dimension2du m_actual_screen_size;
/** Additional details to be shown in case that a texture is not found.
* This is used to specify details like: "while loading kart '...'" */
@ -681,6 +684,7 @@ public:
const core::matrix4 &getProjViewMatrix() const { return m_ProjViewMatrix; }
const core::matrix4 &getInvProjViewMatrix() const { return m_InvProjViewMatrix; }
const core::vector2df &getCurrentScreenSize() const { return m_current_screen_size; }
const core::dimension2du getActualScreenSize() const { return m_actual_screen_size; }
// ------------------------------------------------------------------------
float getSSAORadius() const
{

View File

@ -288,7 +288,8 @@ public:
ParticleEmitter::ParticleEmitter(const ParticleKind* type,
const Vec3 &position,
scene::ISceneNode* parent,
bool randomize_initial_y)
bool randomize_initial_y,
bool important)
: m_position(position)
{
assert(type != NULL);
@ -300,6 +301,7 @@ ParticleEmitter::ParticleEmitter(const ParticleKind* type,
m_emission_decay_rate = 0;
m_is_glsl = CVS->isGLSL();
m_randomize_initial_y = randomize_initial_y;
m_important = important;
setParticleType(type);
@ -508,6 +510,14 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
m_node->setMaterialTexture(0, material->getTexture());
mat0.ZWriteEnable = !material->isTransparent(); // disable z-buffer writes if material is transparent
// fallback for old render engine
if (material->getShaderType() == Material::SHADERTYPE_ADDITIVE)
mat0.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
else if (material->getShaderType() == Material::SHADERTYPE_ALPHA_BLEND)
mat0.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
else if (material->getShaderType() == Material::SHADERTYPE_ALPHA_TEST)
mat0.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
}
else
{

View File

@ -76,6 +76,8 @@ private:
bool m_randomize_initial_y;
bool m_important;
public:
LEAK_CHECK()
@ -83,7 +85,8 @@ public:
ParticleEmitter (const ParticleKind* type,
const Vec3 &position,
scene::ISceneNode* parent = NULL,
bool randomize_initial_y = false);
bool randomize_initial_y = false,
bool important = false);
virtual ~ParticleEmitter();
virtual void update (float dt);
void setCreationRateAbsolute(float fraction);

View File

@ -98,11 +98,11 @@ void PostProcessing::reset()
const core::recti &vp = Camera::getCamera(i)->getViewport();
// Map viewport to [-1,1] x [-1,1]. First define the coordinates
// left, right, top, bottom:
float right = vp.LowerRightCorner.X < UserConfigParams::m_width
float right = vp.LowerRightCorner.X < irr_driver->getActualScreenSize().Width
? 0.0f : 1.0f;
float left = vp.UpperLeftCorner.X > 0.0f ? 0.0f : -1.0f;
float top = vp.UpperLeftCorner.Y > 0.0f ? 0.0f : 1.0f;
float bottom = vp.LowerRightCorner.Y < UserConfigParams::m_height
float bottom = vp.LowerRightCorner.Y < irr_driver->getActualScreenSize().Height
? 0.0f : -1.0f;
// Use left etc to define 4 vertices on which the rendered screen
@ -220,11 +220,22 @@ void PostProcessing::renderEnvMap(const float *bSHCoeff, const float *gSHCoeff,
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
glUseProgram(FullScreenShader::IBLShader::getInstance()->Program);
glBindVertexArray(SharedObject::FullScreenQuadVAO);
if (UserConfigParams::m_degraded_IBL)
{
glUseProgram(FullScreenShader::DegradedIBLShader::getInstance()->Program);
glBindVertexArray(SharedObject::FullScreenQuadVAO);
FullScreenShader::IBLShader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), skybox);
FullScreenShader::IBLShader::getInstance()->setUniforms();
FullScreenShader::DegradedIBLShader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH));
FullScreenShader::DegradedIBLShader::getInstance()->setUniforms();
}
else
{
glUseProgram(FullScreenShader::IBLShader::getInstance()->Program);
glBindVertexArray(SharedObject::FullScreenQuadVAO);
FullScreenShader::IBLShader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), skybox);
FullScreenShader::IBLShader::getInstance()->setUniforms();
}
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
@ -457,15 +468,10 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
}
void PostProcessing::renderPassThrough(GLuint tex)
void PostProcessing::renderPassThrough(GLuint tex, unsigned width, unsigned height)
{
glUseProgram(FullScreenShader::PassThroughShader::getInstance()->Program);
glBindVertexArray(FullScreenShader::PassThroughShader::getInstance()->vao);
FullScreenShader::PassThroughShader::getInstance()->SetTextureUnits(tex);
FullScreenShader::PassThroughShader::getInstance()->setUniforms();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
DrawFullScreenEffect<FullScreenShader::PassThroughShader>(width, height);
}
void PostProcessing::renderTextureLayer(unsigned tex, unsigned layer)
@ -510,10 +516,11 @@ void PostProcessing::renderSSAO()
DrawFullScreenEffect<FullScreenShader::SSAOShader>(irr_driver->getSSAORadius(), irr_driver->getSSAOK(), irr_driver->getSSAOSigma());
}
void PostProcessing::renderMotionBlur(unsigned cam, FrameBuffer &in_fbo, FrameBuffer &out_fbo)
void PostProcessing::renderMotionBlur(unsigned , FrameBuffer &in_fbo, FrameBuffer &out_fbo)
{
MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver->
getCallback(ES_MOTIONBLUR);
unsigned cam = Camera::getActiveCamera()->getIndex();
scene::ICameraSceneNode * const camnode =
Camera::getCamera(cam)->getCameraSceneNode();
@ -540,29 +547,21 @@ void PostProcessing::renderMotionBlur(unsigned cam, FrameBuffer &in_fbo, FrameBu
DrawFullScreenEffect<FullScreenShader::MotionBlurShader>(
// Todo : use a previousPVMatrix per cam, not global
irr_driver->getPreviousPVMatrix(),
cb->getCenter(cam),
cb->getBoostTime(0) * 10, // Todo : should be framerate dependent
core::vector2df(0.5, 0.5),
cb->getBoostTime(Camera::getActiveCamera()->getIndex()) * 10, // Todo : should be framerate dependent
0.15f);
}
static void renderGodFade(GLuint tex, const SColor &col)
{
glUseProgram(FullScreenShader::GodFadeShader::getInstance()->Program);
glBindVertexArray(FullScreenShader::GodFadeShader::getInstance()->vao);
FullScreenShader::GodFadeShader::getInstance()->SetTextureUnits(tex);
FullScreenShader::GodFadeShader::getInstance()->setUniforms(col);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
DrawFullScreenEffect<FullScreenShader::GodFadeShader>(col);
}
static void renderGodRay(GLuint tex, const core::vector2df &sunpos)
{
glUseProgram(FullScreenShader::GodRayShader::getInstance()->Program);
glBindVertexArray(FullScreenShader::GodRayShader::getInstance()->vao);
FullScreenShader::GodRayShader::getInstance()->SetTextureUnits(tex);
FullScreenShader::GodRayShader::getInstance()->setUniforms(sunpos);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
DrawFullScreenEffect<FullScreenShader::GodRayShader>(sunpos);
}
static void toneMap(FrameBuffer &fbo, GLuint rtt, float vignette_weight)
@ -593,10 +592,7 @@ void PostProcessing::applyMLAA()
// Pass 1: color edge detection
glUseProgram(FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->Program);
FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_MLAA_COLORS));
FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->setUniforms(PIXEL_SIZE);
glBindVertexArray(FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
DrawFullScreenEffect<FullScreenShader::MLAAColorEdgeDetectionSHader>(PIXEL_SIZE);
glStencilFunc(GL_EQUAL, 1, ~0);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
@ -607,10 +603,7 @@ void PostProcessing::applyMLAA()
glUseProgram(FullScreenShader::MLAABlendWeightSHader::getInstance()->Program);
FullScreenShader::MLAABlendWeightSHader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), getTextureGLuint(m_areamap));
FullScreenShader::MLAABlendWeightSHader::getInstance()->setUniforms(PIXEL_SIZE);
glBindVertexArray(FullScreenShader::MLAABlendWeightSHader::getInstance()->vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
DrawFullScreenEffect<FullScreenShader::MLAABlendWeightSHader>(PIXEL_SIZE);
// Blit in to tmp1
FrameBuffer::Blit(irr_driver->getFBO(FBO_MLAA_COLORS), irr_driver->getFBO(FBO_MLAA_TMP));
@ -620,10 +613,7 @@ void PostProcessing::applyMLAA()
glUseProgram(FullScreenShader::MLAAGatherSHader::getInstance()->Program);
FullScreenShader::MLAAGatherSHader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_MLAA_BLEND), irr_driver->getRenderTargetTexture(RTT_MLAA_TMP));
FullScreenShader::MLAAGatherSHader::getInstance()->setUniforms(PIXEL_SIZE);
glBindVertexArray(FullScreenShader::MLAAGatherSHader::getInstance()->vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
DrawFullScreenEffect<FullScreenShader::MLAAGatherSHader>(PIXEL_SIZE);
// Done.
glDisable(GL_STENCIL_TEST);
@ -682,7 +672,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
// Fade to quarter
irr_driver->getFBO(FBO_QUARTER1).Bind();
glViewport(0, 0, UserConfigParams::m_width / 4, UserConfigParams::m_height / 4);
glViewport(0, 0, irr_driver->getActualScreenSize().Width / 4, irr_driver->getActualScreenSize().Height / 4);
renderGodFade(out_fbo->getRTT()[0], col);
// Blur
@ -716,7 +706,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
glBlendEquation(GL_FUNC_ADD);
in_fbo->Bind();
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_QUARTER2));
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_QUARTER2), in_fbo->getWidth(), in_fbo->getHeight());
glDisable(GL_BLEND);
}
PROFILER_POP_CPU_MARKER();
@ -732,12 +722,13 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
glClear(GL_STENCIL_BUFFER_BIT);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
FrameBuffer::Blit(*in_fbo, irr_driver->getFBO(FBO_BLOOM_1024), GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(*in_fbo, irr_driver->getFBO(FBO_TMP_1024), GL_COLOR_BUFFER_BIT, GL_LINEAR);
irr_driver->getFBO(FBO_BLOOM_512).Bind();
renderBloom(irr_driver->getRenderTargetTexture(RTT_BLOOM_1024));
irr_driver->getFBO(FBO_BLOOM_1024).Bind();
renderBloom(irr_driver->getRenderTargetTexture(RTT_TMP_1024));
// Downsample
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_1024), irr_driver->getFBO(FBO_BLOOM_512), GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_BLOOM_256), GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_BLOOM_128), GL_COLOR_BUFFER_BIT, GL_LINEAR);
@ -749,22 +740,37 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
// Blur
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_TMP_512), 1., 1.);
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_TMP_256), 1., 1.);
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_128), irr_driver->getFBO(FBO_TMP_128), 1., 1.);
// The fbo sum chain is from https://software.intel.com/en-us/articles/compute-shader-hdr-and-bloom
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_512), irr_driver->getFBO(FBO_TMP_512));
renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_256), irr_driver->getFBO(FBO_TMP_256));
renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_128), irr_driver->getFBO(FBO_TMP_128));
// Additively blend on top of tmp1
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_128), irr_driver->getFBO(FBO_TMP_128), 2., 2.);
glEnable(GL_BLEND);
irr_driver->getFBO(FBO_BLOOM_256).Bind();
renderPassThrough(irr_driver->getFBO(FBO_BLOOM_128).getRTT()[0], 256, 256);
glDisable(GL_BLEND);
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_TMP_256), 2., 2.);
glEnable(GL_BLEND);
irr_driver->getFBO(FBO_BLOOM_512).Bind();
renderPassThrough(irr_driver->getFBO(FBO_BLOOM_256).getRTT()[0], 512, 512);
glDisable(GL_BLEND);
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_TMP_512), 2., 2.);
glEnable(GL_BLEND);
irr_driver->getFBO(FBO_BLOOM_1024).Bind();
renderPassThrough(irr_driver->getFBO(FBO_BLOOM_512).getRTT()[0], 1024, 1024);
glDisable(GL_BLEND);
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_1024), irr_driver->getFBO(FBO_TMP_1024), 2., 2.);
// Additively blend
in_fbo->Bind();
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
FullScreenShader::BloomBlendShader::getInstance()->SetTextureUnits(
irr_driver->getRenderTargetTexture(RTT_BLOOM_128), irr_driver->getRenderTargetTexture(RTT_BLOOM_256), irr_driver->getRenderTargetTexture(RTT_BLOOM_512));
DrawFullScreenEffect<FullScreenShader::BloomBlendShader>();
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_1024), in_fbo->getWidth(), in_fbo->getHeight());
FullScreenShader::LensBlendShader::getInstance()->SetTextureUnits(
@ -800,7 +806,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver->
getCallback(ES_MOTIONBLUR);
if (isRace && UserConfigParams::m_motionblur && World::getWorld() != NULL && cb->getBoostTime(0) > 0.) // motion blur
if (isRace && UserConfigParams::m_motionblur && World::getWorld() != NULL && cb->getBoostTime(Camera::getActiveCamera()->getIndex()) > 0.) // motion blur
{
renderMotionBlur(0, *in_fbo, *out_fbo);
std::swap(in_fbo, out_fbo);
@ -814,7 +820,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
glEnable(GL_FRAMEBUFFER_SRGB);
irr_driver->getFBO(FBO_MLAA_COLORS).Bind();
renderPassThrough(in_fbo->getRTT()[0]);
renderPassThrough(in_fbo->getRTT()[0], irr_driver->getFBO(FBO_MLAA_COLORS).getWidth(), irr_driver->getFBO(FBO_MLAA_COLORS).getHeight());
out_fbo = &irr_driver->getFBO(FBO_MLAA_COLORS);
if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.

View File

@ -91,7 +91,7 @@ public:
void renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &auxiliary);
/** Render tex. Used for blit/texture resize */
void renderPassThrough(unsigned tex);
void renderPassThrough(unsigned tex, unsigned width, unsigned height);
void renderTextureLayer(unsigned tex, unsigned layer);
void applyMLAA();

View File

@ -22,6 +22,7 @@
#include "graphics/callbacks.hpp"
#include "central_settings.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/graphics_restrictions.hpp"
#include "graphics/lod_node.hpp"
#include "graphics/post_processing.hpp"
#include "graphics/referee.hpp"
@ -253,13 +254,13 @@ void IrrDriver::renderGLSL(float dt)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
m_post_processing->renderPassThrough(m_rtts->getFBO(FBO_HALF1_R).getRTT()[0]);
m_post_processing->renderPassThrough(m_rtts->getFBO(FBO_HALF1_R).getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
}
else if (irr_driver->getRSM())
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
m_post_processing->renderPassThrough(m_rtts->getRSM().getRTT()[0]);
m_post_processing->renderPassThrough(m_rtts->getRSM().getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
}
else if (irr_driver->getShadowViz())
{
@ -271,7 +272,7 @@ void IrrDriver::renderGLSL(float dt)
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (CVS->isDefferedEnabled())
camera->activate();
m_post_processing->renderPassThrough(fbo->getRTT()[0]);
m_post_processing->renderPassThrough(fbo->getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
glDisable(GL_FRAMEBUFFER_SRGB);
}
}
@ -281,8 +282,8 @@ void IrrDriver::renderGLSL(float dt)
// Use full screen size
float tmp[2];
tmp[0] = float(UserConfigParams::m_width);
tmp[1] = float(UserConfigParams::m_height);
tmp[0] = float(m_actual_screen_size.Width);
tmp[1] = float(m_actual_screen_size.Height);
glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO);
glBufferSubData(GL_UNIFORM_BUFFER, (16 * 9) * sizeof(float), 2 * sizeof(float), tmp);
@ -293,8 +294,8 @@ void IrrDriver::renderGLSL(float dt)
// Set the viewport back to the full screen for race gui
m_video_driver->setViewPort(core::recti(0, 0,
UserConfigParams::m_width,
UserConfigParams::m_height));
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height));
for(unsigned int i=0; i<Camera::getNumCameras(); i++)
{
@ -378,6 +379,23 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
renderSolidFirstPass();
}
else
{
// We need a cleared depth buffer for some effect (eg particles depth blending)
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKING))
glDisable(GL_FRAMEBUFFER_SRGB);
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind();
// Bind() modifies the viewport. In order not to affect anything else,
// the viewport is just reset here and not removed in Bind().
const core::recti &vp = Camera::getActiveCamera()->getViewport();
glViewport(vp.UpperLeftCorner.X, vp.UpperLeftCorner.Y,
vp.LowerRightCorner.X - vp.UpperLeftCorner.X,
vp.LowerRightCorner.Y - vp.UpperLeftCorner.Y);
glClear(GL_DEPTH_BUFFER_BIT);
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKING))
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
PROFILER_POP_CPU_MARKER();

View File

@ -883,7 +883,7 @@ void IrrDriver::renderTransparent()
irr_driver->getFBO(FBO_COLORS).Bind();
glStencilFunc(GL_EQUAL, 1, 0xFF);
m_post_processing->renderPassThrough(m_rtts->getRenderTarget(RTT_DISPLACE));
m_post_processing->renderPassThrough(m_rtts->getRenderTarget(RTT_DISPLACE), irr_driver->getFBO(FBO_COLORS).getWidth(), irr_driver->getFBO(FBO_COLORS).getHeight());
glDisable(GL_STENCIL_TEST);
}

View File

@ -289,5 +289,5 @@ void IrrDriver::renderLightsScatter(unsigned pointlightcount)
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
getFBO(FBO_COLORS).Bind();
m_post_processing->renderPassThrough(getRenderTargetTexture(RTT_HALF1));
m_post_processing->renderPassThrough(getRenderTargetTexture(RTT_HALF1), getFBO(FBO_COLORS).getWidth(), getFBO(FBO_COLORS).getHeight());
}

View File

@ -105,6 +105,7 @@ RTT::RTT(size_t width, size_t height)
RenderTargetTextures[RTT_BLOOM_1024] = generateRTT(shadowsize0, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_SCALAR_1024] = generateRTT(shadowsize0, GL_R32F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_BLOOM_512] = generateRTT(shadowsize1, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_TMP_1024] = generateRTT(shadowsize0, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_TMP_512] = generateRTT(shadowsize1, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_LENS_512] = generateRTT(shadowsize1, GL_RGBA16F, GL_BGR, GL_FLOAT);
@ -192,6 +193,9 @@ RTT::RTT(size_t width, size_t height)
somevector.push_back(RenderTargetTextures[RTT_SCALAR_1024]);
FrameBuffers.push_back(new FrameBuffer(somevector, 1024, 1024));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_TMP_1024]);
FrameBuffers.push_back(new FrameBuffer(somevector, 1024, 1024));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_BLOOM_512]);
FrameBuffers.push_back(new FrameBuffer(somevector, 512, 512));
somevector.clear();
@ -306,7 +310,9 @@ FrameBuffer* RTT::render(scene::ICameraSceneNode* camera, float dt)
FrameBuffer* frame_buffer = irr_driver->getPostProcessing()->render(camera, false);
// reset
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
glViewport(0, 0,
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height);
irr_driver->setRTT(NULL);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

View File

@ -1570,16 +1570,6 @@ namespace FullScreenShader
AssignSamplerNames(Program, 0, "tex");
}
BloomBlendShader::BloomBlendShader()
{
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/bloomblend.frag").c_str());
AssignUniforms();
AssignSamplerNames(Program, 0, "tex_128", 1, "tex_256", 2, "tex_512");
}
LensBlendShader::LensBlendShader()
{
@ -1641,6 +1631,19 @@ namespace FullScreenShader
AssignSamplerNames(Program, 0, "ntex", 1, "dtex", 2, "probe");
}
DegradedIBLShader::DegradedIBLShader()
{
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/DiffuseIBL.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/SpecularIBL.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/degraded_ibl.frag").c_str());
AssignUniforms();
AssignSamplerNames(Program, 0, "ntex");
}
ShadowedSunLightShaderPCF::ShadowedSunLightShaderPCF()
{
Program = LoadProgram(OBJECT,
@ -1862,11 +1865,10 @@ namespace FullScreenShader
{
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/texturedquad.frag").c_str());
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/passthrough.frag").c_str());
AssignUniforms();
AssignUniforms("width", "height");
AssignSamplerNames(Program, 0, "tex");
vao = createVAO(Program);
}
LayerPassThroughShader::LayerPassThroughShader()
@ -1902,6 +1904,17 @@ namespace FullScreenShader
glShaderStorageBlockBinding(Program, block_idx, 2);
}
ShadowMatrixesGenerationShader::ShadowMatrixesGenerationShader()
{
Program = LoadProgram(OBJECT,
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/shadowmatrixgeneration.comp").c_str());
AssignUniforms("SunCamMatrix");
GLuint block_idx = glGetProgramResourceIndex(Program, GL_SHADER_STORAGE_BLOCK, "BoundingBoxes");
glShaderStorageBlockBinding(Program, block_idx, 2);
block_idx = glGetProgramResourceIndex(Program, GL_SHADER_STORAGE_BLOCK, "NewMatrixData");
glShaderStorageBlockBinding(Program, block_idx, 1);
}
DepthHistogramShader::DepthHistogramShader()
{
Program = LoadProgram(OBJECT,
@ -1965,7 +1978,6 @@ namespace FullScreenShader
AssignUniforms("col");
AssignSamplerNames(Program, 0, "tex");
vao = createVAO(Program);
}
GodRayShader::GodRayShader()
@ -1976,18 +1988,16 @@ namespace FullScreenShader
AssignUniforms("sunpos");
AssignSamplerNames(Program, 0, "tex");
vao = createVAO(Program);
}
MLAAColorEdgeDetectionSHader::MLAAColorEdgeDetectionSHader()
{
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/mlaa_offset.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/mlaa_color1.frag").c_str());
AssignUniforms("PIXEL_SIZE");
AssignSamplerNames(Program, 0, "colorMapG");
vao = createVAO(Program);
}
MLAABlendWeightSHader::MLAABlendWeightSHader()
@ -1998,18 +2008,16 @@ namespace FullScreenShader
AssignUniforms("PIXEL_SIZE");
AssignSamplerNames(Program, 0, "edgesMap", 1, "areaMap");
vao = createVAO(Program);
}
MLAAGatherSHader::MLAAGatherSHader()
{
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/mlaa_offset.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/mlaa_neigh3.frag").c_str());
AssignUniforms("PIXEL_SIZE");
AssignSamplerNames(Program, 0, "blendMap", 1, "colorMap");
vao = createVAO(Program);
}
}

View File

@ -388,12 +388,6 @@ public:
BloomShader();
};
class BloomBlendShader : public ShaderHelperSingleton<BloomBlendShader>, public TextureRead<Bilinear_Filtered, Bilinear_Filtered, Bilinear_Filtered>
{
public:
BloomBlendShader();
};
class LensBlendShader : public ShaderHelperSingleton<LensBlendShader>, public TextureRead<Bilinear_Filtered, Bilinear_Filtered, Bilinear_Filtered>
{
public:
@ -426,6 +420,12 @@ public:
IBLShader();
};
class DegradedIBLShader : public ShaderHelperSingleton<DegradedIBLShader>, public TextureRead<Nearest_Filtered>
{
public:
DegradedIBLShader();
};
class ShadowedSunLightShaderPCF : public ShaderHelperSingleton<ShadowedSunLightShaderPCF, float, float, float, float, float>, public TextureRead<Nearest_Filtered, Nearest_Filtered, Shadow_Sampler>
{
public:
@ -551,11 +551,9 @@ public:
Gaussian3VBlurShader();
};
class PassThroughShader : public ShaderHelperSingleton<PassThroughShader>, public TextureRead<Bilinear_Filtered>
class PassThroughShader : public ShaderHelperSingleton<PassThroughShader, int, int>, public TextureRead<Bilinear_Filtered>
{
public:
GLuint vao;
PassThroughShader();
};
@ -580,6 +578,12 @@ public:
LightspaceBoundingBoxShader();
};
class ShadowMatrixesGenerationShader : public ShaderHelperSingleton <ShadowMatrixesGenerationShader, core::matrix4>
{
public:
ShadowMatrixesGenerationShader();
};
class DepthHistogramShader : public ShaderHelperSingleton<DepthHistogramShader>, public TextureRead <Nearest_Filtered>
{
public:
@ -615,40 +619,30 @@ public:
class GodFadeShader : public ShaderHelperSingleton<GodFadeShader, video::SColorf>, public TextureRead<Bilinear_Filtered>
{
public:
GLuint vao;
GodFadeShader();
};
class GodRayShader : public ShaderHelperSingleton<GodRayShader, core::vector2df>, public TextureRead<Bilinear_Filtered>
{
public:
GLuint vao;
GodRayShader();
};
class MLAAColorEdgeDetectionSHader : public ShaderHelperSingleton<MLAAColorEdgeDetectionSHader, core::vector2df>, public TextureRead<Nearest_Filtered>
{
public:
GLuint vao;
MLAAColorEdgeDetectionSHader();
};
class MLAABlendWeightSHader : public ShaderHelperSingleton<MLAABlendWeightSHader, core::vector2df>, public TextureRead<Bilinear_Filtered, Nearest_Filtered>
{
public:
GLuint vao;
MLAABlendWeightSHader();
};
class MLAAGatherSHader : public ShaderHelperSingleton<MLAAGatherSHader, core::vector2df>, public TextureRead<Nearest_Filtered, Nearest_Filtered>
{
public:
GLuint vao;
MLAAGatherSHader();
};

View File

@ -1,87 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "graphics/shadow.hpp"
#include "graphics/irr_driver.hpp"
#include <IMesh.h>
#include <IMeshSceneNode.h>
#include <ISceneNode.h>
Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node,
float scale = 1.0, float x_offset = 0.0, float y_offset = 0.0,
float z_offset = 0.0)
{
video::SMaterial m;
m.setTexture(0, texture);
m.BackfaceCulling = false;
m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
m.setFlag(video::EMF_ZWRITE_ENABLE , false);
m_mesh = irr_driver->createQuadMesh(&m, /*create_one_quad*/true);
scene::IMeshBuffer *buffer = m_mesh->getMeshBuffer(0);
irr::video::S3DVertex* v=(video::S3DVertex*)buffer->getVertices();
v[0].Pos.X = -scale+x_offset; v[0].Pos.Z = scale+z_offset; v[0].Pos.Y = 0.01f-y_offset;
v[1].Pos.X = scale+x_offset; v[1].Pos.Z = scale+z_offset; v[1].Pos.Y = 0.01f-y_offset;
v[2].Pos.X = scale+x_offset; v[2].Pos.Z = -scale+z_offset; v[2].Pos.Y = 0.01f-y_offset;
v[3].Pos.X = -scale+x_offset; v[3].Pos.Z = -scale+z_offset; v[3].Pos.Y = 0.01f-y_offset;
v[0].TCoords = core::vector2df(0,0);
v[1].TCoords = core::vector2df(1,0);
v[2].TCoords = core::vector2df(1,1);
v[3].TCoords = core::vector2df(0,1);
core::vector3df normal(0, 0, 1.0f);
v[0].Normal = normal;
v[1].Normal = normal;
v[2].Normal = normal;
v[3].Normal = normal;
buffer->recalculateBoundingBox();
m_node = irr_driver->addMesh(m_mesh, "shadow");
#ifdef DEBUG
m_node->setName("shadow");
#endif
m_mesh->drop(); // the node grabs the mesh, so we can drop this reference
m_node->setAutomaticCulling(scene::EAC_OFF);
m_parent_kart_node = node;
m_parent_kart_node->addChild(m_node);
} // Shadow
// ----------------------------------------------------------------------------
Shadow::~Shadow()
{
// Note: the mesh was not loaded from disk, so it is not cached,
// and does not need to be removed. It's clean up when removing the node
m_parent_kart_node->removeChild(m_node);
} // ~Shadow
// ----------------------------------------------------------------------------
/** Removes the shadow, used for the simplified shadow when the kart is in
* the air.
*/
void Shadow::disableShadow()
{
m_node->setVisible(false);
}
// ----------------------------------------------------------------------------
/** Enables the shadow again, after it was disabled with disableShadow().
*/
void Shadow::enableShadow()
{
m_node->setVisible(true);
}
// ----------------------------------------------------------------------------

View File

@ -1,59 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_SHADOW_HPP
#define HEADER_SHADOW_HPP
#include "utils/no_copy.hpp"
#include <string>
namespace irr
{
namespace scene { class ISceneNode; class IMesh; }
namespace video { class ITexture; }
}
using namespace irr;
/**
* \brief This class is used to enable a shadow for a kart.
* For now it uses a simple texture to simulate the shadow, real time shadows might
* be added later.
* \ingroup graphics
*/
class Shadow : public NoCopy
{
private:
/** The scene node for the shadow. */
scene::ISceneNode *m_node;
/** The mesh of the shadow. */
scene::IMesh *m_mesh;
/** The scene node of the kart to which this shadow belongs. */
scene::ISceneNode *m_parent_kart_node;
public:
Shadow(video::ITexture *texture, scene::ISceneNode *node,
float scale, float x_offset, float y_offset,float z_offset);
~Shadow();
void enableShadow();
void disableShadow();
}; // Shadow
#endif
/* EOF */

View File

@ -108,110 +108,46 @@ struct Histogram
void IrrDriver::UpdateSplitAndLightcoordRangeFromComputeShaders(size_t width, size_t height)
{
// Value that should be kept between multiple calls
static GLuint ssbo[2];
static GLsync LightcoordBBFence = 0;
static float tmpshadowSplit[5] = { 1., 5., 20., 50., 150. };
// Currently unused code, that will be used later so please DON'T remove
//static Histogram *Hist[2];
//static size_t currentHist = 0;
//static GLuint ssboSplit[2];
static bool ssboInit = false;
static GLuint CBBssbo, tempShadowMatssbo;
CascadeBoundingBox InitialCBB[4];
if (!LightcoordBBFence)
{
glGenBuffers(2, ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo[0]);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(CascadeBoundingBox), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
CBB[0] = (CascadeBoundingBox *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizeof(CascadeBoundingBox), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo[1]);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(CascadeBoundingBox), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
CBB[1] = (CascadeBoundingBox *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * sizeof(CascadeBoundingBox), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
/* glGenBuffers(2, ssboSplit);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssboSplit[0]);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, sizeof(Histogram), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
Hist[0] = (Histogram *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Histogram), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssboSplit[1]);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, sizeof(Histogram), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
Hist[1] = (Histogram *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Histogram), GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);*/
}
// Use bounding boxes from last frame
if (LightcoordBBFence)
{
while (glClientWaitSync(LightcoordBBFence, GL_SYNC_FLUSH_COMMANDS_BIT, 0) != GL_ALREADY_SIGNALED);
glDeleteSync(LightcoordBBFence);
}
/* {
memcpy(shadowSplit, tmpshadowSplit, 5 * sizeof(float));
unsigned numpix = Hist[currentHist]->count;
unsigned split = 0;
unsigned i;
for (i = 0; i < 1022; i++)
{
split += Hist[currentHist]->bin[i];
if (split > numpix / 2)
break;
}
tmpshadowSplit[1] = (float)++i / 4.;
for (; i < 1023; i++)
{
split += Hist[currentHist]->bin[i];
if (split > 3 * numpix / 4)
break;
}
tmpshadowSplit[2] = (float)++i / 4.;
for (; i < 1024; i++)
{
split += Hist[currentHist]->bin[i];
if (split > 7 * numpix / 8)
break;
}
tmpshadowSplit[3] = (float)++i / 4.;
for (; i < 1024; i++)
{
split += Hist[currentHist]->bin[i];
}
tmpshadowSplit[0] = (float)(Hist[currentHist]->bin[1024] - 1) / 4.;
tmpshadowSplit[4] = (float)(Hist[currentHist]->bin[1025] + 1) / 4.;
printf("numpix is %d\n", numpix);
printf("total : %d\n", split);
printf("split 0 : %f\n", tmpshadowSplit[1]);
printf("split 1 : %f\n", tmpshadowSplit[2]);
printf("split 2 : %f\n", tmpshadowSplit[3]);
printf("min %f max %f\n", tmpshadowSplit[0], tmpshadowSplit[4]);
currentHist = (currentHist + 1) % 2;
}*/
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo[currentCBB]);
// glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssboSplit[currentHist]);
for (unsigned i = 0; i < 4; i++)
{
CBB[currentCBB][i].xmin = CBB[currentCBB][i].ymin = CBB[currentCBB][i].zmin = 1000;
CBB[currentCBB][i].xmax = CBB[currentCBB][i].ymax = CBB[currentCBB][i].zmax = -1000;
InitialCBB[i].xmin = InitialCBB[i].ymin = InitialCBB[i].zmin = 1000;
InitialCBB[i].xmax = InitialCBB[i].ymax = InitialCBB[i].zmax = -1000;
}
// memset(Hist[currentHist], 0, sizeof(Histogram));
// Hist[currentHist]->mindepth = 3000;
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
if (!ssboInit)
{
glGenBuffers(1, &CBBssbo);
glGenBuffers(1, &tempShadowMatssbo);
ssboInit = true;
}
glBindBuffer(GL_SHADER_STORAGE_BUFFER, CBBssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(CascadeBoundingBox), InitialCBB, GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, CBBssbo);
glUseProgram(FullScreenShader::LightspaceBoundingBoxShader::getInstance()->Program);
FullScreenShader::LightspaceBoundingBoxShader::getInstance()->SetTextureUnits(getDepthStencilTexture());
FullScreenShader::LightspaceBoundingBoxShader::getInstance()->setUniforms(m_suncam->getViewMatrix(), tmpshadowSplit[1], tmpshadowSplit[2], tmpshadowSplit[3], tmpshadowSplit[4]);
FullScreenShader::LightspaceBoundingBoxShader::getInstance()->setUniforms(m_suncam->getViewMatrix(), shadowSplit[1], shadowSplit[2], shadowSplit[3], shadowSplit[4]);
glDispatchCompute((int)width / 64, (int)height / 64, 1);
/* glUseProgram(FullScreenShader::DepthHistogramShader::getInstance()->Program);
FullScreenShader::DepthHistogramShader::getInstance()->SetTextureUnits(getDepthStencilTexture());
FullScreenShader::DepthHistogramShader::getInstance()->setUniforms();
glDispatchCompute((int)width / 32, (int)height / 32, 1);*/
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, tempShadowMatssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * 16 * sizeof(float), 0, GL_STATIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, tempShadowMatssbo);
glUseProgram(FullScreenShader::ShadowMatrixesGenerationShader::getInstance()->Program);
FullScreenShader::ShadowMatrixesGenerationShader::getInstance()->setUniforms(m_suncam->getViewMatrix());
glDispatchCompute(4, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
LightcoordBBFence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
currentCBB = (currentCBB + 1) % 2;
glBindBuffer(GL_COPY_READ_BUFFER, tempShadowMatssbo);
glBindBuffer(GL_COPY_WRITE_BUFFER, SharedObject::ViewProjectionMatrixesUBO);
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 80 * sizeof(float), 4 * 16 * sizeof(float));
}
/** Generate View, Projection, Inverse View, Inverse Projection, ViewProjection and InverseProjection matrixes
@ -282,60 +218,42 @@ void IrrDriver::computeMatrixesAndCameras(scene::ICameraSceneNode * const camnod
for (unsigned i = 0; i < 4; i++)
{
core::matrix4 tmp_matrix;
if (!CVS->isSDSMEnabled())
{
camnode->setFarValue(FarValues[i]);
camnode->setNearValue(NearValues[i]);
camnode->render();
const scene::SViewFrustum *frustrum = camnode->getViewFrustum();
float tmp[24] = {
frustrum->getFarLeftDown().X,
frustrum->getFarLeftDown().Y,
frustrum->getFarLeftDown().Z,
frustrum->getFarLeftUp().X,
frustrum->getFarLeftUp().Y,
frustrum->getFarLeftUp().Z,
frustrum->getFarRightDown().X,
frustrum->getFarRightDown().Y,
frustrum->getFarRightDown().Z,
frustrum->getFarRightUp().X,
frustrum->getFarRightUp().Y,
frustrum->getFarRightUp().Z,
frustrum->getNearLeftDown().X,
frustrum->getNearLeftDown().Y,
frustrum->getNearLeftDown().Z,
frustrum->getNearLeftUp().X,
frustrum->getNearLeftUp().Y,
frustrum->getNearLeftUp().Z,
frustrum->getNearRightDown().X,
frustrum->getNearRightDown().Y,
frustrum->getNearRightDown().Z,
frustrum->getNearRightUp().X,
frustrum->getNearRightUp().Y,
frustrum->getNearRightUp().Z,
};
memcpy(m_shadows_cam[i], tmp, 24 * sizeof(float));
std::vector<vector3df> vectors = getFrustrumVertex(*frustrum);
tmp_matrix = getTighestFitOrthoProj(SunCamViewMatrix, vectors, m_shadow_scales[i]);
}
else
{
float left = float(CBB[currentCBB][i].xmin / 4 - 2);
float right = float(CBB[currentCBB][i].xmax / 4 + 2);
float up = float(CBB[currentCBB][i].ymin / 4 - 2);
float down = float(CBB[currentCBB][i].ymax / 4 + 2);
camnode->setFarValue(FarValues[i]);
camnode->setNearValue(NearValues[i]);
camnode->render();
const scene::SViewFrustum *frustrum = camnode->getViewFrustum();
float tmp[24] = {
frustrum->getFarLeftDown().X,
frustrum->getFarLeftDown().Y,
frustrum->getFarLeftDown().Z,
frustrum->getFarLeftUp().X,
frustrum->getFarLeftUp().Y,
frustrum->getFarLeftUp().Z,
frustrum->getFarRightDown().X,
frustrum->getFarRightDown().Y,
frustrum->getFarRightDown().Z,
frustrum->getFarRightUp().X,
frustrum->getFarRightUp().Y,
frustrum->getFarRightUp().Z,
frustrum->getNearLeftDown().X,
frustrum->getNearLeftDown().Y,
frustrum->getNearLeftDown().Z,
frustrum->getNearLeftUp().X,
frustrum->getNearLeftUp().Y,
frustrum->getNearLeftUp().Z,
frustrum->getNearRightDown().X,
frustrum->getNearRightDown().Y,
frustrum->getNearRightDown().Z,
frustrum->getNearRightUp().X,
frustrum->getNearRightUp().Y,
frustrum->getNearRightUp().Z,
};
memcpy(m_shadows_cam[i], tmp, 24 * sizeof(float));
std::vector<vector3df> vectors = getFrustrumVertex(*frustrum);
tmp_matrix = getTighestFitOrthoProj(SunCamViewMatrix, vectors, m_shadow_scales[i]);
// Prevent Matrix without extend
if (left != right && up != down)
{
tmp_matrix.buildProjectionMatrixOrthoLH(left, right,
down, up,
float(CBB[currentCBB][i].zmin / 4 - 100),
float(CBB[currentCBB][i].zmax / 4 + 2));
m_shadow_scales[i] = std::make_pair(right - left, down - up);
}
}
m_shadow_camnodes[i]->setProjectionMatrix(tmp_matrix, true);
m_shadow_camnodes[i]->render();
@ -383,7 +301,13 @@ void IrrDriver::computeMatrixesAndCameras(scene::ICameraSceneNode * const camnod
tmp[144] = float(width);
tmp[145] = float(height);
glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO);
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 9 + 2) * sizeof(float), tmp);
if (CVS->isSDSMEnabled())
{
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 5) * sizeof(float), tmp);
glBufferSubData(GL_UNIFORM_BUFFER, (16 * 9) * sizeof(float), 2 * sizeof(float), &tmp[144]);
}
else
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 9 + 2) * sizeof(float), tmp);
}

View File

@ -2,7 +2,7 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "guiengine/CGUISpriteBank.h"
#include "guiengine/CGUISpriteBank.hpp"
#ifdef _IRR_COMPILE_WITH_GUI_
#include "IGUIEnvironment.h"

View File

@ -689,6 +689,7 @@ namespace GUIEngine
IGUIEnvironment* g_env;
Skin* g_skin = NULL;
ScalableFont *g_font;
ScalableFont *g_outline_font;
ScalableFont *g_large_font;
ScalableFont *g_title_font;
ScalableFont *g_small_font;
@ -974,6 +975,8 @@ namespace GUIEngine
g_large_font = NULL;
g_digit_font->drop();
g_digit_font = NULL;
g_outline_font->drop();
g_outline_font = NULL;
// nothing else to delete for now AFAIK, irrlicht will automatically
// kill everything along the device
@ -1080,6 +1083,9 @@ namespace GUIEngine
sfont_larger->setKerningHeight(-5);
g_large_font = sfont_larger;
g_outline_font = sfont->getHollowCopy();
g_outline_font->m_black_border = true;
Private::large_font_height = g_large_font->getDimension( L"X" ).Height;
ScalableFont* sfont_smaller = sfont->getHollowCopy();

View File

@ -83,6 +83,7 @@ namespace GUIEngine
extern Skin* g_skin;
extern irr::gui::ScalableFont* g_small_font;
extern irr::gui::ScalableFont* g_font;
extern irr::gui::ScalableFont* g_outline_font;
extern irr::gui::ScalableFont* g_large_font;
extern irr::gui::ScalableFont* g_title_font;
extern irr::gui::ScalableFont* g_digit_font;
@ -136,6 +137,8 @@ namespace GUIEngine
*/
inline irr::gui::ScalableFont* getFont() { return Private::g_font; }
inline irr::gui::ScalableFont* getOutlineFont() { return Private::g_outline_font; }
/**
* \return the "large" font (useful for text)
*/

View File

@ -52,6 +52,8 @@ public:
m_message = message;
if(mt==MessageQueue::MT_ACHIEVEMENT)
m_render_type = "achievement-message::neutral";
else if (mt==MessageQueue::MT_ERROR)
m_render_type = "error-message::neutral";
else
m_render_type = "friend-message::neutral";
} // Message
@ -77,7 +79,7 @@ class CompareMessages
public:
/** Used to sort messages by priority in the priority queue. Achievement
* messages (1) need to have a higher priority than friend messages
* (value 0). */
* (value 0), and errors (3) the highest priority. */
bool operator() (const Message *a, const Message *b) const
{
return a->getMessageType() < b->getMessageType();

View File

@ -34,7 +34,7 @@ namespace MessageQueue
* different look. This type is used to sort the messages, so it is
* important that messages that need to be shown as early as possible
* will be listed last (i.e. have highest priority). */
enum MessageType {MT_FRIEND, MT_ACHIEVEMENT};
enum MessageType { MT_FRIEND, MT_ACHIEVEMENT, MT_ERROR};
void add(MessageType mt, const core::stringw &message);
void updatePosition();

View File

@ -668,9 +668,9 @@ void ScalableFont::doDraw(const core::stringw& text,
if (fallback[n])
{
// TODO: don't hardcode colors?
static video::SColor orange(color.getAlpha(), 255, 100, 0);
static video::SColor yellow(color.getAlpha(), 255, 220, 15);
video::SColor title_colors[] = {yellow, orange, orange, yellow};
video::SColor orange(color.getAlpha(), 255, 100, 0);
video::SColor yellow(color.getAlpha(), 255, 220, 15);
video::SColor title_colors[] = {orange, yellow, orange, yellow};
if (charCollector != NULL)
{

View File

@ -19,6 +19,7 @@
#include "guiengine/screen.hpp"
#include "io/file_manager.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/layout_manager.hpp"
#include "guiengine/modaldialog.hpp"
@ -234,16 +235,14 @@ void Screen::manualRemoveWidget(Widget* w)
/** \brief Implementing method from AbstractTopLevelContainer */
int Screen::getWidth()
{
core::dimension2d<u32> frame_size = GUIEngine::getDriver()->getCurrentRenderTargetSize();
return frame_size.Width;
return irr_driver->getActualScreenSize().Width;
}
// -----------------------------------------------------------------------------
/** \brief Implementing method from AbstractTopLevelContainer */
int Screen::getHeight()
{
core::dimension2d<u32> frame_size = GUIEngine::getDriver()->getCurrentRenderTargetSize();
return frame_size.Height;
return irr_driver->getActualScreenSize().Height;
}
// -----------------------------------------------------------------------------

View File

@ -346,8 +346,7 @@ void Skin::drawBgImage()
source_area = core::recti(0, 0, texture_w, texture_h);
core::dimension2d<u32> frame_size =
GUIEngine::getDriver()->getCurrentRenderTargetSize();
core::dimension2d<u32> frame_size = irr_driver->getActualScreenSize();
const int screen_w = frame_size.Width;
const int screen_h = frame_size.Height;
@ -971,7 +970,7 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget,
// automatically guess from position on-screen if tabs go up or down
const bool vertical_flip =
(unsigned int)rect.UpperLeftCorner.Y <
GUIEngine::getDriver()->getCurrentRenderTargetSize().Height/2;
irr_driver->getActualScreenSize().Height / 2;
params->m_vertical_flip = vertical_flip;
core::recti rect2 = rect;
@ -2260,9 +2259,8 @@ void Skin::drawBGFadeColor()
SColor color = SkinConfig::m_colors["dialog_background::neutral"];
if (m_dialog_size < 1.0f)
color.setAlpha( (unsigned int)(color.getAlpha()*m_dialog_size ));
GL32_draw2DRectangle(color,
core::recti(position2d< s32 >(0,0),
GUIEngine::getDriver()->getCurrentRenderTargetSize()) );
GL32_draw2DRectangle(color, core::recti(position2d< s32 >(0,0),
irr_driver->getActualScreenSize()));
} // drawBGFadeColor
// -----------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CGUIEditBox.h"
#include "guiengine/widgets/CGUIEditBox.hpp"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"

View File

@ -3,7 +3,7 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "guiengine/widgets/CGUISTKListBox.h"
#include "guiengine/widgets/CGUISTKListBox.hpp"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"

View File

@ -518,6 +518,7 @@ void DynamicRibbonWidget::clearItems()
m_scroll_offset = 0;
m_max_label_width = 0;
}
// -----------------------------------------------------------------------------
void DynamicRibbonWidget::elementRemoved()
{

View File

@ -22,6 +22,8 @@
#include <irrString.h>
#include <algorithm>
#include "guiengine/widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "utils/leak_check.hpp"
@ -237,6 +239,13 @@ namespace GUIEngine
'updateItemDisplay' to update the display. */
void clearItems();
/** Sort the list of items with a given comparator. */
template<typename Compare>
void sortItems(Compare comp)
{
std::sort(m_items.begin(), m_items.end(), comp);
}
/**
* \brief Register a listener to be notified of selection changes within the ribbon.
* \note The ribbon takes ownership of this listener and will delete it.

View File

@ -68,16 +68,24 @@ void IconButtonWidget::add()
}
else if (m_icon_path_type == ICON_PATH_TYPE_RELATIVE)
{
std::string file = file_manager->getAsset(m_properties[PROP_ICON]);
setTexture(irr_driver->getTexture(file));
// Avoid warning about missing texture in case of e.g.
// screenshot widget
if(m_properties[PROP_ICON] != "")
{
std::string file = file_manager->getAsset(m_properties[PROP_ICON]);
setTexture(irr_driver->getTexture(file));
}
}
}
if (m_texture == NULL)
{
Log::error("icon_button",
"add() : error, cannot find texture '%s'.",
m_properties[PROP_ICON].c_str());
if (m_properties[PROP_ICON].size() > 0)
{
Log::error("icon_button",
"add() : error, cannot find texture '%s' in iconbutton '%s'.",
m_properties[PROP_ICON].c_str(), m_properties[PROP_ID].c_str());
}
std::string file = file_manager->getAsset(FileManager::GUI,"main_help.png");
setTexture(irr_driver->getTexture(file));
if(!m_texture)

View File

@ -17,14 +17,14 @@
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/CGUISpriteBank.h"
#include "guiengine/CGUISpriteBank.hpp"
#include "guiengine/engine.hpp"
#include "io/file_manager.hpp"
#include <IGUIElement.h>
#include <IGUISkin.h>
#include <IGUIEnvironment.h>
#include "IGUIFontBitmap.h"
#include <IGUIFontBitmap.h>
#include <sstream>

Some files were not shown because too many files have changed in this diff Show More