Merged Master

This commit is contained in:
Sachith Hasaranga Seneviratne 2014-09-07 11:28:15 +05:30
commit 118db58a02
178 changed files with 6129 additions and 3618 deletions

View File

@ -14,13 +14,13 @@ before_install:
# Update repos
- sudo apt-get update -qq
# Install dependencies
- sudo apt-get install build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev
- sudo apt-get install build-essential libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev
# Install mesa from an other repo (a newer version is required). Quantal is not supported anymore, saucy is only supported till July 2014,
# so we try to use trusty (precise which is what traiv uses a too old mesa version which doesn't link)
- sudo apt-add-repository "deb http://archive.ubuntu.com/ubuntu trusty main restricted"
- sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 3B4FE6ACC0B21F32
- sudo apt-get update -qq
- sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev
- sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev libglew-dev cmake
script:
# First a debug build:
- mkdir build-debug

View File

@ -15,12 +15,12 @@ option(USE_WIIUSE "Support for wiimote input devices" ON)
option(USE_FRIBIDI "Support for right-to-left languages" ON)
option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
if(UNIX)
if(UNIX OR MINGW)
option(USE_CPP2011 "Activate C++ 2011 mode (GCC only)" OFF)
endif()
if(MSVC)
if(MSVC OR MINGW)
# Normally hide the option to build wiiuse on VS, since it depends
# on the installation of the Windows DDK (Driver Developer Kit),
# on the installation of the Windows DDK (Driver Developer Kit),
# which also needs an absolute path :(
option(WIIUSE_BUILD "Build wiiuse lib (only for developers)" OFF)
mark_as_advanced(WIIUSE_BUILD)
@ -28,6 +28,10 @@ else()
set(WIIUSE_BUILD ON)
endif()
if(MINGW)
set(USE_WIIUSE OFF)
endif()
if(UNIX AND NOT APPLE)
option(USE_XRANDR "Use xrandr instead of vidmode" ON)
option(USE_ASAN "Build with Leak/Address sanitizer" OFF)
@ -69,6 +73,7 @@ endif()
# Build the angelscript library
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/angelscript/projects/cmake")
include_directories("${PROJECT_SOURCE_DIR}/lib/angelscript/include")
# Set include paths
include_directories(${STK_SOURCE_DIR})
@ -80,6 +85,11 @@ if(MSVC)
add_definitions(/D_IRR_STATIC_LIB_)
endif()
if(MINGW)
set(ENV{OPENALDIR} ${PROJECT_SOURCE_DIR}/dependencies)
add_definitions(-D_IRR_STATIC_LIB_)
endif()
if(APPLE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch i386")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch i386 -F/Library/Frameworks")
@ -124,8 +134,15 @@ if(USE_FRIBIDI)
endif()
endif()
# OpenMP
find_package(OpenMP)
if (OPENMP_FOUND)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
if(UNIX)
if(UNIX OR MINGW)
# if(USE_CPP2011)
add_definitions("-std=gnu++0x")
# endif()
@ -135,6 +152,10 @@ endif()
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
# Glew
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIR})
if(UNIX AND NOT APPLE)
if(USE_XRANDR)
find_package(Xrandr REQUIRED)
@ -147,7 +168,7 @@ if(UNIX AND NOT APPLE)
endif()
endif()
# Set some compiler options
if(UNIX)
add_definitions(-Wall)
@ -175,6 +196,9 @@ endif()
# TODO: remove this switch
add_definitions(-DHAVE_OGGVORBIS)
if(WIN32 AND NOT MINGW)
configure_file("${STK_SOURCE_DIR}/windows_installer/icon_rc.template" "${PROJECT_BINARY_DIR}/tmp/icon.rc")
endif()
# Provides list of source and header files (STK_SOURCES and STK_HEADERS)
include(sources.cmake)
@ -230,7 +254,7 @@ else()
endif()
# Build the final executable
add_executable(supertuxkart ${STK_SOURCES} ${STK_HEADERS})
add_executable(supertuxkart ${STK_SOURCES} ${STK_RESOURCES} ${STK_HEADERS})
target_link_libraries(supertuxkart ${PTHREAD_LIBRARY})
endif()
@ -253,8 +277,9 @@ target_link_libraries(supertuxkart
${CURL_LIBRARIES}
${OGGVORBIS_LIBRARIES}
${OPENAL_LIBRARY}
${OPENGL_LIBRARIES})
${OPENGL_LIBRARIES}
${GLEW_LIBRARIES})
if(UNIX AND NOT APPLE)
if(USE_XRANDR)
target_link_libraries(supertuxkart ${XRANDR_LIBRARIES})
@ -288,8 +313,12 @@ if(USE_WIIUSE)
if(APPLE)
find_library(BLUETOOTH_LIBRARY NAMES IOBluetooth PATHS /Developer/Library/Frameworks/IOBluetooth.framework)
target_link_libraries(supertuxkart wiiuse ${BLUETOOTH_LIBRARY})
elseif(MSVC)
add_definitions("/DWIIUSE_STATIC")
elseif(WIN32)
if(MSVC)
add_definitions("/DWIIUSE_STATIC")
else()
add_definitions("-DWIIUSE_STATIC")
endif()
if(WIIUSE_BUILD)
target_link_libraries(supertuxkart wiiuse)
else()
@ -302,12 +331,12 @@ if(USE_WIIUSE)
endif()
if(MSVC)
if(MSVC OR MINGW)
target_link_libraries(supertuxkart iphlpapi.lib)
add_custom_command(TARGET supertuxkart POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/dependencies/dll"
$<TARGET_FILE_DIR:supertuxkart>)
$<TARGET_FILE_DIR:supertuxkart>)
add_custom_target(stkshaders SOURCES ${STK_SHADERS})
endif()
@ -316,7 +345,7 @@ add_subdirectory(tools/font_tool)
# ==== Make dist target ====
if(MSVC)
if(MSVC OR MINGW)
# Don't create a dist target for VS
else()
add_custom_target(dist
@ -340,9 +369,9 @@ endif()
# ==== Checking if stk-assets folder exists ====
if(CHECK_ASSETS)
if((IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/karts) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/library) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/music) AND
if((IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/karts) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/library) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/music) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/sfx) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/textures) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/tracks))
@ -368,11 +397,8 @@ install(DIRECTORY ${STK_DATA_DIR} DESTINATION ${STK_INSTALL_DATA_DIR} PATTERN ".
if(STK_ASSETS_DIR AND CHECK_ASSETS)
install(DIRECTORY ${STK_ASSETS_DIR} DESTINATION ${STK_INSTALL_DATA_DIR}/data PATTERN ".svn" EXCLUDE PATTERN ".git" EXCLUDE)
endif()
install(FILES ${PROJECT_BINARY_DIR}/supertuxkart.desktop DESTINATION share/applications)
install(FILES ${STK_DATA_DIR}/supertuxkart.desktop DESTINATION share/applications)
install(FILES data/supertuxkart_32.png DESTINATION share/icons/hicolor/32x32 RENAME supertuxkart.png)
install(FILES data/supertuxkart_128.png DESTINATION share/icons/hicolor/128x128 RENAME supertuxkart.png)
install(FILES data/supertuxkart_32.png data/supertuxkart_128.png DESTINATION share/pixmaps)
install(FILES data/supertuxkart.appdata DESTINATION share/appdata)
set(PREFIX ${CMAKE_INSTALL_PREFIX})
configure_file(data/supertuxkart_desktop.template supertuxkart.desktop)
add_dependencies(supertuxkart supertuxkart.desktop)

View File

@ -23,7 +23,7 @@ Ubuntu command:
```
sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev \
libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev
libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev libxrandr-dev
```
Unpack the files from the tarball like this:

69
data/gui/gp_info.stkgui Normal file
View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
<header id="name" height="5%" width="80%" align="center" text_align="center"/>
<spacer width="1" height="5%"/>
<box width="95%" height="40%" padding="10" layout="horizontal-row">
<spacer width="10" height="100%"/>
<!-- Left pane -->
<div width="45%" height="95%" align="center" layout="vertical-row">
<placeholder proportion="1" width="100%" height="100%" id="screenshot_div">
</placeholder>
</div>
<spacer width="5%" height="100%"/>
<!-- Right pane -->
<div width="45%" height="95%" align="center" layout="vertical-row">
<list id="tracks" width="100%" height="100%"/>
</div>
</box>
<spacer width="1" height="5%"/>
<box width="95%" height="25%" padding="10" layout="horizontal-row">
<spacer width="1" height="5%"/>
<div width="50%" height="100%" layout="vertical-row">
<div width="100%" height="20%" layout="horizontal-row" >
<label id="ai-text" height="100%" width="50%" I18N="Number of AI karts" text="AI karts"/>
<spinner id="ai-spinner" width="50%" min_value="1" max_value="20" align="center"
wrap_around="true" />
</div>
<spacer height="5%" />
<div width="100%" height="20%" layout="horizontal-row" >
<label id="reverse-text" width="50%" height="100%" I18N="Drive the track reverse" text="Reverse"/>
<spinner id="reverse-spinner" width="50%" align="center" wrap_around="true" />
</div>
<spacer height="5%" />
<div width="100%" height="20%" layout="horizontal-row">
<label id="track-text" width="50%" height="100%" text="Tracks"
I18N="Number of tracks to pick in a random Grand Prix."/>
<spinner id="track-spinner" width="50%" min_value="1" max_value="20" align="center"
wrap_around="true" />
<spacer height="1%" />
</div>
<spacer height="5%" />
<div width="100%" height="20%" layout="horizontal-row" >
<label id="group-text" width="50%" height="100%" I18N="Number of AI karts" text="Track group"/>
<spinner id="group-spinner" width="50%" align="center" wrap_around="true" />
<spacer proportion="1" height="2" />
</div>
</div>
</box>
<spacer width="1" height="5%"/>
<buttonbar id="buttons" height="15%" width="100%" align="center">
<icon-button id="start" width="64" height="64" icon="gui/green_check.png"
I18N="Start race" text="Start Race"/>
<icon-button id="continue" width="64" height="64" icon="gui/green_check.png"
I18N="Continue saved GP" text="Continue saved GP"/>
</buttonbar>
</div>
</stkgui>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
<spacer width="10" proportion="1"/>
<button id="continue" x="20" width="250" align="left" text="Continue"/>
<div x="2%" y="2%" width="96%" height="96%" layout="horizontal-row">
<button id="continue" width="250" align="bottom" text="Continue"/>
<spacer width="20"/>
<button id="save" width="250" align="bottom" text="Save Grand Prix"/>
</div>
</stkgui>

View File

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
<spacer width="10" proportion="1"/>
<button id="continue" x="20" width="250" align="left" text="Continue"/>
<div x="2%" y="2%" width="96%" height="96%" layout="horizontal-row">
<button id="continue" width="250" align="bottom" text="Continue"/>
<spacer width="20"/>
<button id="save" width="250" align="bottom" text="Save Grand Prix"/>
</div>
</stkgui>

View File

@ -1,41 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="5%" y="5%" width="90%" height="90%" layout="vertical-row" >
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row" >
<header width="80%" text="Race Setup" align="center" text_align="center" />
<header height="5%" width="80%" text="Race Setup" align="center" text_align="center" />
<spacer proportion="1" width="25"/>
<spacer height="5%" width="25"/>
<box width="95%" height="40%" padding="10" layout="vertical-row">
<bright width="100%" text="Select a difficulty" align="center" text_align="left" />
<div layout="horizontal-row" width="100%" height="50" align="center">
<bright proportion="1" height="100%"
I18N="In race setup menu" text="Number of AI karts" text_align="right" />
<spacer width="50" height="25"/>
<!--
<spinner id="aikartamount" proportion="3" height="100%" min_value="0" max_value="8" icon="gui/karts%i.png"/> -->
<!-- The maximum is set by stk from data/stk_config.xml. -->
<spinner id="aikartamount" proportion="1" height="100%" min_value="0" wrap_around="true"/>
</div>
<ribbon id="difficulty" height="135" width="100%" align="center">
<icon-button id="novice" width="128" height="128" icon="gui/difficulty_easy.png"
I18N="Difficulty" text="Novice"/>
<icon-button id="intermediate" width="128" height="128" icon="gui/difficulty_medium.png"
I18N="Difficulty" text="Intermediate"/>
<icon-button id="expert" width="128" height="128" icon="gui/difficulty_hard.png"
I18N="Difficulty" text="Expert"/>
<icon-button id="best" width="128" height="128" icon="gui/difficulty_best.png"
I18N="Difficulty" text="SuperTux"/>
</ribbon>
</box>
<spacer height="5%"" width="25"/>
<spacer proportion="1" width="25"/>
<box width="95%" height="40%" padding="10" layout="vertical-row">
<bright width="100%" text="Select a game mode" align="center" text_align="left" />
<ribbon id="difficulty" height="135" width="65%" align="center">
<icon-button id="novice" width="128" height="128" icon="gui/difficulty_easy.png"
I18N="Difficulty" text="Novice"/>
<icon-button id="intermediate" width="128" height="128" icon="gui/difficulty_medium.png"
I18N="Difficulty" text="Intermediate"/>
<icon-button id="expert" width="128" height="128" icon="gui/difficulty_hard.png"
I18N="Difficulty" text="Expert"/>
<icon-button id="best" width="128" height="128" icon="gui/difficulty_best.png"
I18N="Difficulty" text="SuperTux"/>
</ribbon>
<spacer proportion="1" width="25"/>
<bright width="100%" text="Select a game mode" align="center" text_align="left" />
<scrollable_toolbar id="gamemode" height="135" width="85%" label_location="bottom" align="center"
child_width="135" child_height="135" />
<spacer proportion="1" width="25" />
<scrollable_toolbar id="gamemode" height="135" width="85%" label_location="bottom" align="center"
child_width="135" child_height="135" />
<spacer proportion="1" width="25" />
</box>
</div>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
<header id="name" height="5%" width="80%" align="center" text_align="center"/>
<spacer width="1" height="5%"/>
<box width="95%" height="40%" padding="10" layout="horizontal-row">
<!-- Left pane -->
<div proportion="1" height="100%" layout="vertical-row">
<placeholder proportion="1" width="100%" height="100%" id="screenshot_div">
</placeholder>
</div>
<!-- Right pane -->
<div proportion="1" height="100%" layout="vertical-row">
<label id="highscores" width="100%" text_align="center" text="= Highscores ="/>
<spacer width="1" height="2%"/>
<div width="95%" height="fit" layout="horizontal-row">
<icon id="iconscore1" icon="gui/random_kart.png" width="font" height="font"/>
<spacer width="2%" height="1"/>
<label id="highscore1" proportion="1" text="(Empty)"/>
</div>
<spacer width="1" height="2%"/>
<div width="95%" height="fit" layout="horizontal-row">
<icon id="iconscore2" icon="gui/random_kart.png" width="font" height="font"/>
<spacer width="2%" height="1"/>
<label id="highscore2" proportion="1" text="(Empty)"/>
</div>
<spacer width="1" height="2%"/>
<div width="95%" height="fit" layout="horizontal-row">
<icon id="iconscore3" icon="gui/random_kart.png" width="font" height="font"/>
<spacer width="2%" height="1"/>
<label id="highscore3" proportion="1" text="(Empty)"/>
</div>
<spacer width="1" height="10%"/>
<label id="author" width="100%" text_align="center" word_wrap="true"/>
</div>
</box>
<spacer width="1" height="5%"/>
<box width="95%" height="25%" padding="10" layout="vertical-row">
<spacer width="1" height="5%"/>
<div width="75%" height="fit" layout="horizontal-row" >
<spacer width="40" height="2" />
<label id="lap-text" height="100%" width="40%" I18N="Number of laps" text="Number of laps"/>
<spacer witdh="40" height="2" />
<spinner id="lap-spinner" width="20%" min_value="1" max_value="20" align="center"
wrap_around="true" />
<spacer proportion="1" height="2" />
</div>
<div width="75%" height="fit" layout="horizontal-row" >
<spacer width="40" height="2" />
<label id="ai-text" height="100%" width="40%" I18N="Number of AI karts" text="Number of AI karts"/>
<spacer with="40" height="2" />
<spinner id="ai-spinner" width="20%" min_value="1" max_value="20" align="center"
wrap_around="true" />
<spacer proportion="1" height="2" />
</div>
<div width="75%" height="fit" layout="horizontal-row" >
<spacer width="40" height="2" />
<label id="reverse-text" height="100%" width="40%" I18N="Drive the track reverse" text="Drive in reverse"/>
<spacer width="40" height="2" />
<checkbox id="reverse"/>
<spacer proportion="1" height="2" />
</div>
<spacer width="1" height="2%"/>
</box>
<spacer width="1" height="5%"/>
<buttonbar id="buttons" height="15%" width="100%" align="center">
<icon-button id="start" width="64" height="64" icon="gui/green_check.png"
I18N="Start race" text="Start Race"/>
</buttonbar>>
</div>
</stkgui>

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="1%" y="1%" width="99%" height="99%">
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
<label id="name" width="100%" text_align="center"/>
<spacer width="1" height="5%"/>
<div width="95%" proportion="5" layout="horizontal-row">
<!-- Left pane -->
<div proportion="1" height="100%" layout="vertical-row">
<label id="highscores" width="100%" text_align="center" text="= Highscores ="/>
<spacer width="1" height="2%"/>
<div width="95%" height="fit" layout="horizontal-row">
<icon id="iconscore1" icon="gui/random_kart.png" width="font" height="font"/>
<spacer width="2%" height="1"/>
<label id="highscore1" proportion="1" text="(Empty)"/>
</div>
<spacer width="1" height="2%"/>
<div width="95%" height="fit" layout="horizontal-row">
<icon id="iconscore2" icon="gui/random_kart.png" width="font" height="font"/>
<spacer width="2%" height="1"/>
<label id="highscore2" proportion="1" text="(Empty)"/>
</div>
<spacer width="1" height="2%"/>
<div width="95%" height="fit" layout="horizontal-row">
<icon id="iconscore3" icon="gui/random_kart.png" width="font" height="font"/>
<spacer width="2%" height="1"/>
<label id="highscore3" proportion="1" text="(Empty)"/>
</div>
<spacer width="1" proportion="1"/>
<label id="author" width="100%" text_align="center" word_wrap="true"/>
</div>
<!-- Right pane -->
<div proportion="1" height="100%" layout="vertical-row">
<placeholder proportion="1" width="100%" height="100%" id="screenshot_div">
</placeholder>
<div width="75%" height="fit" layout="horizontal-row" >
<spacer proportion="1" height="2" />
<checkbox id="reverse"/>
<spacer width="20" height="2" />
<label id="reverse-text" height="100%" I18N="Drive the track reverse" text="Reverse"/>
<spacer proportion="1" height="2" />
</div>
</div>
</div>
<spacer width="1" height="5%"/>
<spinner id="lapcountspinner" width="50%" min_value="1" max_value="20" align="center" wrap_around="true"
I18N="In the track setup screen (number of laps choice, where %i is the number)" text="%i laps"/>
<spacer width="1" height="5%"/>
<button id="start" text="Start Race" align="center"/>
<spacer width="1" height="2%"/>
</div>
<icon-button id="closePopup" x="0" y="0" width="8%" height="8%" icon="gui/back.png"/>
</div>
</stkgui>

View File

@ -1,5 +1,10 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D Albedo;
layout(bindless_sampler) uniform sampler2D Detail;
#else
uniform sampler2D Albedo;
uniform sampler2D Detail;
#endif
#if __VERSION__ >= 130
in vec2 uv;
@ -16,6 +21,11 @@ vec3 getLightFactor(float specMapValue);
void main(void)
{
vec4 color = texture(Albedo, uv);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
color.xyz = pow(color.xyz, vec3(2.2));
#endif
#endif
vec4 detail = texture(Detail, uv_bis);
color *= detail;
vec3 LightFactor = getLightFactor(1. - color.a);

View File

@ -0,0 +1,8 @@
flat in vec4 glowColor;
out vec4 FragColor;
void main()
{
FragColor = vec4(glowColor.rgb, 1.0);
}

View File

@ -0,0 +1,24 @@
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec4 Color;
layout(location = 3) in vec2 Texcoord;
layout(location = 5) in vec3 Tangent;
layout(location = 6) in vec3 Bitangent;
layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale;
layout(location = 12) in vec4 GlowColor;
flat out vec4 glowColor;
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix);
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.);
glowColor = GlowColor;
}

View File

@ -1,6 +1,12 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D Albedo;
layout(bindless_sampler) uniform sampler2D dtex;
#else
uniform sampler2D Albedo;
uniform vec3 SunDir;
uniform sampler2D dtex;
#endif
uniform vec3 SunDir;
in vec3 nor;
in vec2 uv;
@ -26,6 +32,11 @@ void main(void)
float scattering = mix(fPowEdotL, fLdotNBack, .5);
vec4 color = texture(Albedo, uv);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
color.xyz = pow(color.xyz, vec3(2.2));
#endif
#endif
if (color.a < 0.5) discard;
vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.);
FragColor = vec4(color.xyz * LightFactor, 1.);

View File

@ -3,6 +3,7 @@ uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 InverseViewMatrix;
uniform mat4 InverseProjectionMatrix;
uniform mat4 ProjectionViewMatrix;
uniform vec2 screen;
#else
layout (std140) uniform MatrixesData
@ -11,7 +12,8 @@ layout (std140) uniform MatrixesData
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ProjectionViewMatrix;
mat4 ShadowViewProjMatrixes[4];
vec2 screen;
};
#endif
#endif

View File

@ -0,0 +1,31 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D Albedo;
uniform sampler2D Detail;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
flat in sampler2D secondhandle;
#endif
in vec2 uv;
in vec2 uv_bis;
out vec4 FragColor;
vec3 getLightFactor(float specMapValue);
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 color = texture(handle, uv);
#ifdef SRGBBindlessFix
color.xyz = pow(color.xyz, vec3(2.2));
#endif
vec4 detail = texture(secondhandle, uv_bis);
#else
vec4 color = texture(Albedo, uv);
vec4 detail = texture(Detail, uv_bis);
#endif
color *= detail;
vec3 LightFactor = getLightFactor(1. - color.a);
FragColor = vec4(color.xyz * LightFactor, 1.);
}

View File

@ -9,6 +9,10 @@ layout(location = 3) in vec2 Texcoord;
layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale;
#ifdef GL_ARB_bindless_texture
layout(location = 10) in sampler2D Handle;
#endif
#else
in vec3 Position;
in vec3 Normal;
@ -22,6 +26,9 @@ in vec3 Scale;
out vec3 nor;
out vec2 uv;
#ifdef GL_ARB_bindless_texture
flat out sampler2D handle;
#endif
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
@ -30,7 +37,10 @@ void main()
{
mat4 ModelMatrix = getWorldMatrix(Origin + windDir * Color.r, Orientation, Scale);
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin + windDir * Color.r, Orientation, Scale) * InverseViewMatrix);
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.);
gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.);
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
uv = Texcoord;
#ifdef GL_ARB_bindless_texture
handle = Handle;
#endif
}

View File

@ -0,0 +1,47 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D dtex;
#else
uniform sampler2D Albedo;
uniform sampler2D dtex;
#endif
uniform vec3 SunDir;
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
#endif
in vec3 nor;
in vec2 uv;
out vec4 FragColor;
vec3 getLightFactor(float specMapValue);
void main(void)
{
vec2 texc = gl_FragCoord.xy / screen;
float z = texture(dtex, texc).x;
vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f;
xpos = InverseProjectionMatrix * xpos;
xpos /= xpos.w;
vec3 eyedir = normalize(xpos.xyz);
// Inspired from http://http.developer.nvidia.com/GPUGems3/gpugems3_ch16.html
float fEdotL = max(0., dot(SunDir, eyedir));
float fPowEdotL = pow(fEdotL, 4.);
float fLdotNBack = max(0., - dot(nor, SunDir) * 0.6 + 0.4);
float scattering = mix(fPowEdotL, fLdotNBack, .5);
#ifdef GL_ARB_bindless_texture
vec4 color = texture(handle, uv);
#ifdef SRGBBindlessFix
color.xyz = pow(color.xyz, vec3(2.2));
#endif
#else
vec4 color = texture(Albedo, uv);
#endif
if (color.a < 0.5) discard;
vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.);
FragColor = vec4(color.xyz * LightFactor, 1.);
}

View File

@ -0,0 +1,35 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D normalMap;
uniform sampler2D DiffuseForAlpha;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
flat in sampler2D secondhandle;
#endif
in vec3 tangent;
in vec3 bitangent;
in vec2 uv;
out vec3 EncodedNormal;
vec2 EncodeNormal(vec3 n);
void main()
{
// normal in Tangent Space
#ifdef GL_ARB_bindless_texture
vec3 TS_normal = 2.0 * texture(secondhandle, uv).rgb - 1.0;
float alpha = texture(handle, uv).a;
#else
vec3 TS_normal = 2.0 * texture(normalMap, uv).rgb - 1.0;
float alpha = texture(DiffuseForAlpha, uv).a;
#endif
// Because of interpolation, we need to renormalize
vec3 Frag_tangent = normalize(tangent);
vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent));
vec3 Frag_bitangent = cross(Frag_normal, Frag_tangent);
vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal;
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5;
EncodedNormal.z = exp2(10. * (1. - alpha) + 1.);
}

View File

@ -9,6 +9,11 @@ layout(location = 6) in vec3 Bitangent;
layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale;
#ifdef GL_ARB_bindless_texture
layout(location = 10) in sampler2D Handle;
layout(location = 11) in sampler2D SecondHandle;
#endif
#else
in vec3 Position;
in vec3 Normal;
@ -27,6 +32,10 @@ out vec3 tangent;
out vec3 bitangent;
out vec2 uv;
out vec4 color;
#ifdef GL_ARB_bindless_texture
flat out sampler2D handle;
flat out sampler2D secondhandle;
#endif
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
@ -35,10 +44,14 @@ void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix);
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.);
gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.);
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
tangent = (TransposeInverseModelView * vec4(Tangent, 1.)).xyz;
bitangent = (TransposeInverseModelView * vec4(Bitangent, 1.)).xyz;
uv = Texcoord;
color = Color.zyxw;
#ifdef GL_ARB_bindless_texture
handle = Handle;
secondhandle = SecondHandle;
#endif
}

View File

@ -0,0 +1,23 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D tex;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
#endif
in vec3 nor;
in vec2 uv;
out vec3 EncodedNormal;
vec2 EncodeNormal(vec3 n);
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 col = texture(handle, uv);
#else
vec4 col = texture(tex, uv);
#endif
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
EncodedNormal.z = exp2(10. * (1. - col.a) + 1.);
}

View File

@ -0,0 +1,27 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D Albedo;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
#endif
in vec2 uv;
in vec4 color;
out vec4 FragColor;
vec3 getLightFactor(float specMapValue);
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 col = texture(handle, uv);
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#else
vec4 col = texture(Albedo, uv);
#endif
col.xyz *= pow(color.xyz, vec3(2.2));
vec3 LightFactor = getLightFactor(1.);
FragColor = vec4(col.xyz * LightFactor, 1.);
}

View File

@ -0,0 +1,26 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D tex;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
#endif
in vec2 uv;
in vec4 color;
out vec4 FragColor;
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 col = texture(handle, uv);
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#else
vec4 col = texture(tex, uv);
#endif
col.xyz *= pow(color.xyz, vec3(2.2));
if (col.a < 0.5) discard;
FragColor = vec4(col.xyz, 1.);
}

View File

@ -0,0 +1,35 @@
// See http://www.ozone3d.net/tutorials/glsl_texturing_p04.php for ref
#ifndef GL_ARB_bindless_texture
uniform sampler2D tex;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
#endif
in vec3 nor;
out vec4 FragColor;
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
vec3 getLightFactor(float specMapValue);
void main() {
vec3 texc = gl_FragCoord.xyz / vec3(screen, 1.);
vec3 u = getPosFromUVDepth(texc, InverseProjectionMatrix).xyz;
vec3 r = reflect(u, nor);
float m = 2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0));
r.y = - r.y;
#ifdef GL_ARB_bindless_texture
vec4 detail0 = texture(handle, r.xy / m + .5);
#ifdef SRGBBindlessFix
detail0.xyz = pow(detail0.xyz, vec3(2.2));
#endif
#else
vec4 detail0 = texture(tex, r.xy / m + .5);
#endif
vec3 LightFactor = getLightFactor(1.);
FragColor = vec4(detail0.xyz * LightFactor, 1.);
}

View File

@ -0,0 +1,25 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D tex;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
#endif
in vec3 nor;
in vec2 uv;
out vec3 EncodedNormal;
vec2 EncodeNormal(vec3 n);
void main() {
#ifdef GL_ARB_bindless_texture
vec4 col = texture(handle, uv);
#else
vec4 col = texture(tex, uv);
#endif
if (col.a < 0.5)
discard;
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
EncodedNormal.z = 1.;
}

View File

@ -0,0 +1,28 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D Albedo;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
#endif
in vec2 uv;
in vec4 color;
out vec4 FragColor;
vec3 getLightFactor(float specMapValue);
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 col = texture(handle, uv);
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#else
vec4 col = texture(Albedo, uv);
#endif
col.xyz *= pow(color.xyz, vec3(2.2));
if (col.a * color.a < 0.5) discard;
vec3 LightFactor = getLightFactor(1.);
FragColor = vec4(col.xyz * LightFactor, 1.);
}

View File

@ -0,0 +1,27 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D tex;
#endif
in vec2 uv;
in vec3 nor;
in vec4 color;
#ifdef GL_ARB_bindless_texture
flat in uvec2 handle;
#endif
layout (location = 0) out vec3 RSMColor;
layout (location = 1) out vec3 RSMNormals;
void main()
{
#ifdef GL_ARB_bindless_texture
vec4 col = texture(sampler2D(handle), uv);
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#else
vec4 col = texture(tex, uv);
#endif
if (col.a < .5) discard;
RSMColor = col.xyz * color.rgb;
RSMNormals = .5 * normalize(nor) + .5;
}

View File

@ -0,0 +1,39 @@
uniform mat4 RSMMatrix;
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec4 Color;
layout(location = 3) in vec2 Texcoord;
layout(location = 4) in vec2 SecondTexcoord;
layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale;
#ifdef GL_ARB_bindless_texture
layout(location = 10) in uvec2 Handle;
#endif
out vec3 nor;
out vec2 uv;
out vec2 uv_bis;
out vec4 color;
#ifdef GL_ARB_bindless_texture
flat out uvec2 handle;
#endif
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
mat4 ModelViewProjectionMatrix = RSMMatrix * ModelMatrix;
mat4 TransposeInverseModel = transpose(inverse(ModelMatrix));
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
nor = (TransposeInverseModel * vec4(Normal, 0.)).xyz;
uv = Texcoord;
color = Color.zyxw;
#ifdef GL_ARB_bindless_texture
handle = Handle;
#endif
}

View File

@ -0,0 +1,28 @@
layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;
#ifdef GL_ARB_bindless_texture
flat in uvec2 hdle[3];
#endif
in vec2 tc[3];
in int layerId[3];
out vec2 uv;
#ifdef GL_ARB_bindless_texture
out flat uvec2 handle;
#endif
void main(void)
{
gl_Layer = layerId[0];
#ifdef GL_ARB_bindless_texture
handle = hdle[0];
#endif
for(int i=0; i<3; i++)
{
uv = tc[i];
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}

View File

@ -0,0 +1,21 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D tex;
#endif
#ifdef GL_ARB_bindless_texture
flat in uvec2 handle;
#endif
in vec2 uv;
in vec4 color;
out vec4 FragColor;
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 col = texture(sampler2D(handle), uv);
#else
vec4 col = texture(tex, uv);
#endif
if (col.a < 0.5) discard;
FragColor = vec4(1.);
}

View File

@ -1,3 +1,5 @@
uniform int layer;
uniform vec3 windDir;
#if __VERSION__ >= 330
layout(location = 0) in vec3 Position;
@ -7,6 +9,10 @@ layout(location = 3) in vec2 Texcoord;
layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale;
#ifdef GL_ARB_bindless_texture
layout(location = 10) in uvec2 Handle;
#endif
#else
in vec3 Position;
in vec4 Color;
@ -19,9 +25,15 @@ in vec3 Scale;
#ifdef VSLayer
out vec2 uv;
#ifdef GL_ARB_bindless_texture
flat out uvec2 handle;
#endif
#else
out vec2 tc;
out int layerId;
#ifdef GL_ARB_bindless_texture
flat out uvec2 hdle;
#endif
#endif
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
@ -31,12 +43,18 @@ void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
#ifdef VSLayer
gl_Layer = gl_InstanceID & 3;
gl_Layer = layer;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
uv = Texcoord;
#ifdef GL_ARB_bindless_texture
handle = Handle;
#endif
#else
layerId = gl_InstanceID & 3;
layerId = layer;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
tc = Texcoord;
#ifdef GL_ARB_bindless_texture
hdle = Handle;
#endif
#endif
}

View File

@ -1,3 +1,5 @@
uniform int layer;
#if __VERSION__ >= 330
layout(location = 0) in vec3 Position;
layout(location = 3) in vec2 Texcoord;
@ -5,6 +7,10 @@ layout(location = 3) in vec2 Texcoord;
layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale;
#ifdef GL_ARB_bindless_texture
layout(location = 10) in uvec2 Handle;
#endif
#else
in vec3 Position;
in vec2 Texcoord;
@ -16,9 +22,15 @@ in vec3 Scale;
#ifdef VSLayer
out vec2 uv;
#ifdef GL_ARB_bindless_texture
flat out uvec2 handle;
#endif
#else
out vec2 tc;
out int layerId;
#ifdef GL_ARB_bindless_texture
flat out uvec2 hdle;
#endif
#endif
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
@ -28,12 +40,18 @@ void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
#ifdef VSLayer
gl_Layer = gl_InstanceID & 3;
gl_Layer = layer;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.);
uv = Texcoord;
#ifdef GL_ARB_bindless_texture
handle = Handle;
#endif
#else
layerId = gl_InstanceID & 3;
layerId = layer;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
tc = Texcoord;
#ifdef GL_ARB_bindless_texture
hdle = Handle;
#endif
#endif
}

View File

@ -1,5 +1,10 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D normalMap;
layout(bindless_sampler) uniform sampler2D DiffuseForAlpha;
#else
uniform sampler2D normalMap;
uniform sampler2D DiffuseForAlpha;
#endif
in vec3 tangent;
in vec3 bitangent;

View File

@ -1,4 +1,8 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D tex;
#else
uniform sampler2D tex;
#endif
#if __VERSION__ >= 130
in vec3 nor;

View File

@ -1,4 +1,8 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D Albedo;
#else
uniform sampler2D Albedo;
#endif
in vec2 uv;
in vec4 color;
@ -8,7 +12,14 @@ vec3 getLightFactor(float specMapValue);
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 col = texture(Albedo, uv);
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#else
vec4 col = texture(Albedo, uv);
#endif
col.xyz *= pow(color.xyz, vec3(2.2));
vec3 LightFactor = getLightFactor(1.);
FragColor = vec4(col.xyz * LightFactor, 1.);

View File

@ -1,4 +1,8 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D tex;
#else
uniform sampler2D tex;
#endif
in vec2 uv;
in vec4 color;
@ -7,6 +11,11 @@ out vec4 FragColor;
void main(void)
{
vec4 col = texture(tex, uv);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#endif
col.xyz *= pow(color.xyz, vec3(2.2));
if (col.a < 0.5) discard;
FragColor = vec4(col.xyz, 1.);

View File

@ -1,6 +1,10 @@
// See http://www.ozone3d.net/tutorials/glsl_texturing_p04.php for ref
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D tex;
#else
uniform sampler2D tex;
#endif
#if __VERSION__ >= 130
in vec3 nor;
@ -21,6 +25,11 @@ void main() {
float m = 2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0));
r.y = - r.y;
vec4 detail0 = texture(tex, r.xy / m + .5);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
detail0.xyz = pow(detail0.xyz, vec3(2.2));
#endif
#endif
vec3 LightFactor = getLightFactor(1.);
FragColor = vec4(detail0.xyz * LightFactor, 1.);

View File

@ -1,4 +1,8 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D tex;
#else
uniform sampler2D tex;
#endif
#if __VERSION__ >= 130
in vec3 nor;

View File

@ -1,4 +1,8 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D Albedo;
#else
uniform sampler2D Albedo;
#endif
in vec2 uv;
in vec4 color;
@ -9,6 +13,11 @@ vec3 getLightFactor(float specMapValue);
void main(void)
{
vec4 col = texture(Albedo, uv);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#endif
col.xyz *= pow(color.xyz, vec3(2.2));
if (col.a * color.a < 0.5) discard;
vec3 LightFactor = getLightFactor(1.);

View File

@ -1,6 +1,5 @@
uniform sampler2D ntex;
uniform sampler2D dtex;
uniform float spec;
flat in vec3 center;
flat in float energy;

View File

@ -1,3 +1,4 @@
uniform int layer;
uniform mat4 ModelMatrix;
#if __VERSION__ >= 330
@ -18,11 +19,11 @@ out int layerId;
void main(void)
{
#ifdef VSLayer
gl_Layer = gl_InstanceID & 3;
gl_Layer = layer;
uv = Texcoord;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.);
#else
layerId = gl_InstanceID & 3;
layerId = layer;
tc = Texcoord;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
#endif

View File

@ -1,3 +1,4 @@
uniform int layer;
uniform mat4 ModelMatrix;
uniform vec3 windDir;
@ -21,11 +22,11 @@ out int layerId;
void main(void)
{
#ifdef VSLayer
gl_Layer = gl_InstanceID & 3;
gl_Layer = layer;
uv = Texcoord;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
#else
layerId = gl_InstanceID & 3;
layerId = layer;
tc = Texcoord;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
#endif

View File

@ -1,8 +1,16 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D tex_layout;
layout(bindless_sampler) uniform sampler2D tex_detail0;
layout(bindless_sampler) uniform sampler2D tex_detail1;
layout(bindless_sampler) uniform sampler2D tex_detail2;
layout(bindless_sampler) uniform sampler2D tex_detail3;
#else
uniform sampler2D tex_layout;
uniform sampler2D tex_detail0;
uniform sampler2D tex_detail1;
uniform sampler2D tex_detail2;
uniform sampler2D tex_detail3;
#endif
#if __VERSION__ >= 130
in vec2 uv;
@ -24,6 +32,14 @@ void main() {
vec4 detail2 = texture(tex_detail2, uv);
vec4 detail3 = texture(tex_detail3, uv);
vec4 detail4 = vec4(0.0);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
detail0.xyz = pow(detail0.xyz, vec3(2.2));
detail1.xyz = pow(detail1.xyz, vec3(2.2));
detail2.xyz = pow(detail2.xyz, vec3(2.2));
detail3.xyz = pow(detail3.xyz, vec3(2.2));
#endif
#endif
vec4 splatted = splatting.r * detail0 +
splatting.g * detail1 +

View File

@ -1,4 +1,8 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D tex;
#else
uniform sampler2D tex;
#endif
in vec2 uv;
in vec4 color;
@ -8,6 +12,9 @@ out vec4 FragColor;
void main()
{
vec4 Color = texture(tex, uv);
#ifdef GL_ARB_bindless_texture
Color.xyz = pow(Color.xyz, vec3(2.2));
#endif
Color.xyz *= pow(color.xyz, vec3(2.2));
Color.a *= color.a;
// Premultiply alpha

View File

@ -1,4 +1,9 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D tex;
#else
uniform sampler2D tex;
#endif
uniform float fogmax;
uniform float startH;
@ -15,6 +20,9 @@ out vec4 FragColor;
void main()
{
vec4 diffusecolor = texture(tex, uv);
#ifdef GL_ARB_bindless_texture
diffusecolor.xyz = pow(diffusecolor.xyz, vec3(2.2));
#endif
diffusecolor.xyz *= pow(color.xyz, vec3(2.2));
diffusecolor.a *= color.a;
vec3 tmp = vec3(gl_FragCoord.xy / screen, gl_FragCoord.z);

View File

@ -1,6 +1,12 @@
#ifdef GL_ARB_bindless_texture
layout(bindless_sampler) uniform sampler2D DiffuseMap;
layout(bindless_sampler) uniform sampler2D SpecularMap;
layout(bindless_sampler) uniform sampler2D SSAO;
#else
uniform sampler2D DiffuseMap;
uniform sampler2D SpecularMap;
uniform sampler2D SSAO;
#endif
vec3 getLightFactor(float specMapValue)
{

View File

@ -45,6 +45,6 @@ mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale)
{
mat4 result = transpose(getMatrixFromRotation(rotation));
// FIXME: it's wrong but the fourth column is not used
result[3].xyz -= translation;
// result[3].xyz -= translation;
return getScaleMatrix(1. / scale) * result;
}

View File

@ -155,12 +155,13 @@
otherwise obstricts too much of the view. -->
<camera distance="1.5" forward-up-angle="15"
backward-up-angle="30"/>
<!-- Additional offset to move graphical chassis with regards to the physics. -->
<graphics y-offset="0.0"/>
<!-- Jump animation related values:
animation-time: only if the estimated time for a jump is larger
than this value will the jump animation being
shown. -->
<jump animation-time="0.5" />
<!-- Jump animation related values:
animation-time: only if the estimated time for a jump is larger
than this value will the jump animation being shown. -->
<jump animation-time="0.5" />
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
decrease: multiplicative decrease of skidding factor in each frame.
@ -415,11 +416,14 @@
physical-wheel-position: Defines where the 'physical' (raycast)
wheel will be located. It's a weight factor with 0 = being
at the widest side of the bevel, 1 = at the front and
narrowest part of the kart. -->
narrowest part of the kart. If the value is less than 0, the old
physics settings are used which places the raycast wheels
outside of the chassis and results in more stable physical
behaviour of the karts. -->
<collision impulse-type="normal"
impulse="3000" impulse-time="0.1" terrain-impulse="8000"
impulse="3000" impulse-time="0.1" terrain-impulse="1600"
restitution="1.0" bevel-factor="0.5 0.0 0.7"
physical-wheel-position="0.5" />
physical-wheel-position="-1" />
<!-- If a kart starts within the specified time after 'go',
it receives the corresponding bonus from 'boost'. Those

View File

@ -1,15 +1,14 @@
[Desktop Entry]
Name=SuperTuxKart
Icon=@PREFIX@/share/pixmaps/supertuxkart_128.png
Icon=supertuxkart
GenericName=A kart racing game
GenericName[de]=Ein Kart-Rennspiel
GenericName[fr]=Un jeu de karting
GenericName[gl]=Xogo de carreiras con karts
GenericName[pl]=Wyścigi gokartów
GenericName[ro]=Un joc de curse cu carturi
Exec=@PREFIX@/@STK_INSTALL_BINARY_DIR@/supertuxkart --no-console
Exec=supertuxkart
Terminal=false
StartupNotify=false
Type=Application
TryExec=@PREFIX@/@STK_INSTALL_BINARY_DIR@/supertuxkart
Categories=Game;ArcadeGame;

View File

@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
@ -24,6 +24,12 @@ subject to the following restrictions:
# include <math.h>
#endif
#if defined(__MINGW32__) && __cplusplus >= 201103
#include <cmath>
using std::isinf;
using std::isnan;
#endif
#include "LinearMath/btTransform.h"
//island management, m_activationState1
@ -51,7 +57,7 @@ typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
#endif
/// btCollisionObject can be used to manage collision detection objects.
/// btCollisionObject can be used to manage collision detection objects.
/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
/// They can be added to the btCollisionWorld.
ATTRIBUTE_ALIGNED16(class) btCollisionObject
@ -64,20 +70,20 @@ protected:
///m_interpolationWorldTransform is used for CCD and interpolation
///it can be either previous or future (predicted) transform
btTransform m_interpolationWorldTransform;
//those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
//those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
//without destroying the continuous interpolated motion (which uses this interpolation velocities)
btVector3 m_interpolationLinearVelocity;
btVector3 m_interpolationAngularVelocity;
btVector3 m_anisotropicFriction;
int m_hasAnisotropicFriction;
btScalar m_contactProcessingThreshold;
btScalar m_contactProcessingThreshold;
btBroadphaseProxy* m_broadphaseHandle;
btCollisionShape* m_collisionShape;
///m_extensionPointer is used by some internal low-level Bullet extensions.
void* m_extensionPointer;
///m_rootCollisionShape is temporarily used to store the original collision shape
///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
///If it is NULL, the m_collisionShape is not temporarily replaced.
@ -102,14 +108,14 @@ protected:
void* m_userObjectPointer;
///time of impact calculation
btScalar m_hitFraction;
btScalar m_hitFraction;
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
btScalar m_ccdSweptSphereRadius;
/// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
btScalar m_ccdMotionThreshold;
/// If some object should have elaborate collision filtering by sub-classes
int m_checkCollideWith;
@ -194,7 +200,7 @@ public:
return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0;
}
btCollisionObject();
virtual ~btCollisionObject();
@ -232,7 +238,7 @@ public:
m_collisionShape = collisionShape;
}
///Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
///Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
void* internalGetExtensionPointer() const
{
@ -246,7 +252,7 @@ public:
}
SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;}
void setActivationState(int newState);
void setDeactivationTime(btScalar time)
@ -385,7 +391,7 @@ public:
SIMD_FORCE_INLINE btScalar getHitFraction() const
{
return m_hitFraction;
return m_hitFraction;
}
void setHitFraction(btScalar hitFraction)
@ -393,7 +399,7 @@ public:
m_hitFraction = hitFraction;
}
SIMD_FORCE_INLINE int getCollisionFlags() const
{
return m_collisionFlags;
@ -403,7 +409,7 @@ public:
{
m_collisionFlags = flags;
}
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
btScalar getCcdSweptSphereRadius() const
{
@ -439,7 +445,7 @@ public:
{
return m_userObjectPointer;
}
///users can point to their objects, userPointer is not used by Bullet
void setUserPointer(void* userPointer)
{
@ -477,11 +483,11 @@ struct btCollisionObjectDoubleData
btVector3DoubleData m_interpolationLinearVelocity;
btVector3DoubleData m_interpolationAngularVelocity;
btVector3DoubleData m_anisotropicFriction;
double m_contactProcessingThreshold;
double m_contactProcessingThreshold;
double m_deactivationTime;
double m_friction;
double m_restitution;
double m_hitFraction;
double m_hitFraction;
double m_ccdSweptSphereRadius;
double m_ccdMotionThreshold;
@ -509,11 +515,11 @@ struct btCollisionObjectFloatData
btVector3FloatData m_interpolationLinearVelocity;
btVector3FloatData m_interpolationAngularVelocity;
btVector3FloatData m_anisotropicFriction;
float m_contactProcessingThreshold;
float m_contactProcessingThreshold;
float m_deactivationTime;
float m_friction;
float m_restitution;
float m_hitFraction;
float m_hitFraction;
float m_ccdSweptSphereRadius;
float m_ccdMotionThreshold;

View File

@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
@ -26,6 +26,11 @@ subject to the following restrictions:
#endif
#include <math.h>
#if defined(__MINGW32__) && __cplusplus >= 201103
#include <cmath>
using std::isnan;
#endif
class btCollisionShape;
class btMotionState;
class btTypedConstraint;
@ -51,7 +56,7 @@ enum btRigidBodyFlags
///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
///It is recommended for performance and memory use to share btCollisionShape objects whenever possible.
///There are 3 types of rigid bodies:
///There are 3 types of rigid bodies:
///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics.
///- B) Fixed objects with zero mass. They are not moving (basically collision objects)
///- C) Kinematic objects, which are objects without mass, but the user can move them. There is on-way interaction, and Bullet calculates a velocity based on the timestep and previous and current world transform.
@ -66,12 +71,12 @@ class btRigidBody : public btCollisionObject
btScalar m_inverseMass;
btVector3 m_linearFactor;
btVector3 m_gravity;
btVector3 m_gravity;
btVector3 m_gravity_acceleration;
btVector3 m_invInertiaLocal;
btVector3 m_totalForce;
btVector3 m_totalTorque;
btScalar m_linearDamping;
btScalar m_angularDamping;
@ -92,9 +97,9 @@ class btRigidBody : public btCollisionObject
btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
int m_rigidbodyFlags;
int m_debugBodyId;
protected:
@ -111,7 +116,7 @@ public:
///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument)
///You can use the motion state to synchronize the world transform between physics and graphics objects.
///You can use the motion state to synchronize the world transform between physics and graphics objects.
///And if the motion state is provided, the rigid body will initialize its initial world transform from the motion state,
///m_startWorldTransform is only used when you don't provide a motion state.
struct btRigidBodyConstructionInfo
@ -168,16 +173,16 @@ public:
///btRigidBody constructor using construction info
btRigidBody( const btRigidBodyConstructionInfo& constructionInfo);
///btRigidBody constructor for backwards compatibility.
///btRigidBody constructor for backwards compatibility.
///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo)
btRigidBody( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));
virtual ~btRigidBody()
{
{
//No constraints should point to this rigidbody
//Remove constraints from the dynamics world before you delete the related rigidbodies.
btAssert(m_constraintRefs.size()==0);
//Remove constraints from the dynamics world before you delete the related rigidbodies.
btAssert(m_constraintRefs.size()==0);
}
protected:
@ -187,8 +192,8 @@ protected:
public:
void proceedToTransform(const btTransform& newTrans);
void proceedToTransform(const btTransform& newTrans);
///to keep collision detection and dynamics separate we don't store a rigidbody pointer
///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast
static const btRigidBody* upcast(const btCollisionObject* colObj)
@ -203,15 +208,15 @@ public:
return (btRigidBody*)colObj;
return 0;
}
/// continuous collision detection needs prediction
void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
void saveKinematicState(btScalar step);
void applyGravity();
void setGravity(const btVector3& acceleration);
void setGravity(const btVector3& acceleration);
const btVector3& getGravity() const
{
@ -249,9 +254,9 @@ public:
SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() {
return m_collisionShape;
}
void setMassProps(btScalar mass, const btVector3& inertia);
const btVector3& getLinearFactor() const
{
return m_linearFactor;
@ -265,10 +270,10 @@ public:
m_invMass = m_linearFactor*m_inverseMass;
}
btScalar getInvMass() const { return m_inverseMass; }
const btMatrix3x3& getInvInertiaTensorWorld() const {
return m_invInertiaTensorWorld;
const btMatrix3x3& getInvInertiaTensorWorld() const {
return m_invInertiaTensorWorld;
}
void integrateVelocities(btScalar step);
void setCenterOfMassTransform(const btTransform& xform);
@ -290,7 +295,7 @@ public:
{
return m_totalTorque;
};
const btVector3& getInvInertiaDiagLocal() const
{
return m_invInertiaLocal;
@ -314,8 +319,8 @@ public:
btAssert(!isnan(torque.getZ()));
m_totalTorque += torque*m_angularFactor;
}
void applyForce(const btVector3& force, const btVector3& rel_pos)
void applyForce(const btVector3& force, const btVector3& rel_pos)
{
btAssert(!isnan(force.getX()));
btAssert(!isnan(force.getY()));
@ -326,7 +331,7 @@ public:
applyCentralForce(force);
applyTorque(rel_pos.cross(force*m_linearFactor));
}
void applyCentralImpulse(const btVector3& impulse)
{
btAssert(!isnan(impulse.getX()));
@ -334,7 +339,7 @@ public:
btAssert(!isnan(impulse.getZ()));
m_linearVelocity += impulse *m_linearFactor * m_inverseMass;
}
void applyTorqueImpulse(const btVector3& torque)
{
btAssert(!isnan(torque.getX()));
@ -342,8 +347,8 @@ public:
btAssert(!isnan(torque.getZ()));
m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
}
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
{
btAssert(!isnan(impulse.getX()));
btAssert(!isnan(impulse.getY()));
@ -361,44 +366,44 @@ public:
}
}
void clearForces()
void clearForces()
{
m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
}
void updateInertiaTensor();
const btVector3& getCenterOfMassPosition() const {
return m_worldTransform.getOrigin();
void updateInertiaTensor();
const btVector3& getCenterOfMassPosition() const {
return m_worldTransform.getOrigin();
}
btQuaternion getOrientation() const;
const btTransform& getCenterOfMassTransform() const {
return m_worldTransform;
const btTransform& getCenterOfMassTransform() const {
return m_worldTransform;
}
const btVector3& getLinearVelocity() const {
return m_linearVelocity;
const btVector3& getLinearVelocity() const {
return m_linearVelocity;
}
const btVector3& getAngularVelocity() const {
return m_angularVelocity;
const btVector3& getAngularVelocity() const {
return m_angularVelocity;
}
inline void setLinearVelocity(const btVector3& lin_vel)
{
{
btAssert(!isnan(lin_vel.getX()));
btAssert(!isnan(lin_vel.getY()));
btAssert(!isnan(lin_vel.getZ()));
m_linearVelocity = lin_vel;
m_linearVelocity = lin_vel;
}
inline void setAngularVelocity(const btVector3& ang_vel)
{
inline void setAngularVelocity(const btVector3& ang_vel)
{
btAssert(!isnan(ang_vel.getX()));
btAssert(!isnan(ang_vel.getY()));
btAssert(!isnan(ang_vel.getZ()));
m_angularVelocity = ang_vel;
m_angularVelocity = ang_vel;
}
btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
@ -410,18 +415,18 @@ public:
// return (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
}
void translate(const btVector3& v)
void translate(const btVector3& v)
{
m_worldTransform.getOrigin() += v;
m_worldTransform.getOrigin() += v;
}
void getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
{
btVector3 r0 = pos - getCenterOfMassPosition();
@ -478,12 +483,12 @@ public:
}
const btBroadphaseProxy* getBroadphaseProxy() const
{
return m_broadphaseHandle;
}
btBroadphaseProxy* getBroadphaseProxy()
btBroadphaseProxy* getBroadphaseProxy()
{
return m_broadphaseHandle;
}
@ -567,12 +572,12 @@ public:
return m_deltaAngularVelocity;
}
const btVector3& getPushVelocity() const
const btVector3& getPushVelocity() const
{
return m_pushVelocity;
}
const btVector3& getTurnVelocity() const
const btVector3& getTurnVelocity() const
{
return m_turnVelocity;
}
@ -580,7 +585,7 @@ public:
////////////////////////////////////////////////
///some internal methods, don't use them
btVector3& internalGetDeltaLinearVelocity()
{
return m_deltaLinearVelocity;
@ -600,7 +605,7 @@ public:
{
return m_invMass;
}
btVector3& internalGetPushVelocity()
{
return m_pushVelocity;
@ -640,7 +645,7 @@ public:
m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
}
}
void internalWritebackVelocity()
{
if (m_inverseMass)
@ -656,7 +661,7 @@ public:
void internalWritebackVelocity(btScalar timeStep);
///////////////////////////////////////////////
@ -679,7 +684,7 @@ struct btRigidBodyFloatData
btVector3FloatData m_angularVelocity;
btVector3FloatData m_angularFactor;
btVector3FloatData m_linearFactor;
btVector3FloatData m_gravity;
btVector3FloatData m_gravity;
btVector3FloatData m_gravity_acceleration;
btVector3FloatData m_invInertiaLocal;
btVector3FloatData m_totalForce;
@ -705,7 +710,7 @@ struct btRigidBodyDoubleData
btVector3DoubleData m_angularVelocity;
btVector3DoubleData m_angularFactor;
btVector3DoubleData m_linearFactor;
btVector3DoubleData m_gravity;
btVector3DoubleData m_gravity;
btVector3DoubleData m_gravity_acceleration;
btVector3DoubleData m_invInertiaLocal;
btVector3DoubleData m_totalForce;

View File

@ -21,6 +21,10 @@ add_library(enet STATIC
win32.c
)
if(MINGW)
target_link_libraries(enet wsock32 ws2_32 Winmm)
endif()
#if(WIN32)
# find_library(WS2_LIBRARY NAMES "ws2_32" PATHS "C:/Windows/System32")
# target_link_libraries(enet ${WS2_LIBRARY})

View File

@ -16,6 +16,9 @@ add_definitions(-DNDEBUG=1 -DIRRLICHT_EXPORTS=1 -DPNG_THREAD_UNSAFE_OK -DPNG_NO_
if(MSVC)
add_definitions(/D_IRR_STATIC_LIB_)
add_definitions(/D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff
elseif(MINGW)
add_definitions(-D_IRR_STATIC_LIB_)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff
else()
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include")
@ -766,16 +769,16 @@ if(APPLE)
source/Irrlicht/MacOSX/AppDelegate.mm
source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm
source/Irrlicht/MacOSX/OSXClipboard.mm)
#list(APPEND CMAKE_C_SOURCE_FILE_EXTENSIONS mm)
#set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS cpp)
set_source_files_properties(source/Irrlicht/MacOSX/AppDelegate.mm PROPERTIES COMPILE_FLAGS "-x objective-c++ -O3 -fno-rtti")
set_source_files_properties(source/Irrlicht/MacOSX/AppDelegate.mm PROPERTIES LANGUAGE C)
set_source_files_properties(source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm PROPERTIES COMPILE_FLAGS "-x objective-c++ -O3 -fno-rtti")
set_source_files_properties(source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm PROPERTIES LANGUAGE C)
set_source_files_properties(source/Irrlicht/MacOSX/OSXClipboard.mm PROPERTIES COMPILE_FLAGS "-x objective-c++ -O3 -fno-rtti")
set_source_files_properties(source/Irrlicht/MacOSX/OSXClipboard.mm PROPERTIES LANGUAGE C)
endif()

View File

@ -12,6 +12,9 @@
#include "aabbox3d.h"
#include "rect.h"
#include "irrString.h"
#if defined(WIN32) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
#include <intrin.h>
#endif
// enable this to keep track of changes to the matrix
// and make simpler identity check for seldomly changing matrices
@ -44,6 +47,10 @@ namespace core
template <class T>
class CMatrix4
{
private:
#if defined(WIN32) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
float M_raw[24];
#endif
public:
//! Constructor Flags
@ -402,8 +409,12 @@ namespace core
bool equals(const core::CMatrix4<T>& other, const T tolerance=(T)ROUNDING_ERROR_f64) const;
private:
#if defined(WIN32) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
//! Matrix data, stored in row-major order
T M[16];
T* M = (T*)((uintptr_t)&M_raw[4] & ~0xF);
#else
T M[16];
#endif
#if defined ( USE_MATRIX_TEST )
//! Flag is this matrix is identity matrix
mutable u32 definitelyIdentityMatrix;
@ -658,6 +669,58 @@ namespace core
const T *m1 = other_a.M;
const T *m2 = other_b.M;
#if defined(WIN32) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
// From http://drrobsjournal.blogspot.fr/2012/10/fast-simd-4x4-matrix-multiplication.html
// Use unaligned load/store
const float *matA = other_a.pointer();
const __m128 a = _mm_load_ps(matA); // First row
const __m128 b = _mm_load_ps(&matA[4]); // Second row
const __m128 c = _mm_load_ps(&matA[8]); // Third row
const __m128 d = _mm_load_ps(&matA[12]); // Fourth row
__m128 t1 = _mm_set1_ps(m2[0]);
__m128 t2 = _mm_mul_ps(a, t1);
t1 = _mm_set1_ps(m2[1]);
t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
t1 = _mm_set1_ps(m2[2]);
t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
t1 = _mm_set1_ps(m2[3]);
t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
_mm_store_ps(&M[0], t2);
t1 = _mm_set1_ps(m2[4]);
t2 = _mm_mul_ps(a, t1);
t1 = _mm_set1_ps(m2[5]);
t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
t1 = _mm_set1_ps(m2[6]);
t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
t1 = _mm_set1_ps(m2[7]);
t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
_mm_store_ps(&M[4], t2);
t1 = _mm_set1_ps(m2[8]);
t2 = _mm_mul_ps(a, t1);
t1 = _mm_set1_ps(m2[9]);
t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
t1 = _mm_set1_ps(m2[10]);
t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
t1 = _mm_set1_ps(m2[11]);
t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
_mm_store_ps(&M[8], t2);
t1 = _mm_set1_ps(m2[12]);
t2 = _mm_mul_ps(a, t1);
t1 = _mm_set1_ps(m2[13]);
t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
t1 = _mm_set1_ps(m2[14]);
t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
t1 = _mm_set1_ps(m2[15]);
t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
_mm_store_ps(&M[12], t2);
#else
M[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3];
M[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3];
M[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3];
@ -679,6 +742,7 @@ namespace core
M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
#if defined ( USE_MATRIX_TEST )
definitelyIdentityMatrix=false;
#endif
#endif
return *this;
}
@ -1307,20 +1371,110 @@ namespace core
template <class T>
inline bool CMatrix4<T>::getInverse(CMatrix4<T>& out) const
{
/// Calculates the inverse of this Matrix
/// The inverse is calculated using Cramers rule.
/// If no inverse exists then 'false' is returned.
inline bool CMatrix4<T>::getInverse(CMatrix4<T>& out) const
{
/// Calculates the inverse of this Matrix
/// The inverse is calculated using Cramers rule.
/// If no inverse exists then 'false' is returned.
#if defined ( USE_MATRIX_TEST )
if ( this->isIdentity() )
{
out=*this;
return true;
}
if ( this->isIdentity() )
{
out=*this;
return true;
}
#endif
const CMatrix4<T> &m = *this;
const CMatrix4<T> &m = *this;
#if defined(WIN32) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
float *src = (float*)m.pointer();
float *dst = (float*)out.pointer();
// from http://www.intel.com/design/pentiumiii/sml/245043.htm
{
__m128 minor0 = {}, minor1 = {}, minor2 = {}, minor3 = {};
__m128 row0 = {}, row1 = {}, row2 = {}, row3 = {};
__m128 det = {}, tmp1 = {};
tmp1 = _mm_loadh_pi(_mm_loadl_pi(tmp1, (__m64*)(src)), (__m64*)(src + 4));
row1 = _mm_loadh_pi(_mm_loadl_pi(row1, (__m64*)(src + 8)), (__m64*)(src + 12));
row0 = _mm_shuffle_ps(tmp1, row1, 0x88);
row1 = _mm_shuffle_ps(row1, tmp1, 0xDD);
tmp1 = _mm_loadh_pi(_mm_loadl_pi(tmp1, (__m64*)(src + 2)), (__m64*)(src + 6));
row3 = _mm_loadh_pi(_mm_loadl_pi(row3, (__m64*)(src + 10)), (__m64*)(src + 14));
row2 = _mm_shuffle_ps(tmp1, row3, 0x88);
row3 = _mm_shuffle_ps(row3, tmp1, 0xDD);
// -----------------------------------------------
tmp1 = _mm_mul_ps(row2, row3);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
minor0 = _mm_mul_ps(row1, tmp1);
minor1 = _mm_mul_ps(row0, tmp1);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0);
minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1);
minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E);
// -----------------------------------------------
tmp1 = _mm_mul_ps(row1, row2);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0);
minor3 = _mm_mul_ps(row0, tmp1);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1));
minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3);
minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E);
// -----------------------------------------------
tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
row2 = _mm_shuffle_ps(row2, row2, 0x4E);
minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0);
minor2 = _mm_mul_ps(row0, tmp1);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1));
minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2);
minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E);
// -----------------------------------------------
tmp1 = _mm_mul_ps(row0, row1);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2);
minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2);
minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1));
// -----------------------------------------------
tmp1 = _mm_mul_ps(row0, row3);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1));
minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1);
minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1));
// -----------------------------------------------
tmp1 = _mm_mul_ps(row0, row2);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1);
minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1));
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1));
minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3);
// -----------------------------------------------
det = _mm_mul_ps(row0, minor0);
det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det);
det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det);
tmp1 = _mm_rcp_ss(det);
det = _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1)));
det = _mm_shuffle_ps(det, det, 0x00);
minor0 = _mm_mul_ps(det, minor0);
_mm_storel_pi((__m64*)(dst), minor0);
_mm_storeh_pi((__m64*)(dst + 2), minor0);
minor1 = _mm_mul_ps(det, minor1);
_mm_storel_pi((__m64*)(dst + 4), minor1);
_mm_storeh_pi((__m64*)(dst + 6), minor1);
minor2 = _mm_mul_ps(det, minor2);
_mm_storel_pi((__m64*)(dst + 8), minor2);
_mm_storeh_pi((__m64*)(dst + 10), minor2);
minor3 = _mm_mul_ps(det, minor3);
_mm_storel_pi((__m64*)(dst + 12), minor3);
_mm_storeh_pi((__m64*)(dst + 14), minor3);
}
return true;
#else
f32 d = (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) -
(m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) +
@ -1387,6 +1541,7 @@ namespace core
out.definitelyIdentityMatrix = definitelyIdentityMatrix;
#endif
return true;
#endif
}

View File

@ -194,7 +194,7 @@ CIrrDeviceLinux::~CIrrDeviceLinux()
}
// Reset fullscreen resolution change
switchToFullscreen(true);
restoreResolution();
if (!ExternalWindow)
{
@ -235,43 +235,62 @@ int IrrPrintXError(Display *display, XErrorEvent *event)
}
#endif
bool CIrrDeviceLinux::switchToFullscreen(bool reset)
bool CIrrDeviceLinux::restoreResolution()
{
if (!CreationParams.Fullscreen)
return true;
if (reset)
#ifdef _IRR_LINUX_X11_VIDMODE_
if (UseXVidMode && CreationParams.Fullscreen)
{
#ifdef _IRR_LINUX_X11_VIDMODE_
if (UseXVidMode && CreationParams.Fullscreen)
{
XF86VidModeSwitchToMode(display, screennr, &oldVideoMode);
XF86VidModeSetViewPort(display, screennr, 0, 0);
}
#endif
#ifdef _IRR_LINUX_X11_RANDR_
if (UseXRandR && CreationParams.Fullscreen)
{
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id);
XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime,
crtc->x, crtc->y, old_mode,
crtc->rotation, &output_id, 1);
XRRFreeOutputInfo(output);
XRRFreeCrtcInfo(crtc);
XRRFreeScreenResources(res);
if (s != Success)
return false;
}
#endif
return true;
XF86VidModeSwitchToMode(display, screennr, &oldVideoMode);
XF86VidModeSetViewPort(display, screennr, 0, 0);
}
#endif
#ifdef _IRR_LINUX_X11_RANDR_
if (UseXRandR && CreationParams.Fullscreen && old_mode != BadRRMode)
{
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
if (!res)
return false;
XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id);
if (!output || !output->crtc || output->connection == RR_Disconnected)
{
XRRFreeOutputInfo(output);
return false;
}
XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
if (!crtc)
{
XRRFreeOutputInfo(output);
return false;
}
Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime,
crtc->x, crtc->y, old_mode,
crtc->rotation, &output_id, 1);
XRRFreeOutputInfo(output);
XRRFreeCrtcInfo(crtc);
XRRFreeScreenResources(res);
if (s != Success)
return false;
}
#endif
return true;
}
bool CIrrDeviceLinux::changeResolution()
{
if (!CreationParams.Fullscreen)
return true;
getVideoModeList();
#if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_)
s32 eventbase, errorbase;
s32 bestMode = -1;
@ -333,47 +352,56 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
XFree(modes);
}
else
#endif
#ifdef _IRR_LINUX_X11_RANDR_
if (XRRQueryExtension(display, &eventbase, &errorbase))
while (XRRQueryExtension(display, &eventbase, &errorbase))
{
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
if (output_id == BadRROutput)
break;
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
if (!res)
{
CreationParams.Fullscreen = false;
return CreationParams.Fullscreen;
}
break;
XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id);
if (!output || !output->crtc || output->connection == RR_Disconnected)
{
XRRFreeOutputInfo(output);
XRRFreeScreenResources(res);
break;
}
XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
if (!crtc)
{
XRRFreeOutputInfo(output);
XRRFreeScreenResources(res);
break;
}
float refresh_rate, refresh_rate_new;
unsigned int mode0_width = -1, mode0_height = -1;
core::dimension2d<u32> mode0_size = core::dimension2d<u32>(0, 0);
for (int i = 0; i < res->nmode; i++)
{
const XRRModeInfo* mode = &res->modes[i];
unsigned int w, h;
core::dimension2d<u32> size;
if (crtc->rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT))
{
w = mode->height;
h = mode->width;
size = core::dimension2d<u32>(mode->height, mode->width);
}
else
{
w = mode->width;
h = mode->height;
size = core::dimension2d<u32>(mode->width, mode->height);
}
if (bestMode == -1 && mode->id == output->modes[0])
{
mode0_width = w;
mode0_height = h;
mode0_size = size;
}
if (bestMode == -1 && w == Width && h == Height)
if (bestMode == -1 && size.Width == Width && size.Height == Height)
{
for (int j = 0; j < output->nmode; j++)
{
@ -385,7 +413,7 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
}
}
}
else if (bestMode != -1 && w == Width && h == Height)
else if (bestMode != -1 && size.Width == Width && size.Height == Height)
{
refresh_rate_new = (mode->dotClock * 1000.0) / (mode->hTotal * mode->vTotal);
@ -408,33 +436,29 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
if (bestMode == -1)
{
bestMode = 0;
Width = mode0_width;
Height = mode0_height;
Width = mode0_size.Width;
Height = mode0_size.Height;
}
Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime,
crtc->x, crtc->y, output->modes[bestMode],
crtc->rotation, &output_id, 1);
if (s == Success)
UseXRandR = true;
XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output);
XRRFreeScreenResources(res);
if (s != Success)
{
CreationParams.Fullscreen = false;
return CreationParams.Fullscreen;
}
UseXRandR=true;
break;
}
else
#endif
if (UseXRandR == false)
{
os::Printer::log("VidMode or RandR extension must be installed to allow Irrlicht "
"to switch to fullscreen mode. Running in windowed mode instead.", ELL_WARNING);
os::Printer::log("Could not get video output. Try to run in windowed mode.", ELL_WARNING);
CreationParams.Fullscreen = false;
}
#endif
return CreationParams.Fullscreen;
}
@ -549,7 +573,7 @@ bool CIrrDeviceLinux::createWindow()
screennr = DefaultScreen(display);
switchToFullscreen();
changeResolution();
#ifdef _IRR_COMPILE_WITH_OPENGL_
@ -1592,89 +1616,88 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
}
XFree(modes);
}
else
#endif
#ifdef _IRR_LINUX_X11_RANDR_
if (XRRQueryExtension(display, &eventbase, &errorbase))
output_id = BadRROutput;
old_mode = BadRRMode;
while (XRRQueryExtension(display, &eventbase, &errorbase))
{
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
if (!res)
return &VideoModeList;
XRROutputInfo *output = NULL;
XRROutputInfo* output = NULL;
XRRCrtcInfo* crtc = NULL;
crtc_x = crtc_y = -1;
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
if (!res)
break;
RROutput primary_id = XRRGetOutputPrimary(display, DefaultRootWindow(display));
for (int i = 0; i < res->noutput; i++)
{
output = XRRGetOutputInfo(display, res, res->outputs[i]);
if (!output || !output->crtc || output->connection == RR_Disconnected)
XRROutputInfo* output_tmp = XRRGetOutputInfo(display, res, res->outputs[i]);
if (!output_tmp || !output_tmp->crtc || output_tmp->connection == RR_Disconnected)
{
XRRFreeOutputInfo(output);
XRRFreeOutputInfo(output_tmp);
continue;
}
crtc = XRRGetCrtcInfo(display, res, output->crtc);
if (!crtc)
XRRCrtcInfo* crtc_tmp = XRRGetCrtcInfo(display, res, output_tmp->crtc);
if (!crtc_tmp)
{
XRRFreeOutputInfo(output_tmp);
continue;
}
if (res->outputs[i] == primary_id ||
output_id == BadRROutput || crtc_tmp->x < crtc->x ||
(crtc_tmp->x == crtc->x && crtc_tmp->y < crtc->y))
{
XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output);
continue;
}
if (crtc_x == -1 || crtc->x < crtc_x)
{
crtc_x = crtc->x;
crtc_y = crtc->y;
XRRFreeOutputInfo(output);
output = output_tmp;
crtc = crtc_tmp;
output_id = res->outputs[i];
}
else if (crtc_x == crtc->x && crtc->y < crtc_y)
else
{
crtc_x = crtc->x;
crtc_y = crtc->y;
output_id = res->outputs[i];
XRRFreeCrtcInfo(crtc_tmp);
XRRFreeOutputInfo(output_tmp);
}
XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output);
if (res->outputs[i] == primary_id)
break;
}
output = XRRGetOutputInfo(display, res, output_id);
crtc = XRRGetCrtcInfo(display, res, output->crtc);
if (crtc == NULL)
if (output_id == BadRROutput)
{
XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output);
XRRFreeScreenResources(res);
return &VideoModeList;
os::Printer::log("Could not get video output.", ELL_WARNING);
break;
}
crtc_x = crtc->x;
crtc_y = crtc->y;
for (int i = 0; i < res->nmode; i++)
{
const XRRModeInfo* mode = &res->modes[i];
unsigned int w, h;
core::dimension2d<u32> size;
if (crtc->rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT))
{
w = mode->height;
h = mode->width;
size = core::dimension2d<u32>(mode->height, mode->width);
}
else
{
w = mode->width;
h = mode->height;
size = core::dimension2d<u32>(mode->width, mode->height);
}
for (int j = 0; j < output->nmode; j++)
{
if (mode->id == output->modes[j])
{
VideoModeList.addMode(core::dimension2d<u32>(
w, h), defaultDepth);
VideoModeList.addMode(size, defaultDepth);
break;
}
}
@ -1682,21 +1705,18 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
if (mode->id == crtc->mode)
{
old_mode = crtc->mode;
VideoModeList.setDesktop(defaultDepth,
core::dimension2d<u32>(w, h));
VideoModeList.setDesktop(defaultDepth, size);
}
}
XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output);
XRRFreeScreenResources(res);
XRRFreeScreenResources(res);
break;
}
else
#endif
{
os::Printer::log("VidMode or RandR X11 extension requireed for VideoModeList." , ELL_WARNING);
}
}
if (display && temporaryDisplay)
{
XCloseDisplay(display);

View File

@ -150,7 +150,8 @@ namespace irr
void initXAtoms();
bool switchToFullscreen(bool reset=false);
bool restoreResolution();
bool changeResolution();
//! Implementation of the linux cursor control
class CCursorControl : public gui::ICursorControl

View File

@ -1,5 +1,6 @@
# Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically.
# Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
file(GLOB_RECURSE STK_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${PROJECT_BINARY_DIR}/tmp/*.rc")

View File

@ -114,13 +114,13 @@ void AddonsManager::init(const XMLNode *xml,
if (download)
{
Log::info("NetworkHttp", "Downloading updated addons.xml");
Log::info("addons", "Downloading updated addons.xml.");
Online::HTTPRequest *download_request = new Online::HTTPRequest("addons.xml");
download_request->setURL(addon_list_url);
download_request->executeNow();
if(download_request->hadDownloadError())
{
Log::error("addons", "Error on download addons.xml: %s\n",
Log::error("addons", "Error on download addons.xml: %s.",
download_request->getDownloadErrorMessage());
delete download_request;
return;
@ -129,12 +129,12 @@ void AddonsManager::init(const XMLNode *xml,
UserConfigParams::m_addons_last_updated=StkTime::getTimeSinceEpoch();
}
else
Log::info("NetworkHttp", "Using cached addons.xml");
Log::info("addons", "Using cached addons.xml.");
const XMLNode *xml_addons = new XMLNode(filename);
addons_manager->initAddons(xml_addons); // will free xml_addons
if(UserConfigParams::logAddons())
Log::info("addons", "Addons manager list downloaded");
Log::info("addons", "Addons manager list downloaded.");
} // init
// ----------------------------------------------------------------------------
@ -195,7 +195,7 @@ void AddonsManager::initAddons(const XMLNode *xml)
if(file_manager->fileExists(full_path))
{
if(UserConfigParams::logAddons())
Log::warn("[AddonsManager] Removing cached icon '%s'.\n",
Log::warn("addons", "Removing cached icon '%s'.",
addon.getIconBasename().c_str());
file_manager->removeFile(full_path);
}
@ -226,9 +226,9 @@ void AddonsManager::initAddons(const XMLNode *xml)
}
else
{
Log::error("[AddonsManager]", "Found invalid node '%s' while downloading addons.",
Log::error("addons", "Found invalid node '%s' while downloading addons.",
node->getName().c_str());
Log::error("[AddonsManager]", "Ignored.");
Log::error("addons", "Ignored.");
}
} // for i<xml->getNumNodes
delete xml;
@ -254,7 +254,7 @@ void AddonsManager::initAddons(const XMLNode *xml)
// it from the list.
if(UserConfigParams::logAddons())
Log::warn(
"[AddonsManager] Removing '%s' which is not on the server anymore.\n",
"addons", "Removing '%s' which is not on the server anymore.",
m_addons_list.getData()[i].getId().c_str() );
const std::string &icon = m_addons_list.getData()[i].getIconBasename();
std::string icon_file =file_manager->getAddonsFile("icons/"+icon);
@ -311,7 +311,7 @@ void AddonsManager::checkInstalledAddons()
if(n<0) continue;
if(!m_addons_list.getData()[n].isInstalled())
{
Log::info("[AddonsManager] Marking '%s' as being installed.",
Log::info("addons", "Marking '%s' as being installed.",
kp->getIdent().c_str());
m_addons_list.getData()[n].setInstalled(true);
something_was_changed = true;
@ -330,7 +330,7 @@ void AddonsManager::checkInstalledAddons()
if(n<0) continue;
if(!m_addons_list.getData()[n].isInstalled())
{
Log::info("[AddonsManager] Marking '%s' as being installed.",
Log::info("addons", "Marking '%s' as being installed.",
track->getIdent().c_str());
m_addons_list.getData()[n].setInstalled(true);
something_was_changed = true;
@ -361,7 +361,7 @@ void AddonsManager::downloadIcons()
if(icon=="")
{
if(UserConfigParams::logAddons())
Log::error("[AddonsManager]", "No icon or image specified for '%s'.",
Log::error("addons", "No icon or image specified for '%s'.",
addon.getId().c_str());
continue;
}
@ -400,7 +400,7 @@ void AddonsManager::loadInstalledAddons()
/* checking for installed addons */
if(UserConfigParams::logAddons())
{
Log::info("[AddonsManager]", "Loading an xml file for installed addons: %s",
Log::info("addons", "Loading an xml file for installed addons: %s.",
m_file_installed.c_str());
}
const XMLNode *xml = file_manager->createXMLTree(m_file_installed);
@ -478,15 +478,15 @@ bool AddonsManager::install(const Addon &addon)
if (!success)
{
// TODO: show a message in the interface
Log::error("[AddonsManager]", "Failed to unzip '%s' to '%s'",
Log::error("addons", "Failed to unzip '%s' to '%s'.",
from.c_str(), to.c_str());
Log::error("[AddonsManager]", "Zip file will not be removed.");
Log::error("addons", "Zip file will not be removed.");
return false;
}
if(!file_manager->removeFile(from))
{
Log::error("[AddonsManager]", "Problems removing temporary file '%s'",
Log::error("addons", "Problems removing temporary file '%s'.",
from.c_str());
}
@ -520,7 +520,7 @@ bool AddonsManager::install(const Addon &addon)
}
catch (std::exception& e)
{
Log::error("[AddonsManager]", "ERROR: Cannot load track <%s> : %s",
Log::error("addons", "Cannot load track '%s' : %s.",
addon.getDataDir().c_str(), e.what());
}
}
@ -535,8 +535,8 @@ bool AddonsManager::install(const Addon &addon)
*/
bool AddonsManager::uninstall(const Addon &addon)
{
Log::info("[AddonsManager]", "Uninstalling <%s>",
core::stringc(addon.getName()).c_str());
Log::info("addons", "Uninstalling '%s'.",
core::stringc(addon.getName()).c_str());
// addon is a const reference, and to avoid removing the const, we
// find the proper index again to modify the installed state

View File

@ -376,7 +376,7 @@ void ChallengeData::setRace(RaceManager::Difficulty d) const
else if(m_mode==CM_GRAND_PRIX)
{
race_manager->setMinorMode(m_minor);
race_manager->setGrandPrix(grand_prix_manager->getGrandPrix(m_gp_id));
race_manager->setGrandPrix(*grand_prix_manager->getGrandPrix(m_gp_id));
race_manager->setDifficulty(d);
race_manager->setNumKarts(m_num_karts[d]);
race_manager->setNumLocalPlayers(1);

View File

@ -464,6 +464,9 @@ namespace UserConfigParams
PARAM_PREFIX BoolUserConfigParam m_gi
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_gi",
&m_video_group, "Enable Global Illumination"));
PARAM_PREFIX BoolUserConfigParam m_azdo
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_azdo",
&m_video_group, "Enable 'Approaching Zero Driver Overhead' mode (very experimental !)"));
// ---- Debug - not saved to config file
/** If gamepad debugging is enabled. */

View File

@ -24,7 +24,6 @@
#include "audio/music_manager.hpp"
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/rain.hpp"
#include "io/xml_node.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/explosion_animation.hpp"
@ -52,7 +51,6 @@ Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL)
{
m_mode = CM_NORMAL;
m_index = camera_index;
m_rain = NULL;
m_original_kart = kart;
m_camera = irr_driver->addCameraSceneNode();
@ -92,7 +90,6 @@ Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL)
*/
Camera::~Camera()
{
if(m_rain) delete m_rain;
irr_driver->removeCameraSceneNode(m_camera);
if (s_active_camera == this)
@ -222,13 +219,6 @@ void Camera::setupCamera()
m_camera->setFOV(m_fov);
m_camera->setAspectRatio(m_aspect);
m_camera->setFarValue(World::getWorld()->getTrack()->getCameraFar());
if (UserConfigParams::m_weather_effects &&
World::getWorld()->getTrack()->getWeatherType() == WEATHER_RAIN)
{
m_rain = new Rain(this, NULL);
}
} // setupCamera
// ----------------------------------------------------------------------------
@ -530,12 +520,6 @@ void Camera::update(float dt)
getCameraSettings(&above_kart, &cam_angle, &side_way, &distance, &smoothing);
positionCamera(dt, above_kart, cam_angle, side_way, distance, smoothing);
}
if (UserConfigParams::m_graphical_effects && m_rain)
{
m_rain->setPosition( getCameraSceneNode()->getPosition() );
m_rain->update(dt);
} // UserConfigParams::m_graphical_effects
} // update
// ----------------------------------------------------------------------------

View File

@ -41,7 +41,6 @@ namespace irr
using namespace irr;
class AbstractKart;
class Rain;
/**
* \brief Handles the game camera
@ -120,10 +119,6 @@ private:
/** List of all cameras. */
static std::vector<Camera*> m_all_cameras;
/** Used to show rain graphical effects. */
Rain *m_rain;
/** A class that stores information about the different end cameras
* which can be specified in the scene.xml file. */
class EndCameraInformation

View File

@ -0,0 +1,46 @@
#ifndef GL_HEADER_HPP
#define GL_HEADER_HPP
#define GLEW_STATIC
extern "C" {
#include <GL/glew.h>
}
#include <cinttypes>
#if defined(__APPLE__)
# include <OpenGL/gl.h>
# include <OpenGL/gl3.h>
# define OGL32CTX
# ifdef GL_ARB_instanced_arrays
# define glVertexAttribDivisor glVertexAttribDivisorARB
# endif
# ifndef GL_TEXTURE_SWIZZLE_RGBA
# define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
# endif
#elif defined(ANDROID)
# include <GLES/gl.h>
#elif defined(WIN32)
# define _WINSOCKAPI_
# include <windows.h>
#else
#define GL_GLEXT_PROTOTYPES
#define DEBUG_OUTPUT_DECLARED
# include <GL/gl.h>
# include <GL/glext.h>
#endif
#define Bindless_Texture_Support
#define Base_Instance_Support
#define Buffer_Storage
#define Multi_Draw_Indirect
#define Draw_Indirect
struct DrawElementsIndirectCommand{
GLuint count;
GLuint instanceCount;
GLuint firstIndex;
GLuint baseVertex;
GLuint baseInstance;
};
#endif

View File

@ -3,92 +3,16 @@
#include <string>
#include "config/user_config.hpp"
#include "utils/profiler.hpp"
#include "utils/cpp2011.hpp"
#include "graphics/stkmesh.hpp"
#ifdef _IRR_WINDOWS_API_
#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast<const char*>(X))
PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks;
PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback;
PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback;
PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
PFNGLBINDBUFFERBASEPROC glBindBufferBase;
PFNGLGENBUFFERSPROC glGenBuffers;
PFNGLBINDBUFFERPROC glBindBuffer;
PFNGLBUFFERDATAPROC glBufferData;
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
PFNGLCREATESHADERPROC glCreateShader;
PFNGLCOMPILESHADERPROC glCompileShader;
PFNGLSHADERSOURCEPROC glShaderSource;
PFNGLCREATEPROGRAMPROC glCreateProgram;
PFNGLATTACHSHADERPROC glAttachShader;
PFNGLLINKPROGRAMPROC glLinkProgram;
PFNGLUSEPROGRAMPROC glUseProgram;
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
PFNGLUNIFORM1FPROC glUniform1f;
PFNGLUNIFORM3FPROC glUniform3f;
PFNGLDELETESHADERPROC glDeleteShader;
PFNGLGETSHADERIVPROC glGetShaderiv;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
PFNGLACTIVETEXTUREPROC glActiveTexture;
PFNGLUNIFORM2FPROC glUniform2f;
PFNGLUNIFORM1IPROC glUniform1i;
PFNGLUNIFORM3IPROC glUniform3i;
PFNGLUNIFORM4IPROC glUniform4i;
PFNGLUNIFORM1FVPROC glUniform1fv;
PFNGLUNIFORM4FVPROC glUniform4fv;
PFNGLGETPROGRAMIVPROC glGetProgramiv;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
PFNGLBLENDEQUATIONPROC glBlendEquation;
PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
PFNGLDELETEBUFFERSPROC glDeleteBuffers;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
PFNGLTEXBUFFERPROC glTexBuffer;
PFNGLBUFFERSUBDATAPROC glBufferSubData;
PFNGLMAPBUFFERPROC glMapBuffer;
PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
PFNGLUNMAPBUFFERPROC glUnmapBuffer;
PFNGLFENCESYNCPROC glFenceSync;
PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
PFNGLTEXIMAGE3DPROC glTexImage3D;
PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
PFNGLBLENDCOLORPROC glBlendColor;
PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
PFNGLTEXSTORAGE1DPROC glTexStorage1D;
PFNGLTEXSTORAGE2DPROC glTexStorage2D;
PFNGLTEXSTORAGE3DPROC glTexStorage3D;
PFNGLBINDIMAGETEXTUREPROC glBindImageTexture;
PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
#endif
#include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h"
static bool is_gl_init = false;
#ifdef DEBUG
#ifdef WIN32
#if !defined(__APPLE__)
#define ARB_DEBUG_OUTPUT
#endif
#endif
@ -101,9 +25,11 @@ CALLBACK
debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar* msg, const void *userparam)
{
#ifdef GL_DEBUG_SEVERITY_NOTIFICATION
// ignore minor notifications sent by some drivers (notably the nvidia one)
if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)
return;
#endif
switch(source)
{
@ -172,87 +98,10 @@ void initGL()
if (is_gl_init)
return;
is_gl_init = true;
#ifdef _IRR_WINDOWS_API_
glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks");
glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback");
glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback");
glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback");
glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback");
glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase");
glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer");
glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData");
glMapBuffer = (PFNGLMAPBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glMapBuffer");
glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)IRR_OGL_LOAD_EXTENSION("glMapBufferRange");
glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glUnmapBuffer");
glFenceSync = (PFNGLFENCESYNCPROC)IRR_OGL_LOAD_EXTENSION("glFenceSync");
glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)IRR_OGL_LOAD_EXTENSION("glClientWaitSync");
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer");
glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader");
glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader");
glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource");
glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram");
glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader");
glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram");
glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram");
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray");
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation");
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv");
glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f");
glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f");
glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray");
glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader");
glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv");
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog");
glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture");
glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f");
glUniform4i = (PFNGLUNIFORM4IPROC)IRR_OGL_LOAD_EXTENSION("glUniform4i");
glUniform3i = (PFNGLUNIFORM3IPROC)IRR_OGL_LOAD_EXTENSION("glUniform3i");
glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i");
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv");
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog");
glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings");
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetAttribLocation");
glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glBindAttribLocation");
glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation");
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor");
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced");
glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsBaseVertex");
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsInstanced");
glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsInstancedBaseVertex");
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers");
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glGenVertexArrays");
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)IRR_OGL_LOAD_EXTENSION("glBindVertexArray");
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteVertexArrays");
glTexBuffer = (PFNGLTEXBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glTexBuffer");
glUniform1fv = (PFNGLUNIFORM1FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform1fv");
glUniform4fv = (PFNGLUNIFORM4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform4fv");
glBufferSubData = (PFNGLBUFFERSUBDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferSubData");
glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribIPointer");
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenFramebuffers");
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteFramebuffers");
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindFramebuffer");
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)IRR_OGL_LOAD_EXTENSION("glFramebufferTexture2D");
glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glFramebufferTexture");
glTexImage3D = (PFNGLTEXIMAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexImage3D");
glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)IRR_OGL_LOAD_EXTENSION("glGenerateMipmap");
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)IRR_OGL_LOAD_EXTENSION("glCheckFramebufferStatus");
glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)IRR_OGL_LOAD_EXTENSION("glTexImage2DMultisample");
glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBlitFramebuffer");
glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformBlockIndex");
glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)IRR_OGL_LOAD_EXTENSION("glUniformBlockBinding");
glBlendColor = (PFNGLBLENDCOLORPROC)IRR_OGL_LOAD_EXTENSION("glBlendColor");
glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D");
glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)IRR_OGL_LOAD_EXTENSION("glGetCompressedTexImage");
glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage1D");
glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage2D");
glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage3D");
glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glBindImageTexture");
glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)IRR_OGL_LOAD_EXTENSION("glDispatchCompute");
#ifdef DEBUG
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB");
#endif
#endif
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
Log::fatal("GLEW", "Glew initialisation failed with error %s", glewGetErrorString(err));
#ifdef ARB_DEBUG_OUTPUT
if (glDebugMessageCallbackARB)
glDebugMessageCallbackARB((GLDEBUGPROCARB)debugCallback, NULL);
@ -282,12 +131,21 @@ GLuint LoadShader(const char * file, unsigned type)
char versionString[20];
sprintf(versionString, "#version %d\n", irr_driver->getGLSLVersion());
std::string Code = versionString;
if (UserConfigParams::m_azdo)
Code += "#extension GL_ARB_bindless_texture : enable\n";
else
{
Code += "#extension GL_ARB_bindless_texture : disable\n";
Code += "#undef GL_ARB_bindless_texture\n";
}
std::ifstream Stream(file, std::ios::in);
Code += "//" + std::string(file) + "\n";
if (irr_driver->needUBOWorkaround())
Code += "#define UBO_DISABLED\n";
if (irr_driver->hasVSLayerExtension())
Code += "#define VSLayer\n";
if (irr_driver->needsRGBBindlessWorkaround())
Code += "#define SRGBBindlessFix\n";
Code += LoadHeader();
if (Stream.is_open())
{
@ -539,40 +397,7 @@ void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum
glGetError();
}
class VBOGatherer
{
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
void regenerateBuffer(enum VTXTYPE);
void regenerateVAO(enum VTXTYPE);
size_t getVertexPitch(enum VTXTYPE) const;
VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type);
void append(scene::IMeshBuffer *, VBOGatherer::VTXTYPE tp);
public:
VBOGatherer();
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; }
~VBOGatherer()
{
for (unsigned i = 0; i < VTXTYPE_COUNT; i++)
{
if (vbo[i])
glDeleteBuffers(1, &vbo[i]);
if (ibo[i])
glDeleteBuffers(1, &ibo[i]);
if (vao[i])
glDeleteVertexArrays(1, &vao[i]);
}
}
};
VBOGatherer::VBOGatherer()
VAOManager::VAOManager()
{
vao[0] = vao[1] = vao[2] = 0;
vbo[0] = vbo[1] = vbo[2] = 0;
@ -581,16 +406,81 @@ VBOGatherer::VBOGatherer()
idx_cnt[0] = idx_cnt[1] = idx_cnt[2] = 0;
vtx_mirror[0] = vtx_mirror[1] = vtx_mirror[2] = NULL;
idx_mirror[0] = idx_mirror[1] = idx_mirror[2] = NULL;
instance_count[0] = 0;
for (unsigned i = 0; i < InstanceTypeCount; i++)
{
glGenBuffers(1, &instance_vbo[i]);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[i]);
#ifdef Buffer_Storage
if (irr_driver->hasBufferStorageExtension())
{
glBufferStorage(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
Ptr[i] = glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
}
else
#endif
{
glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_STREAM_DRAW);
}
}
}
void VBOGatherer::regenerateBuffer(enum VTXTYPE tp)
static void cleanVAOMap(std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> Map)
{
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint>::iterator It = Map.begin(), E = Map.end();
for (; It != E; It++)
{
glDeleteVertexArrays(1, &(It->second));
}
}
void VAOManager::cleanInstanceVAOs()
{
cleanVAOMap(InstanceVAO);
InstanceVAO.clear();
}
VAOManager::~VAOManager()
{
cleanInstanceVAOs();
for (unsigned i = 0; i < 3; i++)
{
if (vtx_mirror[i])
free(vtx_mirror[i]);
if (idx_mirror[i])
free(idx_mirror[i]);
if (vbo[i])
glDeleteBuffers(1, &vbo[i]);
if (ibo[i])
glDeleteBuffers(1, &ibo[i]);
if (vao[i])
glDeleteVertexArrays(1, &vao[i]);
}
for (unsigned i = 0; i < InstanceTypeCount; i++)
{
glDeleteBuffers(1, &instance_vbo[i]);
}
}
void VAOManager::regenerateBuffer(enum VTXTYPE tp)
{
glBindVertexArray(0);
if (vbo[tp])
glDeleteBuffers(1, &vbo[tp]);
glGenBuffers(1, &vbo[tp]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW);
#ifdef Buffer_Storage
if (irr_driver->hasBufferStorageExtension())
{
glBufferStorage(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
VBOPtr[tp] = glMapBufferRange(GL_ARRAY_BUFFER, 0, vtx_cnt[tp] * getVertexPitch(tp), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
}
else
#endif
glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW);
if (ibo[tp])
glDeleteBuffers(1, &ibo[tp]);
@ -602,7 +492,7 @@ void VBOGatherer::regenerateBuffer(enum VTXTYPE tp)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void VBOGatherer::regenerateVAO(enum VTXTYPE tp)
void VAOManager::regenerateVAO(enum VTXTYPE tp)
{
if (vao[tp])
glDeleteVertexArrays(1, &vao[tp]);
@ -668,7 +558,100 @@ void VBOGatherer::regenerateVAO(enum VTXTYPE tp)
glBindVertexArray(0);
}
size_t VBOGatherer::getVertexPitch(enum VTXTYPE tp) const
void VAOManager::regenerateInstancedVAO()
{
cleanInstanceVAOs();
enum video::E_VERTEX_TYPE IrrVT[] = { video::EVT_STANDARD, video::EVT_2TCOORDS, video::EVT_TANGENTS };
for (unsigned i = 0; i < VTXTYPE_COUNT; i++)
{
video::E_VERTEX_TYPE tp = IrrVT[i];
if (!vbo[tp] || !ibo[tp])
continue;
GLuint vao = createVAO(vbo[tp], ibo[tp], tp);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeDefault]);
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
glVertexAttribDivisor(7, 1);
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(8, 1);
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(9, 1);
glEnableVertexAttribArray(10);
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
glVertexAttribDivisor(10, 1);
glEnableVertexAttribArray(11);
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
glVertexAttribDivisor(11, 1);
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeDefault)] = vao;
vao = createVAO(vbo[tp], ibo[tp], tp);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeShadow]);
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
glVertexAttribDivisor(7, 1);
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(8, 1);
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(9, 1);
glEnableVertexAttribArray(10);
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
glVertexAttribDivisor(10, 1);
glEnableVertexAttribArray(11);
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
glVertexAttribDivisor(11, 1);
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeShadow)] = vao;
vao = createVAO(vbo[tp], ibo[tp], tp);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeRSM]);
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
glVertexAttribDivisor(7, 1);
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(8, 1);
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(9, 1);
glEnableVertexAttribArray(10);
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
glVertexAttribDivisor(10, 1);
glEnableVertexAttribArray(11);
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
glVertexAttribDivisor(11, 1);
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeRSM)] = vao;
vao = createVAO(vbo[tp], ibo[tp], tp);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeGlow]);
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), 0);
glVertexAttribDivisor(7, 1);
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(8, 1);
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(9, 1);
glEnableVertexAttribArray(12);
glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GlowInstanceData), (GLvoid*)(9 * sizeof(float)));
glVertexAttribDivisor(12, 1);
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeGlow)] = vao;
glBindVertexArray(0);
}
}
size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const
{
switch (tp)
{
@ -684,22 +667,22 @@ size_t VBOGatherer::getVertexPitch(enum VTXTYPE tp) const
}
}
VBOGatherer::VTXTYPE VBOGatherer::getVTXTYPE(video::E_VERTEX_TYPE type)
VAOManager::VTXTYPE VAOManager::getVTXTYPE(video::E_VERTEX_TYPE type)
{
switch (type)
{
default:
assert(0 && "Wrong vtxtype");
case video::EVT_STANDARD:
return VTXTYPE_STANDARD;
case video::EVT_2TCOORDS:
return VTXTYPE_TCOORD;
case video::EVT_TANGENTS:
return VTXTYPE_TANGENT;
default:
assert(0 && "Wrong vtxtype");
}
};
void VBOGatherer::append(scene::IMeshBuffer *mb, VBOGatherer::VTXTYPE tp)
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
{
size_t old_vtx_cnt = vtx_cnt[tp];
vtx_cnt[tp] += mb->getVertexCount();
@ -717,7 +700,7 @@ void VBOGatherer::append(scene::IMeshBuffer *mb, VBOGatherer::VTXTYPE tp)
mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16);
}
std::pair<unsigned, unsigned> VBOGatherer::getBase(scene::IMeshBuffer *mb)
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
{
VTXTYPE tp = getVTXTYPE(mb->getVertexType());
if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end())
@ -727,6 +710,7 @@ std::pair<unsigned, unsigned> VBOGatherer::getBase(scene::IMeshBuffer *mb)
append(mb, tp);
regenerateBuffer(tp);
regenerateVAO(tp);
regenerateInstancedVAO();
}
std::map<scene::IMeshBuffer*, unsigned>::iterator It;
@ -738,63 +722,41 @@ std::pair<unsigned, unsigned> VBOGatherer::getBase(scene::IMeshBuffer *mb)
return std::pair<unsigned, unsigned>(vtx, It->second);
}
static VBOGatherer *gatherersingleton = 0;
std::pair<unsigned, unsigned> getVAOOffsetAndBase(scene::IMeshBuffer *mb)
size_t VAOManager::appendInstance(enum InstanceType, const std::vector<InstanceData> &instance_data)
{
if (!gatherersingleton)
gatherersingleton = new VBOGatherer();
return gatherersingleton->getBase(mb);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[0]);
glBufferSubData(GL_ARRAY_BUFFER, instance_count[0] * sizeof(InstanceData), instance_data.size() * sizeof(InstanceData), instance_data.data());
size_t result = instance_count[0];
instance_count[0] += instance_data.size();
return result;
}
unsigned getVBO(video::E_VERTEX_TYPE type)
{
if (gatherersingleton)
return gatherersingleton->getVBO(type);
return 0;
}
unsigned getVAO(video::E_VERTEX_TYPE type)
{
if (gatherersingleton)
return gatherersingleton->getVAO(type);
return 0;
}
void resetVAO()
{
if (gatherersingleton)
delete gatherersingleton;
gatherersingleton = 0;
}
ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer)
ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t)
{
if (!UserConfigParams::m_profiler_enabled) return;
if (profiler.isFrozen()) return;
if (!timer.canSubmitQuery) return;
#ifdef GL_TIME_ELAPSED
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
if (!timer.initialised)
{
gl_driver->extGlGenQueries(1, &timer.query);
glGenQueries(1, &timer.query);
timer.initialised = true;
}
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, timer.query);
glBeginQuery(GL_TIME_ELAPSED, timer.query);
#endif
}
ScopedGPUTimer::~ScopedGPUTimer()
{
if (!UserConfigParams::m_profiler_enabled) return;
if (profiler.isFrozen()) return;
if (!timer.canSubmitQuery) return;
#ifdef GL_TIME_ELAPSED
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
glEndQuery(GL_TIME_ELAPSED);
timer.canSubmitQuery = false;
#endif
}
GPUTimer::GPUTimer() : initialised(false)
GPUTimer::GPUTimer() : initialised(false), lastResult(0), canSubmitQuery(true)
{
}
@ -803,8 +765,12 @@ unsigned GPUTimer::elapsedTimeus()
if (!initialised)
return 0;
GLuint result;
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
gl_driver->extGlGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
glGetQueryObjectuiv(query, GL_QUERY_RESULT_AVAILABLE, &result);
if (result == GL_FALSE)
return lastResult;
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
lastResult = result / 1000;
canSubmitQuery = true;
return result / 1000;
}
@ -861,7 +827,7 @@ void FrameBuffer::Bind()
glViewport(0, 0, width, height);
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver*)irr_driver->getDevice()->getVideoDriver();
GLenum bufs[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
gl_driver->extGlDrawBuffers(RenderTargets.size(), bufs);
glDrawBuffers(RenderTargets.size(), bufs);
}
void FrameBuffer::Blit(const FrameBuffer &Src, FrameBuffer &Dst, GLbitfield mask, GLenum filter)
@ -924,7 +890,7 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol
glUseProgram(UIShader::ColoredTextureRectShader::getInstance()->Program);
glBindVertexArray(UIShader::ColoredTextureRectShader::getInstance()->vao);
setTexture(UIShader::ColoredTextureRectShader::getInstance()->TU_tex, static_cast<const irr::video::COpenGLTexture*>(texture)->getOpenGLTextureName(), GL_LINEAR, GL_LINEAR);
UIShader::ColoredTextureRectShader::getInstance()->SetTextureUnits(createVector<GLuint>(static_cast<const irr::video::COpenGLTexture*>(texture)->getOpenGLTextureName()));
UIShader::ColoredTextureRectShader::getInstance()->setUniforms(
core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height),
core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height));
@ -944,7 +910,7 @@ void drawTexQuad(GLuint texture, float width, float height,
glUseProgram(UIShader::TextureRectShader::getInstance()->Program);
glBindVertexArray(SharedObject::UIVAO);
setTexture(UIShader::TextureRectShader::getInstance()->TU_tex, texture, GL_LINEAR, GL_LINEAR);
UIShader::TextureRectShader::getInstance()->SetTextureUnits(createVector<GLuint>(texture));
UIShader::TextureRectShader::getInstance()->setUniforms(
core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height),
core::vector2df(tex_center_pos_x, tex_center_pos_y),
@ -1047,7 +1013,7 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program);
glBindVertexArray(SharedObject::UIVAO);
setTexture(UIShader::UniformColoredTextureRectShader::getInstance()->TU_tex, static_cast<const irr::video::COpenGLTexture*>(texture)->getOpenGLTextureName(), GL_LINEAR, GL_LINEAR);
UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector<GLuint>(static_cast<const irr::video::COpenGLTexture*>(texture)->getOpenGLTextureName()));
UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms(
core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), colors);
@ -1083,7 +1049,7 @@ void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h,
glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program);
glBindVertexArray(SharedObject::UIVAO);
setTexture(UIShader::UniformColoredTextureRectShader::getInstance()->TU_tex, texture, GL_LINEAR, GL_LINEAR);
UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector<GLuint>(texture));
UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms(
core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height),
core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height),
@ -1204,3 +1170,30 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect<s32>& position,
glGetError();
}
bool hasGLExtension(const char* extension)
{
if (glGetStringi != NULL)
{
GLint numExtensions = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
for (GLint i = 0; i < numExtensions; i++)
{
const char* foundExtension =
(const char*) glGetStringi(GL_EXTENSIONS, i);
if (foundExtension && strcmp(foundExtension, extension) == 0)
{
return true;
}
}
}
else
{
const char* extensions = (const char*) glGetString(GL_EXTENSIONS);
if (extensions && strstr(extensions, extension) != NULL)
{
return true;
}
}
return false;
}

View File

@ -1,118 +1,12 @@
#ifndef GLWRAP_HEADER_H
#define GLWRAP_HEADER_H
#if defined(__APPLE__)
# include <OpenGL/gl.h>
# include <OpenGL/gl3.h>
# define OGL32CTX
# ifdef GL_ARB_instanced_arrays
# define glVertexAttribDivisor glVertexAttribDivisorARB
# endif
# ifndef GL_TEXTURE_SWIZZLE_RGBA
# define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
# endif
#elif defined(ANDROID)
# include <GLES/gl.h>
#elif defined(WIN32)
# define _WINSOCKAPI_
// has to be included before gl.h because of WINGDIAPI and APIENTRY definitions
# include <windows.h>
# include <GL/gl.h>
#else
#define GL_GLEXT_PROTOTYPES
#define DEBUG_OUTPUT_DECLARED
# include <GL/gl.h>
#endif
#include "gl_headers.hpp"
#include <vector>
#include "irr_driver.hpp"
#include "utils/log.hpp"
// already includes glext.h, which defines useful GL constants.
// COpenGLDriver has already loaded the extension GL functions we use (e.g glBeginQuery)
#include "../../lib/irrlicht/source/Irrlicht/COpenGLDriver.h"
#ifdef WIN32
extern PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks;
extern PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback;
extern PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback;
extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
extern PFNGLGENBUFFERSPROC glGenBuffers;
extern PFNGLBINDBUFFERPROC glBindBuffer;
extern PFNGLBUFFERDATAPROC glBufferData;
extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
extern PFNGLCREATESHADERPROC glCreateShader;
extern PFNGLCOMPILESHADERPROC glCompileShader;
extern PFNGLSHADERSOURCEPROC glShaderSource;
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
extern PFNGLATTACHSHADERPROC glAttachShader;
extern PFNGLLINKPROGRAMPROC glLinkProgram;
extern PFNGLUSEPROGRAMPROC glUseProgram;
extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
extern PFNGLUNIFORM1FPROC glUniform1f;
extern PFNGLUNIFORM3FPROC glUniform3f;
extern PFNGLUNIFORM1FVPROC glUniform1fv;
extern PFNGLUNIFORM4FVPROC glUniform4fv;
extern PFNGLDELETESHADERPROC glDeleteShader;
extern PFNGLGETSHADERIVPROC glGetShaderiv;
extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
extern PFNGLACTIVETEXTUREPROC glActiveTexture;
extern PFNGLUNIFORM2FPROC glUniform2f;
extern PFNGLUNIFORM1IPROC glUniform1i;
extern PFNGLUNIFORM3IPROC glUniform3i;
extern PFNGLUNIFORM4IPROC glUniform4i;
extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
extern PFNGLBLENDEQUATIONPROC glBlendEquation;
extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
extern PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
extern PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
extern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
extern PFNGLTEXBUFFERPROC glTexBuffer;
extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
extern PFNGLMAPBUFFERPROC glMapBuffer;
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
extern PFNGLFENCESYNCPROC glFenceSync;
extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
extern PFNGLTEXIMAGE3DPROC glTexImage3D;
extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
extern PFNGLBLENDCOLORPROC glBlendColor;
extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
extern PFNGLTEXSTORAGE1DPROC glTexStorage1D;
extern PFNGLTEXSTORAGE2DPROC glTexStorage2D;
extern PFNGLTEXSTORAGE3DPROC glTexStorage3D;
extern PFNGLBINDIMAGETEXTUREPROC glBindImageTexture;
extern PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
#ifdef DEBUG
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
#endif
#endif
void initGL();
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount);
@ -194,6 +88,8 @@ class GPUTimer;
class ScopedGPUTimer
{
protected:
GPUTimer &timer;
public:
ScopedGPUTimer(GPUTimer &);
~ScopedGPUTimer();
@ -204,6 +100,8 @@ class GPUTimer
friend class ScopedGPUTimer;
GLuint query;
bool initialised;
unsigned lastResult;
bool canSubmitQuery;
public:
GPUTimer();
unsigned elapsedTimeus();
@ -241,10 +139,109 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = f
bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(const std::string& compressed_tex);
std::pair<unsigned, unsigned> getVAOOffsetAndBase(scene::IMeshBuffer *mb);
unsigned getVAO(video::E_VERTEX_TYPE type);
unsigned getVBO(video::E_VERTEX_TYPE type);
void resetVAO();
enum InstanceType
{
InstanceTypeDefault,
InstanceTypeShadow,
InstanceTypeRSM,
InstanceTypeGlow,
InstanceTypeCount,
};
#ifdef WIN32
#pragma pack(push, 1)
#endif
struct InstanceData
{
struct
{
float X;
float Y;
float Z;
} Origin;
struct
{
float X;
float Y;
float Z;
} Orientation;
struct
{
float X;
float Y;
float Z;
} Scale;
uint64_t Texture;
uint64_t SecondTexture;
#ifdef WIN32
};
#else
} __attribute__((packed));
#endif
struct GlowInstanceData
{
struct
{
float X;
float Y;
float Z;
} Origin;
struct
{
float X;
float Y;
float Z;
} Orientation;
struct
{
float X;
float Y;
float Z;
} Scale;
unsigned Color;
#ifdef WIN32
};
#else
} __attribute__((packed));
#endif
#ifdef WIN32
#pragma pack(pop)
#endif
class VAOManager : public Singleton<VAOManager>
{
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
GLuint instance_vbo[InstanceTypeCount];
size_t instance_count[InstanceTypeCount];
void *Ptr[InstanceTypeCount];
void *VBOPtr[VTXTYPE_COUNT];
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO;
void cleanInstanceVAOs();
void regenerateBuffer(enum VTXTYPE);
void regenerateVAO(enum VTXTYPE);
void regenerateInstancedVAO();
size_t getVertexPitch(enum VTXTYPE) const;
VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type);
void append(scene::IMeshBuffer *, VTXTYPE tp);
public:
VAOManager();
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
size_t appendInstance(enum InstanceType, const std::vector<InstanceData> &instance_data);
GLuint getInstanceBuffer(InstanceType it) { return instance_vbo[it]; }
void *getInstanceBufferPtr(InstanceType it) { return Ptr[it]; }
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
void *getVBOPtr(video::E_VERTEX_TYPE type) { return VBOPtr[getVTXTYPE(type)]; }
unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; }
unsigned getInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
~VAOManager();
};
void draw3DLine(const core::vector3df& start,
const core::vector3df& end, irr::video::SColor color);
@ -264,4 +261,7 @@ void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect<s32>
void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect<s32>& position,
const irr::core::rect<s32>* clip = 0);
bool hasGLExtension(const char* extension);
#endif

View File

@ -6,6 +6,7 @@
#include <IParticleSystemSceneNode.h>
#include "guiengine/engine.hpp"
#include "graphics/particle_emitter.hpp"
#include "../../lib/irrlicht/source/Irrlicht/os.h"
#define COMPONENTCOUNT 8
scene::IParticleSystemSceneNode *ParticleSystemProxy::addParticleNode(
@ -88,7 +89,7 @@ void ParticleSystemProxy::setHeightmap(const std::vector<std::vector<float> > &h
has_height_map = true;
glGenBuffers(1, &heighmapbuffer);
glBindBuffer(GL_TEXTURE_BUFFER, heighmapbuffer);
glBufferData(GL_TEXTURE_BUFFER, width * height * sizeof(float), hm_array, GL_STATIC_DRAW);
glBufferData(GL_TEXTURE_BUFFER, width * height * sizeof(float), hm_array, GL_STREAM_COPY);
glGenTextures(1, &heightmaptexture);
glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, heighmapbuffer);
@ -348,9 +349,7 @@ void ParticleSystemProxy::drawFlip()
glBlendFunc(GL_ONE, GL_ONE);
glUseProgram(ParticleShader::FlipParticleRender::getInstance()->Program);
setTexture(ParticleShader::FlipParticleRender::getInstance()->TU_tex, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
setTexture(ParticleShader::FlipParticleRender::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
ParticleShader::FlipParticleRender::getInstance()->SetTextureUnits(std::vector<GLuint>{ texture, irr_driver->getDepthStencilTexture() });
ParticleShader::FlipParticleRender::getInstance()->setUniforms();
glBindVertexArray(current_rendering_vao);
@ -365,8 +364,7 @@ void ParticleSystemProxy::drawNotFlip()
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(ParticleShader::SimpleParticleRender::getInstance()->Program);
setTexture(ParticleShader::SimpleParticleRender::getInstance()->TU_tex, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
setTexture(ParticleShader::SimpleParticleRender::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
ParticleShader::SimpleParticleRender::getInstance()->SetTextureUnits(std::vector<GLuint>{ texture, irr_driver->getDepthStencilTexture() });
video::SColorf ColorFrom = video::SColorf(getColorFrom()[0], getColorFrom()[1], getColorFrom()[2]);
video::SColorf ColorTo = video::SColorf(getColorTo()[0], getColorTo()[1], getColorTo()[2]);
@ -389,12 +387,12 @@ void ParticleSystemProxy::generateVAOs()
glBindVertexArray(0);
glGenBuffers(1, &initial_values_buffer);
glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer);
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), ParticleParams, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), ParticleParams, GL_STREAM_COPY);
glGenBuffers(2, tfb_buffers);
glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]);
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), InitialValues, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), InitialValues, GL_STREAM_COPY);
glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]);
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), 0, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), 0, GL_STREAM_COPY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenVertexArrays(1, &current_rendering_vao);
@ -423,7 +421,7 @@ void ParticleSystemProxy::generateVAOs()
}
glGenBuffers(1, &quaternionsbuffer);
glBindBuffer(GL_ARRAY_BUFFER, quaternionsbuffer);
glBufferData(GL_ARRAY_BUFFER, 4 * count * sizeof(float), quaternions, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, 4 * count * sizeof(float), quaternions, GL_STREAM_COPY);
delete[] quaternions;
}
@ -452,6 +450,12 @@ void ParticleSystemProxy::render() {
draw();
}
bool ParticleSystemProxy::update()
{
doParticleSystem(os::Timer::getTime());
return (IsVisible && (Particles.size() != 0));
}
void ParticleSystemProxy::OnRegisterSceneNode()
{
doParticleSystem(os::Timer::getTime());

View File

@ -81,6 +81,7 @@ public:
const float* getColorTo() const { return m_color_to; }
void setHeightmap(const std::vector<std::vector<float> >&, float, float, float, float);
void setFlip();
bool update();
};
#endif // GPUPARTICLES_H

View File

@ -112,6 +112,10 @@ IrrDriver::IrrDriver()
m_mipviz = m_wireframe = m_normals = m_ssaoviz = \
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = false;
SkyboxCubeMap = m_last_light_bucket_distance = 0;
m_shadow_camnodes[0] = NULL;
m_shadow_camnodes[1] = NULL;
m_shadow_camnodes[2] = NULL;
m_shadow_camnodes[3] = NULL;
memset(object_count, 0, sizeof(object_count));
} // IrrDriver
@ -166,6 +170,11 @@ void IrrDriver::IncreaseObjectCount()
object_count[m_phase]++;
}
void IrrDriver::IncreasePolyCount(unsigned Polys)
{
poly_count[m_phase] += Polys;
}
core::array<video::IRenderTarget> &IrrDriver::getMainSetup()
{
return m_mrt;
@ -328,8 +337,8 @@ void IrrDriver::initDevice()
} // end if firstTime
const core::dimension2d<u32> ssize = m_device->getVideoModeList()
->getDesktopResolution();
video::IVideoModeList* modes = m_device->getVideoModeList();
const core::dimension2d<u32> ssize = modes->getDesktopResolution();
if (UserConfigParams::m_width > (int)ssize.Width ||
UserConfigParams::m_height > (int)ssize.Height)
{
@ -339,11 +348,14 @@ void IrrDriver::initDevice()
UserConfigParams::m_height = (int)ssize.Height;
}
core::dimension2d<u32> res = core::dimension2du(UserConfigParams::m_width, UserConfigParams::m_height);
res = m_device->getVideoModeList()->getVideoModeResolution(res, res);
if (res.Width > 0 && res.Height > 0)
core::dimension2d<u32> res = core::dimension2du(UserConfigParams::m_width,
UserConfigParams::m_height);
if (modes->getVideoModeCount() > 0)
{
res = modes->getVideoModeResolution(res, res);
UserConfigParams::m_width = res.Width;
UserConfigParams::m_height = res.Height;
}
@ -467,25 +479,57 @@ void IrrDriver::initDevice()
m_need_ubo_workaround = false;
m_need_rh_workaround = false;
m_need_srgb_workaround = false;
#ifdef WIN32
// Fix for Intel Sandy Bridge on Windows which supports GL up to 3.1 only
if (strstr((const char *)glGetString(GL_VENDOR), "Intel") != nullptr && (GLMajorVersion == 3 && GLMinorVersion == 1))
if (strstr((const char *)glGetString(GL_VENDOR), "Intel") != NULL && (GLMajorVersion == 3 && GLMinorVersion == 1))
m_need_ubo_workaround = true;
#endif
// Fix for Nvidia and instanced RH
if (strstr((const char *)glGetString(GL_VENDOR), "NVIDIA") != nullptr)
if (strstr((const char *)glGetString(GL_VENDOR), "NVIDIA") != NULL)
m_need_rh_workaround = true;
// Fix for AMD and bindless sRGB textures
if (strstr((const char *)glGetString(GL_VENDOR), "ATI") != NULL)
m_need_srgb_workaround = true;
}
m_glsl = (GLMajorVersion > 3 || (GLMajorVersion == 3 && GLMinorVersion >= 1));
initGL();
// Parse extensions
hasVSLayer = false;
hasBaseInstance = false;
hasBuffserStorage = false;
hasDrawIndirect = false;
hasComputeShaders = false;
hasTextureStorage = false;
// Default false value for hasVSLayer if --no-graphics argument is used
if (!ProfileWorld::isNoGraphics())
{
const GLubyte *extensions = glGetString(GL_EXTENSIONS);
if (extensions && strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL)
hasVSLayer = true;
if (GLEW_AMD_vertex_shader_layer) {
hasVSLayer = true;
Log::info("GLDriver", "AMD Vertex Shader Layer enabled");
}
if (GLEW_ARB_buffer_storage) {
hasBuffserStorage = true;
Log::info("GLDriver", "ARB Buffer Storage enabled");
}
if (GLEW_ARB_base_instance) {
hasBaseInstance = true;
Log::info("GLDriver", "ARB Base Instance enabled");
}
if (GLEW_ARB_draw_indirect) {
hasDrawIndirect = true;
Log::info("GLDriver", "ARB Draw Indirect enabled");
}
if (GLEW_ARB_compute_shader) {
hasComputeShaders = true;
Log::info("GLDriver", "ARB Compute Shader enabled");
}
if (GLEW_ARB_texture_storage) {
hasTextureStorage = true;
Log::info("GLDriver", "ARB Texture Storage enabled");
}
}
@ -513,8 +557,7 @@ void IrrDriver::initDevice()
m_mrt.clear();
m_mrt.reallocate(2);
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
gl_driver->extGlGenQueries(1, &m_lensflare_query);
glGenQueries(1, &m_lensflare_query);
m_query_issued = false;
scene::IMesh * const sphere = m_scene_manager->getGeometryCreator()->createSphereMesh(1, 16, 16);
@ -733,7 +776,7 @@ void IrrDriver::applyResolutionSettings()
// FIXME: this load sequence is (mostly) duplicated from main.cpp!!
// That's just error prone
// (we're sure to update main.cpp at some point and forget this one...)
m_shaders->killShaders();
// initDevice will drop the current device.
initDevice();
@ -1601,6 +1644,7 @@ video::ITexture* IrrDriver::applyMask(video::ITexture* texture,
// ----------------------------------------------------------------------------
void IrrDriver::setRTT(RTT* rtt)
{
memset(m_shadow_camnodes, 0, 4 * sizeof(void*));
m_rtts = rtt;
}
// ----------------------------------------------------------------------------
@ -1703,13 +1747,14 @@ void IrrDriver::displayFPS()
if (UserConfigParams::m_artist_debug_mode)
{
sprintf(
buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) - LightDst : ~%d",
buffer, "FPS: %i/%i/%i - PolyCount (Solid:%d Shadows:%d) - LightDst : ~%d",
min, fps, max,
object_count[SOLID_NORMAL_AND_DEPTH_PASS],
object_count[SOLID_NORMAL_AND_DEPTH_PASS],
object_count[TRANSPARENT_PASS],
poly_count[SOLID_NORMAL_AND_DEPTH_PASS],
poly_count[SHADOW_PASS],
m_last_light_bucket_distance
);
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
poly_count[SHADOW_PASS] = 0;
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
object_count[TRANSPARENT_PASS] = 0;
@ -2414,8 +2459,8 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy,
if (sun)
{
m_sun_interposer->setPosition(pos);
m_sun_interposer->updateAbsolutePosition();
//m_sun_interposer->setPosition(pos);
//m_sun_interposer->updateAbsolutePosition();
m_lensflare->setPosition(pos);
m_lensflare->updateAbsolutePosition();

View File

@ -78,9 +78,10 @@ enum TypeFBO
{
FBO_SSAO,
FBO_NORMAL_AND_DEPTHS,
FBO_COMBINED_TMP1_TMP2,
FBO_COMBINED_DIFFUSE_SPECULAR,
FBO_COLORS,
FBO_LOG_LUMINANCE,
FBO_DIFFUSE,
FBO_SPECULAR,
FBO_MLAA_COLORS,
FBO_MLAA_BLEND,
FBO_MLAA_TMP,
@ -111,6 +112,7 @@ enum QueryPerf
{
Q_SOLID_PASS1,
Q_SHADOWS,
Q_RSM,
Q_RH,
Q_GI,
Q_ENVMAP,
@ -140,7 +142,9 @@ enum TypeRTT
RTT_LINEAR_DEPTH,
RTT_NORMAL_AND_DEPTH,
RTT_COLOR,
RTT_LOG_LUMINANCE,
RTT_DIFFUSE,
RTT_SPECULAR,
RTT_HALF1,
RTT_HALF2,
@ -196,8 +200,15 @@ class IrrDriver : public IEventReceiver, public NoCopy
private:
int GLMajorVersion, GLMinorVersion;
bool hasVSLayer;
bool hasBaseInstance;
bool hasDrawIndirect;
bool hasBuffserStorage;
bool hasComputeShaders;
bool hasTextureStorage;
bool m_need_ubo_workaround;
bool m_need_rh_workaround;
bool m_need_srgb_workaround;
GLsync m_sync;
/** The irrlicht device. */
IrrlichtDevice *m_device;
/** Irrlicht scene manager. */
@ -290,11 +301,41 @@ public:
return m_need_rh_workaround;
}
bool needsRGBBindlessWorkaround() const
{
return m_need_srgb_workaround;
}
bool hasARB_base_instance() const
{
return hasBaseInstance;
}
bool hasARB_draw_indirect() const
{
return hasDrawIndirect;
}
bool hasVSLayerExtension() const
{
return hasVSLayer;
}
bool hasBufferStorageExtension() const
{
return hasBuffserStorage;
}
bool hasARBComputeShaders() const
{
return hasComputeShaders;
}
bool hasARBTextureStorage() const
{
return hasTextureStorage;
}
video::SColorf getAmbientLight() const;
struct GlowData {
@ -332,12 +373,14 @@ private:
/** Performance stats */
unsigned m_last_light_bucket_distance;
unsigned object_count[PASS_COUNT];
unsigned poly_count[PASS_COUNT];
u32 m_renderpass;
u32 m_lensflare_query;
bool m_query_issued;
class STKMeshSceneNode *m_sun_interposer;
scene::CLensFlareSceneNode *m_lensflare;
scene::ICameraSceneNode *m_suncam;
scene::ICameraSceneNode *m_shadow_camnodes[4];
float m_shadows_cam[4][24];
std::vector<GlowData> m_glowing;
@ -379,6 +422,7 @@ private:
void renderLights(unsigned pointlightCount);
void renderShadowsDebug();
void doScreenShot();
void PrepareDrawCalls(scene::ICameraSceneNode *camnode);
public:
IrrDriver();
~IrrDriver();
@ -394,6 +438,7 @@ public:
return sun_ortho_matrix;
}
void IncreaseObjectCount();
void IncreasePolyCount(unsigned);
core::array<video::IRenderTarget> &getMainSetup();
void updateConfigIfRelevant();
void setAllMaterialFlags(scene::IMesh *mesh) const;
@ -570,7 +615,7 @@ public:
// -----------------------------------------------------------------------
inline video::E_MATERIAL_TYPE getShader(const ShaderType num) {return m_shaders->getShader(num);}
// -----------------------------------------------------------------------
inline void updateShaders() {m_shaders->loadShaders();}
inline void updateShaders() {m_shaders->killShaders();}
// ------------------------------------------------------------------------
inline video::IShaderConstantSetCallBack* getCallback(const ShaderType num)
{

View File

@ -59,6 +59,7 @@ public:
float getEnergy() const { return m_energy; }
float getEffectiveEnergy() const { return m_energy_multiplier * m_energy; }
core::vector3df getColor() const { return core::vector3df(m_color[0], m_color[1], m_color[2]); }
void setColor(float r, float g, float b) { m_color[0] = r; m_color[1] = g; m_color[2] = b; }
float getEnergyMultiplier() const { return m_energy_multiplier; }
void setEnergyMultiplier(float newval) { m_energy_multiplier = newval; }

View File

@ -137,19 +137,24 @@ void LODNode::OnAnimate(u32 timeMs)
}
}
void LODNode::OnRegisterSceneNode()
void LODNode::updateVisibility(bool* shown)
{
if (!isVisible()) return;
if (m_nodes.size() == 0) return;
bool shown = false;
int level = getLevel();
if (level>=0)
for (size_t i = 0; i < m_nodes.size(); i++)
{
m_nodes[level]->updateAbsolutePosition();
m_nodes[level]->OnRegisterSceneNode();
shown = true;
m_nodes[i]->setVisible(i == level);
if (i == level && shown != NULL)
*shown = (i > 0);
}
}
void LODNode::OnRegisterSceneNode()
{
bool shown;
updateVisibility(&shown);
const u32 now = irr_driver->getDevice()->getTimer()->getTime();
@ -158,6 +163,7 @@ void LODNode::OnRegisterSceneNode()
m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH) &&
now > m_last_tick)
{
int level = getLevel();
if (m_previous_visibility == WAS_HIDDEN && shown)
{
scene::IMesh* mesh;
@ -254,20 +260,7 @@ void LODNode::OnRegisterSceneNode()
m_previous_visibility = (shown ? WAS_SHOWN : WAS_HIDDEN);
m_last_tick = now;
// If this node has children other than the LOD nodes, draw them
core::list<ISceneNode*>::Iterator it;
for (it = Children.begin(); it != Children.end(); it++)
{
if (m_nodes_set.find(*it) == m_nodes_set.end())
{
assert(*it != NULL);
if ((*it)->isVisible())
{
(*it)->OnRegisterSceneNode();
}
}
}
scene::ISceneNode::OnRegisterSceneNode();
}
void LODNode::add(int level, scene::ISceneNode* node, bool reparent)

View File

@ -83,6 +83,8 @@ public:
int getLevel();
void updateVisibility(bool* shown = NULL);
/*
//! Returns a reference to the current relative transformation matrix.
//! This is the matrix, this scene node uses instead of scale, translation

View File

@ -450,7 +450,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
else
{
if (m_is_glsl)
m_node = ParticleSystemProxy::addParticleNode(m_is_glsl, true);
m_node = ParticleSystemProxy::addParticleNode(m_is_glsl, false);
else
m_node = irr_driver->addParticleNode();

View File

@ -33,6 +33,7 @@
#include "tracks/track.hpp"
#include "utils/log.hpp"
#include "utils/profiler.hpp"
#include "utils/cpp2011.hpp"
#include <SViewFrustum.h>
@ -216,7 +217,7 @@ static void DrawFullScreenEffect(Args...args)
static
void renderBloom(GLuint in)
{
setTexture(FullScreenShader::BloomShader::getInstance()->TU_tex, in, GL_NEAREST, GL_NEAREST);
FullScreenShader::BloomShader::getInstance()->SetTextureUnits(createVector<GLuint>(in));
DrawFullScreenEffect<FullScreenShader::BloomShader>();
}
@ -227,12 +228,12 @@ void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSH
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
glUseProgram(FullScreenShader::DiffuseEnvMapShader::Program);
glUseProgram(FullScreenShader::DiffuseEnvMapShader::getInstance()->Program);
glBindVertexArray(SharedObject::FullScreenQuadVAO);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
FullScreenShader::DiffuseEnvMapShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH)));
core::matrix4 TVM = irr_driver->getViewMatrix().getTransposed();
FullScreenShader::DiffuseEnvMapShader::setUniforms(TVM, bSHCoeff, gSHCoeff, rSHCoeff, 0);
FullScreenShader::DiffuseEnvMapShader::getInstance()->setUniforms(TVM, std::vector<float>(bSHCoeff, bSHCoeff + 9), std::vector<float>(gSHCoeff, gSHCoeff + 9), std::vector<float>(rSHCoeff, rSHCoeff + 9));
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
@ -263,26 +264,8 @@ void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3
core::matrix4 InvRHMatrix;
RHMatrix.getInverse(InvRHMatrix);
glDisable(GL_DEPTH_TEST);
glActiveTexture(GL_TEXTURE0 + FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_SHR);
glBindTexture(GL_TEXTURE_3D, shr);
{
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
glActiveTexture(GL_TEXTURE0 + FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_SHG);
glBindTexture(GL_TEXTURE_3D, shg);
{
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
glActiveTexture(GL_TEXTURE0 + FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_SHB);
glBindTexture(GL_TEXTURE_3D, shb);
{
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
setTexture(FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_ntex, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
setTexture(FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->SetTextureUnits(createVector<GLuint>(
irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), shr, shg, shb));
DrawFullScreenEffect<FullScreenShader::GlobalIlluminationReconstructionShader>(RHMatrix, InvRHMatrix, rh_extend);
}
@ -295,8 +278,7 @@ void PostProcessing::renderSunlight()
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
setTexture(FullScreenShader::SunLightShader::getInstance()->TU_ntex, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
setTexture(FullScreenShader::SunLightShader::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
FullScreenShader::SunLightShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture()));
DrawFullScreenEffect<FullScreenShader::SunLightShader>(cb->getPosition(), video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue()));
}
@ -309,17 +291,7 @@ void PostProcessing::renderShadowedSunlight(const std::vector<core::matrix4> &su
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
setTexture(FullScreenShader::ShadowedSunLightShader::getInstance()->TU_ntex, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
setTexture(FullScreenShader::ShadowedSunLightShader::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
glActiveTexture(GL_TEXTURE0 + FullScreenShader::ShadowedSunLightShader::getInstance()->TU_shadowtex);
glBindTexture(GL_TEXTURE_2D_ARRAY, depthtex);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
FullScreenShader::ShadowedSunLightShader::getInstance()->SetTextureUnits(createVector<GLuint>( irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), depthtex ));
DrawFullScreenEffect<FullScreenShader::ShadowedSunLightShader>(cb->getPosition(), video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue()));
}
@ -331,17 +303,13 @@ void PostProcessing::renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
{
auxiliary.Bind();
setTexture(FullScreenShader::Gaussian3VBlurShader::getInstance()->TU_tex, in_fbo.getRTT()[0], GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
FullScreenShader::Gaussian3VBlurShader::getInstance()->SetTextureUnits(createVector<GLuint>(in_fbo.getRTT()[0]));
DrawFullScreenEffect<FullScreenShader::Gaussian3VBlurShader>(core::vector2df(inv_width, inv_height));
}
{
in_fbo.Bind();
setTexture(FullScreenShader::Gaussian3HBlurShader::getInstance()->TU_tex, auxiliary.getRTT()[0], GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
FullScreenShader::Gaussian3HBlurShader::getInstance()->SetTextureUnits(createVector<GLuint>(auxiliary.getRTT()[0]));
DrawFullScreenEffect<FullScreenShader::Gaussian3HBlurShader>(core::vector2df(inv_width, inv_height));
}
}
@ -353,17 +321,13 @@ void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
{
auxiliary.Bind();
setTexture(FullScreenShader::Gaussian6VBlurShader::getInstance()->TU_tex, in_fbo.getRTT()[0], GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(createVector<GLuint>(in_fbo.getRTT()[0]));
DrawFullScreenEffect<FullScreenShader::Gaussian6VBlurShader>(core::vector2df(inv_width, inv_height));
}
{
in_fbo.Bind();
setTexture(FullScreenShader::Gaussian6HBlurShader::getInstance()->TU_tex, auxiliary.getRTT()[0], GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(createVector<GLuint>(auxiliary.getRTT()[0]));
DrawFullScreenEffect<FullScreenShader::Gaussian6HBlurShader>(core::vector2df(inv_width, inv_height));
}
}
@ -373,21 +337,12 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight());
float inv_width = 1.0f / in_fbo.getWidth(), inv_height = 1.0f / in_fbo.getHeight();
{
#if WIN32
if (irr_driver->getGLSLVersion() < 430)
#endif
if (irr_driver->hasARBComputeShaders())
{
auxiliary.Bind();
setTexture(FullScreenShader::Gaussian17TapHShader::getInstance()->TU_tex, in_fbo.getRTT()[0], GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
setTexture(FullScreenShader::Gaussian17TapHShader::getInstance()->TU_depth, irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0], GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
FullScreenShader::Gaussian17TapHShader::getInstance()->SetTextureUnits(createVector<GLuint>(in_fbo.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]));
DrawFullScreenEffect<FullScreenShader::Gaussian17TapHShader>(core::vector2df(inv_width, inv_height));
}
#if WIN32
else
{
@ -398,24 +353,15 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
FullScreenShader::ComputeGaussian17TapHShader::getInstance()->setUniforms();
glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1);
}
#endif
}
{
#if WIN32
if (irr_driver->getGLSLVersion() < 430)
#endif
if (irr_driver->hasARBComputeShaders())
{
in_fbo.Bind();
setTexture(FullScreenShader::Gaussian17TapVShader::getInstance()->TU_tex, auxiliary.getRTT()[0], GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
setTexture(FullScreenShader::Gaussian17TapVShader::getInstance()->TU_depth, irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0], GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
FullScreenShader::Gaussian17TapVShader::getInstance()->SetTextureUnits(createVector<GLuint>(auxiliary.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]));
DrawFullScreenEffect<FullScreenShader::Gaussian17TapVShader>(core::vector2df(inv_width, inv_height));
}
#if WIN32
else
{
glUseProgram(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->Program);
@ -425,7 +371,6 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
FullScreenShader::ComputeGaussian17TapVShader::getInstance()->setUniforms();
glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1);
}
#endif
}
}
@ -434,7 +379,7 @@ void PostProcessing::renderPassThrough(GLuint tex)
glUseProgram(FullScreenShader::PassThroughShader::getInstance()->Program);
glBindVertexArray(FullScreenShader::PassThroughShader::getInstance()->vao);
setTexture(FullScreenShader::PassThroughShader::getInstance()->TU_tex, tex, GL_LINEAR, GL_LINEAR);
FullScreenShader::PassThroughShader::getInstance()->SetTextureUnits(createVector<GLuint>(tex));
FullScreenShader::PassThroughShader::getInstance()->setUniforms();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -459,7 +404,7 @@ void PostProcessing::renderGlow(unsigned tex)
glUseProgram(FullScreenShader::GlowShader::getInstance()->Program);
glBindVertexArray(FullScreenShader::GlowShader::getInstance()->vao);
setTexture(FullScreenShader::GlowShader::getInstance()->TU_tex, tex, GL_LINEAR, GL_LINEAR);
FullScreenShader::GlowShader::getInstance()->SetTextureUnits(createVector<GLuint>(tex));
FullScreenShader::GlowShader::getInstance()->setUniforms();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -473,11 +418,11 @@ void PostProcessing::renderSSAO()
// Generate linear depth buffer
irr_driver->getFBO(FBO_LINEAR_DEPTH).Bind();
setTexture(FullScreenShader::LinearizeDepthShader::getInstance()->TU_tex, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
FullScreenShader::LinearizeDepthShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getDepthStencilTexture()));
DrawFullScreenEffect<FullScreenShader::LinearizeDepthShader>(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue());
irr_driver->getFBO(FBO_SSAO).Bind();
setTexture(FullScreenShader::SSAOShader::getInstance()->TU_dtex, irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH), GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST);
FullScreenShader::SSAOShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH)));
glGenerateMipmap(GL_TEXTURE_2D);
DrawFullScreenEffect<FullScreenShader::SSAOShader>(irr_driver->getSSAORadius(), irr_driver->getSSAOK(), irr_driver->getSSAOSigma());
@ -505,8 +450,8 @@ void PostProcessing::renderFog()
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
setTexture(FullScreenShader::FogShader::getInstance()->TU_tex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
DrawFullScreenEffect<FullScreenShader::FogShader>(fogmax, startH, endH, start, end, col);
FullScreenShader::FogShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getDepthStencilTexture()));
DrawFullScreenEffect<FullScreenShader::FogShader>(fogmax, startH, endH, start, end, col);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
@ -533,10 +478,7 @@ void PostProcessing::renderMotionBlur(unsigned cam, FrameBuffer &in_fbo, FrameBu
out_fbo.Bind();
glClear(GL_COLOR_BUFFER_BIT);
setTexture(FullScreenShader::MotionBlurShader::getInstance()->TU_cb, in_fbo.getRTT()[0], GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
setTexture(FullScreenShader::MotionBlurShader::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
FullScreenShader::MotionBlurShader::getInstance()->SetTextureUnits(createVector<GLuint>(in_fbo.getRTT()[0], irr_driver->getDepthStencilTexture()));
DrawFullScreenEffect<FullScreenShader::MotionBlurShader>(
// Todo : use a previousPVMatrix per cam, not global
irr_driver->getPreviousPVMatrix(),
@ -549,7 +491,7 @@ static void renderGodFade(GLuint tex, const SColor &col)
{
glUseProgram(FullScreenShader::GodFadeShader::getInstance()->Program);
glBindVertexArray(FullScreenShader::GodFadeShader::getInstance()->vao);
setTexture(FullScreenShader::GodFadeShader::getInstance()->TU_tex, tex, GL_LINEAR, GL_LINEAR);
FullScreenShader::GodFadeShader::getInstance()->SetTextureUnits(createVector<GLuint>(tex));
FullScreenShader::GodFadeShader::getInstance()->setUniforms(col);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -559,7 +501,7 @@ static void renderGodRay(GLuint tex, const core::vector2df &sunpos)
{
glUseProgram(FullScreenShader::GodRayShader::getInstance()->Program);
glBindVertexArray(FullScreenShader::GodRayShader::getInstance()->vao);
setTexture(FullScreenShader::GodRayShader::getInstance()->TU_tex, tex, GL_LINEAR, GL_LINEAR);
FullScreenShader::GodRayShader::getInstance()->SetTextureUnits(createVector<GLuint>(tex));
FullScreenShader::GodRayShader::getInstance()->setUniforms(sunpos);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -568,15 +510,14 @@ static void renderGodRay(GLuint tex, const core::vector2df &sunpos)
static void toneMap(FrameBuffer &fbo, GLuint rtt)
{
fbo.Bind();
setTexture(FullScreenShader::ToneMapShader::getInstance()->TU_tex, rtt, GL_NEAREST, GL_NEAREST);
FullScreenShader::ToneMapShader::getInstance()->SetTextureUnits(createVector<GLuint>(rtt));
DrawFullScreenEffect<FullScreenShader::ToneMapShader>();
}
static void renderDoF(FrameBuffer &fbo, GLuint rtt)
{
fbo.Bind();
setTexture(FullScreenShader::DepthOfFieldShader::getInstance()->TU_tex, rtt, GL_LINEAR, GL_LINEAR);
setTexture(FullScreenShader::DepthOfFieldShader::getInstance()->TU_depth, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
FullScreenShader::DepthOfFieldShader::getInstance()->SetTextureUnits(createVector<GLuint>(rtt, irr_driver->getDepthStencilTexture()));
DrawFullScreenEffect<FullScreenShader::DepthOfFieldShader>();
}
@ -592,8 +533,8 @@ void PostProcessing::applyMLAA()
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
// Pass 1: color edge detection
setTexture(FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->TU_colorMapG, irr_driver->getRenderTargetTexture(RTT_MLAA_COLORS), GL_NEAREST, GL_NEAREST);
glUseProgram(FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->Program);
FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_MLAA_COLORS)));
FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->setUniforms(PIXEL_SIZE);
glBindVertexArray(FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->vao);
@ -607,8 +548,7 @@ void PostProcessing::applyMLAA()
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(FullScreenShader::MLAABlendWeightSHader::getInstance()->Program);
setTexture(FullScreenShader::MLAABlendWeightSHader::getInstance()->TU_edgesMap, irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), GL_LINEAR, GL_LINEAR);
setTexture(FullScreenShader::MLAABlendWeightSHader::getInstance()->TU_areaMap, getTextureGLuint(m_areamap), GL_NEAREST, GL_NEAREST);
FullScreenShader::MLAABlendWeightSHader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), getTextureGLuint(m_areamap)));
FullScreenShader::MLAABlendWeightSHader::getInstance()->setUniforms(PIXEL_SIZE);
glBindVertexArray(FullScreenShader::MLAABlendWeightSHader::getInstance()->vao);
@ -621,8 +561,7 @@ void PostProcessing::applyMLAA()
irr_driver->getFBO(FBO_MLAA_COLORS).Bind();
glUseProgram(FullScreenShader::MLAAGatherSHader::getInstance()->Program);
setTexture(FullScreenShader::MLAAGatherSHader::getInstance()->TU_colorMap, irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), GL_NEAREST, GL_NEAREST);
setTexture(FullScreenShader::MLAAGatherSHader::getInstance()->TU_blendMap, irr_driver->getRenderTargetTexture(RTT_MLAA_BLEND), GL_NEAREST, GL_NEAREST);
FullScreenShader::MLAAGatherSHader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_MLAA_BLEND), irr_driver->getRenderTargetTexture(RTT_MLAA_TMP)));
FullScreenShader::MLAAGatherSHader::getInstance()->setUniforms(PIXEL_SIZE);
glBindVertexArray(FullScreenShader::MLAAGatherSHader::getInstance()->vao);
@ -661,8 +600,10 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
if (World::getWorld() != NULL)
hasgodrays = World::getWorld()->getTrack()->hasGodRays();
if (isRace && UserConfigParams::m_light_shaft && m_sunpixels > 30 && hasgodrays)
if (isRace && UserConfigParams::m_light_shaft && hasgodrays)
{
Track* track = World::getWorld()->getTrack();
glEnable(GL_DEPTH_TEST);
// Grab the sky
out_fbo->Bind();
@ -670,12 +611,14 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
irr_driver->renderSkybox(camnode);
// Set the sun's color
const SColor col = World::getWorld()->getTrack()->getSunColor();
const SColor col = track->getGodRaysColor();
ColorizeProvider * const colcb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f);
// The sun interposer
STKMeshSceneNode *sun = irr_driver->getSunInterposer();
sun->setPosition(track->getGodRaysPosition());
sun->updateAbsolutePosition();
irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA);
irr_driver->setPhase(GLOW_PASS);
sun->render();
@ -690,7 +633,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getFBO(FBO_QUARTER2));
// Calculate the sun's position in texcoords
const core::vector3df pos = sun->getPosition();
const core::vector3df pos = track->getGodRaysPosition();
float ndc[4];
core::matrix4 trans = camnode->getProjectionMatrix();
trans *= camnode->getViewMatrix();
@ -753,9 +696,8 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
setTexture(FullScreenShader::BloomBlendShader::getInstance()->TU_tex_128, irr_driver->getRenderTargetTexture(RTT_BLOOM_128), GL_LINEAR, GL_LINEAR);
setTexture(FullScreenShader::BloomBlendShader::getInstance()->TU_tex_256, irr_driver->getRenderTargetTexture(RTT_BLOOM_256), GL_LINEAR, GL_LINEAR);
setTexture(FullScreenShader::BloomBlendShader::getInstance()->TU_tex_512, irr_driver->getRenderTargetTexture(RTT_BLOOM_512), GL_LINEAR, GL_LINEAR);
FullScreenShader::BloomBlendShader::getInstance()->SetTextureUnits(createVector<GLuint>(
irr_driver->getRenderTargetTexture(RTT_BLOOM_128), irr_driver->getRenderTargetTexture(RTT_BLOOM_256), irr_driver->getRenderTargetTexture(RTT_BLOOM_512) ));
DrawFullScreenEffect<FullScreenShader::BloomBlendShader>();
glDisable(GL_BLEND);
@ -784,6 +726,10 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
PROFILER_POP_CPU_MARKER();
}
// Workaround a bug with srgb fbo on sandy bridge windows
if (irr_driver->needUBOWorkaround())
return in_fbo;
glEnable(GL_FRAMEBUFFER_SRGB);
irr_driver->getFBO(FBO_MLAA_COLORS).Bind();
renderPassThrough(in_fbo->getRTT()[0]);

View File

@ -19,6 +19,7 @@
#include "graphics/referee.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/light.hpp"
#include "graphics/mesh_tools.hpp"
#include "karts/abstract_kart.hpp"
#include "io/file_manager.hpp"
@ -36,7 +37,6 @@ Vec3 Referee::m_st_start_offset = Vec3(-2, 2, 2);
Vec3 Referee::m_st_start_rotation = Vec3(0, 180, 0);
Vec3 Referee::m_st_scale = Vec3(1, 1, 1);
scene::IAnimatedMesh *Referee::m_st_referee_mesh = NULL;
video::ITexture *Referee::m_st_traffic_lights[3] = {NULL, NULL, NULL};
// ----------------------------------------------------------------------------
/** Loads the static mesh.
@ -93,23 +93,6 @@ void Referee::init()
* RAD_TO_DEGREE;
m_st_start_rotation.setY(m_st_start_rotation.getY()+angle_to_kart);
std::vector<std::string> colors;
node->get("colors", &colors);
if(colors.size()>3)
Log::warn("referee", "Too many colors for referee defined, "
"only first three will be used.");
if(colors.size()<3)
{
Log::fatal("referee",
"Not enough colors for referee defined, aborting.");
}
for(unsigned int i=0; i<3; i++)
{
m_st_traffic_lights[i] = irr_driver->getTexture(FileManager::MODEL, colors[i]);
}
for(unsigned int i=0; i<m_st_referee_mesh->getMeshBufferCount(); i++)
{
scene::IMeshBuffer *mb = m_st_referee_mesh->getMeshBuffer(i);
@ -119,7 +102,7 @@ void Referee::init()
std::string name=StringUtils::getBasename(t->getName()
.getInternalName().c_str());
if(name==colors[0] || name==colors[1] ||name==colors[2] )
if (name == "traffic_light.png")
{
m_st_traffic_buffer = i;
break;
@ -166,6 +149,16 @@ Referee::Referee()
m_st_last_start_frame);
irr_driver->applyObjectPassShader(m_scene_node);
if (irr_driver->isGLSL() && UserConfigParams::m_dynamic_lights)
{
m_light = irr_driver->addLight(core::vector3df(0.0f, 0.0f, 0.6f), 0.7f, 2.0f,
0.7f /* r */, 0.0 /* g */, 0.0f /* b */, false /* sun */, m_scene_node);
}
else
{
m_light = NULL;
}
} // Referee
// ----------------------------------------------------------------------------
@ -212,6 +205,9 @@ void Referee::attachToSceneNode()
if(!m_scene_node->getParent())
m_scene_node->setParent(irr_driver->getSceneManager()
->getRootSceneNode());
if (m_light != NULL)
m_light->setVisible(true);
} // attachToSceneNode
// ----------------------------------------------------------------------------
@ -223,6 +219,8 @@ void Referee::removeFromSceneGraph()
{
if(isAttached())
irr_driver->removeNode(m_scene_node);
if (m_light != NULL)
m_light->setVisible(false);
} // removeFromSceneGraph
// ----------------------------------------------------------------------------
@ -232,9 +230,31 @@ void Referee::removeFromSceneGraph()
*/
void Referee::selectReadySetGo(int rsg)
{
if(m_st_traffic_buffer<0) return;
video::SMaterial &m = m_scene_node->getMesh()->getMeshBuffer(m_st_traffic_buffer)->getMaterial();
m.setTexture(0, m_st_traffic_lights[rsg]);
if (m_st_traffic_buffer < 0)
return;
video::SMaterial &m = m_scene_node->getMaterial(m_st_traffic_buffer); // m_scene_node->getMesh()->getMeshBuffer(m_st_traffic_buffer)->getMaterial();
//if (irr_driver->isGLSL() && UserConfigParams::m_dynamic_lights)
// m.MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
core::matrix4* matrix = &m.getTextureMatrix(0);
matrix->setTextureTranslate(0.0f, rsg*0.333f);
if (m_light != NULL)
{
if (rsg == 0)
{
((LightNode*)m_light)->setColor(0.6f, 0.0f, 0.0f);
}
else if (rsg == 1)
{
((LightNode*)m_light)->setColor(0.7f, 0.23f, 0.0f);
}
else if (rsg == 2)
{
((LightNode*)m_light)->setColor(0.0f, 0.6f, 0.0f);
}
}
// disable lighting, we need to see the traffic light even if facing away
// from the sun

View File

@ -79,6 +79,8 @@ private:
/** The scene node for an instance of the referee. */
scene::IAnimatedMeshSceneNode *m_scene_node;
scene::ISceneNode* m_light;
public:
Referee();
Referee(const AbstractKart &kart);

View File

@ -34,7 +34,6 @@
#include "graphics/screenquad.hpp"
#include "graphics/shaders.hpp"
#include "graphics/stkmeshscenenode.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "graphics/wind.hpp"
#include "io/file_manager.hpp"
#include "items/item.hpp"
@ -47,6 +46,7 @@
#include "utils/helpers.hpp"
#include "utils/log.hpp"
#include "utils/profiler.hpp"
#include "stkscenemanager.hpp"
#include <algorithm>
#include <limits>
@ -148,8 +148,12 @@ void IrrDriver::renderGLSL(float dt)
// TODO: put this outside of the rendering loop
generateDiffuseCoefficients();
PROFILER_PUSH_CPU_MARKER("Update Light Info", 0xFF, 0x0, 0x0);
unsigned plc = UpdateLightsInfo(camnode, dt);
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("Compute camera matrix", 0x0, 0xFF, 0x0);
computeCameraMatrix(camnode, viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
PROFILER_POP_CPU_MARKER();
renderScene(camnode, plc, glows, dt, track->hasShadows(), false);
// Debug physic
@ -272,22 +276,30 @@ void IrrDriver::renderGLSL(float dt)
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow, bool forceRTT)
{
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
m_scene_manager->setActiveCamera(camnode);
PROFILER_PUSH_CPU_MARKER("- Draw Call Generation", 0xFF, 0xFF, 0xFF);
PrepareDrawCalls(camnode);
PROFILER_POP_CPU_MARKER();
// Shadows
{
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS));
// To avoid wrong culling, use the largest view possible
m_scene_manager->setActiveCamera(m_suncam);
if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights &&
UserConfigParams::m_shadows && !irr_driver->needUBOWorkaround() && hasShadow)
{
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
renderShadows();
PROFILER_POP_CPU_MARKER();
if (UserConfigParams::m_gi)
{
PROFILER_PUSH_CPU_MARKER("- RSM", 0xFF, 0x0, 0xFF);
renderRSM();
PROFILER_POP_CPU_MARKER();
}
}
m_scene_manager->setActiveCamera(camnode);
PROFILER_POP_CPU_MARKER();
}
PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00);
@ -323,6 +335,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
renderSolidSecondPass();
PROFILER_POP_CPU_MARKER();
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
if (getNormals())
{
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind();
@ -480,29 +494,25 @@ void IrrDriver::computeSunVisibility()
hasgodrays = World::getWorld()->getTrack()->hasGodRays();
}
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
if (UserConfigParams::m_light_shaft && hasgodrays)//hasflare || hasgodrays)
if (UserConfigParams::m_light_shaft && hasgodrays)
{
GLuint res = 0;
if (m_query_issued)
gl_driver->extGlGetQueryObjectuiv(m_lensflare_query, GL_QUERY_RESULT, &res);
glGetQueryObjectuiv(m_lensflare_query, GL_QUERY_RESULT, &res);
m_post_processing->setSunPixels(res);
// Prepare the query for the next frame.
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
gl_driver->extGlBeginQuery(GL_SAMPLES_PASSED_ARB, m_lensflare_query);
glBeginQuery(GL_SAMPLES_PASSED_ARB, m_lensflare_query);
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
irr_driver->setPhase(GLOW_PASS);
m_sun_interposer->render();
gl_driver->extGlEndQuery(GL_SAMPLES_PASSED_ARB);
glEndQuery(GL_SAMPLES_PASSED_ARB);
m_query_issued = true;
m_lensflare->setStrength(res / 4000.0f);
if (hasflare)
m_lensflare->OnRegisterSceneNode();
// Make sure the color mask is reset
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
@ -514,7 +524,9 @@ void IrrDriver::renderParticles()
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
for (unsigned i = 0; i < ParticlesList::getInstance()->size(); ++i)
ParticlesList::getInstance()->at(i)->render();
// m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
}
/** Given a matrix transform and a set of points returns an orthogonal projection matrix that maps coordinates of
@ -584,14 +596,20 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
50.,
};
float *tmp = new float[18 * 8];
float tmp[16 * 9 + 2];
memcpy(tmp, irr_driver->getViewMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[16], irr_driver->getProjMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[32], irr_driver->getInvViewMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[64], irr_driver->getProjViewMatrix().pointer(), 16 * sizeof(float));
const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix();
for (unsigned i = 0; i < 4; i++)
{
if (!m_shadow_camnodes[i])
m_shadow_camnodes[i] = (scene::ICameraSceneNode *) m_suncam->clone();
}
sun_ortho_matrix.clear();
if (World::getWorld() && World::getWorld()->getTrack())
@ -669,8 +687,8 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
const float units_per_w = w / 1024;
const float units_per_h = h / 1024;*/
m_suncam->setProjectionMatrix(getTighestFitOrthoProj(SunCamViewMatrix, vectors) , true);
m_suncam->render();
m_shadow_camnodes[i]->setProjectionMatrix(getTighestFitOrthoProj(SunCamViewMatrix, vectors) , true);
m_shadow_camnodes[i]->render();
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
}
@ -702,18 +720,17 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
assert(sun_ortho_matrix.size() == 4);
camnode->setNearValue(oldnear);
camnode->setFarValue(oldfar);
camnode->render();
size_t size = irr_driver->getShadowViewProj().size();
for (unsigned i = 0; i < size; i++)
memcpy(&tmp[16 * i + 64], irr_driver->getShadowViewProj()[i].pointer(), 16 * sizeof(float));
memcpy(&tmp[16 * i + 80], irr_driver->getShadowViewProj()[i].pointer(), 16 * sizeof(float));
}
tmp[128] = float(width);
tmp[129] = float(height);
tmp[144] = float(width);
tmp[145] = float(height);
glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO);
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 8 + 2) * sizeof(float), tmp);
delete []tmp;
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 9 + 2) * sizeof(float), tmp);
}
@ -770,20 +787,40 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
glBindVertexArray(getVAO(EVT_STANDARD));
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
for (u32 i = 0; i < glowcount; i++)
{
const GlowData &dat = glows[i];
scene::ISceneNode * const cur = dat.node;
scene::ISceneNode * cur = dat.node;
//TODO : implement culling on gpu
// Quick box-based culling
// const core::aabbox3df nodebox = cur->getTransformedBoundingBox();
// if (!nodebox.intersectsWithBox(cambox))
// continue;
STKMeshSceneNode *node = static_cast<STKMeshSceneNode *>(cur);
node->setGlowColors(SColor(0, (unsigned) (dat.b * 255.f), (unsigned)(dat.g * 255.f), (unsigned)(dat.r * 255.f)));
if (!irr_driver->hasARB_draw_indirect())
node->render();
}
cb->setColor(dat.r, dat.g, dat.b);
cur->render();
if (irr_driver->hasARB_draw_indirect())
{
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
glUseProgram(MeshShader::InstancedColorizeShader::getInstance()->Program);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeGlow));
if (UserConfigParams::m_azdo)
{
if (GlowPassCmd::getInstance()->Size)
{
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
(const void*)(GlowPassCmd::getInstance()->Offset * sizeof(DrawElementsIndirectCommand)),
GlowPassCmd::getInstance()->Size,
sizeof(DrawElementsIndirectCommand));
}
}
else
{
for (unsigned i = 0; i < ListInstancedGlow::getInstance()->size(); i++)
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((GlowPassCmd::getInstance()->Offset + i) * sizeof(DrawElementsIndirectCommand)));
}
}
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,6 @@
#include "graphics/screenquad.hpp"
#include "graphics/shaders.hpp"
#include "graphics/stkmeshscenenode.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "graphics/wind.hpp"
#include "io/file_manager.hpp"
#include "items/item.hpp"
@ -45,17 +44,13 @@ static void renderPointLights(unsigned count)
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glUseProgram(LightShader::PointLightShader::Program);
glBindVertexArray(LightShader::PointLightShader::vao);
glBindBuffer(GL_ARRAY_BUFFER, LightShader::PointLightShader::vbo);
glUseProgram(LightShader::PointLightShader::getInstance()->Program);
glBindVertexArray(LightShader::PointLightShader::getInstance()->vao);
glBindBuffer(GL_ARRAY_BUFFER, LightShader::PointLightShader::getInstance()->vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(LightShader::PointLightInfo), PointLightsInfo);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
LightShader::PointLightShader
::setUniforms(core::vector2df(float(UserConfigParams::m_width),
float(UserConfigParams::m_height)),
200, 0, 1);
LightShader::PointLightShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture()));
LightShader::PointLightShader::getInstance()->setUniforms();
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
}
@ -68,6 +63,9 @@ unsigned IrrDriver::UpdateLightsInfo(scene::ICameraSceneNode * const camnode, fl
std::vector<LightNode *> BucketedLN[15];
for (unsigned int i = 0; i < lightcount; i++)
{
if (!m_lights[i]->isVisible())
continue;
if (!m_lights[i]->isPointLight())
{
m_lights[i]->render();
@ -140,9 +138,8 @@ void IrrDriver::renderLights(unsigned pointlightcount)
if (irr_driver->needRHWorkaround())
{
glUseProgram(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->Program);
setTexture(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->TU_ctex, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
setTexture(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->TU_ntex, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
setTexture(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->TU_dtex, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->SetTextureUnits(
createVector<GLuint>(m_rtts->getRSM().getRTT()[0], m_rtts->getRSM().getRTT()[1], m_rtts->getRSM().getDepthTexture()));
for (unsigned i = 0; i < 32; i++)
{
FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend, i);
@ -152,9 +149,13 @@ void IrrDriver::renderLights(unsigned pointlightcount)
else
{
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::getInstance()->Program);
setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_ctex, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_ntex, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_dtex, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
FullScreenShader::RadianceHintsConstructionShader::getInstance()->SetTextureUnits(
createVector<GLuint>(
m_rtts->getRSM().getRTT()[0],
m_rtts->getRSM().getRTT()[1],
m_rtts->getRSM().getDepthTexture()
)
);
FullScreenShader::RadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
}
@ -162,14 +163,14 @@ void IrrDriver::renderLights(unsigned pointlightcount)
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
sun_ortho_matrix[i] *= getInvViewMatrix();
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
m_rtts->getFBO(FBO_COMBINED_DIFFUSE_SPECULAR).Bind();
if (!UserConfigParams::m_dynamic_lights)
glClearColor(.5, .5, .5, .5);
glClear(GL_COLOR_BUFFER_BIT);
if (!UserConfigParams::m_dynamic_lights)
return;
m_rtts->getFBO(FBO_TMP1_WITH_DS).Bind();
m_rtts->getFBO(FBO_DIFFUSE).Bind();
if (UserConfigParams::m_gi)
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI));
@ -181,7 +182,7 @@ void IrrDriver::renderLights(unsigned pointlightcount)
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
}
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
m_rtts->getFBO(FBO_COMBINED_DIFFUSE_SPECULAR).Bind();
// Render sunlight if and only if track supports shadow
if (!World::getWorld() || World::getWorld()->getTrack()->hasShadows())

View File

@ -16,7 +16,6 @@
#include "graphics/screenquad.hpp"
#include "graphics/shaders.hpp"
#include "graphics/stkmeshscenenode.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "graphics/wind.hpp"
#include "io/file_manager.hpp"
#include "items/item.hpp"
@ -440,6 +439,7 @@ GLuint generateCubeMapFromTextures(const std::vector<video::ITexture *> &texture
swapPixels(tmp, rgba[i], size, x, y, (size - y - 1), x);
}
}
free(tmp);
}
glBindTexture(GL_TEXTURE_CUBE_MAP, result);
@ -448,6 +448,7 @@ GLuint generateCubeMapFromTextures(const std::vector<video::ITexture *> &texture
else
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, size, size, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
for (unsigned i = 0; i < 6; i++)
delete[] rgba[i];
return result;
@ -552,7 +553,7 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
return;
if (!SkyboxCubeMap)
generateSkyboxCubemap();
glBindVertexArray(MeshShader::SkyboxShader::cubevao);
glBindVertexArray(MeshShader::SkyboxShader::getInstance()->cubevao);
glDisable(GL_CULL_FACE);
assert(SkyboxTextures.size() == 6);
@ -567,15 +568,10 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
core::matrix4 invtransform;
transform.getInverse(invtransform);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glUseProgram(MeshShader::SkyboxShader::Program);
MeshShader::SkyboxShader::setUniforms(transform,
core::vector2df(float(UserConfigParams::m_width),
float(UserConfigParams::m_height)),
0);
glUseProgram(MeshShader::SkyboxShader::getInstance()->Program);
MeshShader::SkyboxShader::getInstance()->setUniforms(transform);
MeshShader::SkyboxShader::getInstance()->SetTextureUnits(createVector<GLuint>(SkyboxCubeMap));
glDrawElements(GL_TRIANGLES, 6 * 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}

View File

@ -29,11 +29,9 @@ static GLuint generateRTT3D(GLenum target, size_t w, size_t h, size_t d, GLint i
GLuint result;
glGenTextures(1, &result);
glBindTexture(target, result);
#if WIN32
if (irr_driver->getGLSLVersion() >= 420)
if (irr_driver->hasARBTextureStorage())
glTexStorage3D(target, 1, internalFormat, w, h, d);
else
#endif
glTexImage3D(target, 0, internalFormat, w, h, d, 0, format, type, 0);
return result;
}
@ -43,11 +41,9 @@ static GLuint generateRTT(const core::dimension2du &res, GLint internalFormat, G
GLuint result;
glGenTextures(1, &result);
glBindTexture(GL_TEXTURE_2D, result);
#if WIN32
if (irr_driver->getGLSLVersion() >= 420)
if (irr_driver->hasARBTextureStorage())
glTexStorage2D(GL_TEXTURE_2D, mipmaplevel, internalFormat, res.Width, res.Height);
else
#endif
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, res.Width, res.Height, 0, format, type, 0);
return result;
}
@ -115,6 +111,8 @@ RTT::RTT(size_t width, size_t height)
RenderTargetTextures[RTT_MLAA_BLEND] = generateRTT(res, GL_SRGB8_ALPHA8, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_SSAO] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_DIFFUSE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_SPECULAR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_HALF1] = generateRTT(half, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_QUARTER1] = generateRTT(quarter, GL_RGBA16F, GL_BGRA, GL_FLOAT);
@ -133,7 +131,6 @@ RTT::RTT(size_t width, size_t height)
RenderTargetTextures[RTT_TMP_256] = generateRTT(shadowsize2, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_BLOOM_128] = generateRTT(shadowsize3, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_TMP_128] = generateRTT(shadowsize3, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_LOG_LUMINANCE] = generateRTT(shadowsize0, GL_R16F, GL_RED, GL_FLOAT);
std::vector<GLuint> somevector;
somevector.push_back(RenderTargetTextures[RTT_SSAO]);
@ -143,14 +140,17 @@ RTT::RTT(size_t width, size_t height)
somevector.push_back(RenderTargetTextures[RTT_NORMAL_AND_DEPTH]);
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_TMP1]);
somevector.push_back(RenderTargetTextures[RTT_TMP2]);
somevector.push_back(RenderTargetTextures[RTT_DIFFUSE]);
somevector.push_back(RenderTargetTextures[RTT_SPECULAR]);
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_COLOR]);
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_LOG_LUMINANCE]);
somevector.push_back(RenderTargetTextures[RTT_DIFFUSE]);
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_SPECULAR]);
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_MLAA_COLORS]);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,9 @@
#include <IMeshSceneNode.h>
#include <ISceneNode.h>
Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node, float scale = 1.0, float xOffset = 0.0, float yOffset = 0.0)
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);
@ -33,10 +35,10 @@ Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node, float scale =
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+xOffset; v[0].Pos.Z = scale+yOffset; v[0].Pos.Y = 0.01f;
v[1].Pos.X = scale+xOffset; v[1].Pos.Z = scale+yOffset; v[1].Pos.Y = 0.01f;
v[2].Pos.X = scale+xOffset; v[2].Pos.Z = -scale+yOffset; v[2].Pos.Y = 0.01f;
v[3].Pos.X = -scale+xOffset; v[3].Pos.Z = -scale+yOffset; v[3].Pos.Y = 0.01f;
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);

View File

@ -46,9 +46,8 @@ private:
/** 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 xOffset, float yOffset);
Shadow(video::ITexture *texture, scene::ISceneNode *node,
float scale, float x_offset, float y_offset,float z_offset);
~Shadow();
void enableShadow();
void disableShadow();

View File

@ -75,12 +75,12 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFon
for (unsigned int i = 0; i < m_chars.size(); i++)
{
core::vector3df char_pos(m_chars[i].m_destRect.UpperLeftCorner.X,
m_chars[i].m_destRect.UpperLeftCorner.Y, 0);
core::vector3df char_pos((float) m_chars[i].m_destRect.UpperLeftCorner.X,
(float) m_chars[i].m_destRect.UpperLeftCorner.Y, 0);
char_pos *= scale;
core::vector3df char_pos2(m_chars[i].m_destRect.LowerRightCorner.X,
m_chars[i].m_destRect.LowerRightCorner.Y, 0);
core::vector3df char_pos2((float)m_chars[i].m_destRect.LowerRightCorner.X,
(float) m_chars[i].m_destRect.LowerRightCorner.Y, 0);
char_pos2 *= scale;
core::dimension2di char_size_i = m_chars[i].m_destRect.getSize();
@ -100,8 +100,8 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFon
buffer = map_itr->second;
}
float tex_width = m_chars[i].m_texture->getSize().Width;
float tex_height = m_chars[i].m_texture->getSize().Height;
float tex_width = (float) m_chars[i].m_texture->getSize().Width;
float tex_height = (float)m_chars[i].m_texture->getSize().Height;
video::S3DVertex vertices[] =

View File

@ -33,6 +33,15 @@ void STKAnimatedMesh::cleanGLMeshes()
glDeleteVertexArrays(1, &(mesh.vao));
glDeleteBuffers(1, &(mesh.vertex_buffer));
glDeleteBuffers(1, &(mesh.index_buffer));
if (mesh.instance_buffer)
glDeleteBuffers(1, &(mesh.instance_buffer));
#ifdef Bindless_Texture_Support
for (unsigned j = 0; j < 6; j++)
{
if (mesh.TextureHandles[j] && glIsTextureHandleResidentARB(mesh.TextureHandles[j]))
glMakeTextureHandleNonResidentARB(mesh.TextureHandles[j]);
}
#endif
}
}
@ -45,21 +54,13 @@ void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh)
CAnimatedMeshSceneNode::setMesh(mesh);
}
void STKAnimatedMesh::render()
void STKAnimatedMesh::update()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
bool isTransparentPass =
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
++PassCount;
scene::IMesh* m = getMeshForCurrentFrame();
if (m)
{
Box = m->getBoundingBox();
}
else
{
Log::error("animated mesh", "Animated Mesh returned no mesh to render.");
@ -99,11 +100,21 @@ void STKAnimatedMesh::render()
{
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
MeshSolidMaterial[MatType].push_back(&mesh);
InitTextures(mesh, MatType);
}
if (irr_driver->hasARB_base_instance())
{
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
}
else
{
fillLocalBuffer(mesh, mb);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
}
std::pair<unsigned, unsigned> p = getVAOOffsetAndBase(mb);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
mesh.VAOType = mb->getVertexType();
}
}
firstTime = false;
@ -114,31 +125,47 @@ void STKAnimatedMesh::render()
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
if (isObject(material.MaterialType))
{
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == TRANSPARENT_PASS)
size_t size = mb->getVertexCount() * GLmeshes[i].Stride, offset = GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride;
void *buf;
if (irr_driver->hasBufferStorageExtension())
{
buf = VAOManager::getInstance()->getVBOPtr(mb->getVertexType());
buf = (char *)buf + offset;
}
else
{
glBindVertexArray(0);
size_t size = mb->getVertexCount() * GLmeshes[i].Stride;
glBindBuffer(GL_ARRAY_BUFFER, getVBO(mb->getVertexType()));
if (irr_driver->hasARB_base_instance())
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getVBO(mb->getVertexType()));
else
glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer);
GLbitfield bitfield = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
void * buf = glMapBufferRange(GL_ARRAY_BUFFER, GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride, size, bitfield);
memcpy(buf, mb->getVertices(), size);
buf = glMapBufferRange(GL_ARRAY_BUFFER, offset, size, bitfield);
}
memcpy(buf, mb->getVertices(), size);
if (!irr_driver->hasBufferStorageExtension())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
if (mb)
GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
bool transparent = (rnd && rnd->isTransparent());
// only render transparent buffer if this is the transparent render pass
// and solid only in solid pass
if (transparent != isTransparentPass)
continue;
}
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
}
void STKAnimatedMesh::render()
{
bool isTransparentPass =
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
++PassCount;
update();
/* if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
{
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
core::matrix4 invmodel;
@ -158,7 +185,7 @@ void STKAnimatedMesh::render()
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
return;
}
}*/
if (irr_driver->getPhase() == TRANSPARENT_PASS)
{

View File

@ -7,16 +7,15 @@
#include "graphics/stkmesh.hpp"
#include "utils/ptr_vector.hpp"
class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode
class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode, public STKMeshCommon
{
protected:
bool firstTime;
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix;
void cleanGLMeshes();
public:
virtual void update();
STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent,
irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position = irr::core::vector3df(0,0,0),
@ -25,6 +24,7 @@ public:
virtual void render();
virtual void setMesh(irr::scene::IAnimatedMesh* mesh);
virtual bool glow() const { return false; }
};
#endif // STKANIMATEDMESH_HPP

View File

@ -47,10 +47,12 @@ void STKBillboard::render()
core::vector3df pos = getAbsolutePosition();
glBindVertexArray(billboardvao);
video::ITexture *tex = Material.getTexture(0);
if (tex == NULL)
return;
compressTexture(tex, true, true);
GLuint texid = getTextureGLuint(tex);
setTexture(0, texid, GL_LINEAR, GL_LINEAR);
glUseProgram(MeshShader::BillboardShader::getInstance()->Program);
MeshShader::BillboardShader::getInstance()->SetTextureUnits(createVector<GLuint>(texid));
MeshShader::BillboardShader::getInstance()->setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), pos, Size);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);

View File

@ -1,179 +0,0 @@
#include "stkinstancedscenenode.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/callbacks.hpp"
STKInstancedSceneNode::STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position,
const irr::core::vector3df& rotation,
const irr::core::vector3df& scale) :
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
{
m_ref_count = 0;
irr_driver->grabAllTextures(mesh);
if (irr_driver->isGLSL())
{
createGLMeshes();
setAutomaticCulling(0);
}
}
void STKInstancedSceneNode::cleanGL()
{
for (u32 i = 0; i < GLmeshes.size(); ++i)
{
GLMesh mesh = GLmeshes[i];
if (!mesh.vertex_buffer)
continue;
if (mesh.vao)
glDeleteVertexArrays(1, &(mesh.vao));
if (mesh.vao_shadow_pass)
glDeleteVertexArrays(1, &(mesh.vao_shadow_pass));
glDeleteBuffers(1, &(mesh.vertex_buffer));
glDeleteBuffers(1, &(mesh.index_buffer));
}
glDeleteBuffers(1, &instances_vbo);
}
STKInstancedSceneNode::~STKInstancedSceneNode()
{
irr_driver->dropAllTextures(getMesh());
irr_driver->removeMeshFromCache(getMesh());
if (irr_driver->isGLSL())
cleanGL();
}
void STKInstancedSceneNode::createGLMeshes()
{
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
GLmeshes.push_back(allocateMeshBuffer(mb));
fillLocalBuffer(GLmeshes.back(), mb);
}
isMaterialInitialized = false;
}
void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh)
{
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride));
glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0);
glVertexAttribDivisor(7, 1);
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(8, 1);
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(9, 1);
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride));
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0);
glVertexAttribDivisor(7, 4);
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(8, 4);
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(9, 4);
glBindVertexArray(0);
}
void STKInstancedSceneNode::setFirstTimeMaterial()
{
if (isMaterialInitialized)
return;
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
GLMesh &mesh = GLmeshes[i];
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
initinstancedvaostate(mesh);
MeshSolidMaterial[MatType].push_back(&mesh);
}
isMaterialInitialized = true;
}
void STKInstancedSceneNode::addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale)
{
instance_pos.push_back(origin.X);
instance_pos.push_back(origin.Y);
instance_pos.push_back(origin.Z);
instance_pos.push_back(orientation.X);
instance_pos.push_back(orientation.Y);
instance_pos.push_back(orientation.Z);
instance_pos.push_back(scale.X);
instance_pos.push_back(scale.Y);
instance_pos.push_back(scale.Z);
}
core::matrix4 STKInstancedSceneNode::getInstanceTransform(int id)
{
core::matrix4 mat;
int offset = id * 9;
mat.setTranslation(core::vector3df(
instance_pos[offset],
instance_pos[offset + 1],
instance_pos[offset + 2]));
mat.setRotationDegrees(core::vector3df(
instance_pos[offset + 3],
instance_pos[offset + 4],
instance_pos[offset + 5]));
mat.setScale(core::vector3df(
instance_pos[offset + 6],
instance_pos[offset + 7],
instance_pos[offset + 8]));
return mat;
}
void STKInstancedSceneNode::render()
{
if (!irr_driver->isGLSL())
{
CMeshSceneNode::render();
return;
}
setFirstTimeMaterial();
for(unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++)
{
GLMesh *mesh = MeshSolidMaterial[MAT_DEFAULT][i];
ListInstancedMatDefault::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9));
}
for(unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++)
{
GLMesh *mesh = MeshSolidMaterial[MAT_ALPHA_REF][i];
ListInstancedMatAlphaRef::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9));
}
windDir = getWind();
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
for(unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++)
{
GLMesh *mesh = MeshSolidMaterial[MAT_GRASS][i];
ListInstancedMatGrass::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9, windDir, cb->getPosition()));
}
for(unsigned i = 0; i < MeshSolidMaterial[MAT_NORMAL_MAP].size(); i++)
{
GLMesh *mesh = MeshSolidMaterial[MAT_NORMAL_MAP][i];
ListInstancedMatNormalMap::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9));
}
}

View File

@ -1,60 +0,0 @@
#ifndef STKINSTANCEDSCENENODE_HPP
#define STKINSTANCEDSCENENODE_HPP
#include "stkmesh.hpp"
#include "utils/leak_check.hpp"
class ListInstancedMatDefault : public MeshList<ListInstancedMatDefault, GLMesh *, size_t>
{};
class ListInstancedMatAlphaRef : public MeshList<ListInstancedMatAlphaRef, GLMesh *, size_t>
{};
class ListInstancedMatGrass : public MeshList<ListInstancedMatGrass, GLMesh *, size_t, core::vector3df, core::vector3df>
{};
class ListInstancedMatNormalMap : public MeshList<ListInstancedMatNormalMap, GLMesh *, size_t>
{};
class STKInstancedSceneNode : public irr::scene::CMeshSceneNode
{
protected:
int m_ref_count;
std::vector<GLMesh *> MeshSolidMaterial[MAT_COUNT];
std::vector<GLMesh> GLmeshes;
std::vector<float> instance_pos;
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
GLuint instances_vbo;
void createGLMeshes();
bool isMaterialInitialized;
void setFirstTimeMaterial();
void initinstancedvaostate(GLMesh &mesh);
void cleanGL();
core::vector3df windDir;
public:
STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
const irr::core::vector3df& rotation = irr::core::vector3df(0, 0, 0),
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f));
~STKInstancedSceneNode();
virtual void render();
void addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale);
int getInstanceCount() const { return instance_pos.size() / 9; }
core::matrix4 getInstanceTransform(int id);
void instanceGrab() { m_ref_count++; }
void instanceDrop()
{
m_ref_count--;
if (m_ref_count <= 0)
{
delete this;
}
}
LEAK_CHECK();
};
#endif

View File

@ -126,6 +126,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
GLMesh result = {};
if (!mb)
return result;
result.mb = mb;
result.IndexCount = mb->getIndexCount();
switch (mb->getIndexType())
@ -178,6 +179,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
for (unsigned i = 0; i < 6; i++)
result.textures[i] = mb->getMaterial().getTexture(i);
result.TextureMatrix = 0;
result.VAOType = mb->getVertexType();
return result;
}
@ -229,7 +231,7 @@ core::matrix4 computeMVP(const core::matrix4 &ModelMatrix)
return ModelViewProjectionMatrix;
}
core::vector3df getWind()
core::vector3df getWindDir()
{
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS);
@ -292,4 +294,48 @@ bool isObject(video::E_MATERIAL_TYPE type)
if (type == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
return true;
return false;
}
static void
SetTexture(GLMesh &mesh, unsigned i, bool isSrgb)
{
if (!mesh.textures[i])
mesh.textures[i] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[i], isSrgb);
#ifdef Bindless_Texture_Support
if (UserConfigParams::m_azdo)
{
if (!mesh.TextureHandles[i])
mesh.TextureHandles[i] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[i]), MeshShader::ObjectPass1Shader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[i]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[i]);
}
#endif
}
void InitTextures(GLMesh &mesh, MeshMaterial Mat)
{
switch (Mat)
{
default:
case MAT_DEFAULT:
case MAT_ALPHA_REF:
case MAT_GRASS:
case MAT_SPHEREMAP:
case MAT_UNLIT:
SetTexture(mesh, 0, true);
break;
case MAT_DETAIL:
case MAT_NORMAL_MAP:
SetTexture(mesh, 0, true);
SetTexture(mesh, 1, false);
break;
case MAT_SPLATTING:
SetTexture(mesh, 0, true);
SetTexture(mesh, 1, true);
SetTexture(mesh, 2, true);
SetTexture(mesh, 3, true);
SetTexture(mesh, 4, true);
break;
}
}

View File

@ -35,9 +35,9 @@ enum TransparentMaterial
struct GLMesh {
GLuint vao;
GLuint vao_shadow_pass;
GLuint vertex_buffer;
GLuint index_buffer;
GLuint instance_buffer;
video::ITexture *textures[6];
GLenum PrimitiveType;
GLenum IndexType;
@ -47,6 +47,8 @@ struct GLMesh {
size_t vaoBaseVertex;
size_t vaoOffset;
video::E_VERTEX_TYPE VAOType;
uint64_t TextureHandles[6];
scene::IMeshBuffer *mb;
};
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb);
@ -56,50 +58,132 @@ GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type);
core::matrix4 computeMVP(const core::matrix4 &ModelViewProjectionMatrix);
bool isObject(video::E_MATERIAL_TYPE type);
core::vector3df getWind();
core::vector3df getWindDir();
class STKMeshCommon
{
protected:
bool m_culledForPlayerCam;
bool m_culledForShadowCam[4];
bool m_culledForRSMCam;
public:
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
virtual void update() = 0;
virtual bool glow() const = 0;
virtual bool isImmediateDraw() const { return false; }
bool isCulledForPlayerCam() const { return m_culledForPlayerCam; }
void setCulledForPlayerCam(bool v) { m_culledForPlayerCam = v; }
bool isCulledForShadowCam(unsigned cascade) const { return m_culledForShadowCam[cascade]; }
void setCulledForShadowCam(unsigned cascade, bool v) { m_culledForShadowCam[cascade] = v; }
bool isCulledForRSMCam() const { return m_culledForRSMCam; }
void setCulledForRSMCam(bool v) { m_culledForRSMCam = v; }
};
template<typename T, typename... Args>
class MeshList : public Singleton<T>, public std::vector<STK::Tuple<Args...> >
{};
class MeshList : public Singleton<T>
{
public:
std::vector<STK::Tuple<Args...> > SolidPass, Shadows[4], RSM;
void clear()
{
SolidPass.clear();
RSM.clear();
for (unsigned i = 0; i < 4; i++)
Shadows[i].clear();
}
};
template<typename T>
class InstancedMeshList : public Singleton<T>
{
public:
std::vector<GLMesh *> SolidPass, Shadows[4], RSM;
void clear()
{
SolidPass.clear();
RSM.clear();
for (unsigned i = 0; i < 4; i++)
Shadows[i].clear();
}
};
// -----------------------------------------Mat Default---------------------------------------------------- //
class ListMatDefault : public MeshList<ListMatDefault, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class ListInstancedMatDefault : public InstancedMeshList<ListInstancedMatDefault>
{};
// -----------------------------------------Mat Alpha Ref---------------------------------------------------- //
class ListMatAlphaRef : public MeshList<ListMatAlphaRef, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class ListInstancedMatAlphaRef : public InstancedMeshList<ListInstancedMatAlphaRef>
{};
// -----------------------------------------Mat Normap Map---------------------------------------------------- //
class ListMatNormalMap : public MeshList<ListMatNormalMap, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class ListInstancedMatNormalMap : public InstancedMeshList<ListInstancedMatNormalMap>
{};
// -----------------------------------------Mat Grass---------------------------------------------------- //
class ListMatGrass : public MeshList<ListMatGrass, GLMesh *, core::matrix4, core::matrix4, core::vector3df>
{};
class ListInstancedMatGrass : public InstancedMeshList<ListInstancedMatGrass>
{};
// -----------------------------------------Mat Sphere Map---------------------------------------------------- //
class ListMatSphereMap : public MeshList<ListMatSphereMap, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class ListInstancedMatSphereMap : public InstancedMeshList<ListInstancedMatSphereMap>
{};
// -----------------------------------------Mat Splatting---------------------------------------------------- //
class ListMatSplatting : public MeshList<ListMatSplatting, GLMesh *, core::matrix4, core::matrix4>
{};
// -----------------------------------------Mat Unlit---------------------------------------------------- //
class ListMatUnlit : public MeshList<ListMatUnlit, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class ListInstancedMatUnlit : public InstancedMeshList<ListInstancedMatUnlit>
{};
// -----------------------------------------Mat Details---------------------------------------------------- //
class ListMatDetails : public MeshList<ListMatDetails, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class ListBlendTransparent : public MeshList<ListBlendTransparent, GLMesh *, core::matrix4, core::matrix4>
class ListInstancedMatDetails : public InstancedMeshList<ListInstancedMatDetails>
{};
class ListAdditiveTransparent : public MeshList<ListAdditiveTransparent, GLMesh *, core::matrix4, core::matrix4>
// Transparent
template <typename T, typename ...Args>
class MiscList : public Singleton<T>, public std::vector<STK::Tuple<Args...> >
{};
class ListBlendTransparentFog : public MeshList<ListBlendTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
class ListBlendTransparent : public MiscList<ListBlendTransparent, GLMesh *, core::matrix4, core::matrix4>
{};
class ListAdditiveTransparentFog : public MeshList<ListAdditiveTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
class ListAdditiveTransparent : public MiscList<ListAdditiveTransparent, GLMesh *, core::matrix4, core::matrix4>
{};
class ListDisplacement : public MeshList<ListDisplacement, GLMesh *, core::matrix4>
class ListBlendTransparentFog : public MiscList<ListBlendTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
{};
class ListAdditiveTransparentFog : public MiscList<ListAdditiveTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
{};
class ListDisplacement : public MiscList<ListDisplacement, GLMesh *, core::matrix4>
{};
class ListInstancedGlow : public Singleton<ListInstancedGlow>, public std::vector<GLMesh *>
{};
// Forward pass (for transparents meshes)
@ -108,4 +192,6 @@ void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatr
MeshMaterial MaterialTypeToMeshMaterial(video::E_MATERIAL_TYPE, video::E_VERTEX_TYPE);
TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE, f32 MaterialTypeParam);
void InitTextures(GLMesh &mesh, MeshMaterial);
#endif // STKMESH_H

View File

@ -21,6 +21,7 @@ STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent,
isDisplacement = false;
immediate_draw = false;
update_each_frame = false;
isGlow = false;
if (createGLMeshes)
this->createGLMeshes();
@ -70,35 +71,31 @@ void STKMeshSceneNode::setFirstTimeMaterial()
if (rnd->isTransparent())
{
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam);
if (immediate_draw)
{
fillLocalBuffer(mesh, mb);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
}
else
if (!immediate_draw)
TransparentMesh[TranspMat].push_back(&mesh);
}
else
{
assert(!isDisplacement);
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
if (immediate_draw)
if (!immediate_draw)
{
fillLocalBuffer(mesh, mb);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
InitTextures(mesh, MatType);
MeshSolidMaterial[MatType].push_back(&mesh);
}
else
MeshSolidMaterials[MatType].push_back(&mesh);
}
if (!immediate_draw)
if (!immediate_draw && irr_driver->hasARB_base_instance())
{
std::pair<unsigned, unsigned> p = getVAOOffsetAndBase(mb);
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
mesh.VAOType = mb->getVertexType();
}
else
{
fillLocalBuffer(mesh, mb);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
}
}
isMaterialInitialized = true;
@ -113,12 +110,23 @@ void STKMeshSceneNode::cleanGLMeshes()
continue;
if (mesh.vao)
glDeleteVertexArrays(1, &(mesh.vao));
glDeleteBuffers(1, &(mesh.vertex_buffer));
glDeleteBuffers(1, &(mesh.index_buffer));
if (mesh.vertex_buffer)
glDeleteBuffers(1, &(mesh.vertex_buffer));
if (mesh.index_buffer)
glDeleteBuffers(1, &(mesh.index_buffer));
if (mesh.instance_buffer)
glDeleteBuffers(1, &(mesh.instance_buffer));
#ifdef Bindless_Texture_Support
for (unsigned j = 0; j < 6; j++)
{
if (mesh.TextureHandles[j] && glIsTextureHandleResidentARB(mesh.TextureHandles[j]))
glMakeTextureHandleNonResidentARB(mesh.TextureHandles[j]);
}
#endif
}
GLmeshes.clear();
for (unsigned i = 0; i < MAT_COUNT; i++)
MeshSolidMaterials[i].clearWithoutDeleting();
MeshSolidMaterial[i].clearWithoutDeleting();
}
void STKMeshSceneNode::setMesh(irr::scene::IMesh* mesh)
@ -135,14 +143,12 @@ STKMeshSceneNode::~STKMeshSceneNode()
void STKMeshSceneNode::drawGlow(const GLMesh &mesh)
{
ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
assert(mesh.VAOType == video::EVT_STANDARD);
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::ColorizeShader::getInstance()->setUniforms(AbsoluteTransformation, video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue()));
MeshShader::ColorizeShader::getInstance()->setUniforms(AbsoluteTransformation, video::SColorf(glowcolor.getRed() / 255.f, glowcolor.getGreen() / 255.f, glowcolor.getBlue() / 255.f));
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
}
@ -163,26 +169,8 @@ void STKMeshSceneNode::updatevbo()
}
}
static video::ITexture *spareWhiteTex = 0;
void STKMeshSceneNode::OnRegisterSceneNode()
void STKMeshSceneNode::update()
{
if (isDisplacement)
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
else
CMeshSceneNode::OnRegisterSceneNode();
}
void STKMeshSceneNode::render()
{
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
if (!Mesh || !driver)
return;
++PassCount;
Box = Mesh->getBoundingBox();
setFirstTimeMaterial();
@ -194,13 +182,50 @@ void STKMeshSceneNode::render()
continue;
GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);
}
}
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS && immediate_draw)
void STKMeshSceneNode::OnRegisterSceneNode()
{
if (isDisplacement)
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
else
CMeshSceneNode::OnRegisterSceneNode();
}
static video::ITexture *spareWhiteTex = 0;
void STKMeshSceneNode::render()
{
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
if (!Mesh || !driver)
return;
++PassCount;
update();
bool isTransparent;
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
isTransparent = rnd->isTransparent();
break;
}
if ((irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) && immediate_draw && !isTransparent)
{
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);
glDisable(GL_CULL_FACE);
if (update_each_frame)
updatevbo();
@ -214,6 +239,21 @@ void STKMeshSceneNode::render()
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
if (!mesh.textures[0])
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
#endif
}
else
MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(std::vector < GLuint > { getTextureGLuint(mesh.textures[0]) });
MeshShader::ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
@ -224,53 +264,25 @@ void STKMeshSceneNode::render()
return;
}
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
if (irr_driver->getPhase() == SOLID_LIT_PASS && immediate_draw && !isTransparent)
{
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);
GLMesh* mesh;
for_in(mesh, MeshSolidMaterials[MAT_DEFAULT])
pushVector(ListMatDefault::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterials[MAT_ALPHA_REF])
pushVector(ListMatAlphaRef::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterials[MAT_SPHEREMAP])
pushVector(ListMatSphereMap::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterials[MAT_DETAIL])
pushVector(ListMatDetails::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
windDir = getWind();
for_in(mesh, MeshSolidMaterials[MAT_GRASS])
pushVector(ListMatGrass::getInstance(), mesh, AbsoluteTransformation, invmodel, windDir);
for_in(mesh, MeshSolidMaterials[MAT_UNLIT])
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterials[MAT_SPLATTING])
pushVector(ListMatSplatting::getInstance(), mesh, AbsoluteTransformation, invmodel);
for_in(mesh, MeshSolidMaterials[MAT_NORMAL_MAP])
pushVector(ListMatNormalMap::getInstance(), mesh, AbsoluteTransformation, invmodel, core::matrix4::EM4CONST_IDENTITY);
return;
}
if (irr_driver->getPhase() == SOLID_LIT_PASS)
{
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);
if (immediate_draw)
glDisable(GL_CULL_FACE);
if (!spareWhiteTex)
spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255));
glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program);
// Only untextured
for (unsigned i = 0; i < GLmeshes.size(); i++)
{
glDisable(GL_CULL_FACE);
if (!spareWhiteTex)
spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255));
glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program);
// Only untextured
for (unsigned i = 0; i < GLmeshes.size(); i++)
irr_driver->IncreaseObjectCount();
GLMesh &mesh = GLmeshes[i];
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
if (UserConfigParams::m_azdo)
{
irr_driver->IncreaseObjectCount();
GLMesh &mesh = GLmeshes[i];
@ -278,17 +290,54 @@ void STKMeshSceneNode::render()
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
setTexture(MeshShader::ObjectPass2Shader::getInstance()->TU_Albedo, getTextureGLuint(spareWhiteTex), GL_NEAREST, GL_NEAREST, false);
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
GLuint64 DiffuseHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(DiffuseHandle))
glMakeTextureHandleResidentARB(DiffuseHandle);
GLuint64 SpecularHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_SPECULAR), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[1]);
if (!glIsTextureHandleResidentARB(SpecularHandle))
glMakeTextureHandleResidentARB(SpecularHandle);
GLuint64 SSAOHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_HALF1_R), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[2]);
if (!glIsTextureHandleResidentARB(SSAOHandle))
glMakeTextureHandleResidentARB(SSAOHandle);
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(spareWhiteTex), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0]));
#endif
}
else
MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>(
irr_driver->getRenderTargetTexture(RTT_DIFFUSE),
irr_driver->getRenderTargetTexture(RTT_SPECULAR),
irr_driver->getRenderTargetTexture(RTT_HALF1_R),
getTextureGLuint(spareWhiteTex)));
MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glBindVertexArray(0);
}
glEnable(GL_CULL_FACE);
return;
else
MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>(
irr_driver->getRenderTargetTexture(RTT_DIFFUSE),
irr_driver->getRenderTargetTexture(RTT_SPECULAR),
irr_driver->getRenderTargetTexture(RTT_HALF1_R),
getTextureGLuint(mesh.textures[0])));
MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glBindVertexArray(0);
}
glEnable(GL_CULL_FACE);
return;
}
@ -300,12 +349,15 @@ void STKMeshSceneNode::render()
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
glBindVertexArray(getVAO(video::EVT_STANDARD));
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD));
else
glBindVertexArray(GLmeshes[i].vao);
drawGlow(GLmeshes[i]);
}
}
if (irr_driver->getPhase() == TRANSPARENT_PASS)
if (irr_driver->getPhase() == TRANSPARENT_PASS && isTransparent)
{
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
@ -340,8 +392,21 @@ void STKMeshSceneNode::render()
tmpcol.getGreen() / 255.0f,
tmpcol.getBlue() / 255.0f);
if (!mesh.textures[0])
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::TransparentFogShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::TransparentFogShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
#endif
}
else
MeshShader::TransparentFogShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) });
MeshShader::TransparentFogShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col);
assert(mesh.vao);
@ -360,9 +425,21 @@ void STKMeshSceneNode::render()
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
if (!mesh.textures[0])
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::TransparentShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::TransparentShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
#endif
}
else
MeshShader::TransparentShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) });
MeshShader::TransparentShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
assert(mesh.vao);
@ -375,47 +452,16 @@ void STKMeshSceneNode::render()
}
GLMesh* mesh;
if (World::getWorld() && World::getWorld()->isFogEnabled())
{
const Track * const track = World::getWorld()->getTrack();
// Todo : put everything in a ubo
const float fogmax = track->getFogMax();
const float startH = track->getFogStartHeight();
const float endH = track->getFogEndHeight();
const float start = track->getFogStart();
const float end = track->getFogEnd();
const video::SColor tmpcol = track->getFogColor();
video::SColorf col(tmpcol.getRed() / 255.0f,
tmpcol.getGreen() / 255.0f,
tmpcol.getBlue() / 255.0f);
for_in(mesh, TransparentMesh[TM_DEFAULT])
pushVector(ListBlendTransparentFog::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix,
fogmax, startH, endH, start, end, col);
for_in(mesh, TransparentMesh[TM_ADDITIVE])
pushVector(ListAdditiveTransparentFog::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix,
fogmax, startH, endH, start, end, col);
}
else
{
for_in(mesh, TransparentMesh[TM_DEFAULT])
pushVector(ListBlendTransparent::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix);
for_in(mesh, TransparentMesh[TM_ADDITIVE])
pushVector(ListAdditiveTransparent::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix);
}
for_in(mesh, TransparentMesh[TM_DISPLACEMENT])
pushVector(ListDisplacement::getInstance(), mesh, AbsoluteTransformation);
if (!TransparentMesh[TM_BUBBLE].empty())
glUseProgram(MeshShader::BubbleShader::Program);
glBindVertexArray(getVAO(video::EVT_STANDARD));
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD));
for_in(mesh, TransparentMesh[TM_BUBBLE])
{
if (irr_driver->hasARB_base_instance())
glBindVertexArray(mesh->vao);
drawBubble(*mesh, ModelViewProjectionMatrix);
}
return;
}
}

View File

@ -4,11 +4,9 @@
#include "stkmesh.hpp"
#include "utils/ptr_vector.hpp"
class STKMeshSceneNode : public irr::scene::CMeshSceneNode
class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon
{
protected:
PtrVector<GLMesh, REF> MeshSolidMaterials[MAT_COUNT];
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix;
core::vector3df windDir;
@ -24,7 +22,10 @@ protected:
bool immediate_draw;
bool update_each_frame;
bool isDisplacement;
bool isGlow;
video::SColor glowcolor;
public:
virtual void update();
void setReloadEachFrame(bool);
STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
@ -35,6 +36,7 @@ public:
virtual void setMesh(irr::scene::IMesh* mesh);
virtual void OnRegisterSceneNode();
virtual ~STKMeshSceneNode();
virtual bool isImmediateDraw() const { return immediate_draw; }
void setIsDisplacement(bool v) {
isDisplacement = v;
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
@ -46,6 +48,9 @@ public:
mb->getMaterial().MaterialType = irr_driver->getShader(ES_DISPLACE);
}
}
virtual bool glow() const { return isGlow; }
void setGlowColors(const video::SColor &c) { isGlow = true; glowcolor = c; }
video::SColor getGlowColor() const { return glowcolor; }
};
#endif

View File

@ -0,0 +1,710 @@
#include "stkscenemanager.hpp"
#include "stkmesh.hpp"
#include "irr_driver.hpp"
#include <ISceneManager.h>
#include <ISceneNode.h>
#include "stkanimatedmesh.hpp"
#include "stkmeshscenenode.hpp"
#include "utils/ptr_vector.hpp"
#include <ICameraSceneNode.h>
#include <SViewFrustum.h>
#include "callbacks.hpp"
#include "utils/cpp2011.hpp"
#include <omp.h>
#include "modes/world.hpp"
#include "tracks/track.hpp"
#include "lod_node.hpp"
#include "utils/profiler.hpp"
#include <unordered_map>
#include <SViewFrustum.h>
#include <functional>
static void
FillInstances_impl(std::vector<std::pair<GLMesh *, scene::ISceneNode *> > InstanceList, InstanceData * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &PolyCount, std::function<bool (const scene::ISceneNode *)> cull_func)
{
// Should never be empty
GLMesh *mesh = InstanceList.front().first;
size_t InitialOffset = InstanceBufferOffset;
for (unsigned i = 0; i < InstanceList.size(); i++)
{
auto &Tp = InstanceList[i];
scene::ISceneNode *node = Tp.second;
if (cull_func(node))
continue;
InstanceData &Instance = InstanceBuffer[InstanceBufferOffset++];
const core::matrix4 &mat = node->getAbsoluteTransformation();
const core::vector3df &Origin = mat.getTranslation();
const core::vector3df &Orientation = mat.getRotationDegrees();
const core::vector3df &Scale = mat.getScale();
Instance.Origin.X = Origin.X;
Instance.Origin.Y = Origin.Y;
Instance.Origin.Z = Origin.Z;
Instance.Orientation.X = Orientation.X;
Instance.Orientation.Y = Orientation.Y;
Instance.Orientation.Z = Orientation.Z;
Instance.Scale.X = Scale.X;
Instance.Scale.Y = Scale.Y;
Instance.Scale.Z = Scale.Z;
Instance.Texture = mesh->TextureHandles[0];
Instance.SecondTexture = mesh->TextureHandles[1];
}
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
CurrentCommand.count = mesh->IndexCount;
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
CurrentCommand.baseInstance = InitialOffset;
CurrentCommand.instanceCount = InstanceBufferOffset - InitialOffset;
PolyCount += (InstanceBufferOffset - InitialOffset) * mesh->IndexCount / 3;
}
static void
FillInstancesGlow_impl(std::vector<std::pair<GLMesh *, STKMeshCommon *> > InstanceList, GlowInstanceData * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
size_t &InstanceBufferOffset, size_t &CommandBufferOffset, std::function<bool (const scene::ISceneNode *)> cull_func)
{
// Should never be empty
GLMesh *mesh = InstanceList.front().first;
size_t InitialOffset = InstanceBufferOffset;
for (unsigned i = 0; i < InstanceList.size(); i++)
{
STKMeshSceneNode *node = dynamic_cast<STKMeshSceneNode*>(InstanceList[i].second);
if (cull_func(node))
continue;
GlowInstanceData &Instance = InstanceBuffer[InstanceBufferOffset++];
const core::matrix4 &mat = node->getAbsoluteTransformation();
const core::vector3df &Origin = mat.getTranslation();
const core::vector3df &Orientation = mat.getRotationDegrees();
const core::vector3df &Scale = mat.getScale();
Instance.Color = node->getGlowColor().color;
Instance.Origin.X = Origin.X;
Instance.Origin.Y = Origin.Y;
Instance.Origin.Z = Origin.Z;
Instance.Orientation.X = Orientation.X;
Instance.Orientation.Y = Orientation.Y;
Instance.Orientation.Z = Orientation.Z;
Instance.Scale.X = Scale.X;
Instance.Scale.Y = Scale.Y;
Instance.Scale.Z = Scale.Z;
}
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
CurrentCommand.count = mesh->IndexCount;
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
CurrentCommand.baseInstance = InitialOffset;
CurrentCommand.instanceCount = InstanceBufferOffset - InitialOffset;
}
static
void FillInstances(const std::unordered_map<scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &Polycount,
std::function<bool (const scene::ISceneNode *)> cull_func)
{
auto It = GatheredGLMesh.begin(), E = GatheredGLMesh.end();
for (; It != E; ++It)
{
FillInstances_impl(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, Polycount, cull_func);
if (!UserConfigParams::m_azdo)
InstancedList.push_back(It->second.front().first);
}
}
static
void FillInstancesGrass(const std::unordered_map<scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, const core::vector3df &dir, size_t &PolyCount,
std::function<bool (const scene::ISceneNode *)> cull_func)
{
auto It = GatheredGLMesh.begin(), E = GatheredGLMesh.end();
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
for (; It != E; ++It)
{
FillInstances_impl(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount, cull_func);
if (!UserConfigParams::m_azdo)
InstancedList.push_back(It->second.front().first);
}
}
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForSolidPass[MAT_COUNT];
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForShadowPass[4][MAT_COUNT];
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForRSMPass[MAT_COUNT];
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, STKMeshCommon *> > > MeshForGlowPass;
static std::vector <STKMeshCommon *> DeferredUpdate;
static core::vector3df windDir;
// From irrlicht code
static
bool isBoxInFrontOfPlane(const core::plane3df &plane, const core::vector3df edges[8])
{
for (u32 j = 0; j<8; ++j)
if (plane.classifyPointRelation(edges[j]) != core::ISREL3D_FRONT)
return false;
return true;
}
static
bool isCulled(const scene::ICameraSceneNode *cam, const scene::ISceneNode *node)
{
if (!node->getAutomaticCulling())
return false;
scene::SViewFrustum frust = *cam->getViewFrustum();
//transform the frustum to the node's current absolute transformation
core::matrix4 invTrans(node->getAbsoluteTransformation(), core::matrix4::EM4CONST_INVERSE);
//invTrans.makeInverse();
frust.transform(invTrans);
core::vector3df edges[8];
node->getBoundingBox().getEdges(edges);
for (s32 i = 0; i < scene::SViewFrustum::VF_PLANE_COUNT; ++i)
if (isBoxInFrontOfPlane(frust.planes[i], edges))
return true;
return false;
}
static void
handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *ImmediateDraw)
{
STKMeshCommon *node = dynamic_cast<STKMeshCommon*>(Node);
if (!node)
return;
DeferredUpdate.push_back(node);
if (node->isImmediateDraw())
{
ImmediateDraw->push_back(Node);
return;
}
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
{
GLMesh *mesh;
if (irr_driver->hasARB_draw_indirect())
{
for_in(mesh, node->MeshSolidMaterial[Mat])
{
if (node->glow())
MeshForGlowPass[mesh->mb].emplace_back(mesh, node);
if (Mat != MAT_SPLATTING && mesh->TextureMatrix.isIdentity())
MeshForSolidPass[Mat][mesh->mb].emplace_back(mesh, Node);
else
{
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
ModelMatrix.getInverse(InvModelMatrix);
switch (Mat)
{
case MAT_DEFAULT:
ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_ALPHA_REF:
ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_UNLIT:
ListMatUnlit::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_SPLATTING:
ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix);
break;
}
}
}
}
else
{
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
ModelMatrix.getInverse(InvModelMatrix);
for_in(mesh, node->MeshSolidMaterial[Mat])
{
switch (Mat)
{
case MAT_DEFAULT:
ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_ALPHA_REF:
ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_NORMAL_MAP:
ListMatNormalMap::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_DETAIL:
ListMatDetails::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_UNLIT:
ListMatUnlit::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_SPHEREMAP:
ListMatSphereMap::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_SPLATTING:
ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix);
break;
case MAT_GRASS:
ListMatGrass::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, windDir);
break;
}
}
}
if (!UserConfigParams::m_shadows)
return;
for (unsigned cascade = 0; cascade < 4; ++cascade)
{
if (irr_driver->hasARB_draw_indirect())
{
for_in(mesh, node->MeshSolidMaterial[Mat])
MeshForShadowPass[cascade][Mat][mesh->mb].emplace_back(mesh, Node);
}
else
{
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
ModelMatrix.getInverse(InvModelMatrix);
for_in(mesh, node->MeshSolidMaterial[Mat])
{
switch (Mat)
{
case MAT_DEFAULT:
ListMatDefault::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_ALPHA_REF:
ListMatAlphaRef::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_NORMAL_MAP:
ListMatNormalMap::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_DETAIL:
ListMatDetails::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_UNLIT:
ListMatUnlit::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_SPHEREMAP:
ListMatSphereMap::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_SPLATTING:
ListMatSplatting::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix);
break;
case MAT_GRASS:
ListMatGrass::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, windDir);
}
}
}
}
if (!UserConfigParams::m_gi)
return;
if (irr_driver->hasARB_draw_indirect())
{
for_in(mesh, node->MeshSolidMaterial[Mat])
if (Mat != MAT_SPLATTING)
MeshForRSMPass[Mat][mesh->mb].emplace_back(mesh, Node);
else
{
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
ModelMatrix.getInverse(InvModelMatrix);
ListMatSplatting::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix);
}
}
else
{
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
ModelMatrix.getInverse(InvModelMatrix);
for_in(mesh, node->MeshSolidMaterial[Mat])
{
switch (Mat)
{
case MAT_DEFAULT:
ListMatDefault::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_ALPHA_REF:
ListMatAlphaRef::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_NORMAL_MAP:
ListMatNormalMap::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_DETAIL:
ListMatDetails::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_UNLIT:
ListMatUnlit::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_SPHEREMAP:
ListMatSphereMap::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
break;
case MAT_SPLATTING:
ListMatSplatting::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix);
break;
case MAT_GRASS:
ListMatGrass::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, windDir);
break;
}
}
}
}
// Transparent
GLMesh *mesh;
if (World::getWorld() && World::getWorld()->isFogEnabled())
{
const Track * const track = World::getWorld()->getTrack();
// Todo : put everything in a ubo
const float fogmax = track->getFogMax();
const float startH = track->getFogStartHeight();
const float endH = track->getFogEndHeight();
const float start = track->getFogStart();
const float end = track->getFogEnd();
const video::SColor tmpcol = track->getFogColor();
video::SColorf col(tmpcol.getRed() / 255.0f,
tmpcol.getGreen() / 255.0f,
tmpcol.getBlue() / 255.0f);
for_in(mesh, node->TransparentMesh[TM_DEFAULT])
pushVector(ListBlendTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
fogmax, startH, endH, start, end, col);
for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
pushVector(ListAdditiveTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
fogmax, startH, endH, start, end, col);
}
else
{
for_in(mesh, node->TransparentMesh[TM_DEFAULT])
pushVector(ListBlendTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
pushVector(ListAdditiveTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
}
for_in(mesh, node->TransparentMesh[TM_DISPLACEMENT])
pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
}
static void
parseSceneManager(core::list<scene::ISceneNode*> List, std::vector<scene::ISceneNode *> *ImmediateDraw,
scene::ICameraSceneNode* cam)
{
core::list<scene::ISceneNode*>::Iterator I = List.begin(), E = List.end();
for (; I != E; ++I)
{
if (LODNode *node = dynamic_cast<LODNode *>(*I))
node->updateVisibility();
if (!(*I)->isVisible())
continue;
(*I)->updateAbsolutePosition();
if (ParticleSystemProxy *node = dynamic_cast<ParticleSystemProxy *>(*I))
{
if (!isCulled(cam, *I) && node->update())
ParticlesList::getInstance()->push_back(node);
continue;
}
handleSTKCommon(*I, ImmediateDraw);
parseSceneManager((*I)->getChildren(), ImmediateDraw, cam);
}
}
template<MeshMaterial Mat> static void
GenDrawCalls(unsigned cascade, std::vector<GLMesh *> &InstancedList,
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &PolyCount)
{
std::function<bool(const scene::ISceneNode *)> shadowculling = [&](const scene::ISceneNode *nd) {return dynamic_cast<const STKMeshCommon*>(nd)->isCulledForShadowCam(cascade); };
if (irr_driver->hasARB_draw_indirect())
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
FillInstances(MeshForShadowPass[cascade][Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount, shadowculling);
if (UserConfigParams::m_azdo)
ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat];
}
template<MeshMaterial Mat> static void
GenDrawCallsGrass(unsigned cascade, std::vector<GLMesh *> &InstancedList,
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, const core::vector3df &dir, size_t &PolyCount)
{
std::function<bool(const scene::ISceneNode *)> shadowculling = [&](const scene::ISceneNode *nd) {return dynamic_cast<const STKMeshCommon*>(nd)->isCulledForShadowCam(cascade); };
if (irr_driver->hasARB_draw_indirect())
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
FillInstancesGrass(MeshForShadowPass[cascade][Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, dir, PolyCount, shadowculling);
if (UserConfigParams::m_azdo)
ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat];
}
void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
{
windDir = getWindDir();
ListBlendTransparent::getInstance()->clear();
ListAdditiveTransparent::getInstance()->clear();
ListBlendTransparentFog::getInstance()->clear();
ListAdditiveTransparentFog::getInstance()->clear();
ListDisplacement::getInstance()->clear();
ListMatDefault::getInstance()->clear();
ListMatAlphaRef::getInstance()->clear();
ListMatSphereMap::getInstance()->clear();
ListMatDetails::getInstance()->clear();
ListMatUnlit::getInstance()->clear();
ListMatNormalMap::getInstance()->clear();
ListMatGrass::getInstance()->clear();
ListMatSplatting::getInstance()->clear();
ImmediateDrawList::getInstance()->clear();
ParticlesList::getInstance()->clear();
ListInstancedGlow::getInstance()->clear();
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
{
MeshForSolidPass[Mat].clear();
MeshForRSMPass[Mat].clear();
for (unsigned cascade = 0; cascade < 4; ++cascade)
MeshForShadowPass[cascade][Mat].clear();
}
MeshForGlowPass.clear();
DeferredUpdate.clear();
core::list<scene::ISceneNode*> List = m_scene_manager->getRootSceneNode()->getChildren();
parseSceneManager(List, ImmediateDrawList::getInstance(), camnode);
#pragma omp parallel for
for (int i = 0; i < (int)DeferredUpdate.size(); i++)
{
scene::ISceneNode *node = dynamic_cast<scene::ISceneNode *>(DeferredUpdate[i]);
DeferredUpdate[i]->setCulledForPlayerCam(isCulled(camnode, node));
DeferredUpdate[i]->setCulledForRSMCam(isCulled(m_suncam, node));
DeferredUpdate[i]->setCulledForShadowCam(0, isCulled(m_shadow_camnodes[0], node));
DeferredUpdate[i]->setCulledForShadowCam(1, isCulled(m_shadow_camnodes[1], node));
DeferredUpdate[i]->setCulledForShadowCam(2, isCulled(m_shadow_camnodes[2], node));
DeferredUpdate[i]->setCulledForShadowCam(3, isCulled(m_shadow_camnodes[3], node));
}
// Add a 1 s timeout
if (!m_sync)
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
PROFILER_PUSH_CPU_MARKER("- Sync Stall", 0xFF, 0x0, 0x0);
GLenum reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000);
PROFILER_POP_CPU_MARKER();
/* switch (reason)
{
case GL_ALREADY_SIGNALED:
printf("Already Signaled\n");
break;
case GL_TIMEOUT_EXPIRED:
printf("Timeout Expired\n");
break;
case GL_CONDITION_SATISFIED:
printf("Condition Satisfied\n");
break;
case GL_WAIT_FAILED:
printf("Wait Failed\n");
break;
}*/
for (unsigned i = 0; i < DeferredUpdate.size(); i++)
DeferredUpdate[i]->update();
if (!irr_driver->hasARB_draw_indirect())
return;
InstanceData *InstanceBuffer;
InstanceData *ShadowInstanceBuffer;
InstanceData *RSMInstanceBuffer;
GlowInstanceData *GlowInstanceBuffer;
DrawElementsIndirectCommand *CmdBuffer;
DrawElementsIndirectCommand *ShadowCmdBuffer;
DrawElementsIndirectCommand *RSMCmdBuffer;
DrawElementsIndirectCommand *GlowCmdBuffer;
if (irr_driver->hasBufferStorageExtension())
{
InstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeDefault);
ShadowInstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeShadow);
RSMInstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeRSM);
GlowInstanceBuffer = (GlowInstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeGlow);
CmdBuffer = SolidPassCmd::getInstance()->Ptr;
ShadowCmdBuffer = ShadowPassCmd::getInstance()->Ptr;
GlowCmdBuffer = GlowPassCmd::getInstance()->Ptr;
RSMCmdBuffer = RSMPassCmd::getInstance()->Ptr;
}
ListInstancedMatDefault::getInstance()->clear();
ListInstancedMatAlphaRef::getInstance()->clear();
ListInstancedMatGrass::getInstance()->clear();
ListInstancedMatNormalMap::getInstance()->clear();
ListInstancedMatSphereMap::getInstance()->clear();
ListInstancedMatDetails::getInstance()->clear();
ListInstancedMatUnlit::getInstance()->clear();
size_t SolidPoly = 0, ShadowPoly = 0, MiscPoly = 0;
PROFILER_PUSH_CPU_MARKER("- Draw Command upload", 0xFF, 0x0, 0xFF);
auto playercamculling = [](const scene::ISceneNode *nd) {return dynamic_cast<const STKMeshCommon*>(nd)->isCulledForPlayerCam(); };
#pragma omp parallel sections
{
#pragma omp section
{
size_t offset = 0, current_cmd = 0;
if (!irr_driver->hasBufferStorageExtension())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeDefault));
InstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
CmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
// Default Material
SolidPassCmd::getInstance()->Offset[MAT_DEFAULT] = current_cmd;
FillInstances(MeshForSolidPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
SolidPassCmd::getInstance()->Size[MAT_DEFAULT] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_DEFAULT];
// Alpha Ref
SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = current_cmd;
FillInstances(MeshForSolidPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
SolidPassCmd::getInstance()->Size[MAT_ALPHA_REF] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF];
// Unlit
SolidPassCmd::getInstance()->Offset[MAT_UNLIT] = current_cmd;
FillInstances(MeshForSolidPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
SolidPassCmd::getInstance()->Size[MAT_UNLIT] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_UNLIT];
// Spheremap
SolidPassCmd::getInstance()->Offset[MAT_SPHEREMAP] = current_cmd;
FillInstances(MeshForSolidPass[MAT_SPHEREMAP], ListInstancedMatSphereMap::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
SolidPassCmd::getInstance()->Size[MAT_SPHEREMAP] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_SPHEREMAP];
// Detail
SolidPassCmd::getInstance()->Offset[MAT_DETAIL] = current_cmd;
FillInstances(MeshForSolidPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
SolidPassCmd::getInstance()->Size[MAT_DETAIL] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_DETAIL];
// Normal Map
SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = current_cmd;
FillInstances(MeshForSolidPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
SolidPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP];
// Grass
SolidPassCmd::getInstance()->Offset[MAT_GRASS] = current_cmd;
FillInstancesGrass(MeshForSolidPass[MAT_GRASS], ListInstancedMatGrass::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, windDir, SolidPoly, playercamculling);
SolidPassCmd::getInstance()->Size[MAT_GRASS] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_GRASS];
if (!irr_driver->hasBufferStorageExtension())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
}
#pragma omp section
{
size_t offset = 0, current_cmd = 0;
if (!irr_driver->hasBufferStorageExtension())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeGlow));
GlowInstanceBuffer = (GlowInstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
GlowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
// Glow
if (irr_driver->hasARB_draw_indirect())
GlowPassCmd::getInstance()->Offset = offset; // Store command buffer offset
auto It = MeshForGlowPass.begin(), E = MeshForGlowPass.end();
for (; It != E; ++It)
{
FillInstancesGlow_impl(It->second, GlowInstanceBuffer, GlowCmdBuffer, offset, current_cmd, playercamculling);
if (!UserConfigParams::m_azdo)
ListInstancedGlow::getInstance()->push_back(It->second.front().first);
}
if (UserConfigParams::m_azdo)
GlowPassCmd::getInstance()->Size = current_cmd - GlowPassCmd::getInstance()->Offset;
if (!irr_driver->hasBufferStorageExtension())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
}
#pragma omp section
{
irr_driver->setPhase(SHADOW_PASS);
size_t offset = 0, current_cmd = 0;
if (!irr_driver->hasBufferStorageExtension())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeShadow));
ShadowInstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
ShadowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
for (unsigned i = 0; i < 4; i++)
{
// Mat default
GenDrawCalls<MAT_DEFAULT>(i, ListInstancedMatDefault::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat AlphaRef
GenDrawCalls<MAT_ALPHA_REF>(i, ListInstancedMatAlphaRef::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Unlit
GenDrawCalls<MAT_UNLIT>(i, ListInstancedMatUnlit::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat NormalMap
GenDrawCalls<MAT_NORMAL_MAP>(i, ListInstancedMatNormalMap::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Spheremap
GenDrawCalls<MAT_SPHEREMAP>(i, ListInstancedMatSphereMap::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Detail
GenDrawCalls<MAT_DETAIL>(i, ListInstancedMatDetails::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Grass
GenDrawCallsGrass<MAT_GRASS>(i, ListInstancedMatGrass::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, windDir, ShadowPoly);
}
if (!irr_driver->hasBufferStorageExtension())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
}
#pragma omp section
{
auto rsmcamculling = [](const scene::ISceneNode *nd) {return dynamic_cast<const STKMeshCommon*>(nd)->isCulledForRSMCam(); };
size_t offset = 0, current_cmd = 0;
if (!irr_driver->hasBufferStorageExtension())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeRSM));
RSMInstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, RSMPassCmd::getInstance()->drawindirectcmd);
RSMCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
// Default Material
RSMPassCmd::getInstance()->Offset[MAT_DEFAULT] = current_cmd;
FillInstances(MeshForRSMPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling);
RSMPassCmd::getInstance()->Size[MAT_DEFAULT] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_DEFAULT];
// Alpha Ref
RSMPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = current_cmd;
FillInstances(MeshForRSMPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling);
RSMPassCmd::getInstance()->Size[MAT_ALPHA_REF] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_ALPHA_REF];
// Unlit
RSMPassCmd::getInstance()->Offset[MAT_UNLIT] = current_cmd;
FillInstances(MeshForRSMPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling);
RSMPassCmd::getInstance()->Size[MAT_UNLIT] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_UNLIT];
// Detail
RSMPassCmd::getInstance()->Offset[MAT_DETAIL] = current_cmd;
FillInstances(MeshForRSMPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling);
RSMPassCmd::getInstance()->Size[MAT_DETAIL] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_DETAIL];
// Normal Map
RSMPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = current_cmd;
FillInstances(MeshForRSMPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling);
RSMPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_NORMAL_MAP];
if (!irr_driver->hasBufferStorageExtension())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
}
}
PROFILER_POP_CPU_MARKER();
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] += SolidPoly;
poly_count[SHADOW_PASS] += ShadowPoly;
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
}

View File

@ -0,0 +1,68 @@
// Not really a scene manager yet but hold algorithm that
// rework scene manager output
#ifndef HEADER_STKSCENEMANAGER_HPP
#define HEADER_STKSCENEMANAGER_HPP
#include "utils/singleton.hpp"
#include "gl_headers.hpp"
#include "stkmesh.hpp"
#include "gpuparticles.hpp"
template<typename T>
class CommandBuffer : public Singleton<T>
{
public:
GLuint drawindirectcmd;
DrawElementsIndirectCommand *Ptr;
CommandBuffer()
{
glGenBuffers(1, &drawindirectcmd);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd);
#ifdef Buffer_Storage
if (irr_driver->hasBufferStorageExtension())
{
glBufferStorage(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
Ptr = (DrawElementsIndirectCommand *)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
}
else
#endif
{
glBufferData(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_STREAM_DRAW);
}
}
};
class ImmediateDrawList : public Singleton<ImmediateDrawList>, public std::vector<scene::ISceneNode *>
{};
class ParticlesList : public Singleton<ParticlesList>, public std::vector<ParticleSystemProxy *>
{};
class SolidPassCmd : public CommandBuffer<SolidPassCmd>
{
public:
size_t Offset[MAT_COUNT], Size[MAT_COUNT];
};
class ShadowPassCmd : public CommandBuffer<ShadowPassCmd>
{
public:
size_t Offset[4][MAT_COUNT], Size[4][MAT_COUNT];
};
class RSMPassCmd : public CommandBuffer<RSMPassCmd>
{
public:
size_t Offset[MAT_COUNT], Size[MAT_COUNT];
};
class GlowPassCmd : public CommandBuffer<GlowPassCmd>
{
public:
size_t Offset, Size;
};
#endif

View File

@ -18,92 +18,80 @@
#include "audio/sfx_base.hpp"
#include "audio/sfx_manager.hpp"
#include "graphics/camera.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/gpuparticles.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/material.hpp"
#include "graphics/per_camera_node.hpp"
#include "graphics/rain.hpp"
#include "graphics/shaders.hpp"
#include "graphics/weather.hpp"
#include "modes/world.hpp"
#include "states_screens/race_gui.hpp"
#include "utils/constants.hpp"
#include "utils/random_generator.hpp"
#include <ISceneManager.h>
#include <SMeshBuffer.h>
// The weather manager
using namespace video;
using namespace scene;
using namespace core;
// The rain manager
Rain::Rain(Camera *camera, irr::scene::ISceneNode* parent) : m_thunder_sound(0)
Weather::Weather(bool lightning, std::string sound)
{
m_lightning = camera->getIndex()==0;
m_lightning = lightning;
m_thunder_sound = NULL;
m_weather_sound = NULL;
if (m_lightning)
m_thunder_sound = sfx_manager->createSoundSource("thunder");
{
m_thunder_sound = sfx_manager->createSoundSource("thunder");
}
Material* m = material_manager->getMaterial("rain.png");
assert(m != NULL);
if (sound != "")
{
m_weather_sound = sfx_manager->createSoundSource(sound);
}
RandomGenerator g;
m_next_lightning = (float)g.get(35);
// RainNode *node = new RainNode(irr_driver->getSceneManager(), m->getTexture());
// m_node = irr_driver->addPerCameraNode(node, camera->getCameraSceneNode(), parent);
// m_node->setAutomaticCulling(0);
} // Rain
} // Weather
// ----------------------------------------------------------------------------
Rain::~Rain()
Weather::~Weather()
{
// m_node->drop(); // drop STK's reference
// m_node->remove(); // Then remove it from the scene graph.
if (m_lightning && m_thunder_sound != NULL) sfx_manager->deleteSFX(m_thunder_sound);
if (m_thunder_sound != NULL)
sfx_manager->deleteSFX(m_thunder_sound);
if (m_weather_sound != NULL)
sfx_manager->deleteSFX(m_weather_sound);
}
// ----------------------------------------------------------------------------
void Rain::update(float dt)
void Weather::update(float dt)
{
if (m_lightning)
{
m_next_lightning -= dt;
if (m_next_lightning < 0.0f)
{
RaceGUIBase* gui_base = World::getWorld()->getRaceGUI();
if (gui_base != NULL)
{
gui_base->doLightning();
if (m_thunder_sound) m_thunder_sound->play();
}
if (m_thunder_sound)
{
m_thunder_sound->play();
}
}
RandomGenerator g;
m_next_lightning = 35 + (float)g.get(35);
}
}
} // update
// ----------------------------------------------------------------------------
void Rain::setPosition(const core::vector3df& position)
void Weather::playSound()
{
// m_node->getChild()->setPosition(position);
} // setPosition
// ----------------------------------------------------------------------------
void Rain::setCamera(scene::ICameraSceneNode* camera)
{
// m_node->setCamera(camera);
if (m_weather_sound)
{
m_weather_sound->setLoop(true);
m_weather_sound->play();
}
}

View File

@ -16,38 +16,25 @@
// 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_RAIN_HPP
#define HEADER_RAIN_HPP
class Camera;
class PerCameraNode;
#include <vector3d.h>
namespace irr
{
namespace video { class SMaterial; class ITexture; }
namespace scene { class ICameraSceneNode; class ISceneNode; }
}
using namespace irr;
#ifndef HEADER_WEATHER_HPP
#define HEADER_WEATHER_HPP
class SFXBase;
class Rain
class Weather
{
PerCameraNode* m_node;
float m_next_lightning;
bool m_lightning;
float m_next_lightning;
SFXBase* m_thunder_sound;
SFXBase* m_weather_sound;
public:
Rain(Camera* camera, irr::scene::ISceneNode* parent);
virtual ~Rain();
Weather(bool lightning, std::string sound);
virtual ~Weather();
void update(float dt);
void setPosition(const irr::core::vector3df& position);
void setCamera(scene::ICameraSceneNode* camera);
void playSound();
};
#endif

View File

@ -170,7 +170,7 @@ namespace GUIEngine
inline Skin* getSkin() { return Private::g_skin; }
Screen* getScreenNamed(const char* name);
/** \return the height of the title font in pixels */
int getTitleFontHeight();

View File

@ -43,6 +43,8 @@ void ButtonWidget::add()
m_id = m_element->getID();
m_element->setTabOrder(m_id);
m_element->setTabGroup(false);
if (!m_is_visible)
m_element->setVisible(false);
}
// -----------------------------------------------------------------------------

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