Merge branch 'origin/master' into fixes
This commit is contained in:
commit
e5abf4cec3
6
.gitignore
vendored
6
.gitignore
vendored
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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"/>
|
||||
|
@ -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" />
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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" >
|
||||
|
@ -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
2
data/po/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
transifex
|
||||
tx.exe
|
@ -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
|
26
data/po/pull_from_transifex.sh
Normal file
26
data/po/pull_from_transifex.sh
Normal 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
@ -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 "---------------------------"
|
||||
|
@ -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++) {
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.));
|
||||
|
@ -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.);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
18
data/shaders/degraded_ibl.frag
Normal file
18
data/shaders/degraded_ibl.frag
Normal 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.);
|
||||
}
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
11
data/shaders/passthrough.frag
Normal file
11
data/shaders/passthrough.frag
Normal 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);
|
||||
}
|
52
data/shaders/shadowmatrixgeneration.comp
Normal file
52
data/shaders/shadowmatrixgeneration.comp
Normal 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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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"/>
|
||||
|
@ -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/ocean/achievement.png
Normal file
BIN
data/skins/ocean/achievement.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
data/skins/ocean/error.png
Executable file
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
BIN
data/skins/ocean/friend.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
@ -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
BIN
data/skins/peach/error.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@ -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
6
doc/assets_version
Normal 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
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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, " ", "\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=\""
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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") );
|
||||
|
@ -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. */
|
||||
} ;
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
*/
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -518,6 +518,7 @@ void DynamicRibbonWidget::clearItems()
|
||||
m_scroll_offset = 0;
|
||||
m_max_label_width = 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void DynamicRibbonWidget::elementRemoved()
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user