trying to merge upstream

This commit is contained in:
konstin 2014-05-31 15:11:05 +02:00
commit 2534abeed2
173 changed files with 4904 additions and 4960 deletions

View File

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

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

View File

@ -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>

View File

@ -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%" />

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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 ************ -->

View File

@ -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>

View File

@ -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>

View 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>

View 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>

View File

@ -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

View File

@ -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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -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.);
}

View File

@ -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));
}

View File

@ -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;

View File

@ -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.);
}

View File

@ -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;

View File

@ -20,6 +20,7 @@ layout (std140) uniform MatrixesData
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
vec2 screen;
};
#endif

View File

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

View File

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

101
data/shaders/gi.frag Normal file
View 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.);
}

View File

@ -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.);
}

View File

@ -5,6 +5,7 @@ layout (std140) uniform MatrixesData
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
vec2 screen;
};
uniform vec3 windDir;

View File

@ -11,6 +11,7 @@ layout (std140) uniform MatrixesData
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
vec2 screen;
};
#endif

View File

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

View File

@ -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;
}

View File

@ -11,6 +11,7 @@ layout (std140) uniform MatrixesData
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
vec2 screen;
};
#endif

View File

@ -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;

View File

@ -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.);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
View 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
View 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
View 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;
}

View 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
View 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
View 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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View 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.);
}

View File

@ -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;

View File

@ -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.);
}

View File

@ -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);

View File

@ -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;

View File

@ -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. -->

View File

@ -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. -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

View File

@ -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
// ----------------------------------------------------------------------------

View File

@ -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. */

View File

@ -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>
// -----------------------------------------------------------------------------

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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:

View File

@ -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 &center_pos_x, float &center_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 &center_pos_x, float &center_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();
}

View File

@ -5,6 +5,12 @@
# include <OpenGL/gl.h>
# include <OpenGL/gl3.h>
# define OGL32CTX
# ifdef GL_ARB_instanced_arrays
# define glVertexAttribDivisor glVertexAttribDivisorARB
# endif
# ifndef GL_TEXTURE_SWIZZLE_RGBA
# define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
# endif
#elif defined(ANDROID)
# include <GLES/gl.h>
#elif defined(WIN32)
@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

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

View File

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

View File

@ -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;

View File

@ -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; }
} ;

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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

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