trying to merge upstream
@ -17,6 +17,7 @@ option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
|
||||
|
||||
if(UNIX)
|
||||
option(USE_CPP2011 "Activate C++ 2011 mode (GCC only)" OFF)
|
||||
option(USE_XRANDR "Use xrandr instead of vidmode" OFF)
|
||||
endif()
|
||||
if(MSVC)
|
||||
# Normally hide the option to build wiiuse on VS, since it depends
|
||||
@ -117,6 +118,11 @@ if(USE_FRIBIDI)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Xrandr
|
||||
if(UNIX AND USE_XRANDR)
|
||||
find_package(Xrandr REQUIRED)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
if(USE_CPP2011)
|
||||
add_definitions("-std=c++0x")
|
||||
@ -278,6 +284,11 @@ if(USE_WIIUSE)
|
||||
|
||||
endif()
|
||||
|
||||
# Xrandr
|
||||
if(UNIX AND USE_XRANDR)
|
||||
target_link_libraries(supertuxkart ${XRANDR_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries(supertuxkart iphlpapi.lib)
|
||||
add_custom_command(TARGET supertuxkart POST_BUILD
|
||||
@ -308,12 +319,6 @@ else()
|
||||
)
|
||||
endif()
|
||||
|
||||
# ==== Install target ====
|
||||
install(TARGETS supertuxkart RUNTIME DESTINATION ${STK_INSTALL_BINARY_DIR} BUNDLE DESTINATION .)
|
||||
install(DIRECTORY ${STK_DATA_DIR} DESTINATION ${STK_INSTALL_DATA_DIR} PATTERN ".svn" EXCLUDE)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/supertuxkart.desktop DESTINATION share/applications)
|
||||
install(FILES data/supertuxkart_32.png data/supertuxkart_128.png DESTINATION share/pixmaps)
|
||||
install(FILES data/supertuxkart.appdata DESTINATION share/appdata)
|
||||
|
||||
# ==== Checking if data folder exists ====
|
||||
if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data)
|
||||
@ -322,7 +327,20 @@ endif()
|
||||
|
||||
# ==== Checking if stk-assets folder exists ====
|
||||
if(CHECK_ASSETS)
|
||||
if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../stk-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
|
||||
(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))
|
||||
message(STATUS "Assets found in data directory")
|
||||
elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../stk-assets)
|
||||
set(STK_ASSETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../stk-assets/)
|
||||
message(STATUS "Assets found")
|
||||
elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../supertuxkart-assets)
|
||||
set(STK_ASSETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../supertuxkart-assets/)
|
||||
message(STATUS "Assets found")
|
||||
else()
|
||||
set (CUR_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
get_filename_component(PARENT_DIR ${CUR_DIR} PATH)
|
||||
message( FATAL_ERROR "${PARENT_DIR}/stk-assets folder doesn't exist. "
|
||||
@ -330,6 +348,18 @@ if(CHECK_ASSETS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# ==== Install target ====
|
||||
install(TARGETS supertuxkart RUNTIME DESTINATION ${STK_INSTALL_BINARY_DIR} BUNDLE DESTINATION .)
|
||||
install(DIRECTORY ${STK_DATA_DIR} DESTINATION ${STK_INSTALL_DATA_DIR} PATTERN ".svn" EXCLUDE PATTERN ".git" EXCLUDE)
|
||||
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 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)
|
||||
|
18
cmake/FindXrandr.cmake
Normal file
@ -0,0 +1,18 @@
|
||||
find_path(XRANDR_INCLUDE_DIR NAMES X11/extensions/Xrandr.h
|
||||
PATH_SUFFIXES X11/extensions
|
||||
DOC "The XRANDR include directory"
|
||||
)
|
||||
|
||||
find_library(XRANDR_LIBRARY NAMES Xrandr
|
||||
DOC "The XRANDR library"
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(XRANDR DEFAULT_MSG XRANDR_LIBRARY XRANDR_INCLUDE_DIR)
|
||||
|
||||
if(XRANDR_FOUND)
|
||||
set( XRANDR_LIBRARIES ${XRANDR_LIBRARY} )
|
||||
set( XRANDR_INCLUDE_DIRS ${XRANDR_INCLUDE_DIR} )
|
||||
endif()
|
||||
|
||||
mark_as_advanced(XRANDR_INCLUDE_DIR XRANDR_LIBRARY)
|
35
data/gfx/gfx_fallingLeaf_a.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- For sky particles, the size of the box is ignored -->
|
||||
<particles emitter="box" box_x="10.0" box_y="0.5" box_z="10.0">
|
||||
|
||||
<spreading angle="3" />
|
||||
|
||||
<velocity x="-0.00"
|
||||
y="-0.002"
|
||||
z="-0.00" />
|
||||
|
||||
<material file="gfx_leaf_a.png" clampu="Y" clampv="Y" />
|
||||
|
||||
<!-- Amount of particles emitted per second -->
|
||||
<rate min="2"
|
||||
max="5" />
|
||||
|
||||
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
|
||||
<lifetime min="30000"
|
||||
max="30000" />
|
||||
|
||||
<!-- Size of the particles -->
|
||||
<size min="0.40"
|
||||
max="0.60" />
|
||||
|
||||
<color min="40 40 255"
|
||||
max="255 255 255" />
|
||||
|
||||
<!-- How much time in milliseconds before the particle is fully faded out -->
|
||||
<fadeout time="100" />
|
||||
|
||||
<wind speed="0.16"
|
||||
flips="Y" />
|
||||
|
||||
</particles>
|
@ -16,7 +16,7 @@
|
||||
<spacer height="4" width="10" />
|
||||
-->
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<checkbox id="dynamiclight"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Advanced pipeline (lights, etc.)" I18N="Video settings"/>
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<spacer width="70" height="10" />
|
||||
<label text="Shadows" I18N="Video settings"/>
|
||||
<spacer width="10" height="10"/>
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<spacer width="70" height="10"/>
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
@ -53,16 +53,27 @@
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<spacer width="70" height="10"/>
|
||||
<checkbox id="ssao"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Ambient Occlusion" I18N="Video settings"/>
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="ssao"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Ambient Occlusion" I18N="Video settings"/>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="global_illumination"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Global illumination" I18N="Video settings"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="motionblur"/>
|
||||
<spacer width="10" height="10"/>
|
||||
@ -80,7 +91,7 @@
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="glow"/>
|
||||
<spacer width="10" height="10"/>
|
||||
@ -98,7 +109,7 @@
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="weather_gfx"/>
|
||||
<spacer width="10" height="10"/>
|
||||
@ -116,7 +127,7 @@
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="ubo"/>
|
||||
<spacer width="10" height="10"/>
|
||||
@ -134,7 +145,7 @@
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="hd-textures"/>
|
||||
<spacer width="10" height="10"/>
|
||||
@ -153,7 +164,7 @@
|
||||
|
||||
<spacer height="20" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<label text="Animated Characters" I18N="Video settings" width="40%"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<gauge id="steering_animations" min_value="0" max_value="2" width="50%" />
|
||||
@ -161,7 +172,7 @@
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<label text="Texture filtering" I18N="Video settings" width="40%"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<gauge id="filtering" min_value="0" max_value="5" width="50%" />
|
||||
|
@ -11,10 +11,10 @@
|
||||
|
||||
<spacer height="20" width="20" />
|
||||
|
||||
<!-- TODO: ok button? -->
|
||||
|
||||
<button id="cancel" I18N="When configuring input" text="Press ESC to cancel" align="center"/>
|
||||
|
||||
<buttonbar proportion="1" id="options" width="100%" height="100%">
|
||||
<button id="ok" I18N="When configuring input" text="OK" align="center"/>
|
||||
<button id="cancel" I18N="When configuring input" text="Cancel" align="center"/>
|
||||
</buttonbar>
|
||||
<spacer height="15" width="20" />
|
||||
|
||||
</div>
|
||||
|
@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-16"?>
|
||||
<stkgui>
|
||||
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
|
||||
<header align="center" width="80%" text="Login" text_align="center"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="login_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="tab_login" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in login menu" text="Sign In"/>
|
||||
<icon-button id="tab_guest_login" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in login menu" text="Sign In As Guest"/>
|
||||
<icon-button id="tab_register" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in login menu" text="Register"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
<header id="title" width="96%" height="fit" text_align="center" word_wrap="true"
|
||||
I18N="In the login dialog" text="Sign in"/>
|
||||
|
||||
<spacer height="20" width="20"/>
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit" >
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the login dialog" text="Username"/>
|
||||
<textbox proportion="2" height="fit" id="username" I18N="In the login dialog"/>
|
||||
</div>
|
||||
<spacer height="20" width="20"/>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the login dialog" text="Password"/>
|
||||
<textbox x="5" proportion="2" height="fit" id="password" I18N="In the login dialog"/>
|
||||
</div>
|
||||
<spacer height="20" width="20"/>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the login dialog" text="Stay signed in"/>
|
||||
<div proportion="2" height="100%" layout="horizontal-row">
|
||||
<checkbox width="fit" height="fit" id="remember" I18N="In the login dialog"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label id="info" proportion="1" width="90%" align="center" text_align="center"
|
||||
word_wrap="true" text=""/>
|
||||
<spacer height="20" width="20"/>
|
||||
<buttonbar id="options" width="90%" height="13%" align="bottom">
|
||||
<icon-button id="sign_in" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Login dialog" text="Sign In" label_location="bottom"/>
|
||||
<icon-button id="recovery" width="64" height="64" icon="gui/main_help.png"
|
||||
I18N="Login dialog" text="Recovery" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Login dialog" text="Close" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
<spacer height="20" width="20"/>
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
|
||||
</stkgui>
|
@ -3,55 +3,59 @@
|
||||
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
|
||||
<header align="center" width="80%" text="Login" text_align="center"/>
|
||||
<header align="center" width="80%" text="Create User" text_align="center"
|
||||
I18N="In the registration dialog" />
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="login_tabs" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="tab_login" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in login menu" text="Sign In"/>
|
||||
<icon-button id="tab_guest_login" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in login menu" text="Sign In As Guest"/>
|
||||
<icon-button id="tab_register" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in login menu" text="Register"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
<header id="title" width="96%" height="fit" text_align="center" word_wrap="true"
|
||||
I18N="In the login dialog" text="Sign in"/>
|
||||
<spacer height="40" width="20"/>
|
||||
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the registration dialog" text="Username"/>
|
||||
<textbox proportion="2" height="fit" id="username" I18N="In the registration dialog"/>
|
||||
<label proportion="1" height="100%" text_align="left"
|
||||
I18N="In the registration dialog" text="Local Username"/>
|
||||
<textbox id="local_username" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_online" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Online"/>
|
||||
<checkbox id="online" I18N="In the login screen" text_align="left"/>
|
||||
</div>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_username" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the registration dialog" text="Online Username"/>
|
||||
<textbox id="username" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the registration dialog" text="Password"/>
|
||||
<textbox proportion="2" height="fit" id="password" I18N="In the registration dialog"/>
|
||||
<label id="label_password" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the registration dialog" text="Password"/>
|
||||
<textbox id="password" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the registration dialog" text="Confirm"/>
|
||||
<textbox proportion="2" height="fit" id="password_confirm" I18N="In the registration dialog"/>
|
||||
<label id="label_password_confirm" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the registration dialog" text="Confirm"/>
|
||||
<textbox id="password_confirm" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the registration dialog" text="Email"/>
|
||||
<textbox proportion="2" height="fit" id="email" I18N="In the registration dialog"/>
|
||||
<label id="label_email" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the registration dialog" text="Email"/>
|
||||
<textbox id="email" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the registration dialog" text="Confirm"/>
|
||||
<textbox proportion="2" height="fit" id="email_confirm" I18N="In the registration dialog"/>
|
||||
<label id="label_email_confirm" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the registration dialog" text="Confirm"/>
|
||||
<textbox id="email_confirm" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
<spacer height="20" width="50"/>
|
||||
|
||||
@ -66,7 +70,7 @@
|
||||
|
||||
<buttonbar id="options" width="25%" height="14%" align="center">
|
||||
<icon-button id="next" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Registration dialog" text="Next" label_location="none"/>
|
||||
I18N="Registration dialog" text="OK" label_location="none"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Registration dialog" text="Cancel" label_location="none"/>
|
||||
</buttonbar>
|
||||
|
@ -39,6 +39,12 @@
|
||||
<label height="100%" I18N="In the ui settings" text="Allow STK to connect to the Internet"/>
|
||||
</div>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="show-login"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Always show login screen"/>
|
||||
</div>
|
||||
|
||||
<spacer height="18" width="4"/>
|
||||
|
||||
<!-- ************ LANGUAGE CHOICE ************ -->
|
||||
|
@ -1,28 +0,0 @@
|
||||
<stkgui>
|
||||
|
||||
<div x="2%" y="2%" width="96%" height="97%" layout="vertical-row" >
|
||||
|
||||
<header text_align="center" width="80%" align="center" text="Select a Player"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<box proportion="6" width="75%" align="center" layout="vertical-row" padding="8">
|
||||
<list id="gameslots" x="0" y="0" width="100%" height="100%"/>
|
||||
</box>
|
||||
|
||||
<spacer width="20" height="25"/>
|
||||
|
||||
<div layout="horizontal-row" align="center" width="70%" height="fit">
|
||||
<checkbox id="rememberme" />
|
||||
<label text="Remember me" height="100%"/>
|
||||
</div>
|
||||
|
||||
<spacer width="20" height="15"/>
|
||||
|
||||
<button id="creategame" x="20"
|
||||
I18N="In story mode 'select a game slot' menu"
|
||||
text="Create a new player" align="center"/>
|
||||
|
||||
<spacer width="20" height="15"/>
|
||||
</div>
|
||||
|
||||
</stkgui>
|
@ -1,36 +0,0 @@
|
||||
<stkgui>
|
||||
|
||||
<div x="5%" y="5%" width="90%" height="90%" layout="vertical-row" >
|
||||
|
||||
<header width="80%" text="New Game" align="center" text_align="center" />
|
||||
|
||||
<spacer proportion="1" width="25"/>
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="50" align="center">
|
||||
<label proportion="1" height="100%"
|
||||
I18N="In the new story mode game dialog" text="Select your identity" text_align="right" />
|
||||
<spacer width="50" height="25"/>
|
||||
<spinner id="identity" proportion="1" height="100%" min_value="0" wrap_around="true"/>
|
||||
</div>
|
||||
|
||||
<spacer proportion="1" width="25"/>
|
||||
|
||||
<ribbon id="difficulty" height="135" width="85%" 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"/>
|
||||
</ribbon>
|
||||
|
||||
<spacer width="25" proportion="1"/>
|
||||
|
||||
<button id="startgame" text="Start Game" align="center"/>
|
||||
|
||||
<spacer width="25" height="5"/>
|
||||
|
||||
<button id="cancel" text="Cancel" align="center"/>
|
||||
</div>
|
||||
|
||||
</stkgui>
|
65
data/gui/user_screen.stkgui
Normal file
@ -0,0 +1,65 @@
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
|
||||
<header align="center" width="80%" text="Login" text_align="center"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<box proportion="1" width="98%" layout="vertical-row">
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<scrollable_ribbon id="players" height="120" y="10" x="10" width="98%" align="center" label_location="each"
|
||||
square_items="true" child_width="160" child_height="120" />
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the login screen" text="Online"/>
|
||||
<checkbox id="online" I18N="In the login screen" text_align="left"/>
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_remember" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Remember password"/>
|
||||
<checkbox id="remember-user" I18N="In the login screen" text_align="left"/>
|
||||
</div>
|
||||
<!-- Disable guest accounts for now
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_guest" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Guest login"/>
|
||||
<checkbox id="guest" I18N="In the login screen" text_align="left"/>
|
||||
</div>
|
||||
-->
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_username" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Username"/>
|
||||
<textbox id="username" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
<spacer height="20" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_password" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the registration dialog" text="Password"/>
|
||||
<textbox id="password" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
</div>
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit">
|
||||
<label id="message" width="80%" align="center" text_align="left"/>
|
||||
</div>
|
||||
<spacer width="20" height="25"/>
|
||||
<buttonbar id="options" width="90%" height="13%" align="bottom">
|
||||
<icon-button id="ok" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Login dialog" text="OK" label_location="bottom"/>
|
||||
<icon-button id="new_user" width="64" height="64" icon="gui/gp_add_track.png"
|
||||
I18N="Login dialog" text="Add user" label_location="bottom"/>
|
||||
<icon-button id="delete" width="64" height="64" icon="gui/gp_remove_track.png"
|
||||
I18N="Login dialog" text="Delete" label_location="bottom"/>
|
||||
<icon-button id="rename" width="64" height="64" icon="gui/gp_rename.png"
|
||||
I18N="Login dialog" text="Rename" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Login dialog" text="Cancel" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
</box>
|
||||
<spacer width="20" height="15"/>
|
||||
</div>
|
||||
|
||||
</stkgui>
|
74
data/gui/user_screen_tab.stkgui
Normal file
@ -0,0 +1,74 @@
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
|
||||
<header text_align="center" width="80%" align="center" text="SuperTuxKart Options"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="options_choice" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
|
||||
I18N="Section in the settings menu" text="Players"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="98%" layout="vertical-row">
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<scrollable_ribbon id="players" height="120" y="10" x="10" width="98%" align="center" label_location="each"
|
||||
square_items="true" child_width="160" child_height="120" />
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the login screen" text="Online"/>
|
||||
<checkbox id="online" I18N="In the login screen" text_align="left"/>
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_remember" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Remember password"/>
|
||||
<checkbox id="remember-user" I18N="In the login screen" text_align="left"/>
|
||||
</div>
|
||||
<!-- Disable guest accounts for now
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_guest" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Guest login"/>
|
||||
<checkbox id="guest" I18N="In the login screen" text_align="left"/>
|
||||
</div>
|
||||
-->
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_username" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the login screen" text="Username"/>
|
||||
<textbox id="username" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
<spacer height="20" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_password" proportion="1" height="100%" text_align="left"
|
||||
I18N="In the registration dialog" text="Password"/>
|
||||
<textbox id="password" proportion="2" height="fit" I18N="In the registration dialog"/>
|
||||
</div>
|
||||
</div>
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit">
|
||||
<label id="message" width="80%" align="center" text_align="left"/>
|
||||
</div>
|
||||
<spacer width="20" height="25"/>
|
||||
<buttonbar id="options" width="90%" height="13%" align="bottom">
|
||||
<icon-button id="ok" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Login dialog" text="OK" label_location="bottom"/>
|
||||
<icon-button id="new_user" width="64" height="64" icon="gui/gp_add_track.png"
|
||||
I18N="Login dialog" text="Add user" label_location="bottom"/>
|
||||
<icon-button id="delete" width="64" height="64" icon="gui/gp_remove_track.png"
|
||||
I18N="Login dialog" text="Delete" label_location="bottom"/>
|
||||
<icon-button id="rename" width="64" height="64" icon="gui/gp_rename.png"
|
||||
I18N="Login dialog" text="Rename" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Login dialog" text="Cancel" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
</box>
|
||||
<spacer width="20" height="15"/>
|
||||
</div>
|
||||
|
||||
</stkgui>
|
@ -55,7 +55,7 @@
|
||||
from BurningWell.
|
||||
|
||||
* zipper_collect
|
||||
by Dakal, released under CC-BY-SA 3.0
|
||||
by Connor, released as Public Domain
|
||||
|
||||
* rubber_ball and jump-bomb.jpg
|
||||
by Samuncle, released under CC-BY-SA
|
||||
|
@ -2,34 +2,22 @@
|
||||
<materials>
|
||||
<material name="banana.png"/>
|
||||
<material name="gift-box.png"/>
|
||||
<material name="gift-loop.png" sphere="Y"/>
|
||||
<material name="gold.png" light="Y" smooth-reflection="Y"/>
|
||||
<material name="silver.png" light="Y" smooth-reflection="Y"/>
|
||||
<material name="bronze.png" light="Y" smooth-reflection="Y"/>
|
||||
<material name="gift-loop.png" shader="spheremap"/>
|
||||
<material name="gold.png" light="Y" shader="spheremap"/>
|
||||
<material name="silver.png" light="Y" shader="spheremap"/>
|
||||
<material name="bronze.png" light="Y" shader="spheremap"/>
|
||||
|
||||
<material name="stk_mod_nitroBarrel.png" />
|
||||
<material name="stk_mod_nitroBottle.png" />
|
||||
<material name="stk_mod_nitroLogo.png" compositing="additive" light="N" disable-z-write="Y" />
|
||||
<material name="stk_mod_nitroLogo.png" shader="additive" disable-z-write="Y" />
|
||||
|
||||
<material name="traffic_light_green.jpg" light="N"/>
|
||||
<material name="traffic_light_yellow.jpg" light="N"/>
|
||||
<material name="traffic_light_red.jpg" light="N"/>
|
||||
<material name="traffic_light_green.jpg" shader="unlit"/>
|
||||
<material name="traffic_light_yellow.jpg" shader="unlit"/>
|
||||
<material name="traffic_light_red.jpg" shader="unlit"/>
|
||||
|
||||
<material name="bubblegum_shield.png" compositing="blend" disable-z-write="Y"/>
|
||||
<material name="bubblegum_shield_nolok.png" compositing="blend" disable-z-write="Y"/>
|
||||
<material name="bubblegum_shield.png" shader="alphablend" disable-z-write="Y"/>
|
||||
<material name="bubblegum_shield_nolok.png" shader="alphablend" disable-z-write="Y"/>
|
||||
<material name="parachute.png" backface-culling="n" ignore="Y"/>
|
||||
<material name="zipper.png" light="N" zipper="Y"/>
|
||||
<material name="zipper_collect.png" light="N" zipper="Y"/>
|
||||
<material name="bowling-icon.png" transparency="Y" light="N"/>
|
||||
<material name="bubblegum-icon.png" transparency="Y" light="N"/>
|
||||
<material name="cake-icon.png" transparency="Y" light="N" />
|
||||
<material name="anchor-icon.png" clampU="Y" clampV="Y" transparency="Y" light="N" ignore="Y"/>
|
||||
<material name="plunger-icon.png" transparency="Y" light="N"/>
|
||||
<material name="parachute-icon.png" clampU="Y" clampV="Y" ignore="Y"/>
|
||||
<material name="anchor-attach-icon.png" clampU="Y" clampV="Y" transparency="Y" light="N" ignore="Y"/>
|
||||
<material name="parachute-attach-icon.png" clampU="Y" clampV="Y" ignore="Y"/>
|
||||
<material name="bomb-attach-icon.png" clampU="Y" clampV="Y" ignore="Y"/>
|
||||
|
||||
<material name="balldimpleddark.jpg"/>
|
||||
<material name="zipper.png" shader="unlit" zipper="Y"/>
|
||||
</materials>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 7.0 KiB |
@ -1,24 +0,0 @@
|
||||
uniform sampler2D Albedo;
|
||||
uniform sampler2D caustictex;
|
||||
uniform vec2 dir;
|
||||
uniform vec2 dir2;
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
vec3 getLightFactor(float specMapValue);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture(Albedo, uv);
|
||||
float caustic = texture(caustictex, uv + dir).x;
|
||||
float caustic2 = texture(caustictex, (uv.yx + dir2 * vec2(-0.6, 0.3)) * vec2(0.6)).x;
|
||||
|
||||
vec3 LightFactor = getLightFactor(1.) + caustic * caustic2 * 10;
|
||||
FragColor = vec4(color.xyz * LightFactor, 1.);
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D oldtex;
|
||||
uniform vec2 pixel;
|
||||
uniform vec2 multi;
|
||||
uniform int size;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float res = 0.0;
|
||||
vec2 tc = gl_TexCoord[0].xy;
|
||||
// tc.y = 1.0 - tc.y;
|
||||
tc *= multi;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
float col = texture(tex, tc).x;
|
||||
res = max(col, res);
|
||||
|
||||
tc += pixel;
|
||||
}
|
||||
|
||||
float old = texture(oldtex, gl_TexCoord[0].xy).x;
|
||||
|
||||
FragColor = vec4(mix(old, res, 0.7));
|
||||
}
|
@ -1,10 +1,19 @@
|
||||
uniform sampler2D displacement_tex;
|
||||
uniform sampler2D mask_tex;
|
||||
uniform sampler2D color_tex;
|
||||
uniform vec2 screen;
|
||||
uniform vec2 dir;
|
||||
uniform vec2 dir2;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
in vec2 uv_bis;
|
||||
|
@ -1,7 +1,15 @@
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D dtex;
|
||||
uniform mat4 invprojm;
|
||||
uniform vec2 screen;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
@ -13,7 +21,7 @@ float range = 100.;
|
||||
void main()
|
||||
{
|
||||
float curdepth = texture(dtex, uv).x;
|
||||
vec4 FragPos = invprojm * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f);
|
||||
vec4 FragPos = InverseProjectionMatrix * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f);
|
||||
FragPos /= FragPos.w;
|
||||
|
||||
float depth = FragPos.z;
|
||||
@ -21,62 +29,58 @@ void main()
|
||||
|
||||
vec2 offset = 10. / screen;
|
||||
|
||||
vec4 col = texture2D(tex, uv);
|
||||
vec4 col = texture(tex, uv);
|
||||
vec4 colOriginal = col;
|
||||
// Weight from here http://artmartinsh.blogspot.fr/2010/02/glsl-lens-blur-filter-with-bokeh.html
|
||||
|
||||
col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(0.15, 0.37) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(0.29,0.29) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(-0.37,0.15) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(0.37, -0.15) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(-0.15, -0.37) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(-0.15, 0.37) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(0.37, 0.15) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(-0.37, -0.15) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur);
|
||||
col += texture2D(tex, uv + (vec2(0.15, -0.37) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.15, 0.37) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.29,0.29) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.37,0.15) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.37, -0.15) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.15, -0.37) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.15, 0.37) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.37, 0.15) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.37, -0.15) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.15, -0.37) * offset) * blur);
|
||||
|
||||
col += texture2D(tex, uv + (vec2(0.15, 0.37) * offset) * blur * 0.9);
|
||||
col += texture2D(tex, uv + (vec2(-0.37, 0.15) * offset) * blur * 0.9);
|
||||
col += texture2D(tex, uv + (vec2(0.37, -0.15) * offset) * blur * 0.9);
|
||||
col += texture2D(tex, uv + (vec2(-0.15, -0.37) * offset) * blur * 0.9);
|
||||
col += texture2D(tex, uv + (vec2(-0.15, 0.37) * offset) * blur * 0.9);
|
||||
col += texture2D(tex, uv + (vec2(0.37, 0.15) * offset) * blur * 0.9);
|
||||
col += texture2D(tex, uv + (vec2(-0.37, -0.15) * offset) * blur * 0.9);
|
||||
col += texture2D(tex, uv + (vec2(0.15, -0.37) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(0.15, 0.37) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(-0.37, 0.15) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(0.37, -0.15) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(-0.15, -0.37) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(-0.15, 0.37) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(0.37, 0.15) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(-0.37, -0.15) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(0.15, -0.37) * offset) * blur * 0.9);
|
||||
|
||||
col += texture2D(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.7);
|
||||
col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.7);
|
||||
col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.7);
|
||||
col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.7);
|
||||
col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.7);
|
||||
col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.7);
|
||||
col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.7);
|
||||
col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur *0.7);
|
||||
col += texture(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur *0.7);
|
||||
|
||||
col += texture2D(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.4);
|
||||
col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.4);
|
||||
col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.4);
|
||||
col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.4);
|
||||
col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.4);
|
||||
col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.4);
|
||||
col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.4);
|
||||
col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur * 0.4);
|
||||
|
||||
col = vec4(col.rgb / 41.0, col.a);
|
||||
depth = clamp((FragPos.z/280), 0., 1.);
|
||||
depth = (1 - depth);
|
||||
vec3 final = colOriginal.rgb * depth + col.rgb * (1 - depth);
|
||||
|
||||
/*
|
||||
FragColor.xyz = vec3(depth);
|
||||
FragColor.a = 1.0;
|
||||
*/
|
||||
FragColor = vec4(final, 1.);
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ViewMatrix;
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
in vec2 quadcorner;
|
||||
in vec2 texcoord;
|
||||
|
@ -20,6 +20,7 @@ layout (std140) uniform MatrixesData
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
31
data/shaders/gaussian17taph.frag
Normal file
@ -0,0 +1,31 @@
|
||||
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
uniform float sigma = 5.;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
|
||||
float g0, g1, g2;
|
||||
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
|
||||
g1 = exp(-0.5 / (sigma * sigma));
|
||||
g2 = g1 * g1;
|
||||
vec4 sum = texture(tex, vec2(X, Y)) * g0;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
for (int i = 1; i < 9; i++) {
|
||||
sum += texture(tex, vec2(X - i * pixel.x, Y)) * g0;
|
||||
sum += texture(tex, vec2(X + i * pixel.x, Y)) * g0;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
}
|
||||
|
||||
FragColor = sum;
|
||||
}
|
32
data/shaders/gaussian17tapv.frag
Normal file
@ -0,0 +1,32 @@
|
||||
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
uniform float sigma = 5.;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
|
||||
float g0, g1, g2;
|
||||
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
|
||||
g1 = exp(-0.5 / (sigma * sigma));
|
||||
g2 = g1 * g1;
|
||||
vec4 sum = texture(tex, vec2(X, Y)) * g0;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
for (int i = 1; i < 9; i++) {
|
||||
sum += texture(tex, vec2(X, Y - i * pixel.y)) * g0;
|
||||
sum += texture(tex, vec2(X, Y + i * pixel.y)) * g0;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
}
|
||||
|
||||
FragColor = sum;
|
||||
}
|
||||
|
101
data/shaders/gi.frag
Normal file
@ -0,0 +1,101 @@
|
||||
// From http://graphics.cs.aueb.gr/graphics/research_illumination.html
|
||||
// "Real-Time Diffuse Global Illumination Using Radiance Hints"
|
||||
// paper and shader code
|
||||
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D dtex;
|
||||
|
||||
uniform sampler3D SHR;
|
||||
uniform sampler3D SHG;
|
||||
uniform sampler3D SHB;
|
||||
|
||||
uniform float R_wcs = 10.;
|
||||
uniform vec3 extents;
|
||||
uniform mat4 RHMatrix;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
vec4 SHBasis (const in vec3 dir)
|
||||
{
|
||||
float L00 = 0.282095;
|
||||
float L1_1 = 0.488603 * dir.y;
|
||||
float L10 = 0.488603 * dir.z;
|
||||
float L11 = 0.488603 * dir.x;
|
||||
return vec4 (L11, L1_1, L10, L00);
|
||||
}
|
||||
|
||||
vec3 SH2RGB (in vec4 sh_r, in vec4 sh_g, in vec4 sh_b, in vec3 dir)
|
||||
{
|
||||
vec4 Y = vec4(1.023326*dir.x, 1.023326*dir.y, 1.023326*dir.z, 0.886226);
|
||||
return vec3 (dot(Y,sh_r), dot(Y,sh_g), dot(Y,sh_b));
|
||||
}
|
||||
|
||||
in vec2 uv;
|
||||
layout (location = 0) out vec4 Diffuse;
|
||||
layout (location = 1) out vec4 Specular;
|
||||
|
||||
vec3 DecodeNormal(vec2 n);
|
||||
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
|
||||
|
||||
vec3 resolution = vec3(32, 16, 32);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 GI = vec3(0.);
|
||||
|
||||
float depth = texture2D(dtex, uv).x;
|
||||
// Discard background fragments
|
||||
if (depth==1.0) discard;
|
||||
|
||||
vec4 pos_screen_space = getPosFromUVDepth(vec3(uv, depth), InverseProjectionMatrix);
|
||||
vec4 tmp = (inverse(RHMatrix) * InverseViewMatrix * pos_screen_space);
|
||||
vec3 pos = tmp.xyz / tmp.w;
|
||||
vec3 normal_screen_space = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
|
||||
vec3 normal = (transpose(ViewMatrix) * vec4(normal_screen_space, 0.)).xyz;
|
||||
|
||||
// Convert to grid coordinates
|
||||
vec3 uvw = .5 + 0.5 * pos / extents;
|
||||
if (uvw.x < 0. || uvw.x > 1. || uvw.y < 0. || uvw.y > 1. || uvw.z < 0. || uvw.z > 1.) discard;
|
||||
|
||||
// Sample the RH volume at 4 locations, one directly above the shaded point,
|
||||
// three on a ring 80degs away from the normal direction.
|
||||
vec3 rnd = vec3(0,0,0);
|
||||
|
||||
// Generate the sample locations
|
||||
vec3 v_rand = vec3(0.5);
|
||||
vec3 tangent = normalize(cross(normal, v_rand));
|
||||
vec3 bitangent = cross(normal, tangent);
|
||||
vec3 D[4];
|
||||
D[0] = vec3(1.0,0.0,0.0);
|
||||
int i;
|
||||
for (i=1; i<4; i++)
|
||||
{
|
||||
D[i] = vec3(0.1, 0.8*cos((rnd.x*1.5+i)*6.2832/3.0), 0.8*sin((rnd.x*1.5+i)*6.2832/3.0));
|
||||
D[i] = normalize(D[i]);
|
||||
}
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
vec3 SampleDir = normal * D[i].x + tangent * D[i].y + bitangent *D[i].z;
|
||||
vec3 SampleOffset = (0.5 * normal + SampleDir) / resolution;
|
||||
vec3 uvw_new = uvw + SampleOffset;
|
||||
|
||||
vec4 IncidentSHR = texture(SHR, uvw_new);
|
||||
vec4 IncidentSHG = texture(SHG, uvw_new);
|
||||
vec4 IncidentSHB = texture(SHB, uvw_new);
|
||||
|
||||
GI += SH2RGB(IncidentSHR, IncidentSHG, IncidentSHB, -normal);
|
||||
}
|
||||
GI /= 4;
|
||||
|
||||
Diffuse = max(16. * vec4(GI, 1.), vec4(0.));
|
||||
Specular = vec4(0.);
|
||||
}
|
@ -29,6 +29,6 @@ void main(void)
|
||||
|
||||
vec4 color = texture(Albedo, uv);
|
||||
if (color.a < 0.5) discard;
|
||||
vec3 LightFactor = scattering + getLightFactor(1.);
|
||||
vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.);
|
||||
FragColor = vec4(color.xyz * LightFactor, 1.);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ layout (std140) uniform MatrixesData
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
uniform vec3 windDir;
|
||||
|
@ -11,6 +11,7 @@ layout (std140) uniform MatrixesData
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
13
data/shaders/linearizedepth.frag
Normal file
@ -0,0 +1,13 @@
|
||||
uniform sampler2D tex;
|
||||
uniform float zn;
|
||||
uniform float zf;
|
||||
|
||||
in vec2 uv;
|
||||
out float Depth;
|
||||
|
||||
void main()
|
||||
{
|
||||
float d = texture(tex, uv).x;
|
||||
float c0 = zn * zf, c1 = zn - zf, c2 = zf;
|
||||
Depth = c0 / (d * c1 + c2);
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col1 = texture(tex1, gl_TexCoord[0].xy);
|
||||
vec4 col2 = vec4(vec3(texture(tex2, gl_TexCoord[0].xy).x), 1.0);
|
||||
|
||||
FragColor = col1 * col2;
|
||||
}
|
@ -11,6 +11,7 @@ layout (std140) uniform MatrixesData
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -2,9 +2,18 @@ uniform sampler2D Albedo;
|
||||
uniform sampler2D DiffuseMap;
|
||||
uniform sampler2D SpecularMap;
|
||||
uniform sampler2D SSAO;
|
||||
uniform vec2 screen;
|
||||
uniform vec3 ambient;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec3 nor;
|
||||
in vec2 uv;
|
||||
|
@ -1,8 +1,11 @@
|
||||
// See http://www.ozone3d.net/tutorials/glsl_texturing_p04.php for ref
|
||||
|
||||
#ifdef UBO_DISABLED
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 InverseViewMatrix;
|
||||
uniform mat4 InverseProjectionMatrix;
|
||||
uniform vec2 screen;
|
||||
#else
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
@ -11,11 +14,11 @@ layout (std140) uniform MatrixesData
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
uniform samplerCube tex;
|
||||
uniform vec2 screen;
|
||||
uniform sampler2D tex;
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec3 nor;
|
||||
@ -25,17 +28,18 @@ varying vec3 nor;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
|
||||
vec3 getLightFactor(float specMapValue);
|
||||
|
||||
void main() {
|
||||
vec3 fpos = gl_FragCoord.xyz / vec3(screen, 1.);
|
||||
vec4 xpos = 2.0 * vec4(fpos, 1.0) - 1.0;
|
||||
xpos = InverseProjectionMatrix * xpos;
|
||||
vec3 texc = gl_FragCoord.xyz / vec3(screen, 1.);
|
||||
vec3 u = getPosFromUVDepth(texc, InverseProjectionMatrix).xyz;
|
||||
vec3 r = reflect(u, nor);
|
||||
|
||||
xpos.xyz /= xpos.w;
|
||||
vec3 viewSampleDir = reflect(xpos.xyz, nor);
|
||||
// Convert sampleDir in world space (where tex was generated)
|
||||
vec4 sampleDir = transpose(InverseViewMatrix) * vec4(viewSampleDir, 0.);
|
||||
vec4 detail0 = texture(tex, sampleDir.xyz);
|
||||
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);
|
||||
vec3 LightFactor = getLightFactor(1.);
|
||||
|
||||
FragColor = vec4(detail0.xyz, 1.);
|
||||
FragColor = vec4(detail0.xyz * LightFactor, 1.);
|
||||
}
|
||||
|
@ -1,7 +1,16 @@
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D dtex;
|
||||
uniform mat4 invproj;
|
||||
uniform vec2 screen;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
in float lf;
|
||||
in vec2 tc;
|
||||
|
@ -1,5 +1,12 @@
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ViewMatrix;
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
uniform vec3 color_from;
|
||||
uniform vec3 color_to;
|
||||
|
||||
|
@ -1,60 +0,0 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
// Separated penumbra, horizontal
|
||||
|
||||
void main()
|
||||
{
|
||||
float sum = 0.0;
|
||||
vec4 tmp;
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
float width = 0.0;
|
||||
float zsum = 0.00001;
|
||||
|
||||
tmp = texture(tex, vec2(X - 5.13333 * pixel.x, Y));
|
||||
sum += tmp.x * 0.00640869;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X - 3.26667 * pixel.x, Y));
|
||||
sum += tmp.x * 0.083313;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X - 1.4 * pixel.x, Y));
|
||||
sum += tmp.x * 0.305481;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X, Y));
|
||||
sum += tmp.x * 0.209473;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X + 1.4 * pixel.x, Y));
|
||||
sum += tmp.x * 0.305481;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X + 3.26667 * pixel.x, Y));
|
||||
sum += tmp.x * 0.083313;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X + 5.13333 * pixel.x, Y));
|
||||
sum += tmp.x * 0.00640869;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
float hasz = step(0.7, zsum);
|
||||
FragColor = vec4(sum, (width / zsum) * hasz, hasz, 1.0);
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
varying vec2 uv;
|
||||
#define FragColor gl_FragColor
|
||||
#endif
|
||||
|
||||
|
||||
// Separated penumbra, vertical
|
||||
|
||||
void main()
|
||||
{
|
||||
float sum = 0.0;
|
||||
vec4 tmp;
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
float width = 0.0;
|
||||
float zsum = 0.00001;
|
||||
|
||||
tmp = texture(tex, vec2(X, Y - 5.13333 * pixel.y));
|
||||
sum += tmp.x * 0.00640869;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X, Y - 3.26667 * pixel.y));
|
||||
sum += tmp.x * 0.083313;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X, Y - 1.4 * pixel.y));
|
||||
sum += tmp.x * 0.305481;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X, Y));
|
||||
sum += tmp.x * 0.209473;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X, Y + 1.4 * pixel.y));
|
||||
sum += tmp.x * 0.305481;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X, Y + 3.26667 * pixel.y));
|
||||
sum += tmp.x * 0.083313;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
tmp = texture(tex, vec2(X, Y + 5.13333 * pixel.y));
|
||||
sum += tmp.x * 0.00640869;
|
||||
zsum += tmp.z;
|
||||
width += tmp.y;
|
||||
|
||||
float hasz = step(0.7, zsum);
|
||||
FragColor = vec4(sum, (width / zsum) * hasz, hasz, 1.0);
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D dtex;
|
||||
uniform float spec;
|
||||
uniform vec2 screen;
|
||||
|
||||
#ifdef UBO_DISABLED
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 InverseViewMatrix;
|
||||
uniform mat4 InverseProjectionMatrix;
|
||||
uniform vec2 screen;
|
||||
#else
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
@ -16,12 +16,14 @@ layout (std140) uniform MatrixesData
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
flat in vec3 center;
|
||||
flat in float energy;
|
||||
flat in vec3 col;
|
||||
flat in float radius;
|
||||
|
||||
out vec4 Diffuse;
|
||||
out vec4 Specular;
|
||||
@ -46,8 +48,7 @@ void main()
|
||||
vec3 light_col = col.xyz;
|
||||
float d = distance(light_pos, xpos.xyz);
|
||||
float att = energy * 20. / (1. + d * d);
|
||||
float max_d = 5. * energy;
|
||||
att *= (max_d - d) / max_d;
|
||||
att *= (radius - d) / radius;
|
||||
if (att <= 0.) discard;
|
||||
|
||||
// Light Direction
|
||||
|
@ -11,16 +11,19 @@ layout (std140) uniform MatrixesData
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
in vec3 Position;
|
||||
in float Energy;
|
||||
in vec3 Color;
|
||||
in float Radius;
|
||||
|
||||
flat out vec3 center;
|
||||
flat out float energy;
|
||||
flat out vec3 col;
|
||||
flat out float radius;
|
||||
|
||||
const float zNear = 1.;
|
||||
|
||||
@ -86,12 +89,11 @@ vec4 ComputeClipRegion(vec3 lightPosView, float lightRadius)
|
||||
|
||||
void main(void)
|
||||
{
|
||||
float radius = 5. * Energy;
|
||||
vec4 Center = ViewMatrix * vec4(Position, 1.);
|
||||
Center /= Center.w;
|
||||
|
||||
vec2 ProjectedCornerPosition;
|
||||
vec4 clip = ComputeClipRegion(Center.xyz, radius);
|
||||
vec4 clip = ComputeClipRegion(Center.xyz, Radius);
|
||||
switch (gl_VertexID)
|
||||
{
|
||||
case 0:
|
||||
@ -110,7 +112,7 @@ void main(void)
|
||||
|
||||
// Work out nearest depth for quad Z
|
||||
// Clamp to near plane in case this light intersects the near plane... don't want our quad to be clipped
|
||||
float quadDepth = max(zNear, Center.z - radius);
|
||||
float quadDepth = max(zNear, Center.z - Radius);
|
||||
|
||||
// Project quad depth into clip space
|
||||
vec4 quadClip = ProjectionMatrix * vec4(0., 0., quadDepth, 1.0f);
|
||||
@ -119,4 +121,5 @@ void main(void)
|
||||
col = Color;
|
||||
center = Position;
|
||||
energy = Energy;
|
||||
radius = Radius;
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D normals_and_depth;
|
||||
uniform mat4 invproj;
|
||||
uniform vec2 screen;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 xy = gl_FragCoord.xy / screen;
|
||||
float FragZ = gl_FragCoord.z;
|
||||
float EnvZ = texture(normals_and_depth, xy).a;
|
||||
vec4 FragmentPos = invproj * (2. * vec4(xy, FragZ, 1.0) - 1.);
|
||||
FragmentPos /= FragmentPos.w;
|
||||
vec4 EnvPos = invproj * (2. * vec4(xy, EnvZ, 1.0) - 1.);
|
||||
EnvPos /= EnvPos.w;
|
||||
float len = dot(vec3(1.0), abs(texture(normals_and_depth, xy).xyz));
|
||||
float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
|
||||
FragColor = texture(tex, gl_PointCoord.xy);
|
||||
FragColor.a *= alpha;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
uniform float screenw;
|
||||
|
||||
void main()
|
||||
{
|
||||
const float size = 0.5;
|
||||
|
||||
vec4 eyepos = gl_Vertex;
|
||||
vec4 projCorner = gl_ProjectionMatrix * vec4(vec2(size), eyepos.z, eyepos.w);
|
||||
|
||||
gl_PointSize = screenw * projCorner.x / projCorner.w;
|
||||
gl_Position = gl_ProjectionMatrix * eyepos;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
uniform float time;
|
||||
uniform vec3 campos;
|
||||
uniform mat4 viewm;
|
||||
|
||||
in vec3 initialPosition;
|
||||
out vec3 currentPosition;
|
||||
|
||||
void main()
|
||||
{
|
||||
// This simulation will run accurately for a bit under five days.
|
||||
vec4 start = vec4(initialPosition, 1.0);
|
||||
start.y -= time;
|
||||
|
||||
// How many times has it fell?
|
||||
float count = floor(start.y / 24.0);
|
||||
start.x += sin(count);
|
||||
start.z += cos(count);
|
||||
|
||||
vec2 signs = sign(start.xz);
|
||||
start.xz = mod(start.xz, 17.5) * signs;
|
||||
|
||||
start.y = mod(start.y, 24.0) - 3.0;
|
||||
|
||||
start.xyz += campos;
|
||||
|
||||
currentPosition = (viewm * start).xyz;
|
||||
gl_Position = vec4(0.);
|
||||
}
|
96
data/shaders/rh.frag
Normal file
@ -0,0 +1,96 @@
|
||||
// From http://graphics.cs.aueb.gr/graphics/research_illumination.html
|
||||
// "Real-Time Diffuse Global Illumination Using Radiance Hints"
|
||||
// paper and shader code
|
||||
|
||||
uniform float R_wcs = 10.; // Rmax: maximum sampling distance (in WCS units)
|
||||
uniform vec3 extents;
|
||||
uniform mat4 RHMatrix;
|
||||
uniform mat4 RSMMatrix;
|
||||
uniform sampler2D dtex;
|
||||
uniform sampler2D ctex;
|
||||
uniform sampler2D ntex;
|
||||
|
||||
flat in int slice;
|
||||
layout (location = 0) out vec4 SHRed;
|
||||
layout (location = 1) out vec4 SHGreen;
|
||||
layout (location = 2) out vec4 SHBlue;
|
||||
|
||||
vec3 resolution = vec3(32, 16, 32);
|
||||
#define SAMPLES 16
|
||||
|
||||
vec4 SHBasis (const in vec3 dir)
|
||||
{
|
||||
float L00 = 0.282095;
|
||||
float L1_1 = 0.488603 * dir.y;
|
||||
float L10 = 0.488603 * dir.z;
|
||||
float L11 = 0.488603 * dir.x;
|
||||
return vec4 (L11, L1_1, L10, L00);
|
||||
}
|
||||
|
||||
vec4 DirToSh(vec3 dir, float flux)
|
||||
{
|
||||
return SHBasis (dir) * flux;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
||||
vec3 normalizedRHCenter = 2. * vec3(gl_FragCoord.xy, slice) / resolution - 1.;
|
||||
vec3 RHcenter = (RHMatrix * vec4(normalizedRHCenter * extents, 1.)).xyz;
|
||||
|
||||
vec4 ShadowProjectedRH = RSMMatrix * vec4(RHcenter, 1.);
|
||||
|
||||
vec3 RHCellSize = extents / resolution;
|
||||
vec2 RHuv = .5 * ShadowProjectedRH.xy / ShadowProjectedRH.w + .5;
|
||||
float RHdepth = .5 * ShadowProjectedRH.z / ShadowProjectedRH.w + .5;
|
||||
|
||||
vec4 SHr = vec4(0.);
|
||||
vec4 SHg = vec4(0.);
|
||||
vec4 SHb = vec4(0.);
|
||||
|
||||
int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y);
|
||||
float phi = 30. * (x ^ y) + 10. * x * y;
|
||||
|
||||
for (int i = 0; i < SAMPLES; i++)
|
||||
{
|
||||
// produce a new sample location on the RSM texture
|
||||
float alpha = (i + .5) / SAMPLES;
|
||||
float theta = 2. * 3.14 * 7. * alpha;
|
||||
float h = alpha;
|
||||
vec2 offset = h * vec2(cos(theta), sin(theta));
|
||||
vec2 uv = RHuv + offset * 0.01;
|
||||
|
||||
// Get world position and normal from the RSM sample
|
||||
float depth = texture2D(dtex, uv).z;
|
||||
vec4 RSMPos = inverse(RSMMatrix) * (2. * vec4(uv, depth, 1.) - 1.);
|
||||
RSMPos /= RSMPos.w;
|
||||
vec3 RSMAlbedo = texture(ctex, uv).xyz;
|
||||
vec3 normal = normalize(2. * texture(ntex, uv).xyz - 1.);
|
||||
|
||||
// Sampled location inside the RH cell
|
||||
vec3 offset3d = vec3(uv, 0);
|
||||
vec3 SamplePos = RHcenter + .5 * offset3d.xzy * RHCellSize;
|
||||
|
||||
// Normalize distance to RSM sample
|
||||
float dist = distance(SamplePos, RSMPos.xyz) / R_wcs;
|
||||
// Determine the incident direction.
|
||||
// Avoid very close samples (and numerical instability problems)
|
||||
vec3 RSM_to_RH_dir = (dist <= 0.00) ? vec3(0.) : normalize(SamplePos - RSMPos.xyz);
|
||||
float dotprod = max(dot(RSM_to_RH_dir, normal.xyz), 0.);
|
||||
float factor = dotprod / (0.1 + dist * dist);
|
||||
|
||||
vec3 color = RSMAlbedo.rgb * factor;
|
||||
|
||||
SHr += DirToSh(RSM_to_RH_dir, color.r);
|
||||
SHg += DirToSh(RSM_to_RH_dir, color.g);
|
||||
SHb += DirToSh(RSM_to_RH_dir, color.b);
|
||||
}
|
||||
|
||||
SHr /= 3.14159 * SAMPLES;
|
||||
SHg /= 3.14159 * SAMPLES;
|
||||
SHb /= 3.14159 * SAMPLES;
|
||||
|
||||
SHRed = SHr;
|
||||
SHGreen = SHg;
|
||||
SHBlue = SHb;
|
||||
}
|
14
data/shaders/rhdebug.frag
Normal file
@ -0,0 +1,14 @@
|
||||
uniform sampler3D SHR;
|
||||
uniform sampler3D SHG;
|
||||
uniform sampler3D SHB;
|
||||
|
||||
in vec3 uvw;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float r = texture(SHR, uvw).w;
|
||||
float g = texture(SHG, uvw).w;
|
||||
float b = texture(SHB, uvw).w;
|
||||
FragColor = max(vec4(r, g, b, 1.0), vec4(0.));
|
||||
}
|
30
data/shaders/rhdebug.vert
Normal file
@ -0,0 +1,30 @@
|
||||
uniform vec3 extents;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
uniform mat4 RHMatrix;
|
||||
|
||||
ivec3 resolution = ivec3(32, 16, 32);
|
||||
|
||||
out vec3 uvw;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// Determine the RH center
|
||||
float gx = int(gl_VertexID) & (resolution.x - 1);
|
||||
float gy = int(gl_VertexID >> 5) & (resolution.y - 1);
|
||||
float gz = int(gl_VertexID >> 9) & (resolution.z - 1);
|
||||
uvw = vec3(gx, gy, gz) / vec3(resolution);
|
||||
vec3 WorldPos = (2. * uvw - 1.) * extents;
|
||||
gl_Position = ProjectionMatrix * ViewMatrix * RHMatrix * vec4(WorldPos, 1.);
|
||||
gl_PointSize = 100. / gl_Position.w;
|
||||
|
||||
}
|
20
data/shaders/rhpassthrough.geom
Normal file
@ -0,0 +1,20 @@
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices=3) out;
|
||||
|
||||
in int layer[3];
|
||||
in vec2 uv_in[3];
|
||||
flat out int slice;
|
||||
out vec2 uv;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Layer = layer[0];
|
||||
for(int i=0; i<3; i++)
|
||||
{
|
||||
slice = layer[0];
|
||||
uv = uv_in[i];
|
||||
gl_Position = gl_in[i].gl_Position;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
12
data/shaders/rsm.frag
Normal file
@ -0,0 +1,12 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 uv;
|
||||
in vec3 nor;
|
||||
layout (location = 0) out vec3 RSMColor;
|
||||
layout (location = 1) out vec3 RSMNormals;
|
||||
|
||||
void main()
|
||||
{
|
||||
RSMColor = texture(tex, uv).xyz;
|
||||
RSMNormals = .5 * normalize(nor) + .5;
|
||||
}
|
26
data/shaders/rsm.vert
Normal file
@ -0,0 +1,26 @@
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform mat4 InverseModelMatrix;
|
||||
uniform mat4 RSMMatrix;
|
||||
|
||||
uniform mat4 TextureMatrix =
|
||||
mat4(1., 0., 0., 0.,
|
||||
0., 1., 0., 0.,
|
||||
0., 0., 1., 0.,
|
||||
0., 0., 0., 1.);
|
||||
|
||||
|
||||
in vec3 Position;
|
||||
in vec2 Texcoord;
|
||||
in vec3 Normal;
|
||||
out vec3 nor;
|
||||
out vec2 uv;
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
mat4 ModelViewProjectionMatrix = RSMMatrix * ModelMatrix;
|
||||
mat4 TransposeInverseModel = transpose(InverseModelMatrix);
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
|
||||
nor = (vec4(Normal, 0.)).xyz;
|
||||
uv = (TextureMatrix * vec4(Texcoord, 1., 1.)).xy;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
uniform sampler2D halft; // half is a reserved word
|
||||
uniform sampler2D quarter;
|
||||
uniform sampler2D eighth;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 val[3];
|
||||
val[0] = texture(halft, uv).xyz;
|
||||
val[1] = texture(quarter, uv).xyz;
|
||||
val[2] = texture(eighth, uv).xyz;
|
||||
|
||||
// Find the first level with a penumbra value
|
||||
int i;
|
||||
float q = 0.0;
|
||||
float outval = 1.0;
|
||||
|
||||
float hasshadow = dot(vec3(1.0), vec3(val[0].z, val[1].z, val[2].z));
|
||||
|
||||
if (hasshadow > 0.9)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (val[i].z > 0.9)
|
||||
{
|
||||
q = val[i].y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
q *= 8.0;
|
||||
q = max(1.0, q);
|
||||
q = log2(q);
|
||||
q = min(1.9, q);
|
||||
|
||||
// q is now between 0 and 1.9.
|
||||
int down = int(floor(q));
|
||||
int up = down + 1;
|
||||
float interp = q - float(down);
|
||||
|
||||
outval = 1.0 - mix(val[down].x, val[up].x, interp);
|
||||
}
|
||||
|
||||
FragColor = vec4(vec3(outval), 1.0);
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D ctex;
|
||||
uniform vec3 campos;
|
||||
uniform int low;
|
||||
|
||||
in vec3 wpos;
|
||||
in vec2 texc;
|
||||
out vec4 FragColor;
|
||||
|
||||
float luminanceImp()
|
||||
{
|
||||
// A full-res fetch kills on low-end
|
||||
if (low > 0) return 1.0;
|
||||
|
||||
const vec3 weights = vec3(0.2126, 0.7152, 0.0722); // ITU-R BT. 709
|
||||
vec3 col = texture(ctex, texc).xyz;
|
||||
|
||||
float luma = dot(weights, col);
|
||||
|
||||
// Dark surfaces need less resolution
|
||||
float f = smoothstep(0.1, 0.4, luma);
|
||||
f = max(0.05, f);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
float normalImp(vec3 normal)
|
||||
{
|
||||
vec3 camdir = normalize(campos - wpos);
|
||||
vec3 N = normalize(normal);
|
||||
|
||||
// Boost surfaces facing the viewer directly
|
||||
float f = 2.0 * max(0.0, dot(N, camdir));
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
float depthImp(float linearz)
|
||||
{
|
||||
/* const float skip = 0.7;
|
||||
|
||||
float f = min(linearz, skip);
|
||||
f *= 1.0/skip;*/
|
||||
|
||||
float z = log(1.0 + linearz * 9.0) / log(10.0);
|
||||
|
||||
float f = 1.0 - (z * 0.9);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 ntmp = texture(ntex, texc);
|
||||
vec3 normal = ntmp.xyz * 2.0 - 1.0;
|
||||
float linearz = ntmp.a;
|
||||
|
||||
float importance = normalImp(normal) * depthImp(linearz) * luminanceImp();
|
||||
importance = clamp(importance, 0.0, 1.0);
|
||||
|
||||
float low = step(0.001, importance);
|
||||
|
||||
// Quantize it
|
||||
const float steps = 16.0;
|
||||
importance *= steps;
|
||||
importance = ceil(importance) * low;
|
||||
importance /= steps;
|
||||
|
||||
FragColor = vec4(importance);
|
||||
gl_FragDepth = 1.0 - importance;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
uniform sampler2D dtex;
|
||||
uniform mat4 ipvmat;
|
||||
uniform mat4 shadowmat;
|
||||
|
||||
out vec3 wpos;
|
||||
out vec2 texc;
|
||||
|
||||
float decdepth(vec4 rgba) {
|
||||
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
texc = gl_Vertex.xy / vec2(32767.0);
|
||||
float z = decdepth(vec4(texture(dtex, texc).xyz, 0.0));
|
||||
|
||||
vec3 tmp = vec3(texc, z);
|
||||
tmp = tmp * 2.0 - 1.0;
|
||||
|
||||
vec4 xpos = vec4(tmp, 1.0);
|
||||
xpos = ipvmat * xpos;
|
||||
xpos.xyz /= xpos.w;
|
||||
|
||||
wpos = xpos.xyz;
|
||||
|
||||
// Now we have this pixel's world-space position. Convert to shadow space.
|
||||
vec4 pos = shadowmat * vec4(xpos.xyz, 1.0);
|
||||
|
||||
gl_Position = pos;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
uniform sampler2D tex;
|
||||
uniform int hastex;
|
||||
uniform int viz;
|
||||
uniform int wireframe;
|
||||
uniform float objectid;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
if (hastex != 0) {
|
||||
float alpha = texture(tex, uv).a;
|
||||
|
||||
if (alpha < 0.5)
|
||||
discard;
|
||||
}
|
||||
|
||||
if (viz < 1)
|
||||
{
|
||||
FragColor = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
|
||||
}
|
||||
else {
|
||||
if (wireframe > 0)
|
||||
FragColor = vec4(1.0);
|
||||
else
|
||||
FragColor = texture(tex, uv);
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
uniform sampler2D warpx;
|
||||
uniform sampler2D warpy;
|
||||
|
||||
out vec2 uv;
|
||||
|
||||
float decdepth(vec4 rgba) {
|
||||
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
uv = gl_MultiTexCoord0.xy;
|
||||
|
||||
vec2 tc = pos.xy * vec2(0.5) + vec2(0.5);
|
||||
|
||||
float movex = decdepth(texture(warpx, tc));
|
||||
float movey = decdepth(texture(warpy, tc));
|
||||
|
||||
float dx = movex * 2.0 - 1.0;
|
||||
float dy = movey * 2.0 - 1.0;
|
||||
|
||||
dx *= 2.0;
|
||||
dy *= 2.0;
|
||||
|
||||
gl_Position = pos + vec4(dx, dy, vec2(0.0));
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
uniform sampler2D tex;
|
||||
uniform int size;
|
||||
uniform vec2 pixel;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 origtc = gl_TexCoord[0].xy;
|
||||
|
||||
// Get total sum
|
||||
float first = 1.0, last = 0.0;
|
||||
float lower = 0.0;
|
||||
float total = 0.0;
|
||||
vec2 tc = 0.5 * pixel;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
float col = texture(tex, tc).x;
|
||||
|
||||
lower += col * step(tc.x, origtc.x);
|
||||
total += col;
|
||||
|
||||
if (col > 0.0001)
|
||||
{
|
||||
first = min(first, tc.x);
|
||||
last = max(last, tc.x);
|
||||
}
|
||||
|
||||
tc += pixel;
|
||||
}
|
||||
|
||||
float res = (lower / total) - origtc.x;
|
||||
|
||||
// Outside the edges?
|
||||
if (origtc.x <= first)
|
||||
{
|
||||
res = origtc.x * -2.1;
|
||||
}
|
||||
else if (origtc.x >= last)
|
||||
{
|
||||
res = (1.0 - origtc.x) * 2.1;
|
||||
}
|
||||
|
||||
res = res * 0.5 + 0.5;
|
||||
res = clamp(res, 0.01, 0.99);
|
||||
|
||||
FragColor = encdepth(res);
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
uniform sampler2D tex;
|
||||
uniform int size;
|
||||
uniform vec2 pixel;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
vec4 encdepth(float v) {
|
||||
vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
|
||||
enc = fract(enc);
|
||||
enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
|
||||
return enc;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 origtc = gl_TexCoord[0].xy;
|
||||
|
||||
// Get total sum
|
||||
float first = 1.0, last = 0.0;
|
||||
float lower = 0.0;
|
||||
float total = 0.0;
|
||||
vec2 tc = pixel * 0.5;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
float col = texture(tex, tc).x;
|
||||
|
||||
lower += col * step(tc.y, origtc.y);
|
||||
total += col;
|
||||
|
||||
if (col > 0.0001)
|
||||
{
|
||||
first = min(first, tc.y);
|
||||
last = max(last, tc.y);
|
||||
}
|
||||
|
||||
tc += pixel;
|
||||
}
|
||||
|
||||
float res = (lower / total) - origtc.y;
|
||||
|
||||
// Outside the edges?
|
||||
if (origtc.y <= first)
|
||||
{
|
||||
res = origtc.y * -2.1;
|
||||
}
|
||||
else if (origtc.y >= last)
|
||||
{
|
||||
res = (1.0 - origtc.y) * 2.1;
|
||||
}
|
||||
|
||||
res = res * 0.5 + 0.5;
|
||||
res = clamp(res, 0.01, 0.99);
|
||||
|
||||
FragColor = encdepth(res);
|
||||
}
|
@ -3,6 +3,7 @@ uniform mat4 ViewMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 InverseViewMatrix;
|
||||
uniform mat4 InverseProjectionMatrix;
|
||||
uniform vec2 screen;
|
||||
#else
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
@ -11,12 +12,11 @@ layout (std140) uniform MatrixesData
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
uniform samplerCube tex;
|
||||
uniform vec2 screen;
|
||||
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
out vec4 FragColor;
|
||||
|
24
data/shaders/slicedscreenquad.vert
Normal file
@ -0,0 +1,24 @@
|
||||
in vec2 Position;
|
||||
in vec2 Texcoord;
|
||||
|
||||
#ifndef VSLayer
|
||||
out int layer;
|
||||
out vec2 uv_in;
|
||||
#else
|
||||
out vec2 uv;
|
||||
flat out int slice;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void main() {
|
||||
#ifdef VSLayer
|
||||
gl_Layer = gl_InstanceID;
|
||||
uv = Texcoord;
|
||||
slice = gl_InstanceID;
|
||||
#else
|
||||
layer = gl_InstanceID;
|
||||
uv_in = Texcoord;
|
||||
#endif
|
||||
gl_Position = vec4(Position, 0., 1.);
|
||||
}
|
@ -6,9 +6,18 @@ uniform sampler2D tex_detail3;
|
||||
uniform sampler2D DiffuseMap;
|
||||
uniform sampler2D SpecularMap;
|
||||
uniform sampler2D SSAO;
|
||||
uniform vec2 screen;
|
||||
uniform vec3 ambient;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
in vec2 uv_bis;
|
||||
|
@ -1,80 +1,81 @@
|
||||
// From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/
|
||||
// and improvements here http://graphics.cs.williams.edu/papers/SAOHPG12/
|
||||
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D dtex;
|
||||
uniform sampler2D noise_texture;
|
||||
uniform vec4 samplePoints[16];
|
||||
|
||||
#ifdef UBO_DISABLED
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 InverseViewMatrix;
|
||||
uniform mat4 InverseProjectionMatrix;
|
||||
#else
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
};
|
||||
#endif
|
||||
|
||||
in vec2 uv;
|
||||
out float AO;
|
||||
|
||||
const float sigma = 1.;
|
||||
const float tau = 7.;
|
||||
const float beta = 0.0001;
|
||||
const float epsilon = .00001;
|
||||
const float radius = 2.;
|
||||
const float k = 1.5;
|
||||
|
||||
#define SAMPLES 16
|
||||
|
||||
const float invSamples = 1. / SAMPLES;
|
||||
|
||||
vec3 DecodeNormal(vec2 n);
|
||||
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 cur = texture(ntex, uv);
|
||||
float curdepth = texture(dtex, uv).x;
|
||||
vec4 FragPos = getPosFromUVDepth(vec3(uv, curdepth), InverseProjectionMatrix);
|
||||
|
||||
// get the normal of current fragment
|
||||
vec3 ddx = dFdx(FragPos.xyz);
|
||||
vec3 ddy = dFdy(FragPos.xyz);
|
||||
vec3 norm = normalize(cross(ddy, ddx));
|
||||
// Workaround for nvidia and skyboxes
|
||||
float len = dot(vec3(1.0), abs(cur.xyz));
|
||||
if (len < 0.2) discard;
|
||||
|
||||
int x = int(1024. * uv.x), y = int(1024. * uv.y);
|
||||
float r = radius / FragPos.z;
|
||||
float phi = 30. * (x ^ y) + 10. * x * y;
|
||||
float bl = 0.0;
|
||||
|
||||
for(int i = 0; i < SAMPLES; ++i) {
|
||||
float alpha = (i + .5) * invSamples;
|
||||
float theta = 2. * 3.14 * tau * alpha + phi;
|
||||
float h = r * alpha;
|
||||
vec2 occluder_uv = h * vec2(cos(theta), sin(theta));
|
||||
occluder_uv += uv;
|
||||
|
||||
if (occluder_uv.x < 0. || occluder_uv.x > 1. || occluder_uv.y < 0. || occluder_uv.y > 1.) continue;
|
||||
|
||||
float m = round(log2(h)) + 7.;
|
||||
|
||||
float occluderFragmentDepth = textureLod(dtex, occluder_uv, m).x;
|
||||
vec4 OccluderPos = getPosFromUVDepth(vec3(occluder_uv, occluderFragmentDepth), InverseProjectionMatrix);
|
||||
|
||||
vec3 vi = (OccluderPos - FragPos).xyz;
|
||||
bl += max(0, dot(vi, norm) - FragPos.z * beta) / (dot(vi, vi) + epsilon);
|
||||
}
|
||||
|
||||
AO = max(pow(1.0 - 2. * sigma * bl * invSamples, k), 0.);
|
||||
}
|
||||
// From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/
|
||||
// and improvements here http://graphics.cs.williams.edu/papers/SAOHPG12/
|
||||
|
||||
uniform sampler2D dtex;
|
||||
uniform vec4 samplePoints[16];
|
||||
|
||||
#ifdef UBO_DISABLED
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 InverseViewMatrix;
|
||||
uniform mat4 InverseProjectionMatrix;
|
||||
uniform vec2 screen;
|
||||
#else
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
in vec2 uv;
|
||||
out float AO;
|
||||
|
||||
const float sigma = 1.;
|
||||
const float tau = 7.;
|
||||
const float beta = 0.001;
|
||||
const float epsilon = .00001;
|
||||
const float radius = 1.;
|
||||
const float k = 1.5;
|
||||
|
||||
#define SAMPLES 16
|
||||
|
||||
const float invSamples = 1. / SAMPLES;
|
||||
|
||||
vec3 getXcYcZc(int x, int y, float zC)
|
||||
{
|
||||
// We use perspective symetric projection matrix hence P(0,2) = P(1, 2) = 0
|
||||
float xC= (1. - 2 * (float(x) + 0.5) / screen.x) * zC / ProjectionMatrix[0][0];
|
||||
float yC= (1. + 2 * (float(y) + 0.5) / screen.y) * zC / ProjectionMatrix[1][1];
|
||||
return vec3(xC, yC, zC);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
float lineardepth = textureLod(dtex, uv, 0.).x;
|
||||
int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y);
|
||||
vec3 FragPos = getXcYcZc(x, y, lineardepth);
|
||||
|
||||
// get the normal of current fragment
|
||||
vec3 ddx = dFdx(FragPos);
|
||||
vec3 ddy = dFdy(FragPos);
|
||||
vec3 norm = -normalize(cross(ddy, ddx));
|
||||
|
||||
float r = radius / FragPos.z;
|
||||
float phi = 30. * (x ^ y) + 10. * x * y;
|
||||
float bl = 0.0;
|
||||
|
||||
for(int i = 0; i < SAMPLES; ++i) {
|
||||
float alpha = (i + .5) * invSamples;
|
||||
float theta = 2. * 3.14 * tau * alpha + phi;
|
||||
float h = r * alpha;
|
||||
vec2 offset = h * vec2(cos(theta), sin(theta)) * screen;
|
||||
|
||||
float m = round(log2(h) + 6);
|
||||
ivec2 ioccluder_uv = ivec2(x, y) + ivec2(offset);
|
||||
|
||||
if (ioccluder_uv.x < 0 || ioccluder_uv.x > screen.x || ioccluder_uv.y < 0 || ioccluder_uv.y > screen.y) continue;
|
||||
|
||||
float LinearoccluderFragmentDepth = textureLod(dtex, vec2(ioccluder_uv) / screen, m).x;
|
||||
vec3 OccluderPos = getXcYcZc(ioccluder_uv.x, ioccluder_uv.y, LinearoccluderFragmentDepth);
|
||||
|
||||
vec3 vi = OccluderPos - FragPos;
|
||||
bl += max(0, dot(vi, norm) - FragPos.z * beta) / (dot(vi, vi) + epsilon);
|
||||
}
|
||||
|
||||
AO = max(pow(1.0 - 2. * sigma * bl * invSamples, k), 0.);
|
||||
}
|
@ -6,8 +6,17 @@ uniform float endH;
|
||||
uniform float start;
|
||||
uniform float end;
|
||||
uniform vec3 col;
|
||||
uniform mat4 ipvmat;
|
||||
uniform vec2 screen;
|
||||
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
@ -26,7 +35,7 @@ void main()
|
||||
tmp = 2. * tmp - 1.;
|
||||
|
||||
vec4 xpos = vec4(tmp, 1.0);
|
||||
xpos = ipvmat * xpos;
|
||||
xpos = InverseProjectionMatrix * xpos;
|
||||
xpos.xyz /= xpos.w;
|
||||
|
||||
float dist = length(xpos.xyz);
|
||||
|
@ -1,9 +1,18 @@
|
||||
uniform sampler2D DiffuseMap;
|
||||
uniform sampler2D SpecularMap;
|
||||
uniform sampler2D SSAO;
|
||||
uniform vec2 screen;
|
||||
uniform vec3 ambient;
|
||||
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
|
||||
vec3 getLightFactor(float specMapValue)
|
||||
{
|
||||
vec2 tc = gl_FragCoord.xy / screen;
|
||||
|
@ -25,6 +25,8 @@ Note that checkboxes are an exception and have the following styles :
|
||||
"neutral+checked"
|
||||
"focused+unchecked"
|
||||
"focused+checked"
|
||||
"deactivated+unchecked"
|
||||
"deactivated+checked"
|
||||
|
||||
"Advanced stretching" images are split this way :
|
||||
|
||||
@ -66,11 +68,15 @@ when the border that intersect at this corner are enabled.
|
||||
<!-- Stateless -->
|
||||
<element type="background" image="ocean/background.jpg" />
|
||||
|
||||
<element type="button" state="neutral" image="ocean/glassbutton.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
<element type="button" state="focused" image="ocean/glassbutton_focused.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
<element type="button" state="neutral" image="ocean/glassbutton.png"
|
||||
<element type="button" state="deactivated" image="ocean/glassbutton_deactivated.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
@ -131,6 +137,10 @@ when the border that intersect at this corner are enabled.
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner" state="deactivated" image="ocean/glassspinner_deactivated.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<!-- player name spinner color in multiplayer-->
|
||||
<element type="spinner1" state="neutral" image="ocean/glass_square1.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
@ -157,6 +167,8 @@ when the border that intersect at this corner are enabled.
|
||||
<element type="checkbox" state="neutral+checked" image="ocean/glasscheckbox_checked.png"/>
|
||||
<element type="checkbox" state="focused+unchecked" image="ocean/glasscheckbox_focus.png"/>
|
||||
<element type="checkbox" state="focused+checked" image="ocean/glasscheckbox_checked_focus.png"/>
|
||||
<element type="checkbox" state="deactivated+unchecked" image="ocean/glasscheckbox_deactivated.png"/>
|
||||
<element type="checkbox" state="deactivated+checked" image="ocean/glasscheckbox_checked_deactivated.png"/>
|
||||
|
||||
<!-- are always in neutral state for now. No splitting into 9 areas is done; the image is just stretched.
|
||||
Note: the body of a guage is the same as for for spinners. -->
|
||||
|
@ -25,6 +25,8 @@ Note that checkboxes are an exception and have the following styles :
|
||||
"neutral+checked"
|
||||
"focused+unchecked"
|
||||
"focused+checked"
|
||||
"deactivated+unchecked"
|
||||
"deactivated+checked"
|
||||
|
||||
"Advanced stretching" images are split this way :
|
||||
|
||||
@ -66,11 +68,15 @@ when the border that intersect at this corner are enabled.
|
||||
<!-- Stateless -->
|
||||
<element type="background" image="peach/background.jpg" />
|
||||
|
||||
<element type="button" state="neutral" image="peach/glassbutton.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
<element type="button" state="focused" image="peach/glassbutton_focused.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
<element type="button" state="neutral" image="peach/glassbutton.png"
|
||||
<element type="button" state="deactivated" image="peach/glassbutton_deactivated.png"
|
||||
left_border="13" right_border="13" top_border="13" bottom_border="13"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
|
||||
|
||||
@ -132,6 +138,10 @@ when the border that intersect at this corner are enabled.
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner" state="deactivated" image="peach/glassspinner_deactivated.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
|
||||
<element type="spinner1" state="neutral" image="peach/glass_square1.png"
|
||||
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||
@ -156,6 +166,8 @@ when the border that intersect at this corner are enabled.
|
||||
<element type="checkbox" state="neutral+checked" image="peach/glasscheckbox_checked.png"/>
|
||||
<element type="checkbox" state="focused+unchecked" image="peach/glasscheckbox_focus.png"/>
|
||||
<element type="checkbox" state="focused+checked" image="peach/glasscheckbox_checked_focus.png"/>
|
||||
<element type="checkbox" state="deactivated+unchecked" image="peach/glasscheckbox_deactivated.png"/>
|
||||
<element type="checkbox" state="deactivated+checked" image="peach/glasscheckbox_checked_deactivated.png"/>
|
||||
|
||||
<!-- are always in neutral state for now. No splitting into 9 areas is done; the image is just stretched.
|
||||
Note: the body of a guage is the same as for for spinners. -->
|
||||
|
BIN
data/skins/ocean/glassbutton_deactivated.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
data/skins/ocean/glasscheckbox_checked_deactivated.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
data/skins/ocean/glasscheckbox_deactivated.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
data/skins/ocean/glassspinner_deactivated.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
data/skins/peach/glassbutton_deactivated.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
data/skins/peach/glasscheckbox_checked_deactivated.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
data/skins/peach/glasscheckbox_deactivated.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
data/skins/peach/glassspinner_deactivated.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
@ -21,6 +21,12 @@ else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include")
|
||||
endif()
|
||||
|
||||
# Xrandr
|
||||
if(UNIX AND USE_XRANDR)
|
||||
add_definitions(-DNO_IRR_LINUX_X11_VIDMODE_)
|
||||
add_definitions(-D_IRR_LINUX_X11_RANDR_)
|
||||
endif()
|
||||
|
||||
set(IRRLICHT_SOURCES
|
||||
source/Irrlicht/CTRStencilShadow.cpp
|
||||
source/Irrlicht/CGUIListBox.cpp
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace video { class ITexture; }
|
||||
namespace gui
|
||||
{
|
||||
class IGUIFont;
|
||||
@ -564,6 +565,10 @@ namespace gui
|
||||
|
||||
//! get the type of this skin
|
||||
virtual EGUI_SKIN_TYPE getType() const { return EGST_UNKNOWN; }
|
||||
|
||||
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
|
||||
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
|
||||
const video::SColor* const colors, bool useAlphaChannelOfTexture) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -249,11 +249,16 @@ void CGUIButton::draw()
|
||||
pos.X -= ImageRect.getWidth() / 2;
|
||||
pos.Y -= ImageRect.getHeight() / 2;
|
||||
|
||||
driver->draw2DImage(Image,
|
||||
ScaleImage? AbsoluteRect :
|
||||
core::recti(pos, ImageRect.getSize()),
|
||||
ImageRect, &AbsoluteClippingRect,
|
||||
0, UseAlphaChannel);
|
||||
skin->draw2DImage(Image,
|
||||
ScaleImage ? AbsoluteRect :
|
||||
core::recti(pos, ImageRect.getSize()),
|
||||
ImageRect, &AbsoluteClippingRect,
|
||||
0, UseAlphaChannel);
|
||||
//driver->draw2DImage(Image,
|
||||
// ScaleImage? AbsoluteRect :
|
||||
// core::recti(pos, ImageRect.getSize()),
|
||||
// ImageRect, &AbsoluteClippingRect,
|
||||
// 0, UseAlphaChannel);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -179,6 +179,13 @@ CGUISkin::~CGUISkin()
|
||||
}
|
||||
|
||||
|
||||
void CGUISkin::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
|
||||
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
|
||||
const video::SColor* const colors, bool useAlphaChannelOfTexture)
|
||||
{
|
||||
Driver->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture);
|
||||
}
|
||||
|
||||
//! returns default color
|
||||
video::SColor CGUISkin::getColor(EGUI_DEFAULT_COLOR color) const
|
||||
{
|
||||
|
@ -224,6 +224,10 @@ namespace gui
|
||||
//! scripting languages, editors, debuggers or xml deserialization purposes.
|
||||
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0);
|
||||
|
||||
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
|
||||
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
|
||||
const video::SColor* const colors, bool useAlphaChannelOfTexture);
|
||||
|
||||
private:
|
||||
|
||||
video::SColor Colors[EGDC_COUNT];
|
||||
|
@ -264,6 +264,7 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
|
||||
// enumerate video modes
|
||||
s32 modeCount;
|
||||
XF86VidModeModeInfo** modes;
|
||||
float refresh_rate;
|
||||
|
||||
XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes);
|
||||
|
||||
@ -271,13 +272,37 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
|
||||
for (s32 i = 0; i<modeCount; ++i)
|
||||
{
|
||||
if (bestMode==-1 && modes[i]->hdisplay >= Width && modes[i]->vdisplay >= Height)
|
||||
{
|
||||
float pixels_per_second = modes[i]->dotclock * 1000.0;
|
||||
float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal;
|
||||
refresh_rate = pixels_per_second / pixels_per_frame;
|
||||
bestMode = i;
|
||||
}
|
||||
else if (bestMode!=-1 &&
|
||||
modes[i]->hdisplay == modes[bestMode]->hdisplay &&
|
||||
modes[i]->vdisplay == modes[bestMode]->vdisplay)
|
||||
{
|
||||
float pixels_per_second = modes[i]->dotclock * 1000.0;
|
||||
float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal;
|
||||
float refresh_rate_tmp = pixels_per_second / pixels_per_frame;
|
||||
|
||||
if (refresh_rate_tmp > refresh_rate)
|
||||
{
|
||||
refresh_rate = refresh_rate_tmp;
|
||||
bestMode = i;
|
||||
}
|
||||
}
|
||||
else if (bestMode!=-1 &&
|
||||
modes[i]->hdisplay >= Width &&
|
||||
modes[i]->vdisplay >= Height &&
|
||||
modes[i]->hdisplay <= modes[bestMode]->hdisplay &&
|
||||
modes[i]->vdisplay <= modes[bestMode]->vdisplay)
|
||||
{
|
||||
float pixels_per_second = modes[i]->dotclock * 1000.0;
|
||||
float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal;
|
||||
refresh_rate = pixels_per_second / pixels_per_frame;
|
||||
bestMode = i;
|
||||
}
|
||||
}
|
||||
if (bestMode != -1)
|
||||
{
|
||||
@ -721,8 +746,21 @@ bool CIrrDeviceLinux::createWindow()
|
||||
|
||||
if (!CreationParams.WindowId)
|
||||
{
|
||||
Atom *list;
|
||||
Atom type;
|
||||
int form;
|
||||
unsigned long remain, len;
|
||||
|
||||
Atom WMCheck = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", false);
|
||||
Status s = XGetWindowProperty(display, DefaultRootWindow(display),
|
||||
WMCheck, 0L, 1L, False, XA_WINDOW,
|
||||
&type, &form, &len, &remain,
|
||||
(unsigned char **)&list);
|
||||
|
||||
bool netWM = (s == Success) && len;
|
||||
attributes.override_redirect = !netWM && CreationParams.Fullscreen;
|
||||
|
||||
// create new Window
|
||||
attributes.override_redirect = false;
|
||||
window = XCreateWindow(display,
|
||||
RootWindow(display, visual->screen),
|
||||
0, 0, Width, Height, 0, visual->depth,
|
||||
@ -737,31 +775,45 @@ bool CIrrDeviceLinux::createWindow()
|
||||
|
||||
if (CreationParams.Fullscreen)
|
||||
{
|
||||
// Workaround for Gnome which sometimes creates window smaller than display
|
||||
XSizeHints *hints = XAllocSizeHints();
|
||||
hints->flags=PMinSize;
|
||||
hints->min_width=Width;
|
||||
hints->min_height=Height;
|
||||
XSetWMNormalHints(display, window, hints);
|
||||
XFree(hints);
|
||||
if (netWM)
|
||||
{
|
||||
// Workaround for Gnome which sometimes creates window smaller than display
|
||||
XSizeHints *hints = XAllocSizeHints();
|
||||
hints->flags=PMinSize;
|
||||
hints->min_width=Width;
|
||||
hints->min_height=Height;
|
||||
XSetWMNormalHints(display, window, hints);
|
||||
XFree(hints);
|
||||
|
||||
// Set the fullscreen mode via the window manager. This allows alt-tabing, volume hot keys & others.
|
||||
// Get the needed atom from there freedesktop names
|
||||
Atom WMStateAtom = XInternAtom(display, "_NET_WM_STATE", true);
|
||||
Atom WMFullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true);
|
||||
// Set the fullscreen property
|
||||
XChangeProperty(display, window, WMStateAtom, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(& WMFullscreenAtom), 1);
|
||||
|
||||
// Notify the root window
|
||||
XEvent xev = {0}; // The event should be filled with zeros before setting its attributes
|
||||
|
||||
xev.type = ClientMessage;
|
||||
xev.xclient.window = window;
|
||||
xev.xclient.message_type = WMStateAtom;
|
||||
xev.xclient.format = 32;
|
||||
xev.xclient.data.l[0] = 1;
|
||||
xev.xclient.data.l[1] = WMFullscreenAtom;
|
||||
XSendEvent(display, DefaultRootWindow(display), false, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
|
||||
// Set the fullscreen mode via the window manager. This allows alt-tabing, volume hot keys & others.
|
||||
// Get the needed atom from there freedesktop names
|
||||
Atom WMStateAtom = XInternAtom(display, "_NET_WM_STATE", true);
|
||||
Atom WMFullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true);
|
||||
// Set the fullscreen property
|
||||
XChangeProperty(display, window, WMStateAtom, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(& WMFullscreenAtom), 1);
|
||||
|
||||
// Notify the root window
|
||||
XEvent xev = {0}; // The event should be filled with zeros before setting its attributes
|
||||
|
||||
xev.type = ClientMessage;
|
||||
xev.xclient.window = window;
|
||||
xev.xclient.message_type = WMStateAtom;
|
||||
xev.xclient.format = 32;
|
||||
xev.xclient.data.l[0] = 1;
|
||||
xev.xclient.data.l[1] = WMFullscreenAtom;
|
||||
XSendEvent(display, DefaultRootWindow(display), false, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
|
||||
}
|
||||
else
|
||||
{
|
||||
XSetInputFocus(display, window, RevertToParent, CurrentTime);
|
||||
int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync,
|
||||
GrabModeAsync, CurrentTime);
|
||||
IrrPrintXGrabError(grabKb, "XGrabKeyboard");
|
||||
int grabPointer = XGrabPointer(display, window, True, ButtonPressMask,
|
||||
GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
|
||||
IrrPrintXGrabError(grabPointer, "XGrabPointer");
|
||||
XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -297,33 +297,6 @@ public:
|
||||
return true;
|
||||
} // operator<
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Compares two addons according to the sort order currently defined.
|
||||
* Comparison is done for sorting in descending order.
|
||||
* \param a The addon to compare this addon to.
|
||||
*/
|
||||
bool operator>(const Addon &a) const
|
||||
{
|
||||
switch(m_sort_order)
|
||||
{
|
||||
case SO_DEFAULT:
|
||||
if(testStatus(AS_FEATURED) &&
|
||||
!a.testStatus(AS_FEATURED)) return true;
|
||||
if(!testStatus(AS_FEATURED) &&
|
||||
a.testStatus(AS_FEATURED)) return false;
|
||||
// Otherwise fall through to name comparison!
|
||||
case SO_NAME:
|
||||
// m_id is the lower case name
|
||||
return m_id > a.m_id;
|
||||
break;
|
||||
case SO_DATE:
|
||||
return m_date < a.m_date;
|
||||
break;
|
||||
} // switch
|
||||
// Fix compiler warning.
|
||||
return true;
|
||||
} // operator>
|
||||
|
||||
}; // Addon
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "achievements/achievements_manager.hpp"
|
||||
#include "config/player_profile.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/utf_writer.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
@ -38,12 +39,6 @@ void PlayerManager::create()
|
||||
{
|
||||
assert(!m_player_manager);
|
||||
m_player_manager = new PlayerManager();
|
||||
if(m_player_manager->getNumPlayers() == 0)
|
||||
{
|
||||
m_player_manager->addDefaultPlayer();
|
||||
m_player_manager->save();
|
||||
}
|
||||
|
||||
} // create
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -120,7 +115,8 @@ void PlayerManager::resumeSavedSession()
|
||||
*/
|
||||
void PlayerManager::onSTKQuit()
|
||||
{
|
||||
getCurrentPlayer()->onSTKQuit();
|
||||
if (getCurrentPlayer() && getCurrentPlayer()->isLoggedIn())
|
||||
getCurrentPlayer()->requestSignOut();
|
||||
} // onSTKQuit
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -134,12 +130,9 @@ void PlayerManager::onSTKQuit()
|
||||
*/
|
||||
|
||||
Online::XMLRequest *PlayerManager::requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
bool save_session,
|
||||
bool request_now)
|
||||
const irr::core::stringw &password)
|
||||
{
|
||||
return getCurrentPlayer()->requestSignIn(username, password, save_session,
|
||||
request_now);
|
||||
return getCurrentPlayer()->requestSignIn(username, password);
|
||||
} // requestSignIn
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -173,7 +166,18 @@ PlayerManager::PlayerManager()
|
||||
*/
|
||||
PlayerManager::~PlayerManager()
|
||||
{
|
||||
// If the passwords should not be remembered, clear all saved sessions.
|
||||
if(!UserConfigParams::m_remember_user)
|
||||
{
|
||||
PlayerProfile *player;
|
||||
for_in(player, m_all_players)
|
||||
{
|
||||
player->clearSession();
|
||||
}
|
||||
|
||||
}
|
||||
save();
|
||||
|
||||
} // ~PlayerManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -197,14 +201,21 @@ void PlayerManager::load()
|
||||
return;
|
||||
}
|
||||
|
||||
m_current_player = NULL;
|
||||
for(unsigned int i=0; i<m_player_data->getNumNodes(); i++)
|
||||
std::vector<XMLNode*> player_list;
|
||||
m_player_data->getNodes("player", player_list);
|
||||
for(unsigned int i=0; i<player_list.size(); i++)
|
||||
{
|
||||
const XMLNode *player_xml = m_player_data->getNode(i);
|
||||
const XMLNode *player_xml = player_list[i];
|
||||
PlayerProfile *player = new Online::OnlinePlayerProfile(player_xml);
|
||||
m_all_players.push_back(player);
|
||||
if(player->isDefault())
|
||||
m_current_player = player;
|
||||
}
|
||||
m_current_player = NULL;
|
||||
const XMLNode *current = m_player_data->getNode("current");
|
||||
if(current)
|
||||
{
|
||||
stringw name;
|
||||
current->get("player", &name);
|
||||
m_current_player = getPlayer(name);
|
||||
}
|
||||
|
||||
} // load
|
||||
@ -218,6 +229,12 @@ void PlayerManager::load()
|
||||
*/
|
||||
void PlayerManager::initRemainingData()
|
||||
{
|
||||
// Filter the player nodes out (there is one additional node 'online-ids'
|
||||
// which makes this necessary), otherwise the index of m_all_players
|
||||
// is not identical with the index in the xml file.
|
||||
std::vector<XMLNode*> player_nodes;
|
||||
if(m_player_data)
|
||||
m_player_data->getNodes("player", player_nodes);
|
||||
for (unsigned int i = 0; i<m_all_players.size(); i++)
|
||||
{
|
||||
// On the first time STK is run, there is no player data,
|
||||
@ -226,7 +243,7 @@ void PlayerManager::initRemainingData()
|
||||
if (!m_player_data)
|
||||
m_all_players[i].initRemainingData();
|
||||
else // not a first time start, load remaining data
|
||||
m_all_players[i].loadRemainingData(m_player_data->getNode(i));
|
||||
m_all_players[i].loadRemainingData(player_nodes[i]);
|
||||
}
|
||||
|
||||
delete m_player_data;
|
||||
@ -249,6 +266,12 @@ void PlayerManager::save()
|
||||
players_file << L"<?xml version=\"1.0\"?>\n";
|
||||
players_file << L"<players version=\"1\" >\n";
|
||||
|
||||
if(m_current_player && UserConfigParams::m_remember_user)
|
||||
{
|
||||
players_file << L" <current player=\""
|
||||
<< m_current_player->getName() << L"\"/>\n";
|
||||
}
|
||||
|
||||
PlayerProfile *player;
|
||||
for_in(player, m_all_players)
|
||||
{
|
||||
@ -270,9 +293,11 @@ void PlayerManager::save()
|
||||
/** Adds a new player to the list of all players.
|
||||
* \param name Name of the new player.
|
||||
*/
|
||||
void PlayerManager::addNewPlayer(const core::stringw& name)
|
||||
PlayerProfile* PlayerManager::addNewPlayer(const core::stringw& name)
|
||||
{
|
||||
m_all_players.push_back( new Online::OnlinePlayerProfile(name) );
|
||||
PlayerProfile *profile = new Online::OnlinePlayerProfile(name);
|
||||
m_all_players.push_back(profile);
|
||||
return profile;
|
||||
} // addNewPlayer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -281,6 +306,8 @@ void PlayerManager::addNewPlayer(const core::stringw& name)
|
||||
void PlayerManager::deletePlayer(PlayerProfile *player)
|
||||
{
|
||||
m_all_players.erase(player);
|
||||
if(player==m_current_player)
|
||||
m_current_player = NULL;
|
||||
} // deletePlayer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -315,7 +342,7 @@ void PlayerManager::enforceCurrentPlayer()
|
||||
if (!player->isGuestAccount())
|
||||
{
|
||||
Log::info("PlayerManager", "Enfocring current player '%s'.",
|
||||
player->getName().c_str());
|
||||
player->getName().c_str());
|
||||
m_current_player = player;
|
||||
return;
|
||||
}
|
||||
@ -350,6 +377,20 @@ void PlayerManager::addDefaultPlayer()
|
||||
m_all_players.push_back(new Online::OnlinePlayerProfile(_LTR("Guest"), /*guest*/true));
|
||||
} // addDefaultPlayer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the number of 'real' (non-guest) players.
|
||||
*/
|
||||
unsigned int PlayerManager::getNumNonGuestPlayers() const
|
||||
{
|
||||
unsigned int count=0;
|
||||
const PlayerProfile *player;
|
||||
for_in(player, m_all_players)
|
||||
{
|
||||
if(!player->isGuestAccount()) count ++;
|
||||
}
|
||||
return count;
|
||||
} // getNumNonGuestPlayers
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** This returns a unique id. This is 1 + largest id used so far.
|
||||
*/
|
||||
@ -399,24 +440,15 @@ PlayerProfile *PlayerManager::getPlayer(const irr::core::stringw &name)
|
||||
} // getPlayer
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets the current player. This is the player that is used for story mode
|
||||
* and achievements. If 'remember_me' is set, this information will be
|
||||
* stored in the players.xml file, and automatically loaded next time
|
||||
* STK is started.
|
||||
* and achievements.
|
||||
* \param Player profile to be the current player.
|
||||
* \param remember_me If this player should be marked as default
|
||||
* player in players.xml
|
||||
*/
|
||||
void PlayerManager::setCurrentPlayer(PlayerProfile *player, bool remember_me)
|
||||
void PlayerManager::setCurrentPlayer(PlayerProfile *player)
|
||||
{
|
||||
// Reset current default player
|
||||
if(m_current_player)
|
||||
m_current_player->setDefault(false);
|
||||
m_current_player = player;
|
||||
if(m_current_player)
|
||||
{
|
||||
m_current_player->setDefault(remember_me);
|
||||
m_current_player->computeActive();
|
||||
}
|
||||
} // setCurrentPlayer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -91,11 +91,12 @@ public:
|
||||
void initRemainingData();
|
||||
unsigned int getUniqueId() const;
|
||||
void addDefaultPlayer();
|
||||
void addNewPlayer(const irr::core::stringw& name);
|
||||
PlayerProfile* addNewPlayer(const irr::core::stringw& name);
|
||||
void deletePlayer(PlayerProfile *player);
|
||||
void setCurrentPlayer(PlayerProfile *player, bool remember_me);
|
||||
void setCurrentPlayer(PlayerProfile *player);
|
||||
const PlayerProfile *getPlayerById(unsigned int id);
|
||||
void enforceCurrentPlayer();
|
||||
unsigned int getNumNonGuestPlayers() const;
|
||||
static void setUserDetails(Online::HTTPRequest *request,
|
||||
const std::string &action,
|
||||
const std::string &php_name = "");
|
||||
@ -110,9 +111,7 @@ public:
|
||||
static void onSTKQuit();
|
||||
static void requestSignOut();
|
||||
static Online::XMLRequest *requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
bool save_session,
|
||||
bool request_now = true);
|
||||
const irr::core::stringw &password);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current player. */
|
||||
|
@ -21,14 +21,13 @@
|
||||
#include "achievements/achievements_manager.hpp"
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "config/player_manager.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "online/online_player_profile.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "io/utf_writer.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** Constructor to create a new player that didn't exist before.
|
||||
* \param name Name of the player.
|
||||
@ -43,13 +42,12 @@ PlayerProfile::PlayerProfile(const core::stringw& name, bool is_guest)
|
||||
m_is_guest_account = is_guest;
|
||||
m_use_frequency = is_guest ? -1 : 0;
|
||||
m_unique_id = PlayerManager::get()->getUniqueId();
|
||||
m_is_default = false;
|
||||
m_is_default = false;
|
||||
m_saved_session = false;
|
||||
m_saved_token = "";
|
||||
m_saved_user_id = 0;
|
||||
m_achievements_status = NULL;
|
||||
m_story_mode_status = NULL;
|
||||
m_last_online_name = "";
|
||||
m_last_was_online = false;
|
||||
initRemainingData();
|
||||
} // PlayerProfile
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -59,11 +57,12 @@ PlayerProfile::PlayerProfile(const core::stringw& name, bool is_guest)
|
||||
* that the achievement and story mode data depends on other data to be
|
||||
* read first (challenges and achievement files), which in turn can only be
|
||||
* created later in the startup process (they depend on e.g. all tracks to
|
||||
* be known). On the other hand, automatic login needs to happen asap
|
||||
* (i.e. as soon as the network thread is started), which needs the main
|
||||
* player data (i.e. the default player, and saved session data). So the
|
||||
* constructor only reads this data, the rest of the player data is handled
|
||||
* in loadRemainingData later in the initialisation process.
|
||||
* be known). On the other hand, automatic login needs to happen asap (i.e.
|
||||
* as soon as the network thread is started) to avoid the player having to
|
||||
* wait for the login to finish , which needs the main player data (i.e.
|
||||
* the default player, and saved session data). So the constructor only
|
||||
* reads this data, the rest of the player data is handled in
|
||||
* loadRemainingData later in the initialisation process.
|
||||
* \param node The XML node representing this player.
|
||||
*/
|
||||
PlayerProfile::PlayerProfile(const XMLNode* node)
|
||||
@ -71,21 +70,27 @@ PlayerProfile::PlayerProfile(const XMLNode* node)
|
||||
m_saved_session = false;
|
||||
m_saved_token = "";
|
||||
m_saved_user_id = 0;
|
||||
m_last_online_name = "";
|
||||
m_last_was_online = false;
|
||||
m_story_mode_status = NULL;
|
||||
m_achievements_status = NULL;
|
||||
m_icon_filename = "";
|
||||
|
||||
node->get("name", &m_local_name );
|
||||
node->get("guest", &m_is_guest_account);
|
||||
node->get("use-frequency", &m_use_frequency );
|
||||
node->get("unique-id", &m_unique_id );
|
||||
node->get("is-default", &m_is_default );
|
||||
node->get("saved-session", &m_saved_session );
|
||||
node->get("saved-user", &m_saved_user_id );
|
||||
node->get("saved-token", &m_saved_token );
|
||||
node->get("name", &m_local_name );
|
||||
node->get("guest", &m_is_guest_account);
|
||||
node->get("use-frequency", &m_use_frequency );
|
||||
node->get("unique-id", &m_unique_id );
|
||||
node->get("saved-session", &m_saved_session );
|
||||
node->get("saved-user", &m_saved_user_id );
|
||||
node->get("saved-token", &m_saved_token );
|
||||
node->get("last-online-name", &m_last_online_name);
|
||||
node->get("last-was-online", &m_last_was_online );
|
||||
node->get("icon-filename", &m_icon_filename );
|
||||
|
||||
#ifdef DEBUG
|
||||
m_magic_number = 0xABCD1234;
|
||||
#endif
|
||||
|
||||
} // PlayerProfile
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -110,6 +115,8 @@ void PlayerProfile::loadRemainingData(const XMLNode *node)
|
||||
const XMLNode *xml_achievements = node->getNode("achievements");
|
||||
m_achievements_status = AchievementsManager::get()
|
||||
->createAchievementsStatus(xml_achievements);
|
||||
// Fix up any potentially missing icons.
|
||||
addIcon();
|
||||
} // initRemainingData
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -121,8 +128,63 @@ void PlayerProfile::initRemainingData()
|
||||
m_story_mode_status = unlock_manager->createStoryModeStatus();
|
||||
m_achievements_status =
|
||||
AchievementsManager::get()->createAchievementsStatus();
|
||||
|
||||
addIcon();
|
||||
} // initRemainingData
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** Creates an icon for a player if non exist so far. It takes the unique
|
||||
* player id modulo the number of karts to pick an icon from the karts. It
|
||||
* then uses the unique number plus the extentsion of the original icon as the
|
||||
* file name (it's not possible to use the player name, since the name is in
|
||||
* utf-16, but typically the file systems are not, resulting in incorrect file
|
||||
* names). The icon is then copied to the user config directory, so that it
|
||||
* can be replaced by an icon made by the user.
|
||||
* If there should be an error copying the file, the icon filename is set
|
||||
* to "". Every time stk is started, it will try to fix missing icons
|
||||
* (which allows it to start from old/incompatible config files).
|
||||
* \pre This function must only be called after all karts are read in.
|
||||
*/
|
||||
void PlayerProfile::addIcon()
|
||||
{
|
||||
if (m_icon_filename.size() > 0)
|
||||
return;
|
||||
|
||||
int n = m_unique_id % kart_properties_manager->getNumberOfKarts();
|
||||
std::string source = kart_properties_manager->getKartById(n)
|
||||
->getAbsoluteIconFile();
|
||||
// Create the filename for the icon of this player: the unique id
|
||||
// followed by .png or .jpg.
|
||||
std::ostringstream out;
|
||||
out << m_unique_id <<"."<<StringUtils::getExtension(source);
|
||||
if(file_manager->copyFile(source,
|
||||
file_manager->getUserConfigFile(out.str())) )
|
||||
{
|
||||
m_icon_filename = out.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_icon_filename = "";
|
||||
}
|
||||
} // addIcon
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** Returns the name of the icon file for this player. If the player icon
|
||||
* file is undefined, it returns a "?" mark texture. Note, getAsset does
|
||||
* not return a reference, but only a temporary string. So we must return a
|
||||
* copy of the string (not a reference to).
|
||||
*/
|
||||
const std::string PlayerProfile::getIconFilename() const
|
||||
{
|
||||
// If the icon file is undefined or does not exist, return the "?" icon
|
||||
if(m_icon_filename.size()==0 ||
|
||||
!file_manager->fileExists(file_manager->getUserConfigFile(m_icon_filename)))
|
||||
{
|
||||
return file_manager->getAsset(FileManager::GUI, "main_help.png");
|
||||
}
|
||||
|
||||
return file_manager->getUserConfigFile(m_icon_filename);
|
||||
} // getIconFilename
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/** Writes the data for this player to the specified UTFWriter.
|
||||
* \param out The utf writer to write the data to.
|
||||
@ -133,13 +195,15 @@ void PlayerProfile::save(UTFWriter &out)
|
||||
<< L"\" guest=\"" << m_is_guest_account
|
||||
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n";
|
||||
|
||||
out << L" is-default=\"" << m_is_default
|
||||
<< L"\" unique-id=\"" << m_unique_id
|
||||
out << L" icon-filename=\"" << m_icon_filename <<L"\"\n";
|
||||
|
||||
out << L" unique-id=\"" << m_unique_id
|
||||
<< L"\" saved-session=\"" << m_saved_session << L"\"\n";
|
||||
|
||||
out << L" saved-user=\"" << m_saved_user_id
|
||||
<< L"\" saved-token=\"" << m_saved_token << L"\">\n";
|
||||
|
||||
<< L"\" saved-token=\"" << m_saved_token << L"\"\n";
|
||||
out << L" last-online-name=\"" << m_last_online_name
|
||||
<< L"\" last-was-online=\"" << m_last_was_online<< L"\">\n";
|
||||
{
|
||||
if(m_story_mode_status)
|
||||
m_story_mode_status->save(out);
|
||||
@ -202,11 +266,4 @@ bool PlayerProfile::operator<(const PlayerProfile &other)
|
||||
} // operator<
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** \brief Needed for toggling sort order **/
|
||||
bool PlayerProfile::operator>(const PlayerProfile &other)
|
||||
{
|
||||
return m_use_frequency > other.m_use_frequency;
|
||||
} // operator>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
@ -83,8 +83,8 @@ private:
|
||||
/** A unique number for this player, used to link it to challenges etc. */
|
||||
unsigned int m_unique_id;
|
||||
|
||||
/** True if this is the default (last used) player. */
|
||||
bool m_is_default;
|
||||
/** Absolute path of the icon file for this player. */
|
||||
std::string m_icon_filename;
|
||||
|
||||
/** True if this user has a saved session. */
|
||||
bool m_saved_session;
|
||||
@ -95,6 +95,12 @@ private:
|
||||
/** The token of the saved session. */
|
||||
std::string m_saved_token;
|
||||
|
||||
/** The online user name used last (empty if not used online). */
|
||||
core::stringw m_last_online_name;
|
||||
|
||||
/** True if the last time this player was used as online. */
|
||||
bool m_last_was_online;
|
||||
|
||||
/** The complete challenge state. */
|
||||
StoryModeStatus *m_story_mode_status;
|
||||
|
||||
@ -110,29 +116,28 @@ public:
|
||||
void initRemainingData();
|
||||
void incrementUseFrequency();
|
||||
bool operator<(const PlayerProfile &other);
|
||||
bool operator>(const PlayerProfile &other);
|
||||
void raceFinished();
|
||||
void saveSession(int user_id, const std::string &token);
|
||||
void clearSession();
|
||||
void addIcon();
|
||||
|
||||
/** Abstract virtual classes, to be implemented by the OnlinePlayer. */
|
||||
virtual void setUserDetails(Online::HTTPRequest *request,
|
||||
const std::string &action,
|
||||
const std::string &php_script = "") = 0;
|
||||
const std::string &php_script = "") const = 0;
|
||||
virtual uint32_t getOnlineId() const = 0;
|
||||
virtual PlayerProfile::OnlineState getOnlineState() const = 0;
|
||||
virtual Online::OnlineProfile* getProfile() const = 0;
|
||||
virtual void requestPoll() const = 0;
|
||||
virtual void requestSavedSession() = 0;
|
||||
virtual void onSTKQuit() const = 0;
|
||||
virtual Online::XMLRequest* requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
bool save_session,
|
||||
bool request_now = true) = 0;
|
||||
const irr::core::stringw &password) = 0;
|
||||
virtual void signIn(bool success, const XMLNode * input) = 0;
|
||||
virtual void signOut(bool success, const XMLNode * input) = 0;
|
||||
virtual void signOut(bool success, const XMLNode * input,
|
||||
const irr::core::stringw &info) = 0;
|
||||
virtual void requestSignOut() = 0;
|
||||
virtual bool isLoggedIn() const { return false; }
|
||||
const std::string getIconFilename() const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the name of this player. */
|
||||
void setName(const core::stringw& name)
|
||||
@ -160,16 +165,21 @@ public:
|
||||
#endif
|
||||
return m_is_guest_account;
|
||||
} // isGuestAccount
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the last used online name. */
|
||||
const core::stringw& getLastOnlineName() const
|
||||
{
|
||||
return m_last_online_name;
|
||||
} // getLastOnlineName
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the last used online name. */
|
||||
void setLastOnlineName(const core::stringw &name)
|
||||
{
|
||||
m_last_online_name = name;
|
||||
} // setLastOnlineName
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the unique id of this player. */
|
||||
unsigned int getUniqueID() const { return m_unique_id; }
|
||||
// -----------------------------------------------------------------------
|
||||
/** Returns true if this is the default (last used) player. */
|
||||
bool isDefault() const { return m_is_default; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets if this player is the default player or not. */
|
||||
void setDefault(bool is_default) { m_is_default = is_default; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returnes if the feature (kart, track) is locked. */
|
||||
bool isLocked(const std::string &feature) const
|
||||
@ -252,6 +262,13 @@ public:
|
||||
return m_saved_token;
|
||||
} // getSavedToken
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if the last time this player was used it was used online or
|
||||
* offline. */
|
||||
bool wasOnlineLastTime() const { return m_last_was_online; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets if this player was logged in last time it was used. */
|
||||
void setWasOnlineLastTime(bool b) { m_last_was_online = b; }
|
||||
// ------------------------------------------------------------------------
|
||||
}; // class PlayerProfile
|
||||
|
||||
#endif
|
||||
|
@ -464,6 +464,9 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX BoolUserConfigParam m_dof
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_dof",
|
||||
&m_video_group, "Enable Depth of Field"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_gi
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_gi",
|
||||
&m_video_group, "Enable Global Illumination"));
|
||||
|
||||
// ---- Debug - not saved to config file
|
||||
/** If gamepad debugging is enabled. */
|
||||
@ -677,6 +680,15 @@ namespace UserConfigParams
|
||||
"wasn't asked, 1: allowed, 2: "
|
||||
"not allowed") );
|
||||
|
||||
// ---- User managerment
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_remember_user
|
||||
PARAM_DEFAULT( BoolUserConfigParam(true, "remember_me",
|
||||
"Automatically remember login data"));
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_always_show_login_screen
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "always_show_login_screen",
|
||||
"Always show the login screen even if last player's session was saved."));
|
||||
// ---- Online gameplay related
|
||||
|
||||
PARAM_PREFIX GroupUserConfigParam m_online_group
|
||||
|
@ -255,126 +255,6 @@ void SunLightProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
|
||||
void ShadowPassProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const int hastex = mat.TextureLayer[0].Texture != NULL;
|
||||
srv->setVertexShaderConstant("hastex", &hastex, 1);
|
||||
|
||||
int viz = irr_driver->getShadowViz();
|
||||
srv->setVertexShaderConstant("viz", &viz, 1);
|
||||
|
||||
int wireframe = mat.Wireframe;
|
||||
srv->setVertexShaderConstant("wireframe", &wireframe, 1);
|
||||
|
||||
float objectid = 0;
|
||||
if (hastex)
|
||||
{
|
||||
const stringc name = mat.TextureLayer[0].Texture->getName().getPath();
|
||||
objectid = shash8((const u8 *) name.c_str(), name.size()) / 255.0f;
|
||||
}
|
||||
srv->setVertexShaderConstant("objectid", &objectid, 1);
|
||||
|
||||
//if (!firstdone)
|
||||
// Can't use the firstdone optimization, as this callback is used for multiple shaders
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("warpx", &tex, 1);
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("warpy", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ShadowImportanceProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("shadowmat", m_shadowmat.pointer(), 16);
|
||||
srv->setVertexShaderConstant("ipvmat", m_invprojview.pointer(), 16);
|
||||
|
||||
srv->setVertexShaderConstant("campos", m_campos, 3);
|
||||
|
||||
int low = UserConfigParams::m_shadows == 1;
|
||||
srv->setVertexShaderConstant("low", &low, 1);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("ntex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("dtex", &tex, 1);
|
||||
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("ctex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CollapseProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("pixel", m_pixel, 2);
|
||||
srv->setVertexShaderConstant("multi", m_multi, 2);
|
||||
srv->setVertexShaderConstant("size", &m_size, 1);
|
||||
|
||||
//if (!firstdone)
|
||||
// Can't use the firstdone optimization, as this callback is used for multiple shaders
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("oldtex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MultiplyProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex1", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("tex2", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ShadowGenProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("halft", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("quarter", &tex, 1);
|
||||
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("eighth", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void DisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
|
||||
|
@ -426,98 +426,6 @@ private:
|
||||
|
||||
//
|
||||
|
||||
class ShadowPassProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ShadowImportanceProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void updateIPVMatrix()
|
||||
{
|
||||
// Update the IPV matrix, only once per frame since it's costly
|
||||
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
const core::vector3df &campos =
|
||||
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
|
||||
m_campos[0] = campos.X;
|
||||
m_campos[1] = campos.Y;
|
||||
m_campos[2] = campos.Z;
|
||||
|
||||
m_invprojview = drv->getTransform(video::ETS_PROJECTION);
|
||||
m_invprojview *= drv->getTransform(video::ETS_VIEW);
|
||||
m_invprojview.makeInverse();
|
||||
}
|
||||
|
||||
void setShadowMatrix(const core::matrix4 &mat)
|
||||
{
|
||||
m_shadowmat = mat;
|
||||
}
|
||||
|
||||
private:
|
||||
core::matrix4 m_invprojview, m_shadowmat;
|
||||
float m_campos[3];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class CollapseProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setResolution(const int x, const int y)
|
||||
{
|
||||
m_pixel[0] = 1.0f / x;
|
||||
m_pixel[1] = 1.0f / y;
|
||||
|
||||
m_multi[0] = m_multi[1] = 1;
|
||||
|
||||
if (x < 2 || y < 2)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
// No increase for the other direction
|
||||
if (m_pixel[i] > 0.9f) m_pixel[i] = m_multi[i] = 0;
|
||||
}
|
||||
|
||||
std::swap(m_multi[0], m_multi[1]);
|
||||
}
|
||||
|
||||
m_size = (int)std::max(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
float m_pixel[2];
|
||||
int m_size;
|
||||
float m_multi[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MultiplyProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ShadowGenProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class DisplaceProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
|
@ -87,7 +87,7 @@ static void
|
||||
CALLBACK
|
||||
#endif
|
||||
debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
|
||||
const GLchar* msg, const void *userparam)
|
||||
const GLchar* msg, const void *userparam)
|
||||
{
|
||||
switch(source)
|
||||
{
|
||||
@ -153,58 +153,58 @@ debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei le
|
||||
|
||||
void initGL()
|
||||
{
|
||||
if (is_gl_init)
|
||||
return;
|
||||
is_gl_init = true;
|
||||
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");
|
||||
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");
|
||||
glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation");
|
||||
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor");
|
||||
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced");
|
||||
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");
|
||||
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");
|
||||
glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation");
|
||||
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor");
|
||||
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced");
|
||||
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsInstanced");
|
||||
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");
|
||||
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");
|
||||
@ -221,7 +221,7 @@ void initGL()
|
||||
glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D");
|
||||
glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)IRR_OGL_LOAD_EXTENSION("glGetCompressedTexImage");
|
||||
#ifdef DEBUG
|
||||
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB");
|
||||
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB");
|
||||
#endif
|
||||
#endif
|
||||
#ifdef ARB_DEBUG_OUTPUT
|
||||
@ -233,69 +233,69 @@ void initGL()
|
||||
// Mostly from shader tutorial
|
||||
GLuint LoadShader(const char * file, unsigned type)
|
||||
{
|
||||
GLuint Id = glCreateShader(type);
|
||||
GLuint Id = glCreateShader(type);
|
||||
char versionString[20];
|
||||
sprintf(versionString, "#version %d\n", irr_driver->getGLSLVersion());
|
||||
std::string Code = versionString;
|
||||
std::ifstream Stream(file, std::ios::in);
|
||||
std::ifstream Stream(file, std::ios::in);
|
||||
Code += "//" + std::string(file) + "\n";
|
||||
if (UserConfigParams::m_ubo_disabled)
|
||||
Code += "#define UBO_DISABLED\n";
|
||||
if (irr_driver->hasVSLayerExtension())
|
||||
Code += "#define VSLayer\n";
|
||||
if (Stream.is_open())
|
||||
{
|
||||
std::string Line = "";
|
||||
while (getline(Stream, Line))
|
||||
Code += "\n" + Line;
|
||||
Stream.close();
|
||||
}
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
Log::info("GLWrap", "Compiling shader : %s", file);
|
||||
char const * SourcePointer = Code.c_str();
|
||||
int length = strlen(SourcePointer);
|
||||
glShaderSource(Id, 1, &SourcePointer, &length);
|
||||
glCompileShader(Id);
|
||||
if (Stream.is_open())
|
||||
{
|
||||
std::string Line = "";
|
||||
while (getline(Stream, Line))
|
||||
Code += "\n" + Line;
|
||||
Stream.close();
|
||||
}
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
Log::info("GLWrap", "Compiling shader : %s", file);
|
||||
char const * SourcePointer = Code.c_str();
|
||||
int length = strlen(SourcePointer);
|
||||
glShaderSource(Id, 1, &SourcePointer, &length);
|
||||
glCompileShader(Id);
|
||||
|
||||
glGetShaderiv(Id, GL_COMPILE_STATUS, &Result);
|
||||
if (Result == GL_FALSE)
|
||||
glGetShaderiv(Id, GL_COMPILE_STATUS, &Result);
|
||||
if (Result == GL_FALSE)
|
||||
{
|
||||
Log::error("GLWrap", "Error in shader %s", file);
|
||||
glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage);
|
||||
glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage);
|
||||
Log::error("GLWrap", ErrorMessage);
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
|
||||
glGetError();
|
||||
|
||||
return Id;
|
||||
return Id;
|
||||
}
|
||||
|
||||
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount)
|
||||
{
|
||||
GLuint Program = glCreateProgram();
|
||||
GLuint Program = glCreateProgram();
|
||||
loadAndAttach(Program, GL_VERTEX_SHADER, vertex_file_path);
|
||||
glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS);
|
||||
glLinkProgram(Program);
|
||||
glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS);
|
||||
glLinkProgram(Program);
|
||||
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
glGetProgramiv(Program, GL_LINK_STATUS, &Result);
|
||||
if (Result == GL_FALSE)
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
glGetProgramiv(Program, GL_LINK_STATUS, &Result);
|
||||
if (Result == GL_FALSE)
|
||||
{
|
||||
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage);
|
||||
printf(ErrorMessage);
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage);
|
||||
printf(ErrorMessage);
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
|
||||
glGetError();
|
||||
|
||||
return Program;
|
||||
return Program;
|
||||
}
|
||||
|
||||
GLuint getTextureGLuint(irr::video::ITexture *tex)
|
||||
@ -353,10 +353,10 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha)
|
||||
{
|
||||
float alpha = data[4 * i + 3];
|
||||
if (alpha > 0.)
|
||||
alpha = pow(alpha / 255., 1. / 2.2);
|
||||
data[4 * i] *= alpha;
|
||||
data[4 * i + 1] *= alpha;
|
||||
data[4 * i + 2] *= alpha;
|
||||
alpha = pow(alpha / 255.f, 1.f / 2.2f);
|
||||
data[4 * i ] = (unsigned char)(data[4 * i ] * alpha);
|
||||
data[4 * i + 1] = (unsigned char)(data[4 * i + 1] * alpha);
|
||||
data[4 * i + 2] = (unsigned char)(data[4 * i + 2] * alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,11 +387,11 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Try to load a compressed texture from the given file name.
|
||||
* Data in the specified file need to have a specific format. See the
|
||||
* saveCompressedTexture() function for a description of the format.
|
||||
* \return true if the loading succeeded, false otherwise.
|
||||
* \see saveCompressedTexture
|
||||
*/
|
||||
* Data in the specified file need to have a specific format. See the
|
||||
* saveCompressedTexture() function for a description of the format.
|
||||
* \return true if the loading succeeded, false otherwise.
|
||||
* \see saveCompressedTexture
|
||||
*/
|
||||
bool loadCompressedTexture(const std::string& compressed_tex)
|
||||
{
|
||||
std::ifstream ifs(compressed_tex.c_str(), std::ios::in | std::ios::binary);
|
||||
@ -414,7 +414,7 @@ bool loadCompressedTexture(const std::string& compressed_tex)
|
||||
if (!ifs.fail())
|
||||
{
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, internal_format,
|
||||
w, h, 0, size, (GLvoid*)data);
|
||||
w, h, 0, size, (GLvoid*)data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
delete[] data;
|
||||
ifs.close();
|
||||
@ -426,14 +426,14 @@ bool loadCompressedTexture(const std::string& compressed_tex)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Try to save the last texture sent to glTexImage2D in a file of the given
|
||||
* file name. This function should only be used for textures sent to
|
||||
* glTexImage2D with a compressed internal format as argument.<br>
|
||||
* \note The following format is used to save the compressed texture:<br>
|
||||
* <internal-format><width><height><size><data> <br>
|
||||
* The first four elements are integers and the last one is stored
|
||||
* on \c size bytes.
|
||||
* \see loadCompressedTexture
|
||||
*/
|
||||
* file name. This function should only be used for textures sent to
|
||||
* glTexImage2D with a compressed internal format as argument.<br>
|
||||
* \note The following format is used to save the compressed texture:<br>
|
||||
* <internal-format><width><height><size><data> <br>
|
||||
* The first four elements are integers and the last one is stored
|
||||
* on \c size bytes.
|
||||
* \see loadCompressedTexture
|
||||
*/
|
||||
void saveCompressedTexture(const std::string& compressed_tex)
|
||||
{
|
||||
int internal_format, width, height, size, compressionSuccessful;
|
||||
@ -462,12 +462,12 @@ void saveCompressedTexture(const std::string& compressed_tex)
|
||||
|
||||
void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + TextureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, TextureId);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MagFilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glActiveTexture(GL_TEXTURE0 + TextureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, TextureId);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MagFilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
int aniso = UserConfigParams::m_anisotropic;
|
||||
if (aniso == 0) aniso = 1;
|
||||
@ -476,20 +476,12 @@ void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum
|
||||
glGetError();
|
||||
}
|
||||
|
||||
void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height)
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, Src);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, Dst);
|
||||
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer)
|
||||
{
|
||||
if (!UserConfigParams::m_profiler_enabled) return;
|
||||
if (profiler.isFrozen()) return;
|
||||
|
||||
#ifdef GL_TIME_ELAPSED
|
||||
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
|
||||
if (!timer.initialised)
|
||||
{
|
||||
@ -497,14 +489,17 @@ ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer)
|
||||
timer.initialised = true;
|
||||
}
|
||||
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, timer.query);
|
||||
#endif
|
||||
}
|
||||
ScopedGPUTimer::~ScopedGPUTimer()
|
||||
{
|
||||
if (!UserConfigParams::m_profiler_enabled) return;
|
||||
if (profiler.isFrozen()) return;
|
||||
|
||||
#ifdef GL_TIME_ELAPSED
|
||||
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
|
||||
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
|
||||
#endif
|
||||
}
|
||||
|
||||
GPUTimer::GPUTimer() : initialised(false)
|
||||
@ -521,8 +516,83 @@ unsigned GPUTimer::elapsedTimeus()
|
||||
return result / 1000;
|
||||
}
|
||||
|
||||
FrameBuffer::FrameBuffer() {}
|
||||
|
||||
FrameBuffer::FrameBuffer(const std::vector<GLuint> &RTTs, size_t w, size_t h, bool layered) :
|
||||
DepthTexture(0), RenderTargets(RTTs), width(w), height(h)
|
||||
{
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
if (layered)
|
||||
{
|
||||
for (unsigned i = 0; i < RTTs.size(); i++)
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, RTTs[i], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned i = 0; i < RTTs.size(); i++)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, RTTs[i], 0);
|
||||
}
|
||||
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
assert(result == GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||
}
|
||||
|
||||
FrameBuffer::FrameBuffer(const std::vector<GLuint> &RTTs, GLuint DS, size_t w, size_t h, bool layered) :
|
||||
DepthTexture(DS), RenderTargets(RTTs), width(w), height(h)
|
||||
{
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
if (layered)
|
||||
{
|
||||
for (unsigned i = 0; i < RTTs.size(); i++)
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, RTTs[i], 0);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, DS, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned i = 0; i < RTTs.size(); i++)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, RTTs[i], 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, DS, 0);
|
||||
}
|
||||
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
assert(result == GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||
}
|
||||
|
||||
FrameBuffer::~FrameBuffer()
|
||||
{
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
}
|
||||
|
||||
void FrameBuffer::Bind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
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);
|
||||
}
|
||||
|
||||
void FrameBuffer::Blit(const FrameBuffer &Src, FrameBuffer &Dst, GLbitfield mask, GLenum filter)
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, Src.fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, Dst.fbo);
|
||||
glBlitFramebuffer(0, 0, Src.width, Src.height, 0, 0, Dst.width, Dst.height, mask, filter);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::BlitToDefault(size_t x0, size_t y0, size_t x1, size_t y1)
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, 0, width, height, x0, y0, x1, y1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
void draw3DLine(const core::vector3df& start,
|
||||
const core::vector3df& end, irr::video::SColor color)
|
||||
const core::vector3df& end, irr::video::SColor color)
|
||||
{
|
||||
if (!irr_driver->isGLSL()) {
|
||||
irr_driver->getVideoDriver()->draw3DLine(start, end, color);
|
||||
@ -546,8 +616,8 @@ void draw3DLine(const core::vector3df& start,
|
||||
}
|
||||
|
||||
static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height,
|
||||
float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y,
|
||||
float tex_width, float tex_height)
|
||||
float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y,
|
||||
float tex_width, float tex_height)
|
||||
{
|
||||
unsigned colors[] = {
|
||||
col[0].getRed(), col[0].getGreen(), col[0].getBlue(), col[0].getAlpha(),
|
||||
@ -573,8 +643,8 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol
|
||||
}
|
||||
|
||||
void drawTexQuad(const video::ITexture *texture, float width, float height,
|
||||
float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y,
|
||||
float tex_width, float tex_height)
|
||||
float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y,
|
||||
float tex_width, float tex_height)
|
||||
{
|
||||
glUseProgram(UIShader::TextureRectShader::Program);
|
||||
glBindVertexArray(UIShader::TextureRectShader::vao);
|
||||
@ -591,12 +661,12 @@ void drawTexQuad(const video::ITexture *texture, float width, float height,
|
||||
|
||||
static void
|
||||
getSize(const video::ITexture* texture, const core::rect<s32>& destRect,
|
||||
const core::rect<s32>& sourceRect,
|
||||
float &width, float &height,
|
||||
float ¢er_pos_x, float ¢er_pos_y,
|
||||
float &tex_width, float &tex_height,
|
||||
float &tex_center_pos_x, float &tex_center_pos_y
|
||||
)
|
||||
const core::rect<s32>& sourceRect,
|
||||
float &width, float &height,
|
||||
float ¢er_pos_x, float ¢er_pos_y,
|
||||
float &tex_width, float &tex_height,
|
||||
float &tex_center_pos_x, float &tex_center_pos_y
|
||||
)
|
||||
{
|
||||
core::dimension2d<u32> frame_size =
|
||||
irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
|
||||
@ -638,8 +708,8 @@ float &tex_center_pos_x, float &tex_center_pos_y
|
||||
}
|
||||
|
||||
void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
|
||||
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
|
||||
const video::SColor &colors, bool useAlphaChannelOfTexture)
|
||||
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
|
||||
const video::SColor &colors, bool useAlphaChannelOfTexture)
|
||||
{
|
||||
if (!irr_driver->isGLSL()) {
|
||||
video::SColor duplicatedArray[4] = {
|
||||
@ -655,7 +725,7 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
|
||||
tex_center_pos_x, tex_center_pos_y;
|
||||
|
||||
getSize(texture, destRect, sourceRect, width, height, center_pos_x, center_pos_y,
|
||||
tex_width, tex_height, tex_center_pos_x, tex_center_pos_y);
|
||||
tex_width, tex_height, tex_center_pos_x, tex_center_pos_y);
|
||||
|
||||
if (useAlphaChannelOfTexture)
|
||||
{
|
||||
@ -674,7 +744,7 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
const core::dimension2d<u32>& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
|
||||
glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y,
|
||||
clipRect->getWidth(), clipRect->getHeight());
|
||||
clipRect->getWidth(), clipRect->getHeight());
|
||||
}
|
||||
|
||||
glUseProgram(UIShader::UniformColoredTextureRectShader::Program);
|
||||
@ -694,14 +764,14 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
|
||||
}
|
||||
|
||||
void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
|
||||
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
|
||||
const video::SColor* const colors, bool useAlphaChannelOfTexture)
|
||||
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
|
||||
const video::SColor* const colors, bool useAlphaChannelOfTexture)
|
||||
{
|
||||
if (!irr_driver->isGLSL())
|
||||
{
|
||||
irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture);
|
||||
return;
|
||||
}
|
||||
if (!irr_driver->isGLSL())
|
||||
{
|
||||
irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture);
|
||||
return;
|
||||
}
|
||||
|
||||
float width, height,
|
||||
center_pos_x, center_pos_y,
|
||||
@ -709,17 +779,17 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
|
||||
tex_center_pos_x, tex_center_pos_y;
|
||||
|
||||
getSize(texture, destRect, sourceRect, width, height, center_pos_x, center_pos_y,
|
||||
tex_width, tex_height, tex_center_pos_x, tex_center_pos_y);
|
||||
tex_width, tex_height, tex_center_pos_x, tex_center_pos_y);
|
||||
|
||||
if (useAlphaChannelOfTexture)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
if (useAlphaChannelOfTexture)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
if (clipRect)
|
||||
{
|
||||
if (!clipRect->isValid())
|
||||
@ -728,55 +798,55 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
const core::dimension2d<u32>& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
|
||||
glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y,
|
||||
clipRect->getWidth(), clipRect->getHeight());
|
||||
clipRect->getWidth(), clipRect->getHeight());
|
||||
}
|
||||
if (colors)
|
||||
drawTexColoredQuad(texture, colors, width, height, center_pos_x, center_pos_y,
|
||||
tex_center_pos_x, tex_center_pos_y, tex_width, tex_height);
|
||||
else
|
||||
drawTexQuad(texture, width, height, center_pos_x, center_pos_y,
|
||||
tex_center_pos_x, tex_center_pos_y, tex_width, tex_height);
|
||||
if (colors)
|
||||
drawTexColoredQuad(texture, colors, width, height, center_pos_x, center_pos_y,
|
||||
tex_center_pos_x, tex_center_pos_y, tex_width, tex_height);
|
||||
else
|
||||
drawTexQuad(texture, width, height, center_pos_x, center_pos_y,
|
||||
tex_center_pos_x, tex_center_pos_y, tex_width, tex_height);
|
||||
if (clipRect)
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glUseProgram(0);
|
||||
glUseProgram(0);
|
||||
|
||||
glGetError();
|
||||
}
|
||||
|
||||
void GL32_draw2DRectangle(video::SColor color, const core::rect<s32>& position,
|
||||
const core::rect<s32>* clip)
|
||||
const core::rect<s32>* clip)
|
||||
{
|
||||
|
||||
if (!irr_driver->isGLSL())
|
||||
{
|
||||
irr_driver->getVideoDriver()->draw2DRectangle(color, position, clip);
|
||||
return;
|
||||
}
|
||||
if (!irr_driver->isGLSL())
|
||||
{
|
||||
irr_driver->getVideoDriver()->draw2DRectangle(color, position, clip);
|
||||
return;
|
||||
}
|
||||
|
||||
core::dimension2d<u32> frame_size =
|
||||
irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
|
||||
const int screen_w = frame_size.Width;
|
||||
const int screen_h = frame_size.Height;
|
||||
float center_pos_x = float(position.UpperLeftCorner.X + position.LowerRightCorner.X);
|
||||
center_pos_x /= screen_w;
|
||||
center_pos_x -= 1;
|
||||
float center_pos_y = float(position.UpperLeftCorner.Y + position.LowerRightCorner.Y);
|
||||
center_pos_y /= screen_h;
|
||||
center_pos_y = 1 - center_pos_y;
|
||||
float width = float(position.LowerRightCorner.X - position.UpperLeftCorner.X);
|
||||
width /= screen_w;
|
||||
float height = float(position.LowerRightCorner.Y - position.UpperLeftCorner.Y);
|
||||
height /= screen_h;
|
||||
core::dimension2d<u32> frame_size =
|
||||
irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
|
||||
const int screen_w = frame_size.Width;
|
||||
const int screen_h = frame_size.Height;
|
||||
float center_pos_x = float(position.UpperLeftCorner.X + position.LowerRightCorner.X);
|
||||
center_pos_x /= screen_w;
|
||||
center_pos_x -= 1;
|
||||
float center_pos_y = float(position.UpperLeftCorner.Y + position.LowerRightCorner.Y);
|
||||
center_pos_y /= screen_h;
|
||||
center_pos_y = 1 - center_pos_y;
|
||||
float width = float(position.LowerRightCorner.X - position.UpperLeftCorner.X);
|
||||
width /= screen_w;
|
||||
float height = float(position.LowerRightCorner.Y - position.UpperLeftCorner.Y);
|
||||
height /= screen_h;
|
||||
|
||||
if (color.getAlpha() < 255)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
if (color.getAlpha() < 255)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
if (clip)
|
||||
{
|
||||
@ -786,19 +856,19 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect<s32>& position,
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
const core::dimension2d<u32>& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize();
|
||||
glScissor(clip->UpperLeftCorner.X, renderTargetSize.Height - clip->LowerRightCorner.Y,
|
||||
clip->getWidth(), clip->getHeight());
|
||||
clip->getWidth(), clip->getHeight());
|
||||
}
|
||||
|
||||
glUseProgram(UIShader::ColoredRectShader::Program);
|
||||
glBindVertexArray(UIShader::ColoredRectShader::vao);
|
||||
UIShader::ColoredRectShader::setUniforms(center_pos_x, center_pos_y, width, height, color);
|
||||
glUseProgram(UIShader::ColoredRectShader::Program);
|
||||
glBindVertexArray(UIShader::ColoredRectShader::vao);
|
||||
UIShader::ColoredRectShader::setUniforms(center_pos_x, center_pos_y, width, height, color);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
if (clip)
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glUseProgram(0);
|
||||
glUseProgram(0);
|
||||
|
||||
glGetError();
|
||||
}
|
||||
|
@ -5,6 +5,12 @@
|
||||
# include <OpenGL/gl.h>
|
||||
# include <OpenGL/gl3.h>
|
||||
# define OGL32CTX
|
||||
# ifdef GL_ARB_instanced_arrays
|
||||
# define glVertexAttribDivisor glVertexAttribDivisorARB
|
||||
# endif
|
||||
# ifndef GL_TEXTURE_SWIZZLE_RGBA
|
||||
# define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
|
||||
# endif
|
||||
#elif defined(ANDROID)
|
||||
# include <GLES/gl.h>
|
||||
#elif defined(WIN32)
|
||||
@ -18,6 +24,7 @@
|
||||
# include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include "utils/log.hpp"
|
||||
|
||||
// already includes glext.h, which defines useful GL constants.
|
||||
@ -174,6 +181,27 @@ public:
|
||||
unsigned elapsedTimeus();
|
||||
};
|
||||
|
||||
class FrameBuffer
|
||||
{
|
||||
private:
|
||||
GLuint fbo;
|
||||
std::vector<GLuint> RenderTargets;
|
||||
GLuint DepthTexture;
|
||||
size_t width, height;
|
||||
public:
|
||||
FrameBuffer();
|
||||
FrameBuffer(const std::vector <GLuint> &RTTs, size_t w, size_t h, bool layered = false);
|
||||
FrameBuffer(const std::vector <GLuint> &RTTs, GLuint DS, size_t w, size_t h, bool layered = false);
|
||||
~FrameBuffer();
|
||||
void Bind();
|
||||
std::vector<GLuint> &getRTT() { return RenderTargets; }
|
||||
GLuint &getDepthTexture() { assert(DepthTexture); return DepthTexture; }
|
||||
size_t getWidth() const { return width; }
|
||||
size_t getHeight() const { return height; }
|
||||
static void Blit(const FrameBuffer &Src, FrameBuffer &Dst, GLbitfield mask = GL_COLOR_BUFFER_BIT, GLenum filter = GL_NEAREST);
|
||||
void BlitToDefault(size_t, size_t, size_t, size_t);
|
||||
};
|
||||
|
||||
// core::rect<s32> needs these includes
|
||||
#include <rect.h>
|
||||
#include "utils/vec3.hpp"
|
||||
@ -184,7 +212,6 @@ void resetTextureTable();
|
||||
void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = false);
|
||||
bool loadCompressedTexture(const std::string& compressed_tex);
|
||||
void saveCompressedTexture(const std::string& compressed_tex);
|
||||
void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height);
|
||||
|
||||
void draw3DLine(const core::vector3df& start,
|
||||
const core::vector3df& end, irr::video::SColor color);
|
||||
|
@ -195,7 +195,7 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi
|
||||
memcpy(&(initialvalue[i].PositionX), &(particles[i].PositionX), 3 * sizeof(float));
|
||||
generateLifetimeSizeDirection(emitter, initialvalue[i].Lifetime, initialvalue[i].Size,
|
||||
initialvalue[i].DirectionX, initialvalue[i].DirectionY, initialvalue[i].DirectionZ);
|
||||
memcpy(&(particles[i].DirectionX), &(initialvalue[i].DirectionZ), 4 * sizeof(float));
|
||||
memcpy(&(particles[i].DirectionX), &(initialvalue[i].DirectionX), 4 * sizeof(float));
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), initialvalue, GL_STREAM_DRAW);
|
||||
|
@ -1,14 +1,14 @@
|
||||
#ifndef GPUPARTICLES_H
|
||||
#define GPUPARTICLES_H
|
||||
|
||||
|
||||
#include "graphics/glwrap.hpp"
|
||||
|
||||
|
||||
#include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h"
|
||||
#include <ISceneManager.h>
|
||||
#include <IParticleSystemSceneNode.h>
|
||||
|
||||
|
||||
namespace irr { namespace video{ class ITexture; } }
|
||||
|
||||
|
||||
class ParticleSystemProxy : public scene::CParticleSystemSceneNode
|
||||
{
|
||||
protected:
|
||||
@ -19,18 +19,18 @@ protected:
|
||||
float size_increase_factor, track_x, track_z, track_x_len, track_z_len;
|
||||
float m_color_from[3];
|
||||
float m_color_to[3];
|
||||
|
||||
|
||||
static GLuint quad_vertex_buffer;
|
||||
|
||||
|
||||
GLuint texture;
|
||||
unsigned count;
|
||||
static void SimpleParticleVAOBind(GLuint PositionBuffer);
|
||||
static void FlipParticleVAOBind(GLuint PositionBuffer, GLuint QuaternionBuffer);
|
||||
static void SimpleSimulationBind(GLuint PositionBuffer, GLuint InitialValuesBuffer);
|
||||
static void HeightmapSimulationBind(GLuint PositionBuffer, GLuint InitialValuesBuffer);
|
||||
|
||||
|
||||
void generateVAOs();
|
||||
|
||||
|
||||
void simulateHeightmap();
|
||||
void simulateNoHeightmap();
|
||||
void drawFlip();
|
||||
@ -46,14 +46,14 @@ public:
|
||||
const core::vector3df& position = core::vector3df(0, 0, 0),
|
||||
const core::vector3df& rotation = core::vector3df(0, 0, 0),
|
||||
const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f));
|
||||
|
||||
|
||||
ParticleSystemProxy(bool createDefaultEmitter,
|
||||
ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
|
||||
const core::vector3df& position,
|
||||
const core::vector3df& rotation,
|
||||
const core::vector3df& scale);
|
||||
~ParticleSystemProxy();
|
||||
|
||||
|
||||
virtual void setEmitter(scene::IParticleEmitter* emitter);
|
||||
virtual void render();
|
||||
virtual void OnRegisterSceneNode();
|
||||
@ -66,5 +66,5 @@ public:
|
||||
void setHeightmap(const std::vector<std::vector<float> >&, float, float, float, float);
|
||||
void setFlip();
|
||||
};
|
||||
|
||||
|
||||
#endif // GPUPARTICLES_H
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "graphics/post_processing.hpp"
|
||||
#include "graphics/referee.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/shadow_importance.hpp"
|
||||
#include "graphics/stkanimatedmesh.hpp"
|
||||
#include "graphics/stkbillboard.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
@ -111,7 +110,8 @@ IrrDriver::IrrDriver()
|
||||
m_post_processing = NULL;
|
||||
m_wind = new Wind();
|
||||
m_mipviz = m_wireframe = m_normals = m_ssaoviz = \
|
||||
m_lightviz = m_shadowviz = m_distortviz = 0;
|
||||
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = 0;
|
||||
SkyboxCubeMap = 0;
|
||||
} // IrrDriver
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -436,16 +436,24 @@ void IrrDriver::initDevice()
|
||||
|
||||
GLMajorVersion = 2;
|
||||
GLMinorVersion = 1;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &GLMajorVersion);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &GLMinorVersion);
|
||||
// Call to glGetIntegerv should not be made if --no-graphics is used
|
||||
if(!ProfileWorld::isNoGraphics())
|
||||
{
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &GLMajorVersion);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &GLMinorVersion);
|
||||
}
|
||||
Log::info("IrrDriver", "OPENGL VERSION IS %d.%d", GLMajorVersion, GLMinorVersion);
|
||||
m_glsl = (GLMajorVersion > 3 || (GLMajorVersion == 3 && GLMinorVersion >= 1));
|
||||
|
||||
// Parse extensions
|
||||
hasVSLayer = false;
|
||||
const GLubyte *extensions = glGetString(GL_EXTENSIONS);
|
||||
if (extensions && strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL)
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -463,15 +471,11 @@ void IrrDriver::initDevice()
|
||||
if (m_glsl)
|
||||
{
|
||||
Log::info("irr_driver", "GLSL supported.");
|
||||
|
||||
// Order matters, create RTTs as soon as possible, as they are the largest blocks.
|
||||
m_rtts = new RTT();
|
||||
}
|
||||
// m_glsl might be reset in rtt if an error occurs.
|
||||
if(m_glsl)
|
||||
{
|
||||
m_shaders = new Shaders();
|
||||
m_shadow_importance = new ShadowImportance();
|
||||
|
||||
m_mrt.clear();
|
||||
m_mrt.reallocate(2);
|
||||
@ -841,8 +845,7 @@ scene::IMesh *IrrDriver::getMesh(const std::string &filename)
|
||||
filename.c_str());
|
||||
return NULL;
|
||||
}
|
||||
scene::IMeshManipulator *mani = irr_driver->getVideoDriver()->getMeshManipulator();
|
||||
return mani->createMeshWelded(am->getMesh(0));
|
||||
return am->getMesh(0);
|
||||
} // getMesh
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -1202,7 +1205,7 @@ void IrrDriver::suppressSkyBox()
|
||||
{
|
||||
SkyboxTextures.clear();
|
||||
SphericalHarmonicsTextures.clear();
|
||||
if (SkyboxCubeMap)
|
||||
if ((SkyboxCubeMap) && (!ProfileWorld::isNoGraphics()))
|
||||
glDeleteTextures(1, &SkyboxCubeMap);
|
||||
SkyboxCubeMap = 0;
|
||||
}
|
||||
@ -1552,7 +1555,22 @@ video::ITexture* IrrDriver::applyMask(video::ITexture* texture,
|
||||
mask->drop();
|
||||
return t;
|
||||
} // applyMask
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void IrrDriver::onLoadWorld()
|
||||
{
|
||||
if (m_glsl)
|
||||
{
|
||||
const core::recti &viewport = Camera::getCamera(0)->getViewport();
|
||||
size_t width = viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, height = viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y;
|
||||
m_rtts = new RTT(width, height);
|
||||
}
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
void IrrDriver::onUnloadWorld()
|
||||
{
|
||||
delete m_rtts;
|
||||
m_rtts = NULL;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets the ambient light.
|
||||
* \param light The colour of the light to set.
|
||||
@ -1628,7 +1646,7 @@ void IrrDriver::displayFPS()
|
||||
|
||||
if (UserConfigParams::m_artist_debug_mode)
|
||||
{
|
||||
sprintf(buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) KTris - LightDst : ~%d",
|
||||
sprintf(buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) - LightDst : ~%d",
|
||||
min, fps, max, object_count[SOLID_NORMAL_AND_DEPTH_PASS], object_count[SOLID_NORMAL_AND_DEPTH_PASS], object_count[TRANSPARENT_PASS], m_last_light_bucket_distance);
|
||||
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
|
||||
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
|
||||
@ -2306,7 +2324,7 @@ void IrrDriver::applyObjectPassShader()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy,
|
||||
scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, float radius,
|
||||
float r, float g, float b, bool sun, scene::ISceneNode* parent)
|
||||
{
|
||||
if (m_glsl)
|
||||
@ -2315,7 +2333,7 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy,
|
||||
LightNode *light = NULL;
|
||||
|
||||
if (!sun)
|
||||
light = new LightNode(m_scene_manager, parent, energy, r, g, b);
|
||||
light = new LightNode(m_scene_manager, parent, energy, radius, r, g, b);
|
||||
else
|
||||
light = new SunNode(m_scene_manager, parent, r, g, b);
|
||||
|
||||
@ -2363,3 +2381,24 @@ void IrrDriver::clearLights()
|
||||
|
||||
m_lights.clear();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
GLuint IrrDriver::getRenderTargetTexture(TypeRTT which)
|
||||
{
|
||||
return m_rtts->getRenderTarget(which);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
FrameBuffer& IrrDriver::getFBO(TypeFBO which)
|
||||
{
|
||||
return m_rtts->getFBO(which);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
GLuint IrrDriver::getDepthStencilTexture()
|
||||
{
|
||||
return m_rtts->getDepthStencilTexture();
|
||||
}
|
@ -36,6 +36,15 @@
|
||||
#include <SColor.h>
|
||||
#include "IrrlichtDevice.h"
|
||||
#include "ISkinnedMesh.h"
|
||||
//#include "graphics/rtts.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "utils/aligned_array.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene { class ISceneManager; class IMesh; class IAnimatedMeshSceneNode; class IAnimatedMesh;
|
||||
@ -45,17 +54,9 @@ namespace irr
|
||||
}
|
||||
using namespace irr;
|
||||
|
||||
class RTT;
|
||||
class FrameBuffer;
|
||||
class ShadowImportanceProvider;
|
||||
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "utils/aligned_array.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
class AbstractKart;
|
||||
class Camera;
|
||||
class PerCameraNode;
|
||||
@ -74,6 +75,35 @@ enum STKRenderingPass
|
||||
PASS_COUNT,
|
||||
};
|
||||
|
||||
enum TypeFBO
|
||||
{
|
||||
FBO_SSAO,
|
||||
FBO_NORMAL_AND_DEPTHS,
|
||||
FBO_COMBINED_TMP1_TMP2,
|
||||
FBO_COLORS,
|
||||
FBO_LOG_LUMINANCE,
|
||||
FBO_MLAA_COLORS,
|
||||
FBO_TMP1_WITH_DS,
|
||||
FBO_TMP2_WITH_DS,
|
||||
FBO_TMP4,
|
||||
FBO_LINEAR_DEPTH,
|
||||
FBO_HALF1,
|
||||
FBO_HALF2,
|
||||
FBO_QUARTER1,
|
||||
FBO_QUARTER2,
|
||||
FBO_EIGHTH1,
|
||||
FBO_EIGHTH2,
|
||||
FBO_DISPLACE,
|
||||
FBO_BLOOM_1024,
|
||||
FBO_BLOOM_512,
|
||||
FBO_TMP_512,
|
||||
FBO_BLOOM_256,
|
||||
FBO_TMP_256,
|
||||
FBO_BLOOM_128,
|
||||
FBO_TMP_128,
|
||||
FBO_COUNT
|
||||
};
|
||||
|
||||
enum QueryPerf
|
||||
{
|
||||
Q_SOLID_PASS1,
|
||||
@ -84,6 +114,7 @@ enum QueryPerf
|
||||
Q_TRANSPARENT,
|
||||
Q_PARTICLES,
|
||||
Q_DISPLACEMENT,
|
||||
Q_DOF,
|
||||
Q_GODRAYS,
|
||||
Q_BLOOM,
|
||||
Q_TONEMAP,
|
||||
@ -91,6 +122,57 @@ enum QueryPerf
|
||||
Q_LAST
|
||||
};
|
||||
|
||||
enum TypeRTT
|
||||
{
|
||||
RTT_TMP1 = 0,
|
||||
RTT_TMP2,
|
||||
RTT_TMP3,
|
||||
RTT_TMP4,
|
||||
RTT_LINEAR_DEPTH,
|
||||
RTT_NORMAL_AND_DEPTH,
|
||||
RTT_COLOR,
|
||||
RTT_LOG_LUMINANCE,
|
||||
|
||||
RTT_HALF1,
|
||||
RTT_HALF2,
|
||||
|
||||
RTT_QUARTER1,
|
||||
RTT_QUARTER2,
|
||||
// RTT_QUARTER3,
|
||||
// RTT_QUARTER4,
|
||||
|
||||
RTT_EIGHTH1,
|
||||
RTT_EIGHTH2,
|
||||
|
||||
// RTT_SIXTEENTH1,
|
||||
// RTT_SIXTEENTH2,
|
||||
|
||||
RTT_SSAO,
|
||||
|
||||
// RTT_COLLAPSE,
|
||||
// RTT_COLLAPSEH,
|
||||
// RTT_COLLAPSEV,
|
||||
// RTT_COLLAPSEH2,
|
||||
// RTT_COLLAPSEV2,
|
||||
// RTT_WARPH,
|
||||
// RTT_WARPV,
|
||||
|
||||
// RTT_HALF_SOFT,
|
||||
|
||||
RTT_DISPLACE,
|
||||
RTT_MLAA_COLORS,
|
||||
|
||||
RTT_BLOOM_1024,
|
||||
RTT_BLOOM_512,
|
||||
RTT_TMP_512,
|
||||
RTT_BLOOM_256,
|
||||
RTT_TMP_256,
|
||||
RTT_BLOOM_128,
|
||||
RTT_TMP_128,
|
||||
|
||||
RTT_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief class that creates the irrLicht device and offers higher-level
|
||||
* ways to manage the 3D scene
|
||||
@ -121,9 +203,10 @@ private:
|
||||
float m_lwhite;
|
||||
/** RTTs. */
|
||||
RTT *m_rtts;
|
||||
/** Shadow importance. */
|
||||
ShadowImportance *m_shadow_importance;
|
||||
std::vector<core::matrix4> sun_ortho_matrix;
|
||||
core::vector3df rh_extend;
|
||||
core::matrix4 rh_matrix;
|
||||
core::matrix4 rsm_matrix;
|
||||
|
||||
/** Additional details to be shown in case that a texture is not found.
|
||||
* This is used to specify details like: "while loading kart '...'" */
|
||||
@ -228,6 +311,9 @@ private:
|
||||
bool m_mipviz;
|
||||
bool m_normals;
|
||||
bool m_ssaoviz;
|
||||
bool m_rsm;
|
||||
bool m_rh;
|
||||
bool m_gi;
|
||||
bool m_shadowviz;
|
||||
bool m_lightviz;
|
||||
bool m_distortviz;
|
||||
@ -276,7 +362,7 @@ private:
|
||||
void renderParticles();
|
||||
void computeSunVisibility();
|
||||
void renderScene(scene::ICameraSceneNode * const camnode, std::vector<GlowData>& glows, float dt, bool hasShadows);
|
||||
void computeCameraMatrix(scene::ICameraSceneNode * const camnode);
|
||||
void computeCameraMatrix(scene::ICameraSceneNode * const camnode, size_t width, size_t height);
|
||||
void renderShadows();
|
||||
void renderGlow(std::vector<GlowData>& glows);
|
||||
void renderSSAO();
|
||||
@ -477,9 +563,9 @@ public:
|
||||
return (m_shaders == NULL ? NULL : m_shaders->m_callbacks[num]);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
inline GLuint getRenderTargetTexture(TypeRTT which) { return m_rtts->getRenderTarget(which); }
|
||||
inline GLuint getFBO(TypeFBO which) { return m_rtts->getFBO(which); }
|
||||
inline GLuint getDepthStencilTexture() { return m_rtts->getDepthStencilTexture(); }
|
||||
GLuint getRenderTargetTexture(TypeRTT which);
|
||||
FrameBuffer& getFBO(TypeFBO which);
|
||||
GLuint getDepthStencilTexture();
|
||||
// ------------------------------------------------------------------------
|
||||
inline bool isGLSL() const { return m_glsl; }
|
||||
// ------------------------------------------------------------------------
|
||||
@ -493,6 +579,9 @@ public:
|
||||
m_mipviz = false;
|
||||
m_normals = false;
|
||||
m_ssaoviz = false;
|
||||
m_rsm = false;
|
||||
m_rh = false;
|
||||
m_gi = false;
|
||||
m_shadowviz = false;
|
||||
m_lightviz = false;
|
||||
m_distortviz = false;
|
||||
@ -514,6 +603,18 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
bool getSSAOViz() { return m_ssaoviz; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleRSM() { m_rsm = !m_rsm; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getRSM() { return m_rsm; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleRH() { m_rh = !m_rh; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getRH() { return m_rh; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleGI() { m_gi = !m_gi; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getGI() { return m_gi; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleShadowViz() { m_shadowviz = !m_shadowviz; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getShadowViz() { return m_shadowviz; }
|
||||
@ -563,8 +664,8 @@ public:
|
||||
void applyObjectPassShader();
|
||||
void applyObjectPassShader(scene::ISceneNode * const node, bool rimlit = false);
|
||||
// ------------------------------------------------------------------------
|
||||
scene::ISceneNode *addLight(const core::vector3df &pos, float energy = 1., float r = 1.0f,
|
||||
float g = 1.0f, float b = 1.0f, bool sun = false, scene::ISceneNode* parent = NULL);
|
||||
scene::ISceneNode *addLight(const core::vector3df &pos, float energy, float radius, float r,
|
||||
float g, float b, bool sun = false, scene::ISceneNode* parent = NULL);
|
||||
// ------------------------------------------------------------------------
|
||||
void clearLights();
|
||||
// ------------------------------------------------------------------------
|
||||
@ -590,6 +691,10 @@ public:
|
||||
} // addDebugMesh
|
||||
|
||||
#endif
|
||||
|
||||
void onLoadWorld();
|
||||
void onUnloadWorld();
|
||||
|
||||
// --------------------- RTT --------------------
|
||||
/**
|
||||
* Class that provides RTT (currently, only when no other 3D rendering
|
||||
|
@ -34,10 +34,11 @@ using namespace core;
|
||||
aabbox3df LightNode::box;
|
||||
|
||||
|
||||
LightNode::LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float e, float r, float g, float b):
|
||||
LightNode::LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float e, float d, float r, float g, float b):
|
||||
ISceneNode(parent == NULL ? mgr->getRootSceneNode() : parent, mgr, -1)
|
||||
{
|
||||
m_energy = e;
|
||||
m_radius = d;
|
||||
m_energy_multiplier = 1.0f;
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
|
@ -40,7 +40,7 @@ class LightNode: public scene::ISceneNode
|
||||
#endif
|
||||
|
||||
public:
|
||||
LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float energy, float r, float g, float b);
|
||||
LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float energy, float d, float r, float g, float b);
|
||||
virtual ~LightNode();
|
||||
|
||||
virtual void render() OVERRIDE;
|
||||
@ -55,7 +55,7 @@ public:
|
||||
virtual u32 getMaterialCount() const OVERRIDE { return 1; }
|
||||
virtual bool isPointLight() { return true; }
|
||||
|
||||
//float getRadius() const { return m_radius; }
|
||||
float getRadius() const { return m_radius; }
|
||||
float getEnergy() const { return m_energy; }
|
||||
float getEffectiveEnergy() const { return m_energy_multiplier * m_energy; }
|
||||
core::vector3df getColor() const { return core::vector3df(m_color[0], m_color[1], m_color[2]); }
|
||||
@ -66,7 +66,7 @@ public:
|
||||
protected:
|
||||
static core::aabbox3df box;
|
||||
|
||||
//float m_radius;
|
||||
float m_radius;
|
||||
float m_color[3];
|
||||
float m_energy;
|
||||
|
||||
|
@ -54,6 +54,7 @@ const unsigned int VCLAMP = 2;
|
||||
*/
|
||||
Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SOLID;
|
||||
m_deprecated = deprecated;
|
||||
|
||||
node->get("name", &m_texname);
|
||||
@ -73,26 +74,20 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
node->get("clampv", &b); if (b) m_clamp_tex |= VCLAMP; //blender 2.4 style
|
||||
node->get("clampV", &b); if (b) m_clamp_tex |= VCLAMP; //blender 2.5 style
|
||||
|
||||
node->get("transparency", &m_alpha_testing );
|
||||
node->get("lightmap", &m_lightmap );
|
||||
node->get("additive-lightmap",&m_additive_lightmap );
|
||||
|
||||
|
||||
std::string s;
|
||||
node->get("adjust-image", &s );
|
||||
if(s=="premultiply")
|
||||
m_adjust_image = ADJ_PREMUL;
|
||||
else if (s=="divide")
|
||||
m_adjust_image = ADJ_DIV;
|
||||
else if (s=="" || s=="none")
|
||||
m_adjust_image = ADJ_NONE;
|
||||
else
|
||||
Log::warn("material",
|
||||
"Incorrect adjust-image specification: '%s' - ignored.",
|
||||
s.c_str());
|
||||
node->get("alpha", &m_alpha_blending );
|
||||
node->get("light", &m_lighting );
|
||||
//node->get("adjust-image", &s );
|
||||
//if(s=="premultiply")
|
||||
// m_adjust_image = ADJ_PREMUL;
|
||||
//else if (s=="divide")
|
||||
// m_adjust_image = ADJ_DIV;
|
||||
//else if (s=="" || s=="none")
|
||||
// m_adjust_image = ADJ_NONE;
|
||||
//else
|
||||
// Log::warn("material",
|
||||
// "Incorrect adjust-image specification: '%s' - ignored.",
|
||||
// s.c_str());
|
||||
|
||||
node->get("smooth-reflection",&m_smooth_reflection_shader);
|
||||
node->get("high-adhesion", &m_high_tire_adhesion);
|
||||
node->get("reset", &m_drive_reset );
|
||||
|
||||
@ -135,7 +130,6 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
node->get("surface", &m_surface );
|
||||
node->get("ignore", &m_ignore );
|
||||
|
||||
node->get("additive", &m_add );
|
||||
node->get("max-speed", &m_max_speed_fraction);
|
||||
node->get("slowdown-time", &m_slowdown_time );
|
||||
node->get("backface-culling", &m_backface_culling );
|
||||
@ -160,152 +154,199 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
}
|
||||
|
||||
|
||||
s="";
|
||||
node->get("graphical-effect", &s);
|
||||
|
||||
if (s == "water")
|
||||
s = "";
|
||||
if (node->get("shader", &s))
|
||||
{
|
||||
// For backwards compatibility only, eventually remove
|
||||
m_water_splash = true;
|
||||
}
|
||||
else if (s == "bubble")
|
||||
{
|
||||
m_graphical_effect = GE_BUBBLE;
|
||||
}
|
||||
else if (s == "grass")
|
||||
{
|
||||
m_graphical_effect = GE_GRASS;
|
||||
m_grass_speed = 1.5f;
|
||||
m_grass_amplitude = 0.25f;
|
||||
node->get("grass-speed", &m_grass_speed);
|
||||
node->get("grass-amplitude", &m_grass_amplitude);
|
||||
}
|
||||
else if (s == "water_shader")
|
||||
{
|
||||
m_graphical_effect = GE_WATER_SHADER;
|
||||
node->get("water-shader-speed-1", &m_water_shader_speed_1);
|
||||
node->get("water-shader-speed-2", &m_water_shader_speed_2);
|
||||
}
|
||||
else if (s == "normal_map")
|
||||
{
|
||||
m_graphical_effect = GE_NORMAL_MAP;
|
||||
node->get("normal-map", &m_normal_map_tex);
|
||||
node->get("normal-light-map", &m_normal_map_shader_lightmap);
|
||||
|
||||
// TODO: add support for parallax and height maps?
|
||||
/*
|
||||
else if (node->get("normal-heightmap", &m_normal_map_tex))
|
||||
if (s == "solid")
|
||||
{
|
||||
m_is_heightmap = true;
|
||||
m_normal_map = true;
|
||||
m_shader_type = SHADERTYPE_SOLID;
|
||||
}
|
||||
else if (node->get("parallax-map", &m_normal_map_tex))
|
||||
else if (s == "unlit")
|
||||
{
|
||||
m_parallax_map = true;
|
||||
m_parallax_height = 0.2f;
|
||||
node->get("parallax-height", &m_parallax_height);
|
||||
m_shader_type = SHADERTYPE_SOLID_UNLIT;
|
||||
}
|
||||
else if (node->get("parallax-heightmap", &m_normal_map_tex))
|
||||
else if (s == "additive")
|
||||
{
|
||||
m_is_heightmap = true;
|
||||
m_parallax_map = true;
|
||||
m_parallax_height = 0.2f;
|
||||
node->get("parallax-height", &m_parallax_height);
|
||||
m_shader_type = SHADERTYPE_ADDITIVE;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if (s == "spheremap")
|
||||
{
|
||||
m_graphical_effect = GE_SPHERE_MAP;
|
||||
}
|
||||
else if (s == "skybox")
|
||||
{
|
||||
m_graphical_effect = GE_SKYBOX;
|
||||
}
|
||||
else if (s == "splatting")
|
||||
{
|
||||
m_graphical_effect = GE_SPLATTING;
|
||||
node->get("splatting-texture-1", &m_splatting_texture_1);
|
||||
node->get("splatting-texture-2", &m_splatting_texture_2);
|
||||
node->get("splatting-texture-3", &m_splatting_texture_3);
|
||||
node->get("splatting-texture-4", &m_splatting_texture_4);
|
||||
}
|
||||
else if (s == "caustics")
|
||||
{
|
||||
m_graphical_effect = GE_CAUSTICS;
|
||||
}
|
||||
else if (s == "none")
|
||||
{
|
||||
}
|
||||
else if (s != "")
|
||||
{
|
||||
Log::warn("material",
|
||||
"Invalid graphical effect specification: '%s' - ignored.",
|
||||
s.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_graphical_effect = GE_NONE;
|
||||
}
|
||||
|
||||
|
||||
// BACKWARDS COMPATIBILITY, remove eventually
|
||||
bool use_normal_map = false;
|
||||
node->get("use-normal-map", &use_normal_map);
|
||||
|
||||
if (use_normal_map)
|
||||
{
|
||||
if (node->get("normal-map", &m_normal_map_tex))
|
||||
else if (s == "alphatest")
|
||||
{
|
||||
m_graphical_effect = GE_NORMAL_MAP;
|
||||
m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
}
|
||||
else if (s == "alphablend")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_ALPHA_BLEND;
|
||||
}
|
||||
else if (s == "spheremap")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SPHERE_MAP;
|
||||
}
|
||||
else if (s == "water_shader")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_WATER;
|
||||
node->get("water-shader-speed-1", &m_water_shader_speed_1);
|
||||
node->get("water-shader-speed-2", &m_water_shader_speed_2);
|
||||
}
|
||||
else if (s == "grass")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_VEGETATION;
|
||||
m_grass_speed = 1.5f;
|
||||
m_grass_amplitude = 0.25f;
|
||||
node->get("grass-speed", &m_grass_speed);
|
||||
node->get("grass-amplitude", &m_grass_amplitude);
|
||||
}
|
||||
else if (s == "splatting")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SPLATTING;
|
||||
node->get("splatting-texture-1", &m_splatting_texture_1);
|
||||
node->get("splatting-texture-2", &m_splatting_texture_2);
|
||||
node->get("splatting-texture-3", &m_splatting_texture_3);
|
||||
node->get("splatting-texture-4", &m_splatting_texture_4);
|
||||
}
|
||||
else if (s == "bubble")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_BUBBLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("material",
|
||||
"Could not find normal map image in materials.xml");
|
||||
Log::warn("Material", "Unknown shader type <%s> for <%s>", s.c_str(), m_texname.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// BACKWARS COMPATIBILITY, EVENTUALLY REMOVE
|
||||
|
||||
bool b = false;
|
||||
node->get("additive", &b);
|
||||
if (b)
|
||||
m_shader_type = SHADERTYPE_ADDITIVE;
|
||||
|
||||
b = false;
|
||||
node->get("transparency", &b);
|
||||
if (b)
|
||||
m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
|
||||
//node->get("lightmap", &m_lightmap);
|
||||
|
||||
b = false;
|
||||
node->get("alpha", &b);
|
||||
if (b)
|
||||
m_shader_type = SHADERTYPE_ALPHA_BLEND;
|
||||
|
||||
b = true;
|
||||
node->get("light", &b);
|
||||
if (!b)
|
||||
m_shader_type = SHADERTYPE_SOLID_UNLIT;
|
||||
|
||||
b = false;
|
||||
node->get("smooth-reflection", &b);
|
||||
if (b)
|
||||
m_shader_type = SHADERTYPE_SPHERE_MAP;
|
||||
|
||||
|
||||
if (node->get("compositing", &s))
|
||||
{
|
||||
if (s == "blend") m_shader_type = SHADERTYPE_ALPHA_BLEND;
|
||||
else if (s == "test") m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
else if (s == "additive") m_shader_type = SHADERTYPE_ADDITIVE;
|
||||
else if (s == "coverage") m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
else if (s != "none")
|
||||
Log::warn("material", "Unknown compositing mode '%s'", s.c_str());
|
||||
}
|
||||
|
||||
node->get("normal-light-map", &m_normal_map_shader_lightmap);
|
||||
s = "";
|
||||
node->get("graphical-effect", &s);
|
||||
|
||||
if (s == "water")
|
||||
{
|
||||
m_water_splash = true;
|
||||
}
|
||||
else if (s == "bubble")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_BUBBLE;
|
||||
}
|
||||
else if (s == "grass")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_VEGETATION;
|
||||
m_grass_speed = 1.5f;
|
||||
m_grass_amplitude = 0.25f;
|
||||
node->get("grass-speed", &m_grass_speed);
|
||||
node->get("grass-amplitude", &m_grass_amplitude);
|
||||
}
|
||||
else if (s == "water_shader")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_WATER;
|
||||
node->get("water-shader-speed-1", &m_water_shader_speed_1);
|
||||
node->get("water-shader-speed-2", &m_water_shader_speed_2);
|
||||
}
|
||||
else if (s == "normal_map")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SOLID;
|
||||
node->get("normal-map", &m_normal_map_tex);
|
||||
}
|
||||
else if (s == "spheremap")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SPHERE_MAP;
|
||||
}
|
||||
else if (s == "splatting")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SPLATTING;
|
||||
node->get("splatting-texture-1", &m_splatting_texture_1);
|
||||
node->get("splatting-texture-2", &m_splatting_texture_2);
|
||||
node->get("splatting-texture-3", &m_splatting_texture_3);
|
||||
node->get("splatting-texture-4", &m_splatting_texture_4);
|
||||
}
|
||||
else if (s == "none")
|
||||
{
|
||||
}
|
||||
else if (s != "")
|
||||
{
|
||||
Log::warn("material",
|
||||
"Invalid graphical effect specification: '%s' - ignored.",
|
||||
s.c_str());
|
||||
}
|
||||
|
||||
bool use_normal_map = false;
|
||||
node->get("use-normal-map", &use_normal_map);
|
||||
|
||||
if (use_normal_map)
|
||||
{
|
||||
if (node->get("normal-map", &m_normal_map_tex))
|
||||
{
|
||||
//m_graphical_effect = GE_NORMAL_MAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("material",
|
||||
"Could not find normal map image in materials.xml");
|
||||
}
|
||||
}
|
||||
|
||||
bool sphere_map = false;
|
||||
node->get("sphere", &sphere_map);
|
||||
if (sphere_map)
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SPHERE_MAP;
|
||||
}
|
||||
|
||||
bool water_shader = false;
|
||||
node->get("water-shader", &water_shader);
|
||||
if (water_shader)
|
||||
{
|
||||
m_shader_type = SHADERTYPE_WATER;
|
||||
node->get("water-shader-speed-1", &m_water_shader_speed_1);
|
||||
node->get("water-shader-speed-2", &m_water_shader_speed_2);
|
||||
}
|
||||
|
||||
// ---- End backwards compatibility
|
||||
}
|
||||
|
||||
|
||||
// BACKWARDS COMPATIBILITY, remove eventually
|
||||
bool sphere_map = false;
|
||||
node->get("sphere", &sphere_map );
|
||||
if (sphere_map)
|
||||
if (m_disable_z_write && m_shader_type != SHADERTYPE_ALPHA_BLEND && m_shader_type != SHADERTYPE_ADDITIVE)
|
||||
{
|
||||
m_graphical_effect = GE_SPHERE_MAP;
|
||||
}
|
||||
|
||||
|
||||
if (node->get("compositing", &s))
|
||||
{
|
||||
if (s == "blend") m_alpha_blending = true;
|
||||
else if (s == "test") m_alpha_testing = true;
|
||||
else if (s == "additive") m_add = true;
|
||||
// backwards compatibility only, no longer supported
|
||||
else if (s == "coverage") m_alpha_testing = true;
|
||||
else if (s != "none")
|
||||
Log::warn("material", "Unknown compositing mode '%s'",
|
||||
s.c_str());
|
||||
}
|
||||
|
||||
if (m_disable_z_write && !m_alpha_blending && !m_add)
|
||||
{
|
||||
Log::warn("material", "Disabling writes to z buffer only makes sense when compositing is blending or additive (for %s)", m_texname.c_str());
|
||||
Log::debug("material", "Disabling writes to z buffer only makes sense when compositing is blending or additive (for %s)", m_texname.c_str());
|
||||
m_disable_z_write = false;
|
||||
}
|
||||
|
||||
bool water_shader = false;
|
||||
node->get("water-shader", &water_shader);
|
||||
if (water_shader)
|
||||
{
|
||||
// BACKWARDS COMPATIBILITY, eventually remove
|
||||
m_graphical_effect = GE_WATER_SHADER;
|
||||
node->get("water-shader-speed-1", &m_water_shader_speed_1);
|
||||
node->get("water-shader-speed-2", &m_water_shader_speed_2);
|
||||
}
|
||||
|
||||
// Terrain-specifc sound effect
|
||||
const unsigned int children_count = node->getNumNodes();
|
||||
for (unsigned int i=0; i<children_count; i++)
|
||||
@ -376,14 +417,10 @@ void Material::init(unsigned int index)
|
||||
{
|
||||
m_index = index;
|
||||
m_clamp_tex = 0;
|
||||
m_alpha_testing = false;
|
||||
m_lightmap = false;
|
||||
m_additive_lightmap = false;
|
||||
m_adjust_image = ADJ_NONE;
|
||||
m_alpha_blending = false;
|
||||
m_lighting = true;
|
||||
m_shader_type = SHADERTYPE_SOLID;
|
||||
//m_lightmap = false;
|
||||
//m_adjust_image = ADJ_NONE;
|
||||
m_backface_culling = true;
|
||||
m_smooth_reflection_shader = false;
|
||||
m_high_tire_adhesion = false;
|
||||
m_below_surface = false;
|
||||
m_falling_effect = false;
|
||||
@ -391,7 +428,6 @@ void Material::init(unsigned int index)
|
||||
m_ignore = false;
|
||||
m_drive_reset = false;
|
||||
m_collision_reaction = NORMAL;
|
||||
m_add = false;
|
||||
m_disable_z_write = false;
|
||||
m_water_shader_speed_1 = 6.6667f;
|
||||
m_water_shader_speed_2 = 4.0f;
|
||||
@ -403,7 +439,6 @@ void Material::init(unsigned int index)
|
||||
m_sfx_max_speed = 30;
|
||||
m_sfx_min_pitch = 1.0f;
|
||||
m_sfx_max_pitch = 1.0f;
|
||||
m_graphical_effect = GE_NONE;
|
||||
m_zipper = false;
|
||||
m_zipper_duration = -1.0f;
|
||||
m_zipper_fade_out_time = -1.0f;
|
||||
@ -411,8 +446,6 @@ void Material::init(unsigned int index)
|
||||
m_zipper_speed_gain = -1.0f;
|
||||
m_zipper_engine_force = -1.0f;
|
||||
m_zipper_min_speed = -1.0f;
|
||||
m_parallax_map = false;
|
||||
m_is_heightmap = false;
|
||||
m_water_splash = false;
|
||||
m_is_jump_texture = false;
|
||||
m_has_gravity = false;
|
||||
@ -438,8 +471,8 @@ void Material::install(bool is_full_path, bool complain_if_not_found)
|
||||
else
|
||||
{
|
||||
m_texture = irr_driver->getTexture(full_path,
|
||||
isPreMul(),
|
||||
isPreDiv(),
|
||||
false, //isPreMul(),
|
||||
false, //isPreDiv(),
|
||||
complain_if_not_found);
|
||||
}
|
||||
|
||||
@ -659,36 +692,40 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
}
|
||||
|
||||
|
||||
int modes = 0;
|
||||
|
||||
if (!m_lighting && irr_driver->isGLSL() && !m_alpha_blending && !m_add)
|
||||
if (m_shader_type == SHADERTYPE_SOLID_UNLIT)
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
|
||||
modes++;
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->AmbientColor = video::SColor(255, 255, 255, 255);
|
||||
m->DiffuseColor = video::SColor(255, 255, 255, 255);
|
||||
m->EmissiveColor = video::SColor(255, 255, 255, 255);
|
||||
m->SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_alpha_testing)
|
||||
if (m_shader_type == SHADERTYPE_ALPHA_TEST)
|
||||
{
|
||||
m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
modes++;
|
||||
}
|
||||
if (m_alpha_blending)
|
||||
{
|
||||
//m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
|
||||
// EMT_TRANSPARENT_ALPHA_CHANNEL does include vertex color alpha into
|
||||
if (m_shader_type == SHADERTYPE_ALPHA_BLEND)
|
||||
{
|
||||
// EMT_TRANSPARENT_ALPHA_CHANNEL doesn't include vertex color alpha into
|
||||
// account, which messes up fading in/out effects. So we use the more
|
||||
// customizable EMT_ONETEXTURE_BLEND instead.
|
||||
m->MaterialType = video::EMT_ONETEXTURE_BLEND ;
|
||||
m->MaterialType = video::EMT_ONETEXTURE_BLEND;
|
||||
m->MaterialTypeParam =
|
||||
pack_textureBlendFunc(video::EBF_SRC_ALPHA,
|
||||
video::EBF_ONE_MINUS_SRC_ALPHA,
|
||||
video::EMFN_MODULATE_1X,
|
||||
video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
|
||||
|
||||
modes++;
|
||||
}
|
||||
if (m_smooth_reflection_shader)
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SPHERE_MAP)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
@ -697,58 +734,17 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||
|
||||
// sphere map + alpha blending is a supported combination so in
|
||||
// this case don't increase mode count
|
||||
if (m_alpha_blending)
|
||||
{
|
||||
m->BlendOperation = video::EBO_ADD;
|
||||
}
|
||||
else
|
||||
{
|
||||
modes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_graphical_effect == GE_SPHERE_MAP)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_SPHERE_MAP);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||
|
||||
// sphere map + alpha blending is a supported combination so in
|
||||
// this case don't increase mode count
|
||||
if (m_alpha_blending)
|
||||
{
|
||||
m->BlendOperation = video::EBO_ADD;
|
||||
}
|
||||
else
|
||||
{
|
||||
modes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_lightmap)
|
||||
{
|
||||
m->MaterialType = video::EMT_LIGHTMAP;
|
||||
modes++;
|
||||
}
|
||||
if (m_additive_lightmap)
|
||||
{
|
||||
m->MaterialType = video::EMT_LIGHTMAP_ADD;
|
||||
modes++;
|
||||
}
|
||||
//if (m_lightmap)
|
||||
//{
|
||||
// m->MaterialType = video::EMT_LIGHTMAP;
|
||||
//}
|
||||
|
||||
if (m_add)
|
||||
if (m_shader_type == SHADERTYPE_ADDITIVE)
|
||||
{
|
||||
//m->MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||
|
||||
// EMT_TRANSPARENT_ADD_COLOR does include vertex color alpha into
|
||||
// EMT_TRANSPARENT_ADD_COLOR doesn't include vertex color alpha into
|
||||
// account, which messes up fading in/out effects. So we use the
|
||||
// more customizable EMT_ONETEXTURE_BLEND instead
|
||||
m->MaterialType = video::EMT_ONETEXTURE_BLEND ;
|
||||
@ -757,39 +753,39 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
video::EMFN_MODULATE_1X,
|
||||
video::EAS_TEXTURE |
|
||||
video::EAS_VERTEX_COLOR);
|
||||
modes++;
|
||||
}
|
||||
if (m_graphical_effect == GE_NORMAL_MAP)
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SOLID && m_normal_map_tex.size() > 0)
|
||||
{
|
||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
|
||||
if (mb->getVertexType() != video::EVT_TANGENTS)
|
||||
Log::error("material", "Requiring normal map without tangent enabled mesh");
|
||||
ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
if (m_is_heightmap)
|
||||
{
|
||||
video_driver->makeNormalMapTexture( tex );
|
||||
Log::warn("material", "Requiring normal map without tangent enabled mesh for <%s>",
|
||||
m_texname.c_str());
|
||||
}
|
||||
m->setTexture(1, tex);
|
||||
|
||||
bool with_lightmap = false;
|
||||
|
||||
if (m_normal_map_shader_lightmap.size() > 0)
|
||||
else
|
||||
{
|
||||
ITexture* lm_tex = irr_driver->getTexture(m_normal_map_shader_lightmap);
|
||||
m->setTexture(2, lm_tex);
|
||||
with_lightmap = true;
|
||||
ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
m->setTexture(1, tex);
|
||||
|
||||
bool with_lightmap = false;
|
||||
|
||||
//if (m_normal_map_shader_lightmap.size() > 0)
|
||||
//{
|
||||
// ITexture* lm_tex = irr_driver->getTexture(m_normal_map_shader_lightmap);
|
||||
// m->setTexture(2, lm_tex);
|
||||
// with_lightmap = true;
|
||||
//}
|
||||
|
||||
// Material and shaders
|
||||
m->MaterialType = irr_driver->getShader(
|
||||
with_lightmap ? ES_NORMAL_MAP_LIGHTMAP : ES_NORMAL_MAP);
|
||||
m->Lighting = false;
|
||||
m->ZWriteEnable = true;
|
||||
}
|
||||
|
||||
// Material and shaders
|
||||
m->MaterialType = irr_driver->getShader(
|
||||
with_lightmap ? ES_NORMAL_MAP_LIGHTMAP : ES_NORMAL_MAP );
|
||||
m->Lighting = false;
|
||||
m->ZWriteEnable = true;
|
||||
|
||||
modes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -797,29 +793,30 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
m->setTexture(1, NULL);
|
||||
}
|
||||
}
|
||||
if (m_parallax_map)
|
||||
{
|
||||
video::ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
if (m_is_heightmap)
|
||||
{
|
||||
irr_driver->getVideoDriver()->makeNormalMapTexture( tex );
|
||||
}
|
||||
m->setTexture(1, tex);
|
||||
m->MaterialType = video::EMT_PARALLAX_MAP_SOLID;
|
||||
m->MaterialTypeParam = m_parallax_height;
|
||||
m->SpecularColor.set(0,0,0,0);
|
||||
modes++;
|
||||
}
|
||||
//if (m_parallax_map)
|
||||
//{
|
||||
// video::ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
// if (m_is_heightmap)
|
||||
// {
|
||||
// irr_driver->getVideoDriver()->makeNormalMapTexture( tex );
|
||||
// }
|
||||
// m->setTexture(1, tex);
|
||||
// m->MaterialType = video::EMT_PARALLAX_MAP_SOLID;
|
||||
// m->MaterialTypeParam = m_parallax_height;
|
||||
// m->SpecularColor.set(0,0,0,0);
|
||||
// modes++;
|
||||
//}
|
||||
|
||||
if(m_graphical_effect == GE_SKYBOX && irr_driver->isGLSL())
|
||||
{
|
||||
ITexture* tex = irr_driver->getTexture("cloud_mask.png");
|
||||
m->setTexture(1, tex);
|
||||
//if(m_graphical_effect == GE_SKYBOX && irr_driver->isGLSL())
|
||||
//{
|
||||
// ITexture* tex = irr_driver->getTexture("cloud_mask.png");
|
||||
// m->setTexture(1, tex);
|
||||
//
|
||||
//
|
||||
// m->MaterialType = irr_driver->getShader(ES_SKYBOX);
|
||||
//}
|
||||
|
||||
|
||||
m->MaterialType = irr_driver->getShader(ES_SKYBOX);
|
||||
}
|
||||
if (m_graphical_effect == GE_SPLATTING)
|
||||
if (m_shader_type == SHADERTYPE_SPLATTING)
|
||||
{
|
||||
if (irr_driver->supportsSplatting())
|
||||
{
|
||||
@ -846,19 +843,12 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
|
||||
// Material and shaders
|
||||
m->MaterialType = irr_driver->getShader(ES_SPLATTING);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_SOLID;
|
||||
}
|
||||
}
|
||||
if (m_graphical_effect == GE_CAUSTICS && irr_driver->isGLSL())
|
||||
else
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_CAUSTICS);
|
||||
|
||||
m->setTexture(1, irr_driver->getTexture(FileManager::SHADER,
|
||||
"caustics.png"));
|
||||
m->MaterialType = video::EMT_SOLID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Modify lightmap materials so that vertex colors are taken into account.
|
||||
@ -873,7 +863,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
m->SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
if (m_graphical_effect == GE_BUBBLE && mb != NULL)
|
||||
if (m_shader_type == SHADERTYPE_BUBBLE && mb != NULL)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
@ -883,18 +873,11 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
|
||||
m->MaterialType = irr_driver->getShader(ES_BUBBLES);
|
||||
m->BlendOperation = video::EBO_ADD;
|
||||
|
||||
// alpha blending and bubble shading can work together so when both are enabled
|
||||
// don't increment the 'modes' counter to not get the 'too many modes' warning
|
||||
if (!m_alpha_blending)
|
||||
{
|
||||
modes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_graphical_effect == GE_WATER_SHADER)
|
||||
if (m_shader_type == SHADERTYPE_WATER)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
@ -908,10 +891,9 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
|
||||
m->MaterialType = irr_driver->getShader(ES_WATER);
|
||||
}
|
||||
modes++;
|
||||
}
|
||||
|
||||
if (m_graphical_effect == GE_GRASS)
|
||||
if (m_shader_type == SHADERTYPE_VEGETATION)
|
||||
{
|
||||
if (UserConfigParams::m_weather_effects &&
|
||||
irr_driver->isGLSL())
|
||||
@ -923,22 +905,20 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
setAmplitude(m_grass_amplitude);
|
||||
|
||||
// Material and shaders
|
||||
if (m_alpha_testing)
|
||||
{
|
||||
//if (m_alpha_testing)
|
||||
//{
|
||||
m->MaterialType = irr_driver->getShader(ES_GRASS_REF);
|
||||
}
|
||||
else {
|
||||
m->MaterialType = irr_driver->getShader(ES_GRASS);
|
||||
m->BlendOperation = video::EBO_ADD;
|
||||
}
|
||||
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// m->MaterialType = irr_driver->getShader(ES_GRASS);
|
||||
// m->BlendOperation = video::EBO_ADD;
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
}
|
||||
}
|
||||
|
||||
if (modes > 1)
|
||||
{
|
||||
std::cerr << "[Material::setMaterialProperties] More than one main "
|
||||
"mode set for " << m_texname.c_str() << "\n";
|
||||
}
|
||||
|
||||
if (m_disable_z_write)
|
||||
@ -946,15 +926,6 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
m->ZWriteEnable = false;
|
||||
}
|
||||
|
||||
if (!m_lighting)
|
||||
{
|
||||
//m->setFlag( video::EMF_LIGHTING, false );
|
||||
m->AmbientColor = video::SColor(255, 255, 255, 255);
|
||||
m->DiffuseColor = video::SColor(255, 255, 255, 255);
|
||||
m->EmissiveColor = video::SColor(255, 255, 255, 255);
|
||||
m->SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if(UserConfigParams::m_rendering_debug)
|
||||
{
|
||||
@ -1031,7 +1002,7 @@ void Material::adjustForFog(scene::ISceneNode* parent, video::SMaterial *m,
|
||||
// to disable fog in the new pipeline, we slightly abuse the steps :
|
||||
// moving an object into the transparent pass will make it rendered
|
||||
// above fog and thus unaffected by it
|
||||
if (use_fog && !m_fog && !m_alpha_blending && !m_add)
|
||||
if (use_fog && !m_fog && m_shader_type != SHADERTYPE_ALPHA_BLEND && m_shader_type != SHADERTYPE_ADDITIVE)
|
||||
{
|
||||
m->ZWriteEnable = true;
|
||||
m->MaterialType = video::EMT_ONETEXTURE_BLEND;
|
||||
|
@ -46,17 +46,21 @@ class ParticleKind;
|
||||
class Material : public NoCopy
|
||||
{
|
||||
public:
|
||||
enum GraphicalEffect {GE_NONE,
|
||||
/** Effect where the UV texture is moved in a wave pattern */
|
||||
GE_BUBBLE,
|
||||
/** Effect that makes grass wave as in the wind */
|
||||
GE_GRASS,
|
||||
GE_WATER_SHADER,
|
||||
GE_SPHERE_MAP,
|
||||
GE_SPLATTING,
|
||||
GE_SKYBOX,
|
||||
GE_NORMAL_MAP,
|
||||
GE_CAUSTICS};
|
||||
enum ShaderType
|
||||
{
|
||||
SHADERTYPE_SOLID,
|
||||
SHADERTYPE_ALPHA_TEST,
|
||||
SHADERTYPE_ALPHA_BLEND,
|
||||
SHADERTYPE_ADDITIVE,
|
||||
SHADERTYPE_SOLID_UNLIT,
|
||||
/** Effect where the UV texture is moved in a wave pattern */
|
||||
SHADERTYPE_BUBBLE,
|
||||
/** Effect that makes grass wave as in the wind */
|
||||
SHADERTYPE_VEGETATION,
|
||||
SHADERTYPE_WATER,
|
||||
SHADERTYPE_SPHERE_MAP,
|
||||
SHADERTYPE_SPLATTING
|
||||
};
|
||||
|
||||
enum ParticleConditions
|
||||
{
|
||||
@ -82,7 +86,9 @@ private:
|
||||
/** Name of a special sfx to play when a kart is on this terrain, or
|
||||
* "" if no special sfx exists. */
|
||||
std::string m_sfx_name;
|
||||
GraphicalEffect m_graphical_effect;
|
||||
|
||||
ShaderType m_shader_type;
|
||||
|
||||
/** Set if being on this surface means being under some other mesh.
|
||||
* This is used to simulate that a kart is in water: the ground under
|
||||
* the water is marked as 'm_below_surface', which will then trigger a raycast
|
||||
@ -117,11 +123,11 @@ private:
|
||||
bool m_has_gravity;
|
||||
|
||||
/** Speed of the 'main' wave in the water shader. Only used if
|
||||
m_graphical_effect == WATER_SHADER */
|
||||
m_shader_type == SHDERTYPE_WATER */
|
||||
float m_water_shader_speed_1;
|
||||
|
||||
/** Speed of the 'secondary' waves in the water shader. Only used if
|
||||
m_graphical_effect == WATER_SHADER */
|
||||
m_shader_type == SHADERTYPE_WATER */
|
||||
float m_water_shader_speed_2;
|
||||
|
||||
/** If a kart is rescued when crashing into this surface. */
|
||||
@ -130,13 +136,13 @@ private:
|
||||
/** Particles to show on touch */
|
||||
std::string m_collision_particles;
|
||||
|
||||
/** If m_shader_type == SHADERTYPE_VEGETATION */
|
||||
float m_grass_speed;
|
||||
float m_grass_amplitude;
|
||||
|
||||
/** If the property should be ignored in the physics. Example would be
|
||||
* plants that a kart can just drive through. */
|
||||
bool m_ignore;
|
||||
bool m_add;
|
||||
|
||||
bool m_fog;
|
||||
|
||||
@ -144,21 +150,10 @@ private:
|
||||
|
||||
/** For normal maps */
|
||||
std::string m_normal_map_tex;
|
||||
std::string m_normal_map_shader_lightmap;
|
||||
|
||||
//bool m_normal_map_uv2; //!< Whether to use a second UV layer for normal map
|
||||
bool m_is_heightmap;
|
||||
bool m_parallax_map;
|
||||
float m_parallax_height;
|
||||
|
||||
/** Texture clamp bitmask */
|
||||
unsigned int m_clamp_tex;
|
||||
|
||||
bool m_lighting;
|
||||
bool m_smooth_reflection_shader;
|
||||
bool m_alpha_testing;
|
||||
bool m_alpha_blending;
|
||||
|
||||
/** True if backface culliing should be enabled. */
|
||||
bool m_backface_culling;
|
||||
|
||||
@ -167,18 +162,21 @@ private:
|
||||
|
||||
/** Some textures need to be pre-multiplied, some divided to give
|
||||
* the intended effect. */
|
||||
enum {ADJ_NONE, ADJ_PREMUL, ADJ_DIV}
|
||||
m_adjust_image;
|
||||
/** True if (blending) lightmapping is enabled for this material. */
|
||||
bool m_lightmap;
|
||||
/** True if (additive) lightmapping is enabled for this material. */
|
||||
bool m_additive_lightmap;
|
||||
//enum {ADJ_NONE, ADJ_PREMUL, ADJ_DIV}
|
||||
// m_adjust_image;
|
||||
|
||||
/** True if lightmapping is enabled for this material. */
|
||||
//bool m_lightmap;
|
||||
|
||||
/** True if the material shouldn't be "slippy" at an angle */
|
||||
bool m_high_tire_adhesion;
|
||||
|
||||
/** How much the top speed is reduced per second. */
|
||||
float m_slowdown_time;
|
||||
|
||||
/** Maximum speed at which no more slow down occurs. */
|
||||
float m_max_speed_fraction;
|
||||
|
||||
/** Minimum speed on this terrain. This is used for zippers on a ramp to
|
||||
* guarantee the right jump distance. A negative value indicates no
|
||||
* minimum speed. */
|
||||
@ -211,7 +209,7 @@ private:
|
||||
float m_zipper_fade_out_time;
|
||||
/** Additional engine force. */
|
||||
float m_zipper_engine_force;
|
||||
|
||||
|
||||
std::string m_mask;
|
||||
|
||||
/** If m_splatting is true, indicates the first splatting texture */
|
||||
@ -249,7 +247,6 @@ public:
|
||||
bool isIgnore () const { return m_ignore; }
|
||||
/** Returns true if this material is a zipper. */
|
||||
bool isZipper () const { return m_zipper; }
|
||||
bool isSphereMap () const { return m_graphical_effect == GE_SPHERE_MAP; }
|
||||
/** Returns if this material should trigger a rescue if a kart
|
||||
* is driving on it. */
|
||||
bool isDriveReset () const { return m_drive_reset; }
|
||||
@ -264,14 +261,19 @@ public:
|
||||
getTexFname () const { return m_texname; }
|
||||
int getIndex () const { return m_index; }
|
||||
|
||||
bool isTransparent () const { return m_alpha_testing || m_alpha_blending || m_add; }
|
||||
bool isTransparent () const
|
||||
{
|
||||
return m_shader_type == SHADERTYPE_ADDITIVE ||
|
||||
m_shader_type == SHADERTYPE_ALPHA_BLEND ||
|
||||
m_shader_type == SHADERTYPE_ALPHA_TEST;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this materials need pre-multiply of alpha. */
|
||||
bool isPreMul() const {return m_adjust_image==ADJ_PREMUL; }
|
||||
//bool isPreMul() const {return m_adjust_image==ADJ_PREMUL; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this materials need pre-division of alpha. */
|
||||
bool isPreDiv() const {return m_adjust_image==ADJ_DIV; }
|
||||
//bool isPreDiv() const {return m_adjust_image==ADJ_DIV; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the fraction of maximum speed on this material. */
|
||||
float getMaxSpeedFraction() const { return m_max_speed_fraction; }
|
||||
@ -281,9 +283,6 @@ public:
|
||||
* karts. So a short time will slowdown a kart much faster. */
|
||||
float getSlowDownTime() const { return m_slowdown_time; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this material should have smoke effect. */
|
||||
//bool hasSmoke () const { return m_graphical_effect==GE_SMOKE;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this material is under some other mesh and therefore
|
||||
* requires another raycast to find the surface it is under (used for
|
||||
* gfx, e.g. driving under water to find where the water splash should
|
||||
@ -341,14 +340,11 @@ public:
|
||||
* on lower speeds. A negative value indicates no minimum speed. */
|
||||
float getZipperMinSpeed() const { return m_zipper_min_speed; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool isNormalMap() const { return m_graphical_effect == GE_NORMAL_MAP; }
|
||||
|
||||
ShaderType getShaderType() const { return m_shader_type; }
|
||||
// ------------------------------------------------------------------------
|
||||
void onMadeVisible(scene::IMeshBuffer* who);
|
||||
void onHidden(scene::IMeshBuffer* who);
|
||||
void isInitiallyHidden(scene::IMeshBuffer* who);
|
||||
/** For particle system : specify if the particle should be additively blended
|
||||
*/
|
||||
bool isAlphaAdditive() const { return !m_alpha_blending; }
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -453,7 +453,10 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
||||
m_node = irr_driver->addParticleNode();
|
||||
|
||||
if (m_is_glsl)
|
||||
static_cast<ParticleSystemProxy *>(m_node)->setAlphaAdditive(type->getMaterial()->isAlphaAdditive());
|
||||
{
|
||||
bool additive = (type->getMaterial()->getShaderType() == Material::SHADERTYPE_ADDITIVE);
|
||||
static_cast<ParticleSystemProxy *>(m_node)->setAlphaAdditive(additive);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_parent != NULL)
|
||||
|
@ -261,6 +261,35 @@ void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSH
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3df &rh_extend, GLuint shr, GLuint shg, GLuint shb)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glUseProgram(FullScreenShader::GlobalIlluminationReconstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::GlobalIlluminationReconstructionShader::vao);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
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_TEXTURE1);
|
||||
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_TEXTURE2);
|
||||
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(3, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(4, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::GlobalIlluminationReconstructionShader::setUniforms(RHMatrix, rh_extend, 3, 4, 0, 1, 2);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void PostProcessing::renderSunlight()
|
||||
{
|
||||
SunLightProvider * const cb = (SunLightProvider *) irr_driver->getCallback(ES_SUNLIGHT);
|
||||
@ -317,17 +346,18 @@ void PostProcessing::renderShadowedSunlight(const std::vector<core::matrix4> &su
|
||||
}
|
||||
|
||||
|
||||
void PostProcessing::renderGaussian3Blur(GLuint in_fbo, GLuint in_tex, GLuint tmp_fbo, GLuint tmp_tex, size_t width, size_t height)
|
||||
void PostProcessing::renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary)
|
||||
{
|
||||
float inv_width = 1.0f / width, inv_height = 1.0f / height;
|
||||
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();
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fbo);
|
||||
auxiliary.Bind();
|
||||
glUseProgram(FullScreenShader::Gaussian3VBlurShader::Program);
|
||||
glBindVertexArray(FullScreenShader::Gaussian3VBlurShader::vao);
|
||||
|
||||
glUniform2f(FullScreenShader::Gaussian3VBlurShader::uniform_pixel, inv_width, inv_height);
|
||||
|
||||
setTexture(0, in_tex, GL_LINEAR, GL_LINEAR);
|
||||
setTexture(0, 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);
|
||||
glUniform1i(FullScreenShader::Gaussian3VBlurShader::uniform_tex, 0);
|
||||
@ -335,13 +365,13 @@ void PostProcessing::renderGaussian3Blur(GLuint in_fbo, GLuint in_tex, GLuint tm
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, in_fbo);
|
||||
in_fbo.Bind();
|
||||
glUseProgram(FullScreenShader::Gaussian3HBlurShader::Program);
|
||||
glBindVertexArray(FullScreenShader::Gaussian3HBlurShader::vao);
|
||||
|
||||
glUniform2f(FullScreenShader::Gaussian3HBlurShader::uniform_pixel, inv_width, inv_height);
|
||||
|
||||
setTexture(0, tmp_tex, GL_LINEAR, GL_LINEAR);
|
||||
setTexture(0, 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);
|
||||
glUniform1i(FullScreenShader::Gaussian3HBlurShader::uniform_tex, 0);
|
||||
@ -350,17 +380,18 @@ void PostProcessing::renderGaussian3Blur(GLuint in_fbo, GLuint in_tex, GLuint tm
|
||||
}
|
||||
}
|
||||
|
||||
void PostProcessing::renderGaussian6Blur(GLuint in_fbo, GLuint in_tex, GLuint tmp_fbo, GLuint tmp_tex, size_t width, size_t height)
|
||||
void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary)
|
||||
{
|
||||
float inv_width = 1.f / width, inv_height = 1.f / height;
|
||||
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();
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fbo);
|
||||
auxiliary.Bind();
|
||||
glUseProgram(FullScreenShader::Gaussian6VBlurShader::Program);
|
||||
glBindVertexArray(FullScreenShader::Gaussian6VBlurShader::vao);
|
||||
|
||||
glUniform2f(FullScreenShader::Gaussian6VBlurShader::uniform_pixel, inv_width, inv_height);
|
||||
|
||||
setTexture(0, in_tex, GL_LINEAR, GL_LINEAR);
|
||||
setTexture(0, 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);
|
||||
glUniform1i(FullScreenShader::Gaussian6VBlurShader::uniform_tex, 0);
|
||||
@ -368,13 +399,13 @@ void PostProcessing::renderGaussian6Blur(GLuint in_fbo, GLuint in_tex, GLuint tm
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, in_fbo);
|
||||
in_fbo.Bind();
|
||||
glUseProgram(FullScreenShader::Gaussian6HBlurShader::Program);
|
||||
glBindVertexArray(FullScreenShader::Gaussian6HBlurShader::vao);
|
||||
|
||||
glUniform2f(FullScreenShader::Gaussian6HBlurShader::uniform_pixel, inv_width, inv_height);
|
||||
|
||||
setTexture(0, tmp_tex, GL_LINEAR, GL_LINEAR);
|
||||
setTexture(0, 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);
|
||||
glUniform1i(FullScreenShader::Gaussian6HBlurShader::uniform_tex, 0);
|
||||
@ -383,6 +414,40 @@ void PostProcessing::renderGaussian6Blur(GLuint in_fbo, GLuint in_tex, GLuint tm
|
||||
}
|
||||
}
|
||||
|
||||
void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &auxiliary)
|
||||
{
|
||||
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();
|
||||
{
|
||||
auxiliary.Bind();
|
||||
glUseProgram(FullScreenShader::Gaussian17TapHShader::Program);
|
||||
glBindVertexArray(FullScreenShader::Gaussian17TapHShader::vao);
|
||||
|
||||
glUniform2f(FullScreenShader::Gaussian17TapHShader::uniform_pixel, inv_width, inv_height);
|
||||
|
||||
setTexture(0, 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);
|
||||
glUniform1i(FullScreenShader::Gaussian17TapHShader::uniform_tex, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
{
|
||||
in_fbo.Bind();
|
||||
glUseProgram(FullScreenShader::Gaussian17TapVShader::Program);
|
||||
glBindVertexArray(FullScreenShader::Gaussian17TapVShader::vao);
|
||||
|
||||
glUniform2f(FullScreenShader::Gaussian17TapVShader::uniform_pixel, inv_width, inv_height);
|
||||
|
||||
setTexture(0, 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);
|
||||
glUniform1i(FullScreenShader::Gaussian17TapVShader::uniform_tex, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void PostProcessing::renderPassThrough(GLuint tex)
|
||||
{
|
||||
|
||||
@ -418,16 +483,28 @@ void PostProcessing::renderSSAO()
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
// Generate linear depth buffer
|
||||
irr_driver->getFBO(FBO_LINEAR_DEPTH).Bind();
|
||||
glUseProgram(FullScreenShader::LinearizeDepthShader::Program);
|
||||
glBindVertexArray(FullScreenShader::LinearizeDepthShader::vao);
|
||||
setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::LinearizeDepthShader::setUniforms(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue(), 0);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
irr_driver->getFBO(FBO_SSAO).Bind();
|
||||
|
||||
if (!noise_tex)
|
||||
noise_tex = irr_driver->getTexture(file_manager->getAsset("textures/noise.png").c_str());
|
||||
|
||||
glUseProgram(FullScreenShader::SSAOShader::Program);
|
||||
glBindVertexArray(FullScreenShader::SSAOShader::vao);
|
||||
setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
|
||||
|
||||
setTexture(0, irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR);
|
||||
|
||||
FullScreenShader::SSAOShader::setUniforms(0, 1);
|
||||
FullScreenShader::SSAOShader::setUniforms(core::vector2df(float(UserConfigParams::m_width),
|
||||
float(UserConfigParams::m_height)),
|
||||
0, 1);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
@ -467,9 +544,8 @@ void PostProcessing::renderFog()
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void PostProcessing::renderMotionBlur(unsigned cam, GLuint in_rtt, GLuint out_fbo)
|
||||
void PostProcessing::renderMotionBlur(unsigned cam, FrameBuffer &in_fbo, FrameBuffer &out_fbo)
|
||||
{
|
||||
|
||||
MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver->
|
||||
getCallback(ES_MOTIONBLUR);
|
||||
|
||||
@ -486,18 +562,18 @@ void PostProcessing::renderMotionBlur(unsigned cam, GLuint in_rtt, GLuint out_fb
|
||||
const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f;
|
||||
setMotionBlurCenterY(cam, karty);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
|
||||
out_fbo.Bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glUseProgram(FullScreenShader::MotionBlurShader::Program);
|
||||
glBindVertexArray(FullScreenShader::MotionBlurShader::vao);
|
||||
|
||||
setTexture(0, in_rtt, GL_NEAREST, GL_NEAREST);
|
||||
setTexture(0, in_fbo.getRTT()[0], GL_NEAREST, GL_NEAREST);
|
||||
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::MotionBlurShader
|
||||
::setUniforms(cb->getBoostTime(cam), cb->getCenter(cam),
|
||||
cb->getDirection(cam), 0.15f,
|
||||
cb->getDirection(cam), 0.15f,
|
||||
cb->getMaxHeight(cam) * 0.7f, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
@ -523,9 +599,9 @@ static void renderGodRay(GLuint tex, const core::vector2df &sunpos)
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
static void toneMap(GLuint fbo, GLuint rtt)
|
||||
static void toneMap(FrameBuffer &fbo, GLuint rtt)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
fbo.Bind();
|
||||
glUseProgram(FullScreenShader::ToneMapShader::Program);
|
||||
glBindVertexArray(FullScreenShader::ToneMapShader::vao);
|
||||
setTexture(0, rtt, GL_NEAREST, GL_NEAREST);
|
||||
@ -535,15 +611,14 @@ static void toneMap(GLuint fbo, GLuint rtt)
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
static void renderDoF(GLuint fbo, GLuint rtt)
|
||||
static void renderDoF(FrameBuffer &fbo, GLuint rtt)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
fbo.Bind();
|
||||
glUseProgram(FullScreenShader::DepthOfFieldShader::Program);
|
||||
glBindVertexArray(FullScreenShader::DepthOfFieldShader::vao);
|
||||
setTexture(0, rtt, GL_LINEAR, GL_LINEAR);
|
||||
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::DepthOfFieldShader::setUniforms(irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0, 1);
|
||||
FullScreenShader::DepthOfFieldShader::setUniforms(0, 1);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
@ -557,8 +632,7 @@ static void averageTexture(GLuint tex)
|
||||
|
||||
static void computeLogLuminance(GLuint tex)
|
||||
{
|
||||
glViewport(0, 0, 1024, 1024);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_LOG_LUMINANCE));
|
||||
irr_driver->getFBO(FBO_LOG_LUMINANCE).Bind();
|
||||
glUseProgram(FullScreenShader::LogLuminanceShader::Program);
|
||||
glBindVertexArray(FullScreenShader::LogLuminanceShader::vao);
|
||||
setTexture(0, tex, GL_LINEAR, GL_LINEAR);
|
||||
@ -573,7 +647,7 @@ void PostProcessing::applyMLAA()
|
||||
{
|
||||
const core::vector2df &PIXEL_SIZE = core::vector2df(1.0f / UserConfigParams::m_width, 1.0f / UserConfigParams::m_height);
|
||||
IVideoDriver *const drv = irr_driver->getVideoDriver();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP1_WITH_DS));
|
||||
irr_driver->getFBO(FBO_TMP1_WITH_DS).Bind();
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
@ -592,7 +666,7 @@ void PostProcessing::applyMLAA()
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
|
||||
// Pass 2: blend weights
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP2_WITH_DS));
|
||||
irr_driver->getFBO(FBO_TMP2_WITH_DS).Bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glUseProgram(FullScreenShader::MLAABlendWeightSHader::Program);
|
||||
@ -604,10 +678,10 @@ void PostProcessing::applyMLAA()
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
// Blit in to tmp1
|
||||
blitFBO(irr_driver->getFBO(FBO_MLAA_COLORS), irr_driver->getFBO(FBO_TMP1_WITH_DS), UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
FrameBuffer::Blit(irr_driver->getFBO(FBO_MLAA_COLORS), irr_driver->getFBO(FBO_TMP1_WITH_DS));
|
||||
|
||||
// Pass 3: gather
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_MLAA_COLORS));
|
||||
irr_driver->getFBO(FBO_MLAA_COLORS).Bind();
|
||||
|
||||
glUseProgram(FullScreenShader::MLAAGatherSHader::Program);
|
||||
setTexture(0, irr_driver->getRenderTargetTexture(RTT_TMP1), GL_NEAREST, GL_NEAREST);
|
||||
@ -624,7 +698,7 @@ void PostProcessing::applyMLAA()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Render the post-processed scene */
|
||||
void PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
{
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
@ -633,8 +707,8 @@ void PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver->
|
||||
getCallback(ES_GAUSSIAN3H);
|
||||
|
||||
GLuint in_rtt = irr_driver->getRenderTargetTexture(RTT_COLOR), in_fbo = irr_driver->getFBO(FBO_COLORS);
|
||||
GLuint out_rtt = irr_driver->getRenderTargetTexture(RTT_TMP1), out_fbo = irr_driver->getFBO(FBO_TMP1_WITH_DS);
|
||||
FrameBuffer *in_fbo = &irr_driver->getFBO(FBO_COLORS);
|
||||
FrameBuffer *out_fbo = &irr_driver->getFBO(FBO_TMP1_WITH_DS);
|
||||
// Each effect uses these as named, and sets them up for the next effect.
|
||||
// This allows chaining effects where some may be disabled.
|
||||
|
||||
@ -644,9 +718,11 @@ void PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
|
||||
if (UserConfigParams::m_dof)
|
||||
{
|
||||
renderDoF(out_fbo, in_rtt);
|
||||
std::swap(in_rtt, out_rtt);
|
||||
PROFILER_PUSH_CPU_MARKER("- DoF", 0xFF, 0x00, 0x00);
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_DOF));
|
||||
renderDoF(*out_fbo, in_fbo->getRTT()[0]);
|
||||
std::swap(in_fbo, out_fbo);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
{
|
||||
@ -657,7 +733,7 @@ void PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
// Grab the sky
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
|
||||
out_fbo->Bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
irr_driver->renderSkybox(camnode);
|
||||
|
||||
@ -674,17 +750,12 @@ void PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
// Fade to quarter
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER1));
|
||||
irr_driver->getFBO(FBO_QUARTER1).Bind();
|
||||
glViewport(0, 0, UserConfigParams::m_width / 4, UserConfigParams::m_height / 4);
|
||||
renderGodFade(out_rtt, col);
|
||||
renderGodFade(out_fbo->getRTT()[0], col);
|
||||
|
||||
// Blur
|
||||
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1),
|
||||
irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2),
|
||||
UserConfigParams::m_width / 4,
|
||||
UserConfigParams::m_height / 4);
|
||||
|
||||
|
||||
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getFBO(FBO_QUARTER2));
|
||||
|
||||
// Calculate the sun's position in texcoords
|
||||
const core::vector3df pos = sun->getPosition();
|
||||
@ -701,22 +772,18 @@ void PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh;
|
||||
|
||||
// Rays please
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER2));
|
||||
irr_driver->getFBO(FBO_QUARTER2).Bind();
|
||||
renderGodRay(irr_driver->getRenderTargetTexture(RTT_QUARTER1), core::vector2df(sunx, suny));
|
||||
|
||||
// Blur
|
||||
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2),
|
||||
irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1),
|
||||
UserConfigParams::m_width / 4,
|
||||
UserConfigParams::m_height / 4);
|
||||
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER2), irr_driver->getFBO(FBO_QUARTER1));
|
||||
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
// Blend
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, in_fbo);
|
||||
in_fbo->Bind();
|
||||
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_QUARTER2));
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
@ -732,44 +799,24 @@ void PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
{
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, in_fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, irr_driver->getFBO(FBO_BLOOM_1024));
|
||||
glBlitFramebuffer(0, 0, UserConfigParams::m_width, UserConfigParams::m_height, 0, 0, 1024, 1024, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
FrameBuffer::Blit(*in_fbo, irr_driver->getFBO(FBO_BLOOM_1024), GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_BLOOM_512));
|
||||
glViewport(0, 0, 512, 512);
|
||||
irr_driver->getFBO(FBO_BLOOM_512).Bind();
|
||||
renderBloom(irr_driver->getRenderTargetTexture(RTT_BLOOM_1024));
|
||||
|
||||
// Downsample
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, irr_driver->getFBO(FBO_BLOOM_512));
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, irr_driver->getFBO(FBO_BLOOM_256));
|
||||
glBlitFramebuffer(0, 0, 512, 512, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, irr_driver->getFBO(FBO_BLOOM_256));
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, irr_driver->getFBO(FBO_BLOOM_128));
|
||||
glBlitFramebuffer(0, 0, 256, 256, 0, 0, 128, 128, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_BLOOM_256), GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_BLOOM_128), GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
// Blur
|
||||
glViewport(0, 0, 512, 512);
|
||||
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getRenderTargetTexture(RTT_BLOOM_512),
|
||||
irr_driver->getFBO(FBO_TMP_512), irr_driver->getRenderTargetTexture(RTT_TMP_512), 512, 512);
|
||||
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_TMP_512));
|
||||
|
||||
glViewport(0, 0, 256, 256);
|
||||
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getRenderTargetTexture(RTT_BLOOM_256),
|
||||
irr_driver->getFBO(FBO_TMP_256), irr_driver->getRenderTargetTexture(RTT_TMP_256), 256, 256);
|
||||
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_TMP_256));
|
||||
|
||||
glViewport(0, 0, 128, 128);
|
||||
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_128), irr_driver->getRenderTargetTexture(RTT_BLOOM_128),
|
||||
irr_driver->getFBO(FBO_TMP_128), irr_driver->getRenderTargetTexture(RTT_TMP_128), 128, 128);
|
||||
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_128), irr_driver->getFBO(FBO_TMP_128));
|
||||
|
||||
// Additively blend on top of tmp1
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, in_fbo);
|
||||
in_fbo->Bind();
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_CONSTANT_COLOR, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
@ -788,8 +835,7 @@ void PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Tonemap", 0xFF, 0x00, 0x00);
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TONEMAP));
|
||||
toneMap(out_fbo, in_rtt);
|
||||
std::swap(in_rtt, out_rtt);
|
||||
toneMap(*out_fbo, in_fbo->getRTT()[0]);
|
||||
std::swap(in_fbo, out_fbo);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
@ -799,43 +845,23 @@ void PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MOTIONBLUR));
|
||||
if (UserConfigParams::m_motionblur && m_any_boost) // motion blur
|
||||
{
|
||||
renderMotionBlur(0, in_rtt, out_fbo);
|
||||
renderMotionBlur(0, *in_fbo, *out_fbo);
|
||||
std::swap(in_fbo, out_fbo);
|
||||
std::swap(in_rtt, out_rtt);
|
||||
}
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
if (irr_driver->getNormals())
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH));
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
else if (irr_driver->getSSAOViz())
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_SSAO));
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
else if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
|
||||
if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_MLAA_COLORS));
|
||||
renderPassThrough(in_rtt);
|
||||
irr_driver->getFBO(FBO_MLAA_COLORS).Bind();
|
||||
renderPassThrough(in_fbo->getRTT()[0]);
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
applyMLAA();
|
||||
blitFBO(irr_driver->getFBO(FBO_MLAA_COLORS), 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
out_fbo = &irr_driver->getFBO(FBO_MLAA_COLORS);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
renderPassThrough(in_rtt);
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
|
||||
return out_fbo;
|
||||
} // render
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "S3DVertex.h"
|
||||
#include "SMaterial.h"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -80,20 +81,22 @@ public:
|
||||
void renderFog();
|
||||
void renderSSAO();
|
||||
void renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff);
|
||||
void renderGI(const core::matrix4 &RHMatrix, const core::vector3df &rh_extend, unsigned shr, unsigned shg, unsigned shb);
|
||||
|
||||
/** Blur the in texture */
|
||||
void renderGaussian3Blur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t inv_width, size_t inv_height);
|
||||
void renderGaussian6Blur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t width, size_t height);
|
||||
void renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary);
|
||||
void renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary);
|
||||
void renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &auxiliary);
|
||||
|
||||
/** Render tex. Used for blit/texture resize */
|
||||
void renderPassThrough(unsigned tex);
|
||||
void applyMLAA();
|
||||
|
||||
void renderMotionBlur(unsigned cam, unsigned in_rtt, unsigned out_fbo);
|
||||
void renderMotionBlur(unsigned cam, FrameBuffer &in_fbo, FrameBuffer &out_fbo);
|
||||
void renderGlow(unsigned tex);
|
||||
|
||||
/** Render the post-processed scene */
|
||||
void render(scene::ICameraSceneNode * const camnode);
|
||||
FrameBuffer *render(scene::ICameraSceneNode * const camnode);
|
||||
|
||||
/** Use motion blur for a short time */
|
||||
void giveBoost(unsigned int cam_index);
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/screenquad.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/shadow_importance.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "graphics/stkinstancedscenenode.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
@ -50,8 +49,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
STKInstancedSceneNode *InstancedBox = 0;
|
||||
|
||||
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
|
||||
|
||||
@ -144,6 +141,9 @@ void IrrDriver::renderGLSL(float dt)
|
||||
rg->preRenderCallback(camera); // adjusts start referee
|
||||
m_scene_manager->setActiveCamera(camnode);
|
||||
|
||||
const core::recti &viewport = camera->getViewport();
|
||||
|
||||
computeCameraMatrix(camnode, viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
|
||||
renderScene(camnode, glows, dt, track->hasShadows());
|
||||
|
||||
// Debug physic
|
||||
@ -170,7 +170,7 @@ void IrrDriver::renderGLSL(float dt)
|
||||
UtilShader::ColoredLine::setUniforms(it->first);
|
||||
const std::vector<float> &vertex = it->second;
|
||||
const float *tmp = vertex.data();
|
||||
for (int i = 0; i < vertex.size(); i += 1024 * 6)
|
||||
for (unsigned int i = 0; i < vertex.size(); i += 1024 * 6)
|
||||
{
|
||||
unsigned count = MIN2(vertex.size() - i, 1024 * 6);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]);
|
||||
@ -185,10 +185,32 @@ void IrrDriver::renderGLSL(float dt)
|
||||
|
||||
// Render the post-processed scene
|
||||
if (UserConfigParams::m_dynamic_lights)
|
||||
m_post_processing->render(camnode);
|
||||
{
|
||||
FrameBuffer *fbo = m_post_processing->render(camnode);
|
||||
|
||||
if (!UserConfigParams::m_mlaa) // MLAA_COLORS already in srgb space
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
if (irr_driver->getNormals())
|
||||
irr_driver->getFBO(FBO_NORMAL_AND_DEPTHS).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
|
||||
else if (irr_driver->getSSAOViz())
|
||||
irr_driver->getFBO(FBO_SSAO).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
|
||||
else if (irr_driver->getRSM())
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
|
||||
m_post_processing->renderPassThrough(m_rtts->getRSM().getRTT()[0]);
|
||||
}
|
||||
else
|
||||
fbo->BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
|
||||
|
||||
if (!UserConfigParams::m_mlaa)
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
else
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
} // for i<world->getNumKarts()
|
||||
|
||||
@ -240,7 +262,6 @@ void IrrDriver::renderGLSL(float dt)
|
||||
|
||||
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector<GlowData>& glows, float dt, bool hasShadow)
|
||||
{
|
||||
computeCameraMatrix(camnode);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00);
|
||||
@ -286,9 +307,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COLORS));
|
||||
}
|
||||
m_rtts->getFBO(FBO_COLORS).Bind();
|
||||
renderSolidSecondPass();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
@ -300,9 +319,32 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Skybox", 0xFF, 0x00, 0xFF);
|
||||
renderSkybox(camnode);
|
||||
if (!SkyboxTextures.empty())
|
||||
renderSkybox(camnode);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
if (getRH())
|
||||
{
|
||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||
m_rtts->getFBO(FBO_COLORS).Bind();
|
||||
glUseProgram(FullScreenShader::RHDebug::Program);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[0]);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[1]);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[2]);
|
||||
FullScreenShader::RHDebug::setUniforms(rh_matrix, rh_extend, 0, 1, 2);
|
||||
glDrawArrays(GL_POINTS, 0, 32 * 16 * 32);
|
||||
glDisable(GL_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
|
||||
if (getGI())
|
||||
{
|
||||
m_rtts->getFBO(FBO_COLORS).Bind();
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00);
|
||||
// Render anything glowing.
|
||||
if (!m_mipviz && !m_wireframe && UserConfigParams::m_glow)
|
||||
@ -331,6 +373,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
|
||||
renderParticles();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
return;
|
||||
|
||||
// Render displacement
|
||||
{
|
||||
@ -339,6 +383,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
|
||||
renderDisplacement();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
// Ensure that no object will be drawn after that by using invalid pass
|
||||
irr_driver->setPhase(PASS_COUNT);
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
@ -452,8 +498,7 @@ void IrrDriver::computeSunVisibility()
|
||||
|
||||
void IrrDriver::renderSolidFirstPass()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS));
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind();
|
||||
glClearColor(0., 0., 0., 0.);
|
||||
glDepthMask(GL_TRUE);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
@ -477,17 +522,44 @@ void IrrDriver::renderSolidFirstPass()
|
||||
glUseProgram(MeshShader::ObjectPass1Shader::Program);
|
||||
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
|
||||
{
|
||||
drawObjectPass1(*GroupedFPSM<FPSM_DEFAULT>::MeshSet[i], GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT>::TIMVSet[i]);
|
||||
const GLMesh &mesh = *GroupedFPSM<FPSM_DEFAULT>::MeshSet[i];
|
||||
if (mesh.textures[0])
|
||||
{
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
setTexture(0, 0, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, false);
|
||||
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE };
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
draw<MeshShader::ObjectPass1Shader>(mesh, mesh.vao_first_pass, GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT>::TIMVSet[i], 0);
|
||||
if (!mesh.textures[0])
|
||||
{
|
||||
GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
}
|
||||
|
||||
glUseProgram(MeshShader::ObjectRefPass1Shader::Program);
|
||||
for (unsigned i = 0; i < GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet.size(); ++i)
|
||||
{
|
||||
drawObjectRefPass1(*GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::TIMVSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
|
||||
const GLMesh &mesh = *GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i];
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
draw<MeshShader::ObjectRefPass1Shader>(mesh, mesh.vao_first_pass, GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::TIMVSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix, 0);
|
||||
}
|
||||
glUseProgram(MeshShader::NormalMapShader::Program);
|
||||
for (unsigned i = 0; i < GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet.size(); ++i)
|
||||
{
|
||||
drawNormalPass(*GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet[i]);
|
||||
const GLMesh &mesh = *GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i];
|
||||
assert(mesh.textures[1]);
|
||||
compressTexture(mesh.textures[1], false);
|
||||
setTexture(0, getTextureGLuint(mesh.textures[1]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(1, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
draw<MeshShader::NormalMapShader>(mesh, mesh.vao_first_pass, GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet[i], 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -584,8 +656,10 @@ void IrrDriver::renderParticles()
|
||||
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
|
||||
}
|
||||
|
||||
void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode)
|
||||
void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, size_t width, size_t height)
|
||||
{
|
||||
static int tick = 0;
|
||||
tick++;
|
||||
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
|
||||
irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
|
||||
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||
@ -666,11 +740,18 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode)
|
||||
|
||||
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||
}
|
||||
if ((tick % 100) == 2)
|
||||
rsm_matrix = sun_ortho_matrix[3];
|
||||
rh_extend = core::vector3df(128, 64, 128);
|
||||
core::vector3df campos = camnode->getAbsolutePosition();
|
||||
core::vector3df translation(8 * floor(campos.X / 8), 8 * floor(campos.Y / 8), 8 * floor(campos.Z / 8));
|
||||
rh_matrix.setTranslation(translation);
|
||||
|
||||
assert(sun_ortho_matrix.size() == 4);
|
||||
camnode->setNearValue(oldnear);
|
||||
camnode->setFarValue(oldfar);
|
||||
|
||||
float *tmp = new float[16 * 8];
|
||||
float *tmp = new float[18 * 8];
|
||||
|
||||
memcpy(tmp, irr_driver->getViewMatrix().pointer(), 16 * sizeof(float));
|
||||
memcpy(&tmp[16], irr_driver->getProjMatrix().pointer(), 16 * sizeof(float));
|
||||
@ -679,28 +760,59 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode)
|
||||
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));
|
||||
tmp[128] = float(width);
|
||||
tmp[129] = float(height);
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, 16 * 8 * sizeof(float), tmp);
|
||||
delete tmp;
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 8 + 2) * sizeof(float), tmp);
|
||||
delete []tmp;
|
||||
}
|
||||
|
||||
void IrrDriver::renderShadows()
|
||||
{
|
||||
GroupedFPSM<FPSM_DEFAULT>::reset();
|
||||
GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::reset();
|
||||
GroupedFPSM<FPSM_NORMAL_MAP>::reset();
|
||||
irr_driver->setPhase(SHADOW_PASS);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.5, 0.);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getShadowFBO());
|
||||
glViewport(0, 0, 1024, 1024);
|
||||
m_rtts->getShadowFBO().Bind();
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
glDrawBuffer(GL_NONE);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
|
||||
|
||||
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
||||
|
||||
glUseProgram(MeshShader::ShadowShader::Program);
|
||||
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
|
||||
drawShadow(*GroupedFPSM<FPSM_DEFAULT>::MeshSet[i], GroupedFPSM<FPSM_DEFAULT>::MVPSet[i]);
|
||||
for (unsigned i = 0; i < GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet.size(); ++i)
|
||||
drawShadow(*GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i]);
|
||||
|
||||
glUseProgram(MeshShader::RefShadowShader::Program);
|
||||
for (unsigned i = 0; i < GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet.size(); ++i)
|
||||
drawShadowRef(*GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i]);
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
if (!UserConfigParams::m_gi)
|
||||
return;
|
||||
|
||||
m_rtts->getRSM().Bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glUseProgram(MeshShader::RSMShader::Program);
|
||||
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
|
||||
{
|
||||
const GLMesh mesh = *GroupedFPSM<FPSM_DEFAULT>::MeshSet[i];
|
||||
if (!mesh.textures[0])
|
||||
continue;
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
draw<MeshShader::RSMShader>(mesh, mesh.vao_rsm_pass, rsm_matrix, GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -708,7 +820,7 @@ void IrrDriver::renderShadows()
|
||||
void IrrDriver::renderGlow(std::vector<GlowData>& glows)
|
||||
{
|
||||
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_TMP1_WITH_DS));
|
||||
m_rtts->getFBO(FBO_TMP1_WITH_DS).Bind();
|
||||
glClearStencil(0);
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
@ -745,25 +857,18 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
// To half
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP1_WITH_DS));
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, irr_driver->getFBO(FBO_HALF1));
|
||||
glBlitFramebuffer(0, 0, UserConfigParams::m_width, UserConfigParams::m_height, 0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
FrameBuffer::Blit(irr_driver->getFBO(FBO_TMP1_WITH_DS), irr_driver->getFBO(FBO_HALF1), GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
// To quarter
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, irr_driver->getFBO(FBO_HALF1));
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER1));
|
||||
glBlitFramebuffer(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2, 0, 0, UserConfigParams::m_width / 4, UserConfigParams::m_height / 4, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
FrameBuffer::Blit(irr_driver->getFBO(FBO_HALF1), irr_driver->getFBO(FBO_QUARTER1), GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glStencilFunc(GL_EQUAL, 0, ~0);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COLORS));
|
||||
m_rtts->getFBO(FBO_COLORS).Bind();
|
||||
m_post_processing->renderGlow(m_rtts->getRenderTarget(RTT_QUARTER1));
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
@ -789,7 +894,7 @@ static void renderPointLights(unsigned count)
|
||||
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
LightShader::PointLightShader
|
||||
::setUniforms(core::vector2df(float(UserConfigParams::m_width),
|
||||
float(UserConfigParams::m_height) ),
|
||||
float(UserConfigParams::m_height) ),
|
||||
200, 0, 1);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
|
||||
@ -797,21 +902,31 @@ static void renderPointLights(unsigned count)
|
||||
|
||||
void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
{
|
||||
//RH
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
m_rtts->getRH().Bind();
|
||||
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::RadianceHintsConstructionShader::vao);
|
||||
setTexture(0, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(1, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(2, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::RadianceHintsConstructionShader::setUniforms(rsm_matrix, rh_matrix, rh_extend, 0, 1, 2);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
|
||||
sun_ortho_matrix[i] *= getInvViewMatrix();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2));
|
||||
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
|
||||
GLenum bufs[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
|
||||
gl_driver->extGlDrawBuffers(2, bufs);
|
||||
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
glClearColor(.5, .5, .5, .5);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
{
|
||||
gl_driver->extGlDrawBuffers(1, bufs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_gi)
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
|
||||
if (SkyboxCubeMap)
|
||||
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
||||
@ -870,6 +985,9 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
PointLightsInfo[lightnum].red = col.X;
|
||||
PointLightsInfo[lightnum].green = col.Y;
|
||||
PointLightsInfo[lightnum].blue = col.Z;
|
||||
|
||||
// Light radius
|
||||
PointLightsInfo[lightnum].radius = light_node->getRadius();
|
||||
}
|
||||
}
|
||||
if (lightnum > MAXLIGHT)
|
||||
@ -884,20 +1002,16 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
renderPointLights(MIN2(lightnum, MAXLIGHT));
|
||||
if (SkyboxCubeMap)
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
gl_driver->extGlDrawBuffers(1, bufs);
|
||||
}
|
||||
|
||||
void IrrDriver::renderSSAO()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_SSAO));
|
||||
m_rtts->getFBO(FBO_SSAO).Bind();
|
||||
glClearColor(1., 1., 1., 1.);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
m_post_processing->renderSSAO();
|
||||
// Blur it to reduce noise.
|
||||
m_post_processing->renderGaussian6Blur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO),
|
||||
irr_driver->getFBO(FBO_TMP4), irr_driver->getRenderTargetTexture(RTT_TMP4), UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
m_post_processing->renderGaussian17TapBlur(irr_driver->getFBO(FBO_SSAO), irr_driver->getFBO(FBO_TMP4));
|
||||
}
|
||||
|
||||
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
|
||||
@ -1353,8 +1467,6 @@ void IrrDriver::generateSkyboxCubemap()
|
||||
|
||||
void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
|
||||
{
|
||||
if (SkyboxTextures.empty()) return;
|
||||
|
||||
if (!SkyboxCubeMap)
|
||||
generateSkyboxCubemap();
|
||||
glBindVertexArray(MeshShader::SkyboxShader::cubevao);
|
||||
@ -1389,9 +1501,9 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
|
||||
|
||||
void IrrDriver::renderDisplacement()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP4));
|
||||
irr_driver->getFBO(FBO_TMP1_WITH_DS).Bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_DISPLACE));
|
||||
irr_driver->getFBO(FBO_DISPLACE).Bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
DisplaceProvider * const cb = (DisplaceProvider *)irr_driver->getCallback(ES_DISPLACE);
|
||||
@ -1414,7 +1526,7 @@ void IrrDriver::renderDisplacement()
|
||||
m_displacing[i]->render();
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_COLORS));
|
||||
irr_driver->getFBO(FBO_COLORS).Bind();
|
||||
glStencilFunc(GL_EQUAL, 1, 0xFF);
|
||||
m_post_processing->renderPassThrough(m_rtts->getRenderTarget(RTT_DISPLACE));
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
@ -51,14 +51,16 @@ static GLuint generateFBO(GLuint ColorAttachement, GLuint DepthAttachement)
|
||||
return fbo;
|
||||
}
|
||||
|
||||
RTT::RTT()
|
||||
RTT::RTT(size_t width, size_t height)
|
||||
{
|
||||
initGL();
|
||||
m_shadow_FBO = NULL;
|
||||
m_RSM = NULL;
|
||||
m_RH_FBO = NULL;
|
||||
using namespace video;
|
||||
using namespace core;
|
||||
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
const dimension2du res(UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
const dimension2du res(width, height);
|
||||
const dimension2du half = res/2;
|
||||
const dimension2du quarter = res/4;
|
||||
const dimension2du eighth = res/8;
|
||||
@ -83,6 +85,7 @@ RTT::RTT()
|
||||
RenderTargetTextures[RTT_TMP2] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_TMP3] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_TMP4] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_LINEAR_DEPTH] = generateRTT(res, GL_R32F, GL_RED, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGBA16F, GL_RGBA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB, GL_BGR, GL_UNSIGNED_BYTE);
|
||||
@ -106,64 +109,150 @@ RTT::RTT()
|
||||
RenderTargetTextures[RTT_TMP_128] = generateRTT(shadowsize3, GL_RGBA16F, GL_BGR, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_LOG_LUMINANCE] = generateRTT(shadowsize0, GL_R16F, GL_RED, GL_FLOAT);
|
||||
|
||||
FrameBuffers[FBO_SSAO] = generateFBO(RenderTargetTextures[RTT_SSAO]);
|
||||
std::vector<GLuint> somevector;
|
||||
somevector.push_back(RenderTargetTextures[RTT_SSAO]);
|
||||
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
|
||||
// Clear this FBO to 1s so that if no SSAO is computed we can still use it.
|
||||
glClearColor(1., 1., 1., 1.);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
FrameBuffers[FBO_NORMAL_AND_DEPTHS] = generateFBO(RenderTargetTextures[RTT_NORMAL_AND_DEPTH], DepthStencilTexture);
|
||||
FrameBuffers[FBO_COLORS] = generateFBO(RenderTargetTextures[RTT_COLOR], DepthStencilTexture);
|
||||
FrameBuffers[FBO_MLAA_COLORS] = generateFBO(RenderTargetTextures[RTT_MLAA_COLORS], DepthStencilTexture);
|
||||
FrameBuffers[FBO_LOG_LUMINANCE] = generateFBO(RenderTargetTextures[RTT_LOG_LUMINANCE]);
|
||||
FrameBuffers[FBO_TMP1_WITH_DS] = generateFBO(RenderTargetTextures[RTT_TMP1], DepthStencilTexture);
|
||||
FrameBuffers[FBO_TMP2_WITH_DS] = generateFBO(RenderTargetTextures[RTT_TMP2], DepthStencilTexture);
|
||||
FrameBuffers[FBO_TMP4] = generateFBO(RenderTargetTextures[RTT_TMP4], DepthStencilTexture);
|
||||
FrameBuffers[FBO_DISPLACE] = generateFBO(RenderTargetTextures[RTT_DISPLACE], DepthStencilTexture);
|
||||
FrameBuffers[FBO_HALF1] = generateFBO(RenderTargetTextures[RTT_HALF1]);
|
||||
FrameBuffers[FBO_HALF2] = generateFBO(RenderTargetTextures[RTT_HALF2]);
|
||||
FrameBuffers[FBO_QUARTER1] = generateFBO(RenderTargetTextures[RTT_QUARTER1]);
|
||||
FrameBuffers[FBO_QUARTER2] = generateFBO(RenderTargetTextures[RTT_QUARTER2]);
|
||||
FrameBuffers[FBO_EIGHTH1] = generateFBO(RenderTargetTextures[RTT_EIGHTH1]);
|
||||
FrameBuffers[FBO_EIGHTH2] = generateFBO(RenderTargetTextures[RTT_EIGHTH2]);
|
||||
|
||||
FrameBuffers[FBO_BLOOM_1024] = generateFBO(RenderTargetTextures[RTT_BLOOM_1024]);
|
||||
FrameBuffers[FBO_BLOOM_512] = generateFBO(RenderTargetTextures[RTT_BLOOM_512]);
|
||||
FrameBuffers[FBO_TMP_512] = generateFBO(RenderTargetTextures[RTT_TMP_512]);
|
||||
FrameBuffers[FBO_BLOOM_256] = generateFBO(RenderTargetTextures[RTT_BLOOM_256]);
|
||||
FrameBuffers[FBO_TMP_256] = generateFBO(RenderTargetTextures[RTT_TMP_256]);
|
||||
FrameBuffers[FBO_BLOOM_128] = generateFBO(RenderTargetTextures[RTT_BLOOM_128]);
|
||||
FrameBuffers[FBO_TMP_128] = generateFBO(RenderTargetTextures[RTT_TMP_128]);
|
||||
|
||||
FrameBuffers[FBO_COMBINED_TMP1_TMP2] = generateFBO(RenderTargetTextures[RTT_TMP1], DepthStencilTexture);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, RenderTargetTextures[RTT_TMP2], 0);
|
||||
somevector.clear();
|
||||
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]);
|
||||
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]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_MLAA_COLORS]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_TMP1]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_TMP2]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_TMP4]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_LINEAR_DEPTH]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_HALF1]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_HALF2]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_QUARTER1]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, quarter.Width, quarter.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_QUARTER2]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, quarter.Width, quarter.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_EIGHTH1]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, eighth.Width, eighth.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_EIGHTH2]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, eighth.Width, eighth.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_DISPLACE]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_BLOOM_1024]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, 1024, 1024));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_BLOOM_512]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, 512, 512));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_TMP_512]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, 512, 512));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_BLOOM_256]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, 256, 256));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_TMP_256]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, 256, 256));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_BLOOM_128]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, 128, 128));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_TMP_128]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, 128, 128));
|
||||
|
||||
if (irr_driver->getGLSLVersion() >= 150)
|
||||
{
|
||||
glGenFramebuffers(1, &shadowFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO);
|
||||
glGenTextures(1, &shadowColorTex);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowColorTex);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8, 1024, 1024, 4, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
|
||||
glGenTextures(1, &shadowDepthTex);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowDepthTex);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, 1024, 1024, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, shadowColorTex, 0);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowDepthTex, 0);
|
||||
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
assert(result == GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_STENCIL, 1024, 1024, 4, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
|
||||
|
||||
somevector.clear();
|
||||
somevector.push_back(shadowColorTex);
|
||||
m_shadow_FBO = new FrameBuffer(somevector, shadowDepthTex, 1024, 1024, true);
|
||||
|
||||
//Todo : use "normal" shadowtex
|
||||
glGenTextures(1, &RSM_Color);
|
||||
glBindTexture(GL_TEXTURE_2D, RSM_Color);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||
glGenTextures(1, &RSM_Normal);
|
||||
glBindTexture(GL_TEXTURE_2D, RSM_Normal);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, 0);
|
||||
glGenTextures(1, &RSM_Depth);
|
||||
glBindTexture(GL_TEXTURE_2D, RSM_Depth);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, 1024, 1024, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
|
||||
|
||||
somevector.clear();
|
||||
somevector.push_back(RSM_Color);
|
||||
somevector.push_back(RSM_Normal);
|
||||
m_RSM = new FrameBuffer(somevector, RSM_Depth, 1024, 1024, true);
|
||||
|
||||
glGenTextures(1, &RH_Red);
|
||||
glBindTexture(GL_TEXTURE_3D, RH_Red);
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, 32, 16, 32, 0, GL_RGBA, GL_FLOAT, 0);
|
||||
glGenTextures(1, &RH_Green);
|
||||
glBindTexture(GL_TEXTURE_3D, RH_Green);
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, 32, 16, 32, 0, GL_RGBA, GL_FLOAT, 0);
|
||||
glGenTextures(1, &RH_Blue);
|
||||
glBindTexture(GL_TEXTURE_3D, RH_Blue);
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, 32, 16, 32, 0, GL_RGBA, GL_FLOAT, 0);
|
||||
|
||||
somevector.clear();
|
||||
somevector.push_back(RH_Red);
|
||||
somevector.push_back(RH_Green);
|
||||
somevector.push_back(RH_Blue);
|
||||
m_RH_FBO = new FrameBuffer(somevector, 32, 16, true);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
RTT::~RTT()
|
||||
{
|
||||
glDeleteFramebuffers(FBO_COUNT, FrameBuffers);
|
||||
glDeleteTextures(RTT_COUNT, RenderTargetTextures);
|
||||
glDeleteTextures(1, &DepthStencilTexture);
|
||||
if (irr_driver->getGLSLVersion() >= 150)
|
||||
{
|
||||
glDeleteFramebuffers(1, &shadowFBO);
|
||||
glDeleteTextures(1, &shadowColorTex);
|
||||
glDeleteTextures(1, &shadowDepthTex);
|
||||
glDeleteTextures(1, &RSM_Color);
|
||||
glDeleteTextures(1, &RSM_Normal);
|
||||
glDeleteTextures(1, &RSM_Depth);
|
||||
glDeleteTextures(1, &RH_Red);
|
||||
glDeleteTextures(1, &RH_Green);
|
||||
glDeleteTextures(1, &RH_Blue);
|
||||
|
||||
delete m_shadow_FBO;
|
||||
delete m_RH_FBO;
|
||||
delete m_RSM;
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,11 @@
|
||||
#ifndef HEADER_RTTS_HPP
|
||||
#define HEADER_RTTS_HPP
|
||||
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
|
||||
namespace irr {
|
||||
namespace video {
|
||||
class ITexture;
|
||||
@ -25,102 +30,32 @@ namespace irr {
|
||||
|
||||
using irr::video::ITexture;
|
||||
|
||||
enum TypeRTT
|
||||
{
|
||||
RTT_TMP1 = 0,
|
||||
RTT_TMP2,
|
||||
RTT_TMP3,
|
||||
RTT_TMP4,
|
||||
RTT_NORMAL_AND_DEPTH,
|
||||
RTT_COLOR,
|
||||
RTT_LOG_LUMINANCE,
|
||||
|
||||
RTT_HALF1,
|
||||
RTT_HALF2,
|
||||
|
||||
RTT_QUARTER1,
|
||||
RTT_QUARTER2,
|
||||
// RTT_QUARTER3,
|
||||
// RTT_QUARTER4,
|
||||
|
||||
RTT_EIGHTH1,
|
||||
RTT_EIGHTH2,
|
||||
|
||||
// RTT_SIXTEENTH1,
|
||||
// RTT_SIXTEENTH2,
|
||||
|
||||
RTT_SSAO,
|
||||
|
||||
// RTT_COLLAPSE,
|
||||
// RTT_COLLAPSEH,
|
||||
// RTT_COLLAPSEV,
|
||||
// RTT_COLLAPSEH2,
|
||||
// RTT_COLLAPSEV2,
|
||||
// RTT_WARPH,
|
||||
// RTT_WARPV,
|
||||
|
||||
// RTT_HALF_SOFT,
|
||||
|
||||
RTT_DISPLACE,
|
||||
RTT_MLAA_COLORS,
|
||||
|
||||
RTT_BLOOM_1024,
|
||||
RTT_BLOOM_512,
|
||||
RTT_TMP_512,
|
||||
RTT_BLOOM_256,
|
||||
RTT_TMP_256,
|
||||
RTT_BLOOM_128,
|
||||
RTT_TMP_128,
|
||||
|
||||
RTT_COUNT
|
||||
};
|
||||
|
||||
|
||||
enum TypeFBO
|
||||
{
|
||||
FBO_SSAO,
|
||||
FBO_NORMAL_AND_DEPTHS,
|
||||
FBO_COMBINED_TMP1_TMP2,
|
||||
FBO_COLORS,
|
||||
FBO_LOG_LUMINANCE,
|
||||
FBO_MLAA_COLORS,
|
||||
FBO_TMP1_WITH_DS,
|
||||
FBO_TMP2_WITH_DS,
|
||||
FBO_TMP4,
|
||||
FBO_HALF1,
|
||||
FBO_HALF2,
|
||||
FBO_QUARTER1,
|
||||
FBO_QUARTER2,
|
||||
FBO_EIGHTH1,
|
||||
FBO_EIGHTH2,
|
||||
FBO_DISPLACE,
|
||||
FBO_BLOOM_1024,
|
||||
FBO_BLOOM_512,
|
||||
FBO_TMP_512,
|
||||
FBO_BLOOM_256,
|
||||
FBO_TMP_256,
|
||||
FBO_BLOOM_128,
|
||||
FBO_TMP_128,
|
||||
FBO_COUNT
|
||||
};
|
||||
|
||||
class RTT
|
||||
{
|
||||
public:
|
||||
RTT();
|
||||
RTT(size_t width, size_t height);
|
||||
~RTT();
|
||||
|
||||
unsigned getShadowFBO() const { return shadowFBO; }
|
||||
FrameBuffer &getShadowFBO() { return *m_shadow_FBO; }
|
||||
FrameBuffer &getRH() { return *m_RH_FBO; }
|
||||
FrameBuffer &getRSM() { return *m_RSM; }
|
||||
unsigned getShadowDepthTex() const { return shadowDepthTex; }
|
||||
|
||||
unsigned getDepthStencilTexture() const { return DepthStencilTexture; }
|
||||
unsigned getRenderTarget(enum TypeRTT target) const { return RenderTargetTextures[target]; }
|
||||
unsigned getFBO(enum TypeFBO fbo) { return FrameBuffers[fbo]; }
|
||||
FrameBuffer& getFBO(enum TypeFBO fbo) { return FrameBuffers[fbo]; }
|
||||
private:
|
||||
unsigned RenderTargetTextures[RTT_COUNT], FrameBuffers[FBO_COUNT];
|
||||
unsigned RenderTargetTextures[RTT_COUNT];
|
||||
PtrVector<FrameBuffer> FrameBuffers;
|
||||
unsigned DepthStencilTexture;
|
||||
|
||||
unsigned shadowFBO, shadowColorTex, shadowDepthTex;
|
||||
unsigned shadowColorTex, shadowNormalTex, shadowDepthTex;
|
||||
unsigned RSM_Color, RSM_Normal, RSM_Depth;
|
||||
unsigned RH_Red, RH_Green, RH_Blue;
|
||||
FrameBuffer* m_shadow_FBO, *m_RSM, *m_RH_FBO;
|
||||
|
||||
LEAK_CHECK();
|
||||
};
|
||||
|
||||
#endif
|
||||
|