Merged Master
This commit is contained in:
commit
118db58a02
@ -14,13 +14,13 @@ before_install:
|
||||
# Update repos
|
||||
- sudo apt-get update -qq
|
||||
# Install dependencies
|
||||
- sudo apt-get install build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev
|
||||
- sudo apt-get install build-essential libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev
|
||||
# Install mesa from an other repo (a newer version is required). Quantal is not supported anymore, saucy is only supported till July 2014,
|
||||
# so we try to use trusty (precise which is what traiv uses a too old mesa version which doesn't link)
|
||||
- sudo apt-add-repository "deb http://archive.ubuntu.com/ubuntu trusty main restricted"
|
||||
- sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 3B4FE6ACC0B21F32
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev
|
||||
- sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev libglew-dev cmake
|
||||
script:
|
||||
# First a debug build:
|
||||
- mkdir build-debug
|
||||
|
@ -15,12 +15,12 @@ option(USE_WIIUSE "Support for wiimote input devices" ON)
|
||||
option(USE_FRIBIDI "Support for right-to-left languages" ON)
|
||||
option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
|
||||
|
||||
if(UNIX)
|
||||
if(UNIX OR MINGW)
|
||||
option(USE_CPP2011 "Activate C++ 2011 mode (GCC only)" OFF)
|
||||
endif()
|
||||
if(MSVC)
|
||||
if(MSVC OR MINGW)
|
||||
# Normally hide the option to build wiiuse on VS, since it depends
|
||||
# on the installation of the Windows DDK (Driver Developer Kit),
|
||||
# on the installation of the Windows DDK (Driver Developer Kit),
|
||||
# which also needs an absolute path :(
|
||||
option(WIIUSE_BUILD "Build wiiuse lib (only for developers)" OFF)
|
||||
mark_as_advanced(WIIUSE_BUILD)
|
||||
@ -28,6 +28,10 @@ else()
|
||||
set(WIIUSE_BUILD ON)
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
set(USE_WIIUSE OFF)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
option(USE_XRANDR "Use xrandr instead of vidmode" ON)
|
||||
option(USE_ASAN "Build with Leak/Address sanitizer" OFF)
|
||||
@ -69,6 +73,7 @@ endif()
|
||||
# Build the angelscript library
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/angelscript/projects/cmake")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/angelscript/include")
|
||||
|
||||
# Set include paths
|
||||
include_directories(${STK_SOURCE_DIR})
|
||||
|
||||
@ -80,6 +85,11 @@ if(MSVC)
|
||||
add_definitions(/D_IRR_STATIC_LIB_)
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
set(ENV{OPENALDIR} ${PROJECT_SOURCE_DIR}/dependencies)
|
||||
add_definitions(-D_IRR_STATIC_LIB_)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch i386")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch i386 -F/Library/Frameworks")
|
||||
@ -124,8 +134,15 @@ if(USE_FRIBIDI)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# OpenMP
|
||||
find_package(OpenMP)
|
||||
if (OPENMP_FOUND)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
|
||||
if(UNIX OR MINGW)
|
||||
# if(USE_CPP2011)
|
||||
add_definitions("-std=gnu++0x")
|
||||
# endif()
|
||||
@ -135,6 +152,10 @@ endif()
|
||||
find_package(OpenGL REQUIRED)
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
|
||||
# Glew
|
||||
find_package(GLEW REQUIRED)
|
||||
include_directories(${GLEW_INCLUDE_DIR})
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
if(USE_XRANDR)
|
||||
find_package(Xrandr REQUIRED)
|
||||
@ -147,7 +168,7 @@ if(UNIX AND NOT APPLE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
# Set some compiler options
|
||||
if(UNIX)
|
||||
add_definitions(-Wall)
|
||||
@ -175,6 +196,9 @@ endif()
|
||||
# TODO: remove this switch
|
||||
add_definitions(-DHAVE_OGGVORBIS)
|
||||
|
||||
if(WIN32 AND NOT MINGW)
|
||||
configure_file("${STK_SOURCE_DIR}/windows_installer/icon_rc.template" "${PROJECT_BINARY_DIR}/tmp/icon.rc")
|
||||
endif()
|
||||
|
||||
# Provides list of source and header files (STK_SOURCES and STK_HEADERS)
|
||||
include(sources.cmake)
|
||||
@ -230,7 +254,7 @@ else()
|
||||
endif()
|
||||
|
||||
# Build the final executable
|
||||
add_executable(supertuxkart ${STK_SOURCES} ${STK_HEADERS})
|
||||
add_executable(supertuxkart ${STK_SOURCES} ${STK_RESOURCES} ${STK_HEADERS})
|
||||
target_link_libraries(supertuxkart ${PTHREAD_LIBRARY})
|
||||
endif()
|
||||
|
||||
@ -253,8 +277,9 @@ target_link_libraries(supertuxkart
|
||||
${CURL_LIBRARIES}
|
||||
${OGGVORBIS_LIBRARIES}
|
||||
${OPENAL_LIBRARY}
|
||||
${OPENGL_LIBRARIES})
|
||||
|
||||
${OPENGL_LIBRARIES}
|
||||
${GLEW_LIBRARIES})
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
if(USE_XRANDR)
|
||||
target_link_libraries(supertuxkart ${XRANDR_LIBRARIES})
|
||||
@ -288,8 +313,12 @@ if(USE_WIIUSE)
|
||||
if(APPLE)
|
||||
find_library(BLUETOOTH_LIBRARY NAMES IOBluetooth PATHS /Developer/Library/Frameworks/IOBluetooth.framework)
|
||||
target_link_libraries(supertuxkart wiiuse ${BLUETOOTH_LIBRARY})
|
||||
elseif(MSVC)
|
||||
add_definitions("/DWIIUSE_STATIC")
|
||||
elseif(WIN32)
|
||||
if(MSVC)
|
||||
add_definitions("/DWIIUSE_STATIC")
|
||||
else()
|
||||
add_definitions("-DWIIUSE_STATIC")
|
||||
endif()
|
||||
if(WIIUSE_BUILD)
|
||||
target_link_libraries(supertuxkart wiiuse)
|
||||
else()
|
||||
@ -302,12 +331,12 @@ if(USE_WIIUSE)
|
||||
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(MSVC OR MINGW)
|
||||
target_link_libraries(supertuxkart iphlpapi.lib)
|
||||
add_custom_command(TARGET supertuxkart POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${PROJECT_SOURCE_DIR}/dependencies/dll"
|
||||
$<TARGET_FILE_DIR:supertuxkart>)
|
||||
$<TARGET_FILE_DIR:supertuxkart>)
|
||||
add_custom_target(stkshaders SOURCES ${STK_SHADERS})
|
||||
endif()
|
||||
|
||||
@ -316,7 +345,7 @@ add_subdirectory(tools/font_tool)
|
||||
|
||||
|
||||
# ==== Make dist target ====
|
||||
if(MSVC)
|
||||
if(MSVC OR MINGW)
|
||||
# Don't create a dist target for VS
|
||||
else()
|
||||
add_custom_target(dist
|
||||
@ -340,9 +369,9 @@ endif()
|
||||
|
||||
# ==== Checking if stk-assets folder exists ====
|
||||
if(CHECK_ASSETS)
|
||||
if((IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/karts) AND
|
||||
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/library) AND
|
||||
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/music) AND
|
||||
if((IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/karts) AND
|
||||
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/library) AND
|
||||
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/music) AND
|
||||
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/sfx) AND
|
||||
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/textures) AND
|
||||
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/tracks))
|
||||
@ -368,11 +397,8 @@ install(DIRECTORY ${STK_DATA_DIR} DESTINATION ${STK_INSTALL_DATA_DIR} PATTERN ".
|
||||
if(STK_ASSETS_DIR AND CHECK_ASSETS)
|
||||
install(DIRECTORY ${STK_ASSETS_DIR} DESTINATION ${STK_INSTALL_DATA_DIR}/data PATTERN ".svn" EXCLUDE PATTERN ".git" EXCLUDE)
|
||||
endif()
|
||||
install(FILES ${PROJECT_BINARY_DIR}/supertuxkart.desktop DESTINATION share/applications)
|
||||
install(FILES ${STK_DATA_DIR}/supertuxkart.desktop DESTINATION share/applications)
|
||||
install(FILES data/supertuxkart_32.png DESTINATION share/icons/hicolor/32x32 RENAME supertuxkart.png)
|
||||
install(FILES data/supertuxkart_128.png DESTINATION share/icons/hicolor/128x128 RENAME supertuxkart.png)
|
||||
install(FILES data/supertuxkart_32.png data/supertuxkart_128.png DESTINATION share/pixmaps)
|
||||
install(FILES data/supertuxkart.appdata DESTINATION share/appdata)
|
||||
|
||||
|
||||
set(PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
configure_file(data/supertuxkart_desktop.template supertuxkart.desktop)
|
||||
add_dependencies(supertuxkart supertuxkart.desktop)
|
@ -23,7 +23,7 @@ Ubuntu command:
|
||||
|
||||
```
|
||||
sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev \
|
||||
libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev
|
||||
libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev libxrandr-dev
|
||||
```
|
||||
|
||||
Unpack the files from the tarball like this:
|
||||
|
69
data/gui/gp_info.stkgui
Normal file
69
data/gui/gp_info.stkgui
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
|
||||
|
||||
<header id="name" height="5%" width="80%" align="center" text_align="center"/>
|
||||
|
||||
<spacer width="1" height="5%"/>
|
||||
|
||||
<box width="95%" height="40%" padding="10" layout="horizontal-row">
|
||||
<spacer width="10" height="100%"/>
|
||||
<!-- Left pane -->
|
||||
<div width="45%" height="95%" align="center" layout="vertical-row">
|
||||
<placeholder proportion="1" width="100%" height="100%" id="screenshot_div">
|
||||
</placeholder>
|
||||
</div>
|
||||
|
||||
<spacer width="5%" height="100%"/>
|
||||
|
||||
<!-- Right pane -->
|
||||
<div width="45%" height="95%" align="center" layout="vertical-row">
|
||||
<list id="tracks" width="100%" height="100%"/>
|
||||
</div>
|
||||
|
||||
</box>
|
||||
<spacer width="1" height="5%"/>
|
||||
<box width="95%" height="25%" padding="10" layout="horizontal-row">
|
||||
<spacer width="1" height="5%"/>
|
||||
<div width="50%" height="100%" layout="vertical-row">
|
||||
|
||||
<div width="100%" height="20%" layout="horizontal-row" >
|
||||
<label id="ai-text" height="100%" width="50%" I18N="Number of AI karts" text="AI karts"/>
|
||||
<spinner id="ai-spinner" width="50%" min_value="1" max_value="20" align="center"
|
||||
wrap_around="true" />
|
||||
</div>
|
||||
<spacer height="5%" />
|
||||
<div width="100%" height="20%" layout="horizontal-row" >
|
||||
<label id="reverse-text" width="50%" height="100%" I18N="Drive the track reverse" text="Reverse"/>
|
||||
<spinner id="reverse-spinner" width="50%" align="center" wrap_around="true" />
|
||||
</div>
|
||||
<spacer height="5%" />
|
||||
<div width="100%" height="20%" layout="horizontal-row">
|
||||
<label id="track-text" width="50%" height="100%" text="Tracks"
|
||||
I18N="Number of tracks to pick in a random Grand Prix."/>
|
||||
<spinner id="track-spinner" width="50%" min_value="1" max_value="20" align="center"
|
||||
wrap_around="true" />
|
||||
<spacer height="1%" />
|
||||
</div>
|
||||
<spacer height="5%" />
|
||||
<div width="100%" height="20%" layout="horizontal-row" >
|
||||
<label id="group-text" width="50%" height="100%" I18N="Number of AI karts" text="Track group"/>
|
||||
<spinner id="group-spinner" width="50%" align="center" wrap_around="true" />
|
||||
<spacer proportion="1" height="2" />
|
||||
</div>
|
||||
</div>
|
||||
</box>
|
||||
<spacer width="1" height="5%"/>
|
||||
<buttonbar id="buttons" height="15%" width="100%" align="center">
|
||||
|
||||
<icon-button id="start" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Start race" text="Start Race"/>
|
||||
|
||||
<icon-button id="continue" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Continue saved GP" text="Continue saved GP"/>
|
||||
</buttonbar>
|
||||
|
||||
</div>
|
||||
</stkgui>
|
@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
|
||||
<spacer width="10" proportion="1"/>
|
||||
<button id="continue" x="20" width="250" align="left" text="Continue"/>
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="horizontal-row">
|
||||
<button id="continue" width="250" align="bottom" text="Continue"/>
|
||||
<spacer width="20"/>
|
||||
<button id="save" width="250" align="bottom" text="Save Grand Prix"/>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
@ -1,7 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
|
||||
<spacer width="10" proportion="1"/>
|
||||
<button id="continue" x="20" width="250" align="left" text="Continue"/>
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="horizontal-row">
|
||||
<button id="continue" width="250" align="bottom" text="Continue"/>
|
||||
<spacer width="20"/>
|
||||
<button id="save" width="250" align="bottom" text="Save Grand Prix"/>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
|
@ -1,41 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="5%" y="5%" width="90%" height="90%" layout="vertical-row" >
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row" >
|
||||
|
||||
<header width="80%" text="Race Setup" align="center" text_align="center" />
|
||||
<header height="5%" width="80%" text="Race Setup" align="center" text_align="center" />
|
||||
|
||||
<spacer proportion="1" width="25"/>
|
||||
<spacer height="5%" width="25"/>
|
||||
<box width="95%" height="40%" padding="10" layout="vertical-row">
|
||||
<bright width="100%" text="Select a difficulty" align="center" text_align="left" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="50" align="center">
|
||||
<bright proportion="1" height="100%"
|
||||
I18N="In race setup menu" text="Number of AI karts" text_align="right" />
|
||||
<spacer width="50" height="25"/>
|
||||
<!--
|
||||
<spinner id="aikartamount" proportion="3" height="100%" min_value="0" max_value="8" icon="gui/karts%i.png"/> -->
|
||||
<!-- The maximum is set by stk from data/stk_config.xml. -->
|
||||
<spinner id="aikartamount" proportion="1" height="100%" min_value="0" wrap_around="true"/>
|
||||
</div>
|
||||
<ribbon id="difficulty" height="135" width="100%" align="center">
|
||||
<icon-button id="novice" width="128" height="128" icon="gui/difficulty_easy.png"
|
||||
I18N="Difficulty" text="Novice"/>
|
||||
<icon-button id="intermediate" width="128" height="128" icon="gui/difficulty_medium.png"
|
||||
I18N="Difficulty" text="Intermediate"/>
|
||||
<icon-button id="expert" width="128" height="128" icon="gui/difficulty_hard.png"
|
||||
I18N="Difficulty" text="Expert"/>
|
||||
<icon-button id="best" width="128" height="128" icon="gui/difficulty_best.png"
|
||||
I18N="Difficulty" text="SuperTux"/>
|
||||
</ribbon>
|
||||
</box>
|
||||
<spacer height="5%"" width="25"/>
|
||||
|
||||
<spacer proportion="1" width="25"/>
|
||||
<box width="95%" height="40%" padding="10" layout="vertical-row">
|
||||
<bright width="100%" text="Select a game mode" align="center" text_align="left" />
|
||||
|
||||
<ribbon id="difficulty" height="135" width="65%" align="center">
|
||||
<icon-button id="novice" width="128" height="128" icon="gui/difficulty_easy.png"
|
||||
I18N="Difficulty" text="Novice"/>
|
||||
<icon-button id="intermediate" width="128" height="128" icon="gui/difficulty_medium.png"
|
||||
I18N="Difficulty" text="Intermediate"/>
|
||||
<icon-button id="expert" width="128" height="128" icon="gui/difficulty_hard.png"
|
||||
I18N="Difficulty" text="Expert"/>
|
||||
<icon-button id="best" width="128" height="128" icon="gui/difficulty_best.png"
|
||||
I18N="Difficulty" text="SuperTux"/>
|
||||
</ribbon>
|
||||
|
||||
<spacer proportion="1" width="25"/>
|
||||
|
||||
<bright width="100%" text="Select a game mode" align="center" text_align="left" />
|
||||
|
||||
<scrollable_toolbar id="gamemode" height="135" width="85%" label_location="bottom" align="center"
|
||||
child_width="135" child_height="135" />
|
||||
<spacer proportion="1" width="25" />
|
||||
<scrollable_toolbar id="gamemode" height="135" width="85%" label_location="bottom" align="center"
|
||||
child_width="135" child_height="135" />
|
||||
<spacer proportion="1" width="25" />
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
|
90
data/gui/track_info.stkgui
Normal file
90
data/gui/track_info.stkgui
Normal file
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
|
||||
|
||||
<header id="name" height="5%" width="80%" align="center" text_align="center"/>
|
||||
|
||||
<spacer width="1" height="5%"/>
|
||||
|
||||
<box width="95%" height="40%" padding="10" layout="horizontal-row">
|
||||
<!-- Left pane -->
|
||||
<div proportion="1" height="100%" layout="vertical-row">
|
||||
<placeholder proportion="1" width="100%" height="100%" id="screenshot_div">
|
||||
</placeholder>
|
||||
|
||||
</div>
|
||||
<!-- Right pane -->
|
||||
<div proportion="1" height="100%" layout="vertical-row">
|
||||
<label id="highscores" width="100%" text_align="center" text="= Highscores ="/>
|
||||
|
||||
<spacer width="1" height="2%"/>
|
||||
|
||||
<div width="95%" height="fit" layout="horizontal-row">
|
||||
<icon id="iconscore1" icon="gui/random_kart.png" width="font" height="font"/>
|
||||
<spacer width="2%" height="1"/>
|
||||
<label id="highscore1" proportion="1" text="(Empty)"/>
|
||||
</div>
|
||||
|
||||
<spacer width="1" height="2%"/>
|
||||
|
||||
<div width="95%" height="fit" layout="horizontal-row">
|
||||
<icon id="iconscore2" icon="gui/random_kart.png" width="font" height="font"/>
|
||||
<spacer width="2%" height="1"/>
|
||||
<label id="highscore2" proportion="1" text="(Empty)"/>
|
||||
</div>
|
||||
|
||||
<spacer width="1" height="2%"/>
|
||||
|
||||
<div width="95%" height="fit" layout="horizontal-row">
|
||||
<icon id="iconscore3" icon="gui/random_kart.png" width="font" height="font"/>
|
||||
<spacer width="2%" height="1"/>
|
||||
<label id="highscore3" proportion="1" text="(Empty)"/>
|
||||
</div>
|
||||
|
||||
<spacer width="1" height="10%"/>
|
||||
|
||||
<label id="author" width="100%" text_align="center" word_wrap="true"/>
|
||||
</div>
|
||||
|
||||
</box>
|
||||
<spacer width="1" height="5%"/>
|
||||
<box width="95%" height="25%" padding="10" layout="vertical-row">
|
||||
<spacer width="1" height="5%"/>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="2" />
|
||||
<label id="lap-text" height="100%" width="40%" I18N="Number of laps" text="Number of laps"/>
|
||||
<spacer witdh="40" height="2" />
|
||||
<spinner id="lap-spinner" width="20%" min_value="1" max_value="20" align="center"
|
||||
wrap_around="true" />
|
||||
<spacer proportion="1" height="2" />
|
||||
</div>
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="2" />
|
||||
<label id="ai-text" height="100%" width="40%" I18N="Number of AI karts" text="Number of AI karts"/>
|
||||
<spacer with="40" height="2" />
|
||||
<spinner id="ai-spinner" width="20%" min_value="1" max_value="20" align="center"
|
||||
wrap_around="true" />
|
||||
<spacer proportion="1" height="2" />
|
||||
</div>
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="2" />
|
||||
<label id="reverse-text" height="100%" width="40%" I18N="Drive the track reverse" text="Drive in reverse"/>
|
||||
<spacer width="40" height="2" />
|
||||
<checkbox id="reverse"/>
|
||||
<spacer proportion="1" height="2" />
|
||||
</div>
|
||||
<spacer width="1" height="2%"/>
|
||||
</box>
|
||||
<spacer width="1" height="5%"/>
|
||||
<buttonbar id="buttons" height="15%" width="100%" align="center">
|
||||
|
||||
<icon-button id="start" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Start race" text="Start Race"/>
|
||||
|
||||
</buttonbar>>
|
||||
|
||||
</div>
|
||||
</stkgui>
|
@ -1,73 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="99%" height="99%">
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
|
||||
<label id="name" width="100%" text_align="center"/>
|
||||
|
||||
<spacer width="1" height="5%"/>
|
||||
|
||||
<div width="95%" proportion="5" layout="horizontal-row">
|
||||
|
||||
<!-- Left pane -->
|
||||
<div proportion="1" height="100%" layout="vertical-row">
|
||||
<label id="highscores" width="100%" text_align="center" text="= Highscores ="/>
|
||||
|
||||
<spacer width="1" height="2%"/>
|
||||
|
||||
<div width="95%" height="fit" layout="horizontal-row">
|
||||
<icon id="iconscore1" icon="gui/random_kart.png" width="font" height="font"/>
|
||||
<spacer width="2%" height="1"/>
|
||||
<label id="highscore1" proportion="1" text="(Empty)"/>
|
||||
</div>
|
||||
|
||||
<spacer width="1" height="2%"/>
|
||||
|
||||
<div width="95%" height="fit" layout="horizontal-row">
|
||||
<icon id="iconscore2" icon="gui/random_kart.png" width="font" height="font"/>
|
||||
<spacer width="2%" height="1"/>
|
||||
<label id="highscore2" proportion="1" text="(Empty)"/>
|
||||
</div>
|
||||
|
||||
<spacer width="1" height="2%"/>
|
||||
|
||||
<div width="95%" height="fit" layout="horizontal-row">
|
||||
<icon id="iconscore3" icon="gui/random_kart.png" width="font" height="font"/>
|
||||
<spacer width="2%" height="1"/>
|
||||
<label id="highscore3" proportion="1" text="(Empty)"/>
|
||||
</div>
|
||||
|
||||
<spacer width="1" proportion="1"/>
|
||||
|
||||
<label id="author" width="100%" text_align="center" word_wrap="true"/>
|
||||
</div>
|
||||
|
||||
<!-- Right pane -->
|
||||
<div proportion="1" height="100%" layout="vertical-row">
|
||||
<placeholder proportion="1" width="100%" height="100%" id="screenshot_div">
|
||||
</placeholder>
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<spacer proportion="1" height="2" />
|
||||
<checkbox id="reverse"/>
|
||||
<spacer width="20" height="2" />
|
||||
<label id="reverse-text" height="100%" I18N="Drive the track reverse" text="Reverse"/>
|
||||
<spacer proportion="1" height="2" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer width="1" height="5%"/>
|
||||
|
||||
<spinner id="lapcountspinner" width="50%" min_value="1" max_value="20" align="center" wrap_around="true"
|
||||
I18N="In the track setup screen (number of laps choice, where %i is the number)" text="%i laps"/>
|
||||
|
||||
<spacer width="1" height="5%"/>
|
||||
|
||||
<button id="start" text="Start Race" align="center"/>
|
||||
|
||||
<spacer width="1" height="2%"/>
|
||||
</div>
|
||||
|
||||
<icon-button id="closePopup" x="0" y="0" width="8%" height="8%" icon="gui/back.png"/>
|
||||
</div>
|
||||
</stkgui>
|
@ -1,5 +1,10 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D Albedo;
|
||||
layout(bindless_sampler) uniform sampler2D Detail;
|
||||
#else
|
||||
uniform sampler2D Albedo;
|
||||
uniform sampler2D Detail;
|
||||
#endif
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
@ -16,6 +21,11 @@ vec3 getLightFactor(float specMapValue);
|
||||
void main(void)
|
||||
{
|
||||
vec4 color = texture(Albedo, uv);
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
#ifdef SRGBBindlessFix
|
||||
color.xyz = pow(color.xyz, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
vec4 detail = texture(Detail, uv_bis);
|
||||
color *= detail;
|
||||
vec3 LightFactor = getLightFactor(1. - color.a);
|
||||
|
8
data/shaders/glow_object.frag
Normal file
8
data/shaders/glow_object.frag
Normal file
@ -0,0 +1,8 @@
|
||||
flat in vec4 glowColor;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(glowColor.rgb, 1.0);
|
||||
}
|
24
data/shaders/glow_object.vert
Normal file
24
data/shaders/glow_object.vert
Normal file
@ -0,0 +1,24 @@
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec3 Normal;
|
||||
layout(location = 2) in vec4 Color;
|
||||
layout(location = 3) in vec2 Texcoord;
|
||||
layout(location = 5) in vec3 Tangent;
|
||||
layout(location = 6) in vec3 Bitangent;
|
||||
|
||||
layout(location = 7) in vec3 Origin;
|
||||
layout(location = 8) in vec3 Orientation;
|
||||
layout(location = 9) in vec3 Scale;
|
||||
layout(location = 12) in vec4 GlowColor;
|
||||
|
||||
flat out vec4 glowColor;
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix);
|
||||
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.);
|
||||
glowColor = GlowColor;
|
||||
}
|
@ -1,6 +1,12 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D Albedo;
|
||||
layout(bindless_sampler) uniform sampler2D dtex;
|
||||
#else
|
||||
uniform sampler2D Albedo;
|
||||
uniform vec3 SunDir;
|
||||
uniform sampler2D dtex;
|
||||
#endif
|
||||
|
||||
uniform vec3 SunDir;
|
||||
|
||||
in vec3 nor;
|
||||
in vec2 uv;
|
||||
@ -26,6 +32,11 @@ void main(void)
|
||||
float scattering = mix(fPowEdotL, fLdotNBack, .5);
|
||||
|
||||
vec4 color = texture(Albedo, uv);
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
#ifdef SRGBBindlessFix
|
||||
color.xyz = pow(color.xyz, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
if (color.a < 0.5) discard;
|
||||
vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.);
|
||||
FragColor = vec4(color.xyz * LightFactor, 1.);
|
||||
|
@ -3,6 +3,7 @@ uniform mat4 ViewMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 InverseViewMatrix;
|
||||
uniform mat4 InverseProjectionMatrix;
|
||||
uniform mat4 ProjectionViewMatrix;
|
||||
uniform vec2 screen;
|
||||
#else
|
||||
layout (std140) uniform MatrixesData
|
||||
@ -11,7 +12,8 @@ layout (std140) uniform MatrixesData
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ProjectionViewMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
#endif
|
31
data/shaders/instanced_detailledobject_pass2.frag
Normal file
31
data/shaders/instanced_detailledobject_pass2.frag
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D Albedo;
|
||||
uniform sampler2D Detail;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
flat in sampler2D secondhandle;
|
||||
#endif
|
||||
in vec2 uv;
|
||||
in vec2 uv_bis;
|
||||
out vec4 FragColor;
|
||||
|
||||
vec3 getLightFactor(float specMapValue);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 color = texture(handle, uv);
|
||||
#ifdef SRGBBindlessFix
|
||||
color.xyz = pow(color.xyz, vec3(2.2));
|
||||
#endif
|
||||
vec4 detail = texture(secondhandle, uv_bis);
|
||||
#else
|
||||
vec4 color = texture(Albedo, uv);
|
||||
vec4 detail = texture(Detail, uv_bis);
|
||||
#endif
|
||||
color *= detail;
|
||||
vec3 LightFactor = getLightFactor(1. - color.a);
|
||||
FragColor = vec4(color.xyz * LightFactor, 1.);
|
||||
}
|
@ -9,6 +9,10 @@ layout(location = 3) in vec2 Texcoord;
|
||||
layout(location = 7) in vec3 Origin;
|
||||
layout(location = 8) in vec3 Orientation;
|
||||
layout(location = 9) in vec3 Scale;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(location = 10) in sampler2D Handle;
|
||||
#endif
|
||||
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec3 Normal;
|
||||
@ -22,6 +26,9 @@ in vec3 Scale;
|
||||
|
||||
out vec3 nor;
|
||||
out vec2 uv;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat out sampler2D handle;
|
||||
#endif
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
@ -30,7 +37,10 @@ void main()
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin + windDir * Color.r, Orientation, Scale);
|
||||
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin + windDir * Color.r, Orientation, Scale) * InverseViewMatrix);
|
||||
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.);
|
||||
gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.);
|
||||
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
|
||||
uv = Texcoord;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
handle = Handle;
|
||||
#endif
|
||||
}
|
||||
|
47
data/shaders/instanced_grass_pass2.frag
Normal file
47
data/shaders/instanced_grass_pass2.frag
Normal file
@ -0,0 +1,47 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D dtex;
|
||||
#else
|
||||
uniform sampler2D Albedo;
|
||||
uniform sampler2D dtex;
|
||||
#endif
|
||||
|
||||
uniform vec3 SunDir;
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
#endif
|
||||
in vec3 nor;
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
vec3 getLightFactor(float specMapValue);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 texc = gl_FragCoord.xy / screen;
|
||||
float z = texture(dtex, texc).x;
|
||||
|
||||
vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f;
|
||||
xpos = InverseProjectionMatrix * xpos;
|
||||
xpos /= xpos.w;
|
||||
vec3 eyedir = normalize(xpos.xyz);
|
||||
|
||||
// Inspired from http://http.developer.nvidia.com/GPUGems3/gpugems3_ch16.html
|
||||
float fEdotL = max(0., dot(SunDir, eyedir));
|
||||
float fPowEdotL = pow(fEdotL, 4.);
|
||||
|
||||
float fLdotNBack = max(0., - dot(nor, SunDir) * 0.6 + 0.4);
|
||||
float scattering = mix(fPowEdotL, fLdotNBack, .5);
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 color = texture(handle, uv);
|
||||
#ifdef SRGBBindlessFix
|
||||
color.xyz = pow(color.xyz, vec3(2.2));
|
||||
#endif
|
||||
#else
|
||||
vec4 color = texture(Albedo, uv);
|
||||
#endif
|
||||
if (color.a < 0.5) discard;
|
||||
vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.);
|
||||
FragColor = vec4(color.xyz * LightFactor, 1.);
|
||||
}
|
35
data/shaders/instanced_normalmap.frag
Normal file
35
data/shaders/instanced_normalmap.frag
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D DiffuseForAlpha;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
flat in sampler2D secondhandle;
|
||||
#endif
|
||||
in vec3 tangent;
|
||||
in vec3 bitangent;
|
||||
in vec2 uv;
|
||||
out vec3 EncodedNormal;
|
||||
|
||||
vec2 EncodeNormal(vec3 n);
|
||||
|
||||
void main()
|
||||
{
|
||||
// normal in Tangent Space
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec3 TS_normal = 2.0 * texture(secondhandle, uv).rgb - 1.0;
|
||||
float alpha = texture(handle, uv).a;
|
||||
#else
|
||||
vec3 TS_normal = 2.0 * texture(normalMap, uv).rgb - 1.0;
|
||||
float alpha = texture(DiffuseForAlpha, uv).a;
|
||||
#endif
|
||||
// Because of interpolation, we need to renormalize
|
||||
vec3 Frag_tangent = normalize(tangent);
|
||||
vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent));
|
||||
vec3 Frag_bitangent = cross(Frag_normal, Frag_tangent);
|
||||
|
||||
vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal;
|
||||
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5;
|
||||
EncodedNormal.z = exp2(10. * (1. - alpha) + 1.);
|
||||
}
|
@ -9,6 +9,11 @@ layout(location = 6) in vec3 Bitangent;
|
||||
layout(location = 7) in vec3 Origin;
|
||||
layout(location = 8) in vec3 Orientation;
|
||||
layout(location = 9) in vec3 Scale;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(location = 10) in sampler2D Handle;
|
||||
layout(location = 11) in sampler2D SecondHandle;
|
||||
#endif
|
||||
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec3 Normal;
|
||||
@ -27,6 +32,10 @@ out vec3 tangent;
|
||||
out vec3 bitangent;
|
||||
out vec2 uv;
|
||||
out vec4 color;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat out sampler2D handle;
|
||||
flat out sampler2D secondhandle;
|
||||
#endif
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
@ -35,10 +44,14 @@ void main(void)
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix);
|
||||
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.);
|
||||
gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.);
|
||||
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
|
||||
tangent = (TransposeInverseModelView * vec4(Tangent, 1.)).xyz;
|
||||
bitangent = (TransposeInverseModelView * vec4(Bitangent, 1.)).xyz;
|
||||
uv = Texcoord;
|
||||
color = Color.zyxw;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
handle = Handle;
|
||||
secondhandle = SecondHandle;
|
||||
#endif
|
||||
}
|
||||
|
23
data/shaders/instanced_object_pass1.frag
Normal file
23
data/shaders/instanced_object_pass1.frag
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
#endif
|
||||
in vec3 nor;
|
||||
in vec2 uv;
|
||||
out vec3 EncodedNormal;
|
||||
|
||||
vec2 EncodeNormal(vec3 n);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 col = texture(handle, uv);
|
||||
#else
|
||||
vec4 col = texture(tex, uv);
|
||||
#endif
|
||||
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
|
||||
EncodedNormal.z = exp2(10. * (1. - col.a) + 1.);
|
||||
}
|
27
data/shaders/instanced_object_pass2.frag
Normal file
27
data/shaders/instanced_object_pass2.frag
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D Albedo;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
#endif
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
out vec4 FragColor;
|
||||
|
||||
vec3 getLightFactor(float specMapValue);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 col = texture(handle, uv);
|
||||
#ifdef SRGBBindlessFix
|
||||
col.xyz = pow(col.xyz, vec3(2.2));
|
||||
#endif
|
||||
#else
|
||||
vec4 col = texture(Albedo, uv);
|
||||
#endif
|
||||
col.xyz *= pow(color.xyz, vec3(2.2));
|
||||
vec3 LightFactor = getLightFactor(1.);
|
||||
FragColor = vec4(col.xyz * LightFactor, 1.);
|
||||
}
|
26
data/shaders/instanced_object_unlit.frag
Normal file
26
data/shaders/instanced_object_unlit.frag
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
#endif
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 col = texture(handle, uv);
|
||||
#ifdef SRGBBindlessFix
|
||||
col.xyz = pow(col.xyz, vec3(2.2));
|
||||
#endif
|
||||
#else
|
||||
vec4 col = texture(tex, uv);
|
||||
#endif
|
||||
col.xyz *= pow(color.xyz, vec3(2.2));
|
||||
if (col.a < 0.5) discard;
|
||||
FragColor = vec4(col.xyz, 1.);
|
||||
}
|
35
data/shaders/instanced_objectpass_spheremap.frag
Normal file
35
data/shaders/instanced_objectpass_spheremap.frag
Normal file
@ -0,0 +1,35 @@
|
||||
// See http://www.ozone3d.net/tutorials/glsl_texturing_p04.php for ref
|
||||
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
#endif
|
||||
in vec3 nor;
|
||||
out vec4 FragColor;
|
||||
|
||||
|
||||
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
|
||||
vec3 getLightFactor(float specMapValue);
|
||||
|
||||
void main() {
|
||||
vec3 texc = gl_FragCoord.xyz / vec3(screen, 1.);
|
||||
vec3 u = getPosFromUVDepth(texc, InverseProjectionMatrix).xyz;
|
||||
vec3 r = reflect(u, nor);
|
||||
|
||||
float m = 2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0));
|
||||
r.y = - r.y;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 detail0 = texture(handle, r.xy / m + .5);
|
||||
#ifdef SRGBBindlessFix
|
||||
detail0.xyz = pow(detail0.xyz, vec3(2.2));
|
||||
#endif
|
||||
#else
|
||||
vec4 detail0 = texture(tex, r.xy / m + .5);
|
||||
#endif
|
||||
vec3 LightFactor = getLightFactor(1.);
|
||||
|
||||
FragColor = vec4(detail0.xyz * LightFactor, 1.);
|
||||
}
|
25
data/shaders/instanced_objectref_pass1.frag
Normal file
25
data/shaders/instanced_objectref_pass1.frag
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
#endif
|
||||
in vec3 nor;
|
||||
in vec2 uv;
|
||||
out vec3 EncodedNormal;
|
||||
|
||||
vec2 EncodeNormal(vec3 n);
|
||||
|
||||
void main() {
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 col = texture(handle, uv);
|
||||
#else
|
||||
vec4 col = texture(tex, uv);
|
||||
#endif
|
||||
if (col.a < 0.5)
|
||||
discard;
|
||||
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
|
||||
EncodedNormal.z = 1.;
|
||||
}
|
||||
|
28
data/shaders/instanced_objectref_pass2.frag
Normal file
28
data/shaders/instanced_objectref_pass2.frag
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D Albedo;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
#endif
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
out vec4 FragColor;
|
||||
|
||||
vec3 getLightFactor(float specMapValue);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 col = texture(handle, uv);
|
||||
#ifdef SRGBBindlessFix
|
||||
col.xyz = pow(col.xyz, vec3(2.2));
|
||||
#endif
|
||||
#else
|
||||
vec4 col = texture(Albedo, uv);
|
||||
#endif
|
||||
col.xyz *= pow(color.xyz, vec3(2.2));
|
||||
if (col.a * color.a < 0.5) discard;
|
||||
vec3 LightFactor = getLightFactor(1.);
|
||||
FragColor = vec4(col.xyz * LightFactor, 1.);
|
||||
}
|
27
data/shaders/instanced_rsm.frag
Normal file
27
data/shaders/instanced_rsm.frag
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
in vec2 uv;
|
||||
in vec3 nor;
|
||||
in vec4 color;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in uvec2 handle;
|
||||
#endif
|
||||
layout (location = 0) out vec3 RSMColor;
|
||||
layout (location = 1) out vec3 RSMNormals;
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 col = texture(sampler2D(handle), uv);
|
||||
#ifdef SRGBBindlessFix
|
||||
col.xyz = pow(col.xyz, vec3(2.2));
|
||||
#endif
|
||||
#else
|
||||
vec4 col = texture(tex, uv);
|
||||
#endif
|
||||
if (col.a < .5) discard;
|
||||
RSMColor = col.xyz * color.rgb;
|
||||
RSMNormals = .5 * normalize(nor) + .5;
|
||||
}
|
39
data/shaders/instanced_rsm.vert
Normal file
39
data/shaders/instanced_rsm.vert
Normal file
@ -0,0 +1,39 @@
|
||||
uniform mat4 RSMMatrix;
|
||||
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec3 Normal;
|
||||
layout(location = 2) in vec4 Color;
|
||||
layout(location = 3) in vec2 Texcoord;
|
||||
layout(location = 4) in vec2 SecondTexcoord;
|
||||
layout(location = 7) in vec3 Origin;
|
||||
layout(location = 8) in vec3 Orientation;
|
||||
layout(location = 9) in vec3 Scale;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(location = 10) in uvec2 Handle;
|
||||
#endif
|
||||
|
||||
out vec3 nor;
|
||||
out vec2 uv;
|
||||
out vec2 uv_bis;
|
||||
out vec4 color;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat out uvec2 handle;
|
||||
#endif
|
||||
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||
mat4 ModelViewProjectionMatrix = RSMMatrix * ModelMatrix;
|
||||
mat4 TransposeInverseModel = transpose(inverse(ModelMatrix));
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
|
||||
nor = (TransposeInverseModel * vec4(Normal, 0.)).xyz;
|
||||
uv = Texcoord;
|
||||
color = Color.zyxw;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
handle = Handle;
|
||||
#endif
|
||||
}
|
28
data/shaders/instanced_shadow.geom
Normal file
28
data/shaders/instanced_shadow.geom
Normal file
@ -0,0 +1,28 @@
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices=3) out;
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in uvec2 hdle[3];
|
||||
#endif
|
||||
in vec2 tc[3];
|
||||
in int layerId[3];
|
||||
|
||||
out vec2 uv;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
out flat uvec2 handle;
|
||||
#endif
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Layer = layerId[0];
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
handle = hdle[0];
|
||||
#endif
|
||||
for(int i=0; i<3; i++)
|
||||
{
|
||||
uv = tc[i];
|
||||
gl_Position = gl_in[i].gl_Position;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
21
data/shaders/instanced_shadowref.frag
Normal file
21
data/shaders/instanced_shadowref.frag
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in uvec2 handle;
|
||||
#endif
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 col = texture(sampler2D(handle), uv);
|
||||
#else
|
||||
vec4 col = texture(tex, uv);
|
||||
#endif
|
||||
if (col.a < 0.5) discard;
|
||||
FragColor = vec4(1.);
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
uniform int layer;
|
||||
|
||||
uniform vec3 windDir;
|
||||
#if __VERSION__ >= 330
|
||||
layout(location = 0) in vec3 Position;
|
||||
@ -7,6 +9,10 @@ layout(location = 3) in vec2 Texcoord;
|
||||
layout(location = 7) in vec3 Origin;
|
||||
layout(location = 8) in vec3 Orientation;
|
||||
layout(location = 9) in vec3 Scale;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(location = 10) in uvec2 Handle;
|
||||
#endif
|
||||
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec4 Color;
|
||||
@ -19,9 +25,15 @@ in vec3 Scale;
|
||||
|
||||
#ifdef VSLayer
|
||||
out vec2 uv;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat out uvec2 handle;
|
||||
#endif
|
||||
#else
|
||||
out vec2 tc;
|
||||
out int layerId;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat out uvec2 hdle;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
@ -31,12 +43,18 @@ void main(void)
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||
#ifdef VSLayer
|
||||
gl_Layer = gl_InstanceID & 3;
|
||||
gl_Layer = layer;
|
||||
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
|
||||
uv = Texcoord;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
handle = Handle;
|
||||
#endif
|
||||
#else
|
||||
layerId = gl_InstanceID & 3;
|
||||
layerId = layer;
|
||||
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
|
||||
tc = Texcoord;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
hdle = Handle;
|
||||
#endif
|
||||
#endif
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
uniform int layer;
|
||||
|
||||
#if __VERSION__ >= 330
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 3) in vec2 Texcoord;
|
||||
@ -5,6 +7,10 @@ layout(location = 3) in vec2 Texcoord;
|
||||
layout(location = 7) in vec3 Origin;
|
||||
layout(location = 8) in vec3 Orientation;
|
||||
layout(location = 9) in vec3 Scale;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(location = 10) in uvec2 Handle;
|
||||
#endif
|
||||
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec2 Texcoord;
|
||||
@ -16,9 +22,15 @@ in vec3 Scale;
|
||||
|
||||
#ifdef VSLayer
|
||||
out vec2 uv;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat out uvec2 handle;
|
||||
#endif
|
||||
#else
|
||||
out vec2 tc;
|
||||
out int layerId;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat out uvec2 hdle;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
@ -28,12 +40,18 @@ void main(void)
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||
#ifdef VSLayer
|
||||
gl_Layer = gl_InstanceID & 3;
|
||||
gl_Layer = layer;
|
||||
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.);
|
||||
uv = Texcoord;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
handle = Handle;
|
||||
#endif
|
||||
#else
|
||||
layerId = gl_InstanceID & 3;
|
||||
layerId = layer;
|
||||
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
|
||||
tc = Texcoord;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
hdle = Handle;
|
||||
#endif
|
||||
#endif
|
||||
}
|
@ -1,5 +1,10 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D normalMap;
|
||||
layout(bindless_sampler) uniform sampler2D DiffuseForAlpha;
|
||||
#else
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D DiffuseForAlpha;
|
||||
#endif
|
||||
|
||||
in vec3 tangent;
|
||||
in vec3 bitangent;
|
||||
|
@ -1,4 +1,8 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D tex;
|
||||
#else
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec3 nor;
|
||||
|
@ -1,4 +1,8 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D Albedo;
|
||||
#else
|
||||
uniform sampler2D Albedo;
|
||||
#endif
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
@ -8,7 +12,14 @@ vec3 getLightFactor(float specMapValue);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 col = texture(Albedo, uv);
|
||||
#ifdef SRGBBindlessFix
|
||||
col.xyz = pow(col.xyz, vec3(2.2));
|
||||
#endif
|
||||
#else
|
||||
vec4 col = texture(Albedo, uv);
|
||||
#endif
|
||||
col.xyz *= pow(color.xyz, vec3(2.2));
|
||||
vec3 LightFactor = getLightFactor(1.);
|
||||
FragColor = vec4(col.xyz * LightFactor, 1.);
|
||||
|
@ -1,4 +1,8 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D tex;
|
||||
#else
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
@ -7,6 +11,11 @@ out vec4 FragColor;
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = texture(tex, uv);
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
#ifdef SRGBBindlessFix
|
||||
col.xyz = pow(col.xyz, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
col.xyz *= pow(color.xyz, vec3(2.2));
|
||||
if (col.a < 0.5) discard;
|
||||
FragColor = vec4(col.xyz, 1.);
|
||||
|
@ -1,6 +1,10 @@
|
||||
// See http://www.ozone3d.net/tutorials/glsl_texturing_p04.php for ref
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D tex;
|
||||
#else
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec3 nor;
|
||||
@ -21,6 +25,11 @@ void main() {
|
||||
float m = 2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0));
|
||||
r.y = - r.y;
|
||||
vec4 detail0 = texture(tex, r.xy / m + .5);
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
#ifdef SRGBBindlessFix
|
||||
detail0.xyz = pow(detail0.xyz, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
vec3 LightFactor = getLightFactor(1.);
|
||||
|
||||
FragColor = vec4(detail0.xyz * LightFactor, 1.);
|
||||
|
@ -1,4 +1,8 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D tex;
|
||||
#else
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec3 nor;
|
||||
|
@ -1,4 +1,8 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D Albedo;
|
||||
#else
|
||||
uniform sampler2D Albedo;
|
||||
#endif
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
@ -9,6 +13,11 @@ vec3 getLightFactor(float specMapValue);
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = texture(Albedo, uv);
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
#ifdef SRGBBindlessFix
|
||||
col.xyz = pow(col.xyz, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
col.xyz *= pow(color.xyz, vec3(2.2));
|
||||
if (col.a * color.a < 0.5) discard;
|
||||
vec3 LightFactor = getLightFactor(1.);
|
||||
|
@ -1,6 +1,5 @@
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D dtex;
|
||||
uniform float spec;
|
||||
|
||||
flat in vec3 center;
|
||||
flat in float energy;
|
||||
|
@ -1,3 +1,4 @@
|
||||
uniform int layer;
|
||||
uniform mat4 ModelMatrix;
|
||||
|
||||
#if __VERSION__ >= 330
|
||||
@ -18,11 +19,11 @@ out int layerId;
|
||||
void main(void)
|
||||
{
|
||||
#ifdef VSLayer
|
||||
gl_Layer = gl_InstanceID & 3;
|
||||
gl_Layer = layer;
|
||||
uv = Texcoord;
|
||||
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.);
|
||||
#else
|
||||
layerId = gl_InstanceID & 3;
|
||||
layerId = layer;
|
||||
tc = Texcoord;
|
||||
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
|
||||
#endif
|
||||
|
@ -1,3 +1,4 @@
|
||||
uniform int layer;
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform vec3 windDir;
|
||||
|
||||
@ -21,11 +22,11 @@ out int layerId;
|
||||
void main(void)
|
||||
{
|
||||
#ifdef VSLayer
|
||||
gl_Layer = gl_InstanceID & 3;
|
||||
gl_Layer = layer;
|
||||
uv = Texcoord;
|
||||
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
|
||||
#else
|
||||
layerId = gl_InstanceID & 3;
|
||||
layerId = layer;
|
||||
tc = Texcoord;
|
||||
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
|
||||
#endif
|
||||
|
@ -1,8 +1,16 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D tex_layout;
|
||||
layout(bindless_sampler) uniform sampler2D tex_detail0;
|
||||
layout(bindless_sampler) uniform sampler2D tex_detail1;
|
||||
layout(bindless_sampler) uniform sampler2D tex_detail2;
|
||||
layout(bindless_sampler) uniform sampler2D tex_detail3;
|
||||
#else
|
||||
uniform sampler2D tex_layout;
|
||||
uniform sampler2D tex_detail0;
|
||||
uniform sampler2D tex_detail1;
|
||||
uniform sampler2D tex_detail2;
|
||||
uniform sampler2D tex_detail3;
|
||||
#endif
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
in vec2 uv;
|
||||
@ -24,6 +32,14 @@ void main() {
|
||||
vec4 detail2 = texture(tex_detail2, uv);
|
||||
vec4 detail3 = texture(tex_detail3, uv);
|
||||
vec4 detail4 = vec4(0.0);
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
#ifdef SRGBBindlessFix
|
||||
detail0.xyz = pow(detail0.xyz, vec3(2.2));
|
||||
detail1.xyz = pow(detail1.xyz, vec3(2.2));
|
||||
detail2.xyz = pow(detail2.xyz, vec3(2.2));
|
||||
detail3.xyz = pow(detail3.xyz, vec3(2.2));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec4 splatted = splatting.r * detail0 +
|
||||
splatting.g * detail1 +
|
||||
|
@ -1,4 +1,8 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D tex;
|
||||
#else
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
@ -8,6 +12,9 @@ out vec4 FragColor;
|
||||
void main()
|
||||
{
|
||||
vec4 Color = texture(tex, uv);
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
Color.xyz = pow(Color.xyz, vec3(2.2));
|
||||
#endif
|
||||
Color.xyz *= pow(color.xyz, vec3(2.2));
|
||||
Color.a *= color.a;
|
||||
// Premultiply alpha
|
||||
|
@ -1,4 +1,9 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D tex;
|
||||
#else
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
|
||||
uniform float fogmax;
|
||||
uniform float startH;
|
||||
@ -15,6 +20,9 @@ out vec4 FragColor;
|
||||
void main()
|
||||
{
|
||||
vec4 diffusecolor = texture(tex, uv);
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
diffusecolor.xyz = pow(diffusecolor.xyz, vec3(2.2));
|
||||
#endif
|
||||
diffusecolor.xyz *= pow(color.xyz, vec3(2.2));
|
||||
diffusecolor.a *= color.a;
|
||||
vec3 tmp = vec3(gl_FragCoord.xy / screen, gl_FragCoord.z);
|
||||
|
@ -1,6 +1,12 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D DiffuseMap;
|
||||
layout(bindless_sampler) uniform sampler2D SpecularMap;
|
||||
layout(bindless_sampler) uniform sampler2D SSAO;
|
||||
#else
|
||||
uniform sampler2D DiffuseMap;
|
||||
uniform sampler2D SpecularMap;
|
||||
uniform sampler2D SSAO;
|
||||
#endif
|
||||
|
||||
vec3 getLightFactor(float specMapValue)
|
||||
{
|
||||
|
@ -45,6 +45,6 @@ mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale)
|
||||
{
|
||||
mat4 result = transpose(getMatrixFromRotation(rotation));
|
||||
// FIXME: it's wrong but the fourth column is not used
|
||||
result[3].xyz -= translation;
|
||||
// result[3].xyz -= translation;
|
||||
return getScaleMatrix(1. / scale) * result;
|
||||
}
|
@ -155,12 +155,13 @@
|
||||
otherwise obstricts too much of the view. -->
|
||||
<camera distance="1.5" forward-up-angle="15"
|
||||
backward-up-angle="30"/>
|
||||
<!-- Additional offset to move graphical chassis with regards to the physics. -->
|
||||
<graphics y-offset="0.0"/>
|
||||
|
||||
<!-- Jump animation related values:
|
||||
animation-time: only if the estimated time for a jump is larger
|
||||
than this value will the jump animation being
|
||||
shown. -->
|
||||
<jump animation-time="0.5" />
|
||||
<!-- Jump animation related values:
|
||||
animation-time: only if the estimated time for a jump is larger
|
||||
than this value will the jump animation being shown. -->
|
||||
<jump animation-time="0.5" />
|
||||
|
||||
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
|
||||
decrease: multiplicative decrease of skidding factor in each frame.
|
||||
@ -415,11 +416,14 @@
|
||||
physical-wheel-position: Defines where the 'physical' (raycast)
|
||||
wheel will be located. It's a weight factor with 0 = being
|
||||
at the widest side of the bevel, 1 = at the front and
|
||||
narrowest part of the kart. -->
|
||||
narrowest part of the kart. If the value is less than 0, the old
|
||||
physics settings are used which places the raycast wheels
|
||||
outside of the chassis and results in more stable physical
|
||||
behaviour of the karts. -->
|
||||
<collision impulse-type="normal"
|
||||
impulse="3000" impulse-time="0.1" terrain-impulse="8000"
|
||||
impulse="3000" impulse-time="0.1" terrain-impulse="1600"
|
||||
restitution="1.0" bevel-factor="0.5 0.0 0.7"
|
||||
physical-wheel-position="0.5" />
|
||||
physical-wheel-position="-1" />
|
||||
|
||||
<!-- If a kart starts within the specified time after 'go',
|
||||
it receives the corresponding bonus from 'boost'. Those
|
||||
|
@ -1,15 +1,14 @@
|
||||
[Desktop Entry]
|
||||
Name=SuperTuxKart
|
||||
Icon=@PREFIX@/share/pixmaps/supertuxkart_128.png
|
||||
Icon=supertuxkart
|
||||
GenericName=A kart racing game
|
||||
GenericName[de]=Ein Kart-Rennspiel
|
||||
GenericName[fr]=Un jeu de karting
|
||||
GenericName[gl]=Xogo de carreiras con karts
|
||||
GenericName[pl]=Wyścigi gokartów
|
||||
GenericName[ro]=Un joc de curse cu carturi
|
||||
Exec=@PREFIX@/@STK_INSTALL_BINARY_DIR@/supertuxkart --no-console
|
||||
Exec=supertuxkart
|
||||
Terminal=false
|
||||
StartupNotify=false
|
||||
Type=Application
|
||||
TryExec=@PREFIX@/@STK_INSTALL_BINARY_DIR@/supertuxkart
|
||||
Categories=Game;ArcadeGame;
|
@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
@ -24,6 +24,12 @@ subject to the following restrictions:
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__) && __cplusplus >= 201103
|
||||
#include <cmath>
|
||||
using std::isinf;
|
||||
using std::isnan;
|
||||
#endif
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
//island management, m_activationState1
|
||||
@ -51,7 +57,7 @@ typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
|
||||
#endif
|
||||
|
||||
|
||||
/// btCollisionObject can be used to manage collision detection objects.
|
||||
/// btCollisionObject can be used to manage collision detection objects.
|
||||
/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
|
||||
/// They can be added to the btCollisionWorld.
|
||||
ATTRIBUTE_ALIGNED16(class) btCollisionObject
|
||||
@ -64,20 +70,20 @@ protected:
|
||||
///m_interpolationWorldTransform is used for CCD and interpolation
|
||||
///it can be either previous or future (predicted) transform
|
||||
btTransform m_interpolationWorldTransform;
|
||||
//those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
|
||||
//those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
|
||||
//without destroying the continuous interpolated motion (which uses this interpolation velocities)
|
||||
btVector3 m_interpolationLinearVelocity;
|
||||
btVector3 m_interpolationAngularVelocity;
|
||||
|
||||
|
||||
btVector3 m_anisotropicFriction;
|
||||
int m_hasAnisotropicFriction;
|
||||
btScalar m_contactProcessingThreshold;
|
||||
btScalar m_contactProcessingThreshold;
|
||||
|
||||
btBroadphaseProxy* m_broadphaseHandle;
|
||||
btCollisionShape* m_collisionShape;
|
||||
///m_extensionPointer is used by some internal low-level Bullet extensions.
|
||||
void* m_extensionPointer;
|
||||
|
||||
|
||||
///m_rootCollisionShape is temporarily used to store the original collision shape
|
||||
///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
|
||||
///If it is NULL, the m_collisionShape is not temporarily replaced.
|
||||
@ -102,14 +108,14 @@ protected:
|
||||
void* m_userObjectPointer;
|
||||
|
||||
///time of impact calculation
|
||||
btScalar m_hitFraction;
|
||||
|
||||
btScalar m_hitFraction;
|
||||
|
||||
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
|
||||
btScalar m_ccdSweptSphereRadius;
|
||||
|
||||
/// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
|
||||
btScalar m_ccdMotionThreshold;
|
||||
|
||||
|
||||
/// If some object should have elaborate collision filtering by sub-classes
|
||||
int m_checkCollideWith;
|
||||
|
||||
@ -194,7 +200,7 @@ public:
|
||||
return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
btCollisionObject();
|
||||
|
||||
virtual ~btCollisionObject();
|
||||
@ -232,7 +238,7 @@ public:
|
||||
m_collisionShape = collisionShape;
|
||||
}
|
||||
|
||||
///Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
|
||||
///Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
|
||||
///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
|
||||
void* internalGetExtensionPointer() const
|
||||
{
|
||||
@ -246,7 +252,7 @@ public:
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;}
|
||||
|
||||
|
||||
void setActivationState(int newState);
|
||||
|
||||
void setDeactivationTime(btScalar time)
|
||||
@ -385,7 +391,7 @@ public:
|
||||
|
||||
SIMD_FORCE_INLINE btScalar getHitFraction() const
|
||||
{
|
||||
return m_hitFraction;
|
||||
return m_hitFraction;
|
||||
}
|
||||
|
||||
void setHitFraction(btScalar hitFraction)
|
||||
@ -393,7 +399,7 @@ public:
|
||||
m_hitFraction = hitFraction;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int getCollisionFlags() const
|
||||
{
|
||||
return m_collisionFlags;
|
||||
@ -403,7 +409,7 @@ public:
|
||||
{
|
||||
m_collisionFlags = flags;
|
||||
}
|
||||
|
||||
|
||||
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
|
||||
btScalar getCcdSweptSphereRadius() const
|
||||
{
|
||||
@ -439,7 +445,7 @@ public:
|
||||
{
|
||||
return m_userObjectPointer;
|
||||
}
|
||||
|
||||
|
||||
///users can point to their objects, userPointer is not used by Bullet
|
||||
void setUserPointer(void* userPointer)
|
||||
{
|
||||
@ -477,11 +483,11 @@ struct btCollisionObjectDoubleData
|
||||
btVector3DoubleData m_interpolationLinearVelocity;
|
||||
btVector3DoubleData m_interpolationAngularVelocity;
|
||||
btVector3DoubleData m_anisotropicFriction;
|
||||
double m_contactProcessingThreshold;
|
||||
double m_contactProcessingThreshold;
|
||||
double m_deactivationTime;
|
||||
double m_friction;
|
||||
double m_restitution;
|
||||
double m_hitFraction;
|
||||
double m_hitFraction;
|
||||
double m_ccdSweptSphereRadius;
|
||||
double m_ccdMotionThreshold;
|
||||
|
||||
@ -509,11 +515,11 @@ struct btCollisionObjectFloatData
|
||||
btVector3FloatData m_interpolationLinearVelocity;
|
||||
btVector3FloatData m_interpolationAngularVelocity;
|
||||
btVector3FloatData m_anisotropicFriction;
|
||||
float m_contactProcessingThreshold;
|
||||
float m_contactProcessingThreshold;
|
||||
float m_deactivationTime;
|
||||
float m_friction;
|
||||
float m_restitution;
|
||||
float m_hitFraction;
|
||||
float m_hitFraction;
|
||||
float m_ccdSweptSphereRadius;
|
||||
float m_ccdMotionThreshold;
|
||||
|
||||
|
@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
@ -26,6 +26,11 @@ subject to the following restrictions:
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#if defined(__MINGW32__) && __cplusplus >= 201103
|
||||
#include <cmath>
|
||||
using std::isnan;
|
||||
#endif
|
||||
|
||||
class btCollisionShape;
|
||||
class btMotionState;
|
||||
class btTypedConstraint;
|
||||
@ -51,7 +56,7 @@ enum btRigidBodyFlags
|
||||
|
||||
///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
|
||||
///It is recommended for performance and memory use to share btCollisionShape objects whenever possible.
|
||||
///There are 3 types of rigid bodies:
|
||||
///There are 3 types of rigid bodies:
|
||||
///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics.
|
||||
///- B) Fixed objects with zero mass. They are not moving (basically collision objects)
|
||||
///- C) Kinematic objects, which are objects without mass, but the user can move them. There is on-way interaction, and Bullet calculates a velocity based on the timestep and previous and current world transform.
|
||||
@ -66,12 +71,12 @@ class btRigidBody : public btCollisionObject
|
||||
btScalar m_inverseMass;
|
||||
btVector3 m_linearFactor;
|
||||
|
||||
btVector3 m_gravity;
|
||||
btVector3 m_gravity;
|
||||
btVector3 m_gravity_acceleration;
|
||||
btVector3 m_invInertiaLocal;
|
||||
btVector3 m_totalForce;
|
||||
btVector3 m_totalTorque;
|
||||
|
||||
|
||||
btScalar m_linearDamping;
|
||||
btScalar m_angularDamping;
|
||||
|
||||
@ -92,9 +97,9 @@ class btRigidBody : public btCollisionObject
|
||||
btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
|
||||
|
||||
int m_rigidbodyFlags;
|
||||
|
||||
|
||||
int m_debugBodyId;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@ -111,7 +116,7 @@ public:
|
||||
|
||||
///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
|
||||
///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument)
|
||||
///You can use the motion state to synchronize the world transform between physics and graphics objects.
|
||||
///You can use the motion state to synchronize the world transform between physics and graphics objects.
|
||||
///And if the motion state is provided, the rigid body will initialize its initial world transform from the motion state,
|
||||
///m_startWorldTransform is only used when you don't provide a motion state.
|
||||
struct btRigidBodyConstructionInfo
|
||||
@ -168,16 +173,16 @@ public:
|
||||
///btRigidBody constructor using construction info
|
||||
btRigidBody( const btRigidBodyConstructionInfo& constructionInfo);
|
||||
|
||||
///btRigidBody constructor for backwards compatibility.
|
||||
///btRigidBody constructor for backwards compatibility.
|
||||
///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo)
|
||||
btRigidBody( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));
|
||||
|
||||
|
||||
virtual ~btRigidBody()
|
||||
{
|
||||
{
|
||||
//No constraints should point to this rigidbody
|
||||
//Remove constraints from the dynamics world before you delete the related rigidbodies.
|
||||
btAssert(m_constraintRefs.size()==0);
|
||||
//Remove constraints from the dynamics world before you delete the related rigidbodies.
|
||||
btAssert(m_constraintRefs.size()==0);
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -187,8 +192,8 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
void proceedToTransform(const btTransform& newTrans);
|
||||
|
||||
void proceedToTransform(const btTransform& newTrans);
|
||||
|
||||
///to keep collision detection and dynamics separate we don't store a rigidbody pointer
|
||||
///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast
|
||||
static const btRigidBody* upcast(const btCollisionObject* colObj)
|
||||
@ -203,15 +208,15 @@ public:
|
||||
return (btRigidBody*)colObj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// continuous collision detection needs prediction
|
||||
void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
|
||||
|
||||
|
||||
void saveKinematicState(btScalar step);
|
||||
|
||||
|
||||
void applyGravity();
|
||||
|
||||
void setGravity(const btVector3& acceleration);
|
||||
|
||||
void setGravity(const btVector3& acceleration);
|
||||
|
||||
const btVector3& getGravity() const
|
||||
{
|
||||
@ -249,9 +254,9 @@ public:
|
||||
SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() {
|
||||
return m_collisionShape;
|
||||
}
|
||||
|
||||
|
||||
void setMassProps(btScalar mass, const btVector3& inertia);
|
||||
|
||||
|
||||
const btVector3& getLinearFactor() const
|
||||
{
|
||||
return m_linearFactor;
|
||||
@ -265,10 +270,10 @@ public:
|
||||
m_invMass = m_linearFactor*m_inverseMass;
|
||||
}
|
||||
btScalar getInvMass() const { return m_inverseMass; }
|
||||
const btMatrix3x3& getInvInertiaTensorWorld() const {
|
||||
return m_invInertiaTensorWorld;
|
||||
const btMatrix3x3& getInvInertiaTensorWorld() const {
|
||||
return m_invInertiaTensorWorld;
|
||||
}
|
||||
|
||||
|
||||
void integrateVelocities(btScalar step);
|
||||
|
||||
void setCenterOfMassTransform(const btTransform& xform);
|
||||
@ -290,7 +295,7 @@ public:
|
||||
{
|
||||
return m_totalTorque;
|
||||
};
|
||||
|
||||
|
||||
const btVector3& getInvInertiaDiagLocal() const
|
||||
{
|
||||
return m_invInertiaLocal;
|
||||
@ -314,8 +319,8 @@ public:
|
||||
btAssert(!isnan(torque.getZ()));
|
||||
m_totalTorque += torque*m_angularFactor;
|
||||
}
|
||||
|
||||
void applyForce(const btVector3& force, const btVector3& rel_pos)
|
||||
|
||||
void applyForce(const btVector3& force, const btVector3& rel_pos)
|
||||
{
|
||||
btAssert(!isnan(force.getX()));
|
||||
btAssert(!isnan(force.getY()));
|
||||
@ -326,7 +331,7 @@ public:
|
||||
applyCentralForce(force);
|
||||
applyTorque(rel_pos.cross(force*m_linearFactor));
|
||||
}
|
||||
|
||||
|
||||
void applyCentralImpulse(const btVector3& impulse)
|
||||
{
|
||||
btAssert(!isnan(impulse.getX()));
|
||||
@ -334,7 +339,7 @@ public:
|
||||
btAssert(!isnan(impulse.getZ()));
|
||||
m_linearVelocity += impulse *m_linearFactor * m_inverseMass;
|
||||
}
|
||||
|
||||
|
||||
void applyTorqueImpulse(const btVector3& torque)
|
||||
{
|
||||
btAssert(!isnan(torque.getX()));
|
||||
@ -342,8 +347,8 @@ public:
|
||||
btAssert(!isnan(torque.getZ()));
|
||||
m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
|
||||
}
|
||||
|
||||
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
|
||||
|
||||
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
|
||||
{
|
||||
btAssert(!isnan(impulse.getX()));
|
||||
btAssert(!isnan(impulse.getY()));
|
||||
@ -361,44 +366,44 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void clearForces()
|
||||
void clearForces()
|
||||
{
|
||||
m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
|
||||
m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
|
||||
}
|
||||
|
||||
void updateInertiaTensor();
|
||||
|
||||
const btVector3& getCenterOfMassPosition() const {
|
||||
return m_worldTransform.getOrigin();
|
||||
|
||||
void updateInertiaTensor();
|
||||
|
||||
const btVector3& getCenterOfMassPosition() const {
|
||||
return m_worldTransform.getOrigin();
|
||||
}
|
||||
btQuaternion getOrientation() const;
|
||||
|
||||
const btTransform& getCenterOfMassTransform() const {
|
||||
return m_worldTransform;
|
||||
|
||||
const btTransform& getCenterOfMassTransform() const {
|
||||
return m_worldTransform;
|
||||
}
|
||||
const btVector3& getLinearVelocity() const {
|
||||
return m_linearVelocity;
|
||||
const btVector3& getLinearVelocity() const {
|
||||
return m_linearVelocity;
|
||||
}
|
||||
const btVector3& getAngularVelocity() const {
|
||||
return m_angularVelocity;
|
||||
const btVector3& getAngularVelocity() const {
|
||||
return m_angularVelocity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void setLinearVelocity(const btVector3& lin_vel)
|
||||
{
|
||||
{
|
||||
btAssert(!isnan(lin_vel.getX()));
|
||||
btAssert(!isnan(lin_vel.getY()));
|
||||
btAssert(!isnan(lin_vel.getZ()));
|
||||
m_linearVelocity = lin_vel;
|
||||
m_linearVelocity = lin_vel;
|
||||
}
|
||||
|
||||
inline void setAngularVelocity(const btVector3& ang_vel)
|
||||
{
|
||||
inline void setAngularVelocity(const btVector3& ang_vel)
|
||||
{
|
||||
btAssert(!isnan(ang_vel.getX()));
|
||||
btAssert(!isnan(ang_vel.getY()));
|
||||
btAssert(!isnan(ang_vel.getZ()));
|
||||
m_angularVelocity = ang_vel;
|
||||
m_angularVelocity = ang_vel;
|
||||
}
|
||||
|
||||
btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
|
||||
@ -410,18 +415,18 @@ public:
|
||||
// return (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
|
||||
}
|
||||
|
||||
void translate(const btVector3& v)
|
||||
void translate(const btVector3& v)
|
||||
{
|
||||
m_worldTransform.getOrigin() += v;
|
||||
m_worldTransform.getOrigin() += v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
|
||||
{
|
||||
btVector3 r0 = pos - getCenterOfMassPosition();
|
||||
@ -478,12 +483,12 @@ public:
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const btBroadphaseProxy* getBroadphaseProxy() const
|
||||
{
|
||||
return m_broadphaseHandle;
|
||||
}
|
||||
btBroadphaseProxy* getBroadphaseProxy()
|
||||
btBroadphaseProxy* getBroadphaseProxy()
|
||||
{
|
||||
return m_broadphaseHandle;
|
||||
}
|
||||
@ -567,12 +572,12 @@ public:
|
||||
return m_deltaAngularVelocity;
|
||||
}
|
||||
|
||||
const btVector3& getPushVelocity() const
|
||||
const btVector3& getPushVelocity() const
|
||||
{
|
||||
return m_pushVelocity;
|
||||
}
|
||||
|
||||
const btVector3& getTurnVelocity() const
|
||||
const btVector3& getTurnVelocity() const
|
||||
{
|
||||
return m_turnVelocity;
|
||||
}
|
||||
@ -580,7 +585,7 @@ public:
|
||||
|
||||
////////////////////////////////////////////////
|
||||
///some internal methods, don't use them
|
||||
|
||||
|
||||
btVector3& internalGetDeltaLinearVelocity()
|
||||
{
|
||||
return m_deltaLinearVelocity;
|
||||
@ -600,7 +605,7 @@ public:
|
||||
{
|
||||
return m_invMass;
|
||||
}
|
||||
|
||||
|
||||
btVector3& internalGetPushVelocity()
|
||||
{
|
||||
return m_pushVelocity;
|
||||
@ -640,7 +645,7 @@ public:
|
||||
m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void internalWritebackVelocity()
|
||||
{
|
||||
if (m_inverseMass)
|
||||
@ -656,7 +661,7 @@ public:
|
||||
|
||||
void internalWritebackVelocity(btScalar timeStep);
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
@ -679,7 +684,7 @@ struct btRigidBodyFloatData
|
||||
btVector3FloatData m_angularVelocity;
|
||||
btVector3FloatData m_angularFactor;
|
||||
btVector3FloatData m_linearFactor;
|
||||
btVector3FloatData m_gravity;
|
||||
btVector3FloatData m_gravity;
|
||||
btVector3FloatData m_gravity_acceleration;
|
||||
btVector3FloatData m_invInertiaLocal;
|
||||
btVector3FloatData m_totalForce;
|
||||
@ -705,7 +710,7 @@ struct btRigidBodyDoubleData
|
||||
btVector3DoubleData m_angularVelocity;
|
||||
btVector3DoubleData m_angularFactor;
|
||||
btVector3DoubleData m_linearFactor;
|
||||
btVector3DoubleData m_gravity;
|
||||
btVector3DoubleData m_gravity;
|
||||
btVector3DoubleData m_gravity_acceleration;
|
||||
btVector3DoubleData m_invInertiaLocal;
|
||||
btVector3DoubleData m_totalForce;
|
||||
|
@ -21,6 +21,10 @@ add_library(enet STATIC
|
||||
win32.c
|
||||
)
|
||||
|
||||
if(MINGW)
|
||||
target_link_libraries(enet wsock32 ws2_32 Winmm)
|
||||
endif()
|
||||
|
||||
#if(WIN32)
|
||||
# find_library(WS2_LIBRARY NAMES "ws2_32" PATHS "C:/Windows/System32")
|
||||
# target_link_libraries(enet ${WS2_LIBRARY})
|
||||
|
@ -16,6 +16,9 @@ add_definitions(-DNDEBUG=1 -DIRRLICHT_EXPORTS=1 -DPNG_THREAD_UNSAFE_OK -DPNG_NO_
|
||||
if(MSVC)
|
||||
add_definitions(/D_IRR_STATIC_LIB_)
|
||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff
|
||||
elseif(MINGW)
|
||||
add_definitions(-D_IRR_STATIC_LIB_)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include")
|
||||
@ -766,16 +769,16 @@ if(APPLE)
|
||||
source/Irrlicht/MacOSX/AppDelegate.mm
|
||||
source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm
|
||||
source/Irrlicht/MacOSX/OSXClipboard.mm)
|
||||
|
||||
|
||||
#list(APPEND CMAKE_C_SOURCE_FILE_EXTENSIONS mm)
|
||||
#set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS cpp)
|
||||
|
||||
|
||||
set_source_files_properties(source/Irrlicht/MacOSX/AppDelegate.mm PROPERTIES COMPILE_FLAGS "-x objective-c++ -O3 -fno-rtti")
|
||||
set_source_files_properties(source/Irrlicht/MacOSX/AppDelegate.mm PROPERTIES LANGUAGE C)
|
||||
|
||||
|
||||
set_source_files_properties(source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm PROPERTIES COMPILE_FLAGS "-x objective-c++ -O3 -fno-rtti")
|
||||
set_source_files_properties(source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm PROPERTIES LANGUAGE C)
|
||||
|
||||
|
||||
set_source_files_properties(source/Irrlicht/MacOSX/OSXClipboard.mm PROPERTIES COMPILE_FLAGS "-x objective-c++ -O3 -fno-rtti")
|
||||
set_source_files_properties(source/Irrlicht/MacOSX/OSXClipboard.mm PROPERTIES LANGUAGE C)
|
||||
endif()
|
||||
|
@ -12,6 +12,9 @@
|
||||
#include "aabbox3d.h"
|
||||
#include "rect.h"
|
||||
#include "irrString.h"
|
||||
#if defined(WIN32) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
// enable this to keep track of changes to the matrix
|
||||
// and make simpler identity check for seldomly changing matrices
|
||||
@ -44,6 +47,10 @@ namespace core
|
||||
template <class T>
|
||||
class CMatrix4
|
||||
{
|
||||
private:
|
||||
#if defined(WIN32) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
|
||||
float M_raw[24];
|
||||
#endif
|
||||
public:
|
||||
|
||||
//! Constructor Flags
|
||||
@ -402,8 +409,12 @@ namespace core
|
||||
bool equals(const core::CMatrix4<T>& other, const T tolerance=(T)ROUNDING_ERROR_f64) const;
|
||||
|
||||
private:
|
||||
#if defined(WIN32) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
|
||||
//! Matrix data, stored in row-major order
|
||||
T M[16];
|
||||
T* M = (T*)((uintptr_t)&M_raw[4] & ~0xF);
|
||||
#else
|
||||
T M[16];
|
||||
#endif
|
||||
#if defined ( USE_MATRIX_TEST )
|
||||
//! Flag is this matrix is identity matrix
|
||||
mutable u32 definitelyIdentityMatrix;
|
||||
@ -658,6 +669,58 @@ namespace core
|
||||
const T *m1 = other_a.M;
|
||||
const T *m2 = other_b.M;
|
||||
|
||||
#if defined(WIN32) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
|
||||
// From http://drrobsjournal.blogspot.fr/2012/10/fast-simd-4x4-matrix-multiplication.html
|
||||
// Use unaligned load/store
|
||||
|
||||
const float *matA = other_a.pointer();
|
||||
|
||||
const __m128 a = _mm_load_ps(matA); // First row
|
||||
const __m128 b = _mm_load_ps(&matA[4]); // Second row
|
||||
const __m128 c = _mm_load_ps(&matA[8]); // Third row
|
||||
const __m128 d = _mm_load_ps(&matA[12]); // Fourth row
|
||||
|
||||
__m128 t1 = _mm_set1_ps(m2[0]);
|
||||
__m128 t2 = _mm_mul_ps(a, t1);
|
||||
t1 = _mm_set1_ps(m2[1]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
|
||||
t1 = _mm_set1_ps(m2[2]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
|
||||
t1 = _mm_set1_ps(m2[3]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
|
||||
_mm_store_ps(&M[0], t2);
|
||||
|
||||
t1 = _mm_set1_ps(m2[4]);
|
||||
t2 = _mm_mul_ps(a, t1);
|
||||
t1 = _mm_set1_ps(m2[5]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
|
||||
t1 = _mm_set1_ps(m2[6]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
|
||||
t1 = _mm_set1_ps(m2[7]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
|
||||
_mm_store_ps(&M[4], t2);
|
||||
|
||||
t1 = _mm_set1_ps(m2[8]);
|
||||
t2 = _mm_mul_ps(a, t1);
|
||||
t1 = _mm_set1_ps(m2[9]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
|
||||
t1 = _mm_set1_ps(m2[10]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
|
||||
t1 = _mm_set1_ps(m2[11]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
|
||||
_mm_store_ps(&M[8], t2);
|
||||
|
||||
t1 = _mm_set1_ps(m2[12]);
|
||||
t2 = _mm_mul_ps(a, t1);
|
||||
t1 = _mm_set1_ps(m2[13]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
|
||||
t1 = _mm_set1_ps(m2[14]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
|
||||
t1 = _mm_set1_ps(m2[15]);
|
||||
t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
|
||||
_mm_store_ps(&M[12], t2);
|
||||
#else
|
||||
|
||||
M[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3];
|
||||
M[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3];
|
||||
M[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3];
|
||||
@ -679,6 +742,7 @@ namespace core
|
||||
M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
|
||||
#if defined ( USE_MATRIX_TEST )
|
||||
definitelyIdentityMatrix=false;
|
||||
#endif
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
@ -1307,20 +1371,110 @@ namespace core
|
||||
|
||||
|
||||
template <class T>
|
||||
inline bool CMatrix4<T>::getInverse(CMatrix4<T>& out) const
|
||||
{
|
||||
/// Calculates the inverse of this Matrix
|
||||
/// The inverse is calculated using Cramers rule.
|
||||
/// If no inverse exists then 'false' is returned.
|
||||
inline bool CMatrix4<T>::getInverse(CMatrix4<T>& out) const
|
||||
{
|
||||
/// Calculates the inverse of this Matrix
|
||||
/// The inverse is calculated using Cramers rule.
|
||||
/// If no inverse exists then 'false' is returned.
|
||||
|
||||
#if defined ( USE_MATRIX_TEST )
|
||||
if ( this->isIdentity() )
|
||||
{
|
||||
out=*this;
|
||||
return true;
|
||||
}
|
||||
if ( this->isIdentity() )
|
||||
{
|
||||
out=*this;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
const CMatrix4<T> &m = *this;
|
||||
const CMatrix4<T> &m = *this;
|
||||
#if defined(WIN32) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
|
||||
float *src = (float*)m.pointer();
|
||||
float *dst = (float*)out.pointer();
|
||||
// from http://www.intel.com/design/pentiumiii/sml/245043.htm
|
||||
{
|
||||
__m128 minor0 = {}, minor1 = {}, minor2 = {}, minor3 = {};
|
||||
__m128 row0 = {}, row1 = {}, row2 = {}, row3 = {};
|
||||
__m128 det = {}, tmp1 = {};
|
||||
tmp1 = _mm_loadh_pi(_mm_loadl_pi(tmp1, (__m64*)(src)), (__m64*)(src + 4));
|
||||
row1 = _mm_loadh_pi(_mm_loadl_pi(row1, (__m64*)(src + 8)), (__m64*)(src + 12));
|
||||
row0 = _mm_shuffle_ps(tmp1, row1, 0x88);
|
||||
row1 = _mm_shuffle_ps(row1, tmp1, 0xDD);
|
||||
tmp1 = _mm_loadh_pi(_mm_loadl_pi(tmp1, (__m64*)(src + 2)), (__m64*)(src + 6));
|
||||
row3 = _mm_loadh_pi(_mm_loadl_pi(row3, (__m64*)(src + 10)), (__m64*)(src + 14));
|
||||
row2 = _mm_shuffle_ps(tmp1, row3, 0x88);
|
||||
row3 = _mm_shuffle_ps(row3, tmp1, 0xDD);
|
||||
// -----------------------------------------------
|
||||
tmp1 = _mm_mul_ps(row2, row3);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||
minor0 = _mm_mul_ps(row1, tmp1);
|
||||
minor1 = _mm_mul_ps(row0, tmp1);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||
minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0);
|
||||
minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1);
|
||||
minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E);
|
||||
// -----------------------------------------------
|
||||
tmp1 = _mm_mul_ps(row1, row2);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||
minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0);
|
||||
minor3 = _mm_mul_ps(row0, tmp1);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||
minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1));
|
||||
minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3);
|
||||
minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E);
|
||||
// -----------------------------------------------
|
||||
tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||
row2 = _mm_shuffle_ps(row2, row2, 0x4E);
|
||||
minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0);
|
||||
minor2 = _mm_mul_ps(row0, tmp1);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||
minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1));
|
||||
minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2);
|
||||
minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E);
|
||||
// -----------------------------------------------
|
||||
tmp1 = _mm_mul_ps(row0, row1);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||
minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2);
|
||||
minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||
minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2);
|
||||
minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1));
|
||||
// -----------------------------------------------
|
||||
tmp1 = _mm_mul_ps(row0, row3);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||
minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1));
|
||||
minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||
minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1);
|
||||
minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1));
|
||||
// -----------------------------------------------
|
||||
tmp1 = _mm_mul_ps(row0, row2);
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||
minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1);
|
||||
minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1));
|
||||
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||
minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1));
|
||||
minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3);
|
||||
// -----------------------------------------------
|
||||
det = _mm_mul_ps(row0, minor0);
|
||||
det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det);
|
||||
det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det);
|
||||
tmp1 = _mm_rcp_ss(det);
|
||||
det = _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1)));
|
||||
det = _mm_shuffle_ps(det, det, 0x00);
|
||||
minor0 = _mm_mul_ps(det, minor0);
|
||||
_mm_storel_pi((__m64*)(dst), minor0);
|
||||
_mm_storeh_pi((__m64*)(dst + 2), minor0);
|
||||
minor1 = _mm_mul_ps(det, minor1);
|
||||
_mm_storel_pi((__m64*)(dst + 4), minor1);
|
||||
_mm_storeh_pi((__m64*)(dst + 6), minor1);
|
||||
minor2 = _mm_mul_ps(det, minor2);
|
||||
_mm_storel_pi((__m64*)(dst + 8), minor2);
|
||||
_mm_storeh_pi((__m64*)(dst + 10), minor2);
|
||||
minor3 = _mm_mul_ps(det, minor3);
|
||||
_mm_storel_pi((__m64*)(dst + 12), minor3);
|
||||
_mm_storeh_pi((__m64*)(dst + 14), minor3);
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
|
||||
f32 d = (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) -
|
||||
(m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) +
|
||||
@ -1387,6 +1541,7 @@ namespace core
|
||||
out.definitelyIdentityMatrix = definitelyIdentityMatrix;
|
||||
#endif
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -194,7 +194,7 @@ CIrrDeviceLinux::~CIrrDeviceLinux()
|
||||
}
|
||||
|
||||
// Reset fullscreen resolution change
|
||||
switchToFullscreen(true);
|
||||
restoreResolution();
|
||||
|
||||
if (!ExternalWindow)
|
||||
{
|
||||
@ -235,43 +235,62 @@ int IrrPrintXError(Display *display, XErrorEvent *event)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool CIrrDeviceLinux::switchToFullscreen(bool reset)
|
||||
bool CIrrDeviceLinux::restoreResolution()
|
||||
{
|
||||
if (!CreationParams.Fullscreen)
|
||||
return true;
|
||||
if (reset)
|
||||
|
||||
#ifdef _IRR_LINUX_X11_VIDMODE_
|
||||
if (UseXVidMode && CreationParams.Fullscreen)
|
||||
{
|
||||
#ifdef _IRR_LINUX_X11_VIDMODE_
|
||||
if (UseXVidMode && CreationParams.Fullscreen)
|
||||
{
|
||||
XF86VidModeSwitchToMode(display, screennr, &oldVideoMode);
|
||||
XF86VidModeSetViewPort(display, screennr, 0, 0);
|
||||
}
|
||||
#endif
|
||||
#ifdef _IRR_LINUX_X11_RANDR_
|
||||
if (UseXRandR && CreationParams.Fullscreen)
|
||||
{
|
||||
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
|
||||
XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id);
|
||||
XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
|
||||
|
||||
Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime,
|
||||
crtc->x, crtc->y, old_mode,
|
||||
crtc->rotation, &output_id, 1);
|
||||
|
||||
XRRFreeOutputInfo(output);
|
||||
XRRFreeCrtcInfo(crtc);
|
||||
XRRFreeScreenResources(res);
|
||||
|
||||
if (s != Success)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
XF86VidModeSwitchToMode(display, screennr, &oldVideoMode);
|
||||
XF86VidModeSetViewPort(display, screennr, 0, 0);
|
||||
}
|
||||
#endif
|
||||
#ifdef _IRR_LINUX_X11_RANDR_
|
||||
if (UseXRandR && CreationParams.Fullscreen && old_mode != BadRRMode)
|
||||
{
|
||||
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id);
|
||||
if (!output || !output->crtc || output->connection == RR_Disconnected)
|
||||
{
|
||||
XRRFreeOutputInfo(output);
|
||||
return false;
|
||||
}
|
||||
|
||||
XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
|
||||
if (!crtc)
|
||||
{
|
||||
XRRFreeOutputInfo(output);
|
||||
return false;
|
||||
}
|
||||
|
||||
Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime,
|
||||
crtc->x, crtc->y, old_mode,
|
||||
crtc->rotation, &output_id, 1);
|
||||
|
||||
XRRFreeOutputInfo(output);
|
||||
XRRFreeCrtcInfo(crtc);
|
||||
XRRFreeScreenResources(res);
|
||||
|
||||
if (s != Success)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CIrrDeviceLinux::changeResolution()
|
||||
{
|
||||
if (!CreationParams.Fullscreen)
|
||||
return true;
|
||||
|
||||
getVideoModeList();
|
||||
|
||||
#if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_)
|
||||
s32 eventbase, errorbase;
|
||||
s32 bestMode = -1;
|
||||
@ -333,47 +352,56 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
|
||||
|
||||
XFree(modes);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef _IRR_LINUX_X11_RANDR_
|
||||
if (XRRQueryExtension(display, &eventbase, &errorbase))
|
||||
while (XRRQueryExtension(display, &eventbase, &errorbase))
|
||||
{
|
||||
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
|
||||
if (output_id == BadRROutput)
|
||||
break;
|
||||
|
||||
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
|
||||
if (!res)
|
||||
{
|
||||
CreationParams.Fullscreen = false;
|
||||
return CreationParams.Fullscreen;
|
||||
}
|
||||
break;
|
||||
|
||||
XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id);
|
||||
if (!output || !output->crtc || output->connection == RR_Disconnected)
|
||||
{
|
||||
XRRFreeOutputInfo(output);
|
||||
XRRFreeScreenResources(res);
|
||||
break;
|
||||
}
|
||||
|
||||
XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
|
||||
if (!crtc)
|
||||
{
|
||||
XRRFreeOutputInfo(output);
|
||||
XRRFreeScreenResources(res);
|
||||
break;
|
||||
}
|
||||
|
||||
float refresh_rate, refresh_rate_new;
|
||||
unsigned int mode0_width = -1, mode0_height = -1;
|
||||
core::dimension2d<u32> mode0_size = core::dimension2d<u32>(0, 0);
|
||||
|
||||
for (int i = 0; i < res->nmode; i++)
|
||||
{
|
||||
const XRRModeInfo* mode = &res->modes[i];
|
||||
unsigned int w, h;
|
||||
|
||||
core::dimension2d<u32> size;
|
||||
|
||||
if (crtc->rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT))
|
||||
{
|
||||
w = mode->height;
|
||||
h = mode->width;
|
||||
size = core::dimension2d<u32>(mode->height, mode->width);
|
||||
}
|
||||
else
|
||||
{
|
||||
w = mode->width;
|
||||
h = mode->height;
|
||||
size = core::dimension2d<u32>(mode->width, mode->height);
|
||||
}
|
||||
|
||||
if (bestMode == -1 && mode->id == output->modes[0])
|
||||
{
|
||||
mode0_width = w;
|
||||
mode0_height = h;
|
||||
mode0_size = size;
|
||||
}
|
||||
|
||||
if (bestMode == -1 && w == Width && h == Height)
|
||||
if (bestMode == -1 && size.Width == Width && size.Height == Height)
|
||||
{
|
||||
for (int j = 0; j < output->nmode; j++)
|
||||
{
|
||||
@ -385,7 +413,7 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bestMode != -1 && w == Width && h == Height)
|
||||
else if (bestMode != -1 && size.Width == Width && size.Height == Height)
|
||||
{
|
||||
refresh_rate_new = (mode->dotClock * 1000.0) / (mode->hTotal * mode->vTotal);
|
||||
|
||||
@ -408,33 +436,29 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset)
|
||||
if (bestMode == -1)
|
||||
{
|
||||
bestMode = 0;
|
||||
Width = mode0_width;
|
||||
Height = mode0_height;
|
||||
Width = mode0_size.Width;
|
||||
Height = mode0_size.Height;
|
||||
}
|
||||
|
||||
Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime,
|
||||
crtc->x, crtc->y, output->modes[bestMode],
|
||||
crtc->rotation, &output_id, 1);
|
||||
|
||||
if (s == Success)
|
||||
UseXRandR = true;
|
||||
|
||||
XRRFreeCrtcInfo(crtc);
|
||||
XRRFreeOutputInfo(output);
|
||||
XRRFreeScreenResources(res);
|
||||
|
||||
if (s != Success)
|
||||
{
|
||||
CreationParams.Fullscreen = false;
|
||||
return CreationParams.Fullscreen;
|
||||
}
|
||||
|
||||
UseXRandR=true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if (UseXRandR == false)
|
||||
{
|
||||
os::Printer::log("VidMode or RandR extension must be installed to allow Irrlicht "
|
||||
"to switch to fullscreen mode. Running in windowed mode instead.", ELL_WARNING);
|
||||
os::Printer::log("Could not get video output. Try to run in windowed mode.", ELL_WARNING);
|
||||
CreationParams.Fullscreen = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return CreationParams.Fullscreen;
|
||||
}
|
||||
@ -549,7 +573,7 @@ bool CIrrDeviceLinux::createWindow()
|
||||
|
||||
screennr = DefaultScreen(display);
|
||||
|
||||
switchToFullscreen();
|
||||
changeResolution();
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_OPENGL_
|
||||
|
||||
@ -1592,89 +1616,88 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
|
||||
}
|
||||
XFree(modes);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef _IRR_LINUX_X11_RANDR_
|
||||
if (XRRQueryExtension(display, &eventbase, &errorbase))
|
||||
output_id = BadRROutput;
|
||||
old_mode = BadRRMode;
|
||||
|
||||
while (XRRQueryExtension(display, &eventbase, &errorbase))
|
||||
{
|
||||
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
|
||||
|
||||
if (!res)
|
||||
return &VideoModeList;
|
||||
|
||||
XRROutputInfo *output = NULL;
|
||||
XRROutputInfo* output = NULL;
|
||||
XRRCrtcInfo* crtc = NULL;
|
||||
crtc_x = crtc_y = -1;
|
||||
|
||||
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
|
||||
if (!res)
|
||||
break;
|
||||
|
||||
RROutput primary_id = XRRGetOutputPrimary(display, DefaultRootWindow(display));
|
||||
|
||||
for (int i = 0; i < res->noutput; i++)
|
||||
{
|
||||
output = XRRGetOutputInfo(display, res, res->outputs[i]);
|
||||
|
||||
if (!output || !output->crtc || output->connection == RR_Disconnected)
|
||||
XRROutputInfo* output_tmp = XRRGetOutputInfo(display, res, res->outputs[i]);
|
||||
if (!output_tmp || !output_tmp->crtc || output_tmp->connection == RR_Disconnected)
|
||||
{
|
||||
XRRFreeOutputInfo(output);
|
||||
XRRFreeOutputInfo(output_tmp);
|
||||
continue;
|
||||
}
|
||||
|
||||
crtc = XRRGetCrtcInfo(display, res, output->crtc);
|
||||
|
||||
if (!crtc)
|
||||
XRRCrtcInfo* crtc_tmp = XRRGetCrtcInfo(display, res, output_tmp->crtc);
|
||||
if (!crtc_tmp)
|
||||
{
|
||||
XRRFreeOutputInfo(output_tmp);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res->outputs[i] == primary_id ||
|
||||
output_id == BadRROutput || crtc_tmp->x < crtc->x ||
|
||||
(crtc_tmp->x == crtc->x && crtc_tmp->y < crtc->y))
|
||||
{
|
||||
XRRFreeCrtcInfo(crtc);
|
||||
XRRFreeOutputInfo(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (crtc_x == -1 || crtc->x < crtc_x)
|
||||
{
|
||||
crtc_x = crtc->x;
|
||||
crtc_y = crtc->y;
|
||||
XRRFreeOutputInfo(output);
|
||||
|
||||
output = output_tmp;
|
||||
crtc = crtc_tmp;
|
||||
output_id = res->outputs[i];
|
||||
}
|
||||
else if (crtc_x == crtc->x && crtc->y < crtc_y)
|
||||
else
|
||||
{
|
||||
crtc_x = crtc->x;
|
||||
crtc_y = crtc->y;
|
||||
output_id = res->outputs[i];
|
||||
XRRFreeCrtcInfo(crtc_tmp);
|
||||
XRRFreeOutputInfo(output_tmp);
|
||||
}
|
||||
|
||||
XRRFreeCrtcInfo(crtc);
|
||||
XRRFreeOutputInfo(output);
|
||||
if (res->outputs[i] == primary_id)
|
||||
break;
|
||||
}
|
||||
|
||||
output = XRRGetOutputInfo(display, res, output_id);
|
||||
crtc = XRRGetCrtcInfo(display, res, output->crtc);
|
||||
|
||||
if (crtc == NULL)
|
||||
if (output_id == BadRROutput)
|
||||
{
|
||||
XRRFreeCrtcInfo(crtc);
|
||||
XRRFreeOutputInfo(output);
|
||||
XRRFreeScreenResources(res);
|
||||
return &VideoModeList;
|
||||
os::Printer::log("Could not get video output.", ELL_WARNING);
|
||||
break;
|
||||
}
|
||||
|
||||
crtc_x = crtc->x;
|
||||
crtc_y = crtc->y;
|
||||
|
||||
for (int i = 0; i < res->nmode; i++)
|
||||
{
|
||||
const XRRModeInfo* mode = &res->modes[i];
|
||||
unsigned int w, h;
|
||||
core::dimension2d<u32> size;
|
||||
|
||||
if (crtc->rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT))
|
||||
{
|
||||
w = mode->height;
|
||||
h = mode->width;
|
||||
size = core::dimension2d<u32>(mode->height, mode->width);
|
||||
}
|
||||
else
|
||||
{
|
||||
w = mode->width;
|
||||
h = mode->height;
|
||||
size = core::dimension2d<u32>(mode->width, mode->height);
|
||||
}
|
||||
|
||||
for (int j = 0; j < output->nmode; j++)
|
||||
{
|
||||
if (mode->id == output->modes[j])
|
||||
{
|
||||
VideoModeList.addMode(core::dimension2d<u32>(
|
||||
w, h), defaultDepth);
|
||||
VideoModeList.addMode(size, defaultDepth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1682,21 +1705,18 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
|
||||
if (mode->id == crtc->mode)
|
||||
{
|
||||
old_mode = crtc->mode;
|
||||
VideoModeList.setDesktop(defaultDepth,
|
||||
core::dimension2d<u32>(w, h));
|
||||
VideoModeList.setDesktop(defaultDepth, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XRRFreeCrtcInfo(crtc);
|
||||
XRRFreeOutputInfo(output);
|
||||
XRRFreeScreenResources(res);
|
||||
XRRFreeScreenResources(res);
|
||||
break;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
os::Printer::log("VidMode or RandR X11 extension requireed for VideoModeList." , ELL_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (display && temporaryDisplay)
|
||||
{
|
||||
XCloseDisplay(display);
|
||||
|
@ -150,7 +150,8 @@ namespace irr
|
||||
|
||||
void initXAtoms();
|
||||
|
||||
bool switchToFullscreen(bool reset=false);
|
||||
bool restoreResolution();
|
||||
bool changeResolution();
|
||||
|
||||
//! Implementation of the linux cursor control
|
||||
class CCursorControl : public gui::ICursorControl
|
||||
|
@ -1,5 +1,6 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
file(GLOB_RECURSE STK_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${PROJECT_BINARY_DIR}/tmp/*.rc")
|
@ -114,13 +114,13 @@ void AddonsManager::init(const XMLNode *xml,
|
||||
|
||||
if (download)
|
||||
{
|
||||
Log::info("NetworkHttp", "Downloading updated addons.xml");
|
||||
Log::info("addons", "Downloading updated addons.xml.");
|
||||
Online::HTTPRequest *download_request = new Online::HTTPRequest("addons.xml");
|
||||
download_request->setURL(addon_list_url);
|
||||
download_request->executeNow();
|
||||
if(download_request->hadDownloadError())
|
||||
{
|
||||
Log::error("addons", "Error on download addons.xml: %s\n",
|
||||
Log::error("addons", "Error on download addons.xml: %s.",
|
||||
download_request->getDownloadErrorMessage());
|
||||
delete download_request;
|
||||
return;
|
||||
@ -129,12 +129,12 @@ void AddonsManager::init(const XMLNode *xml,
|
||||
UserConfigParams::m_addons_last_updated=StkTime::getTimeSinceEpoch();
|
||||
}
|
||||
else
|
||||
Log::info("NetworkHttp", "Using cached addons.xml");
|
||||
Log::info("addons", "Using cached addons.xml.");
|
||||
|
||||
const XMLNode *xml_addons = new XMLNode(filename);
|
||||
addons_manager->initAddons(xml_addons); // will free xml_addons
|
||||
if(UserConfigParams::logAddons())
|
||||
Log::info("addons", "Addons manager list downloaded");
|
||||
Log::info("addons", "Addons manager list downloaded.");
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -195,7 +195,7 @@ void AddonsManager::initAddons(const XMLNode *xml)
|
||||
if(file_manager->fileExists(full_path))
|
||||
{
|
||||
if(UserConfigParams::logAddons())
|
||||
Log::warn("[AddonsManager] Removing cached icon '%s'.\n",
|
||||
Log::warn("addons", "Removing cached icon '%s'.",
|
||||
addon.getIconBasename().c_str());
|
||||
file_manager->removeFile(full_path);
|
||||
}
|
||||
@ -226,9 +226,9 @@ void AddonsManager::initAddons(const XMLNode *xml)
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("[AddonsManager]", "Found invalid node '%s' while downloading addons.",
|
||||
Log::error("addons", "Found invalid node '%s' while downloading addons.",
|
||||
node->getName().c_str());
|
||||
Log::error("[AddonsManager]", "Ignored.");
|
||||
Log::error("addons", "Ignored.");
|
||||
}
|
||||
} // for i<xml->getNumNodes
|
||||
delete xml;
|
||||
@ -254,7 +254,7 @@ void AddonsManager::initAddons(const XMLNode *xml)
|
||||
// it from the list.
|
||||
if(UserConfigParams::logAddons())
|
||||
Log::warn(
|
||||
"[AddonsManager] Removing '%s' which is not on the server anymore.\n",
|
||||
"addons", "Removing '%s' which is not on the server anymore.",
|
||||
m_addons_list.getData()[i].getId().c_str() );
|
||||
const std::string &icon = m_addons_list.getData()[i].getIconBasename();
|
||||
std::string icon_file =file_manager->getAddonsFile("icons/"+icon);
|
||||
@ -311,7 +311,7 @@ void AddonsManager::checkInstalledAddons()
|
||||
if(n<0) continue;
|
||||
if(!m_addons_list.getData()[n].isInstalled())
|
||||
{
|
||||
Log::info("[AddonsManager] Marking '%s' as being installed.",
|
||||
Log::info("addons", "Marking '%s' as being installed.",
|
||||
kp->getIdent().c_str());
|
||||
m_addons_list.getData()[n].setInstalled(true);
|
||||
something_was_changed = true;
|
||||
@ -330,7 +330,7 @@ void AddonsManager::checkInstalledAddons()
|
||||
if(n<0) continue;
|
||||
if(!m_addons_list.getData()[n].isInstalled())
|
||||
{
|
||||
Log::info("[AddonsManager] Marking '%s' as being installed.",
|
||||
Log::info("addons", "Marking '%s' as being installed.",
|
||||
track->getIdent().c_str());
|
||||
m_addons_list.getData()[n].setInstalled(true);
|
||||
something_was_changed = true;
|
||||
@ -361,7 +361,7 @@ void AddonsManager::downloadIcons()
|
||||
if(icon=="")
|
||||
{
|
||||
if(UserConfigParams::logAddons())
|
||||
Log::error("[AddonsManager]", "No icon or image specified for '%s'.",
|
||||
Log::error("addons", "No icon or image specified for '%s'.",
|
||||
addon.getId().c_str());
|
||||
continue;
|
||||
}
|
||||
@ -400,7 +400,7 @@ void AddonsManager::loadInstalledAddons()
|
||||
/* checking for installed addons */
|
||||
if(UserConfigParams::logAddons())
|
||||
{
|
||||
Log::info("[AddonsManager]", "Loading an xml file for installed addons: %s",
|
||||
Log::info("addons", "Loading an xml file for installed addons: %s.",
|
||||
m_file_installed.c_str());
|
||||
}
|
||||
const XMLNode *xml = file_manager->createXMLTree(m_file_installed);
|
||||
@ -478,15 +478,15 @@ bool AddonsManager::install(const Addon &addon)
|
||||
if (!success)
|
||||
{
|
||||
// TODO: show a message in the interface
|
||||
Log::error("[AddonsManager]", "Failed to unzip '%s' to '%s'",
|
||||
Log::error("addons", "Failed to unzip '%s' to '%s'.",
|
||||
from.c_str(), to.c_str());
|
||||
Log::error("[AddonsManager]", "Zip file will not be removed.");
|
||||
Log::error("addons", "Zip file will not be removed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!file_manager->removeFile(from))
|
||||
{
|
||||
Log::error("[AddonsManager]", "Problems removing temporary file '%s'",
|
||||
Log::error("addons", "Problems removing temporary file '%s'.",
|
||||
from.c_str());
|
||||
}
|
||||
|
||||
@ -520,7 +520,7 @@ bool AddonsManager::install(const Addon &addon)
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
Log::error("[AddonsManager]", "ERROR: Cannot load track <%s> : %s",
|
||||
Log::error("addons", "Cannot load track '%s' : %s.",
|
||||
addon.getDataDir().c_str(), e.what());
|
||||
}
|
||||
}
|
||||
@ -535,8 +535,8 @@ bool AddonsManager::install(const Addon &addon)
|
||||
*/
|
||||
bool AddonsManager::uninstall(const Addon &addon)
|
||||
{
|
||||
Log::info("[AddonsManager]", "Uninstalling <%s>",
|
||||
core::stringc(addon.getName()).c_str());
|
||||
Log::info("addons", "Uninstalling '%s'.",
|
||||
core::stringc(addon.getName()).c_str());
|
||||
|
||||
// addon is a const reference, and to avoid removing the const, we
|
||||
// find the proper index again to modify the installed state
|
||||
|
@ -376,7 +376,7 @@ void ChallengeData::setRace(RaceManager::Difficulty d) const
|
||||
else if(m_mode==CM_GRAND_PRIX)
|
||||
{
|
||||
race_manager->setMinorMode(m_minor);
|
||||
race_manager->setGrandPrix(grand_prix_manager->getGrandPrix(m_gp_id));
|
||||
race_manager->setGrandPrix(*grand_prix_manager->getGrandPrix(m_gp_id));
|
||||
race_manager->setDifficulty(d);
|
||||
race_manager->setNumKarts(m_num_karts[d]);
|
||||
race_manager->setNumLocalPlayers(1);
|
||||
|
@ -464,6 +464,9 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX BoolUserConfigParam m_gi
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_gi",
|
||||
&m_video_group, "Enable Global Illumination"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_azdo
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_azdo",
|
||||
&m_video_group, "Enable 'Approaching Zero Driver Overhead' mode (very experimental !)"));
|
||||
|
||||
// ---- Debug - not saved to config file
|
||||
/** If gamepad debugging is enabled. */
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "audio/music_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/rain.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/explosion_animation.hpp"
|
||||
@ -52,7 +51,6 @@ Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL)
|
||||
{
|
||||
m_mode = CM_NORMAL;
|
||||
m_index = camera_index;
|
||||
m_rain = NULL;
|
||||
m_original_kart = kart;
|
||||
m_camera = irr_driver->addCameraSceneNode();
|
||||
|
||||
@ -92,7 +90,6 @@ Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL)
|
||||
*/
|
||||
Camera::~Camera()
|
||||
{
|
||||
if(m_rain) delete m_rain;
|
||||
irr_driver->removeCameraSceneNode(m_camera);
|
||||
|
||||
if (s_active_camera == this)
|
||||
@ -222,13 +219,6 @@ void Camera::setupCamera()
|
||||
m_camera->setFOV(m_fov);
|
||||
m_camera->setAspectRatio(m_aspect);
|
||||
m_camera->setFarValue(World::getWorld()->getTrack()->getCameraFar());
|
||||
|
||||
if (UserConfigParams::m_weather_effects &&
|
||||
World::getWorld()->getTrack()->getWeatherType() == WEATHER_RAIN)
|
||||
{
|
||||
m_rain = new Rain(this, NULL);
|
||||
}
|
||||
|
||||
} // setupCamera
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -530,12 +520,6 @@ void Camera::update(float dt)
|
||||
getCameraSettings(&above_kart, &cam_angle, &side_way, &distance, &smoothing);
|
||||
positionCamera(dt, above_kart, cam_angle, side_way, distance, smoothing);
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_graphical_effects && m_rain)
|
||||
{
|
||||
m_rain->setPosition( getCameraSceneNode()->getPosition() );
|
||||
m_rain->update(dt);
|
||||
} // UserConfigParams::m_graphical_effects
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -41,7 +41,6 @@ namespace irr
|
||||
using namespace irr;
|
||||
|
||||
class AbstractKart;
|
||||
class Rain;
|
||||
|
||||
/**
|
||||
* \brief Handles the game camera
|
||||
@ -120,10 +119,6 @@ private:
|
||||
/** List of all cameras. */
|
||||
static std::vector<Camera*> m_all_cameras;
|
||||
|
||||
/** Used to show rain graphical effects. */
|
||||
Rain *m_rain;
|
||||
|
||||
|
||||
/** A class that stores information about the different end cameras
|
||||
* which can be specified in the scene.xml file. */
|
||||
class EndCameraInformation
|
||||
|
46
src/graphics/gl_headers.hpp
Normal file
46
src/graphics/gl_headers.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef GL_HEADER_HPP
|
||||
#define GL_HEADER_HPP
|
||||
|
||||
#define GLEW_STATIC
|
||||
extern "C" {
|
||||
#include <GL/glew.h>
|
||||
}
|
||||
#include <cinttypes>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <OpenGL/gl.h>
|
||||
# include <OpenGL/gl3.h>
|
||||
# define OGL32CTX
|
||||
# ifdef GL_ARB_instanced_arrays
|
||||
# define glVertexAttribDivisor glVertexAttribDivisorARB
|
||||
# endif
|
||||
# ifndef GL_TEXTURE_SWIZZLE_RGBA
|
||||
# define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
|
||||
# endif
|
||||
#elif defined(ANDROID)
|
||||
# include <GLES/gl.h>
|
||||
#elif defined(WIN32)
|
||||
# define _WINSOCKAPI_
|
||||
# include <windows.h>
|
||||
#else
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#define DEBUG_OUTPUT_DECLARED
|
||||
# include <GL/gl.h>
|
||||
# include <GL/glext.h>
|
||||
#endif
|
||||
|
||||
#define Bindless_Texture_Support
|
||||
#define Base_Instance_Support
|
||||
#define Buffer_Storage
|
||||
#define Multi_Draw_Indirect
|
||||
#define Draw_Indirect
|
||||
|
||||
struct DrawElementsIndirectCommand{
|
||||
GLuint count;
|
||||
GLuint instanceCount;
|
||||
GLuint firstIndex;
|
||||
GLuint baseVertex;
|
||||
GLuint baseInstance;
|
||||
};
|
||||
|
||||
#endif
|
@ -3,92 +3,16 @@
|
||||
#include <string>
|
||||
#include "config/user_config.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
#include "graphics/stkmesh.hpp"
|
||||
|
||||
#ifdef _IRR_WINDOWS_API_
|
||||
#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast<const char*>(X))
|
||||
PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks;
|
||||
PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback;
|
||||
PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback;
|
||||
PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
|
||||
PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
|
||||
PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
|
||||
PFNGLBINDBUFFERBASEPROC glBindBufferBase;
|
||||
PFNGLGENBUFFERSPROC glGenBuffers;
|
||||
PFNGLBINDBUFFERPROC glBindBuffer;
|
||||
PFNGLBUFFERDATAPROC glBufferData;
|
||||
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
|
||||
PFNGLCREATESHADERPROC glCreateShader;
|
||||
PFNGLCOMPILESHADERPROC glCompileShader;
|
||||
PFNGLSHADERSOURCEPROC glShaderSource;
|
||||
PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||
PFNGLATTACHSHADERPROC glAttachShader;
|
||||
PFNGLLINKPROGRAMPROC glLinkProgram;
|
||||
PFNGLUSEPROGRAMPROC glUseProgram;
|
||||
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
|
||||
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
|
||||
PFNGLUNIFORM1FPROC glUniform1f;
|
||||
PFNGLUNIFORM3FPROC glUniform3f;
|
||||
PFNGLDELETESHADERPROC glDeleteShader;
|
||||
PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
|
||||
PFNGLACTIVETEXTUREPROC glActiveTexture;
|
||||
PFNGLUNIFORM2FPROC glUniform2f;
|
||||
PFNGLUNIFORM1IPROC glUniform1i;
|
||||
PFNGLUNIFORM3IPROC glUniform3i;
|
||||
PFNGLUNIFORM4IPROC glUniform4i;
|
||||
PFNGLUNIFORM1FVPROC glUniform1fv;
|
||||
PFNGLUNIFORM4FVPROC glUniform4fv;
|
||||
PFNGLGETPROGRAMIVPROC glGetProgramiv;
|
||||
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
|
||||
PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
|
||||
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
||||
PFNGLBLENDEQUATIONPROC glBlendEquation;
|
||||
PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
|
||||
PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
|
||||
PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
|
||||
PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
|
||||
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
|
||||
PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||
PFNGLTEXBUFFERPROC glTexBuffer;
|
||||
PFNGLBUFFERSUBDATAPROC glBufferSubData;
|
||||
PFNGLMAPBUFFERPROC glMapBuffer;
|
||||
PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
||||
PFNGLUNMAPBUFFERPROC glUnmapBuffer;
|
||||
PFNGLFENCESYNCPROC glFenceSync;
|
||||
PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
|
||||
PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
|
||||
PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
|
||||
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
||||
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
||||
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
||||
PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
|
||||
PFNGLTEXIMAGE3DPROC glTexImage3D;
|
||||
PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
|
||||
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
||||
PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
|
||||
PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
|
||||
PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
|
||||
PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
|
||||
PFNGLBLENDCOLORPROC glBlendColor;
|
||||
PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
|
||||
PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
|
||||
PFNGLTEXSTORAGE1DPROC glTexStorage1D;
|
||||
PFNGLTEXSTORAGE2DPROC glTexStorage2D;
|
||||
PFNGLTEXSTORAGE3DPROC glTexStorage3D;
|
||||
PFNGLBINDIMAGETEXTUREPROC glBindImageTexture;
|
||||
PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
|
||||
#endif
|
||||
|
||||
#include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h"
|
||||
|
||||
static bool is_gl_init = false;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef WIN32
|
||||
#if !defined(__APPLE__)
|
||||
#define ARB_DEBUG_OUTPUT
|
||||
#endif
|
||||
#endif
|
||||
@ -101,9 +25,11 @@ CALLBACK
|
||||
debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
|
||||
const GLchar* msg, const void *userparam)
|
||||
{
|
||||
#ifdef GL_DEBUG_SEVERITY_NOTIFICATION
|
||||
// ignore minor notifications sent by some drivers (notably the nvidia one)
|
||||
if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)
|
||||
return;
|
||||
#endif
|
||||
|
||||
switch(source)
|
||||
{
|
||||
@ -172,87 +98,10 @@ void initGL()
|
||||
if (is_gl_init)
|
||||
return;
|
||||
is_gl_init = true;
|
||||
#ifdef _IRR_WINDOWS_API_
|
||||
glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks");
|
||||
glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback");
|
||||
glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback");
|
||||
glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback");
|
||||
glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback");
|
||||
glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase");
|
||||
glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers");
|
||||
glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer");
|
||||
glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData");
|
||||
glMapBuffer = (PFNGLMAPBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glMapBuffer");
|
||||
glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)IRR_OGL_LOAD_EXTENSION("glMapBufferRange");
|
||||
glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glUnmapBuffer");
|
||||
glFenceSync = (PFNGLFENCESYNCPROC)IRR_OGL_LOAD_EXTENSION("glFenceSync");
|
||||
glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)IRR_OGL_LOAD_EXTENSION("glClientWaitSync");
|
||||
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer");
|
||||
glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader");
|
||||
glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader");
|
||||
glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource");
|
||||
glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram");
|
||||
glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader");
|
||||
glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram");
|
||||
glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram");
|
||||
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray");
|
||||
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation");
|
||||
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv");
|
||||
glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f");
|
||||
glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f");
|
||||
glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray");
|
||||
glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader");
|
||||
glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv");
|
||||
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog");
|
||||
glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture");
|
||||
glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f");
|
||||
glUniform4i = (PFNGLUNIFORM4IPROC)IRR_OGL_LOAD_EXTENSION("glUniform4i");
|
||||
glUniform3i = (PFNGLUNIFORM3IPROC)IRR_OGL_LOAD_EXTENSION("glUniform3i");
|
||||
glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i");
|
||||
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv");
|
||||
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog");
|
||||
glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings");
|
||||
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetAttribLocation");
|
||||
glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glBindAttribLocation");
|
||||
glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation");
|
||||
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor");
|
||||
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced");
|
||||
glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsBaseVertex");
|
||||
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsInstanced");
|
||||
glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsInstancedBaseVertex");
|
||||
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers");
|
||||
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glGenVertexArrays");
|
||||
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)IRR_OGL_LOAD_EXTENSION("glBindVertexArray");
|
||||
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteVertexArrays");
|
||||
glTexBuffer = (PFNGLTEXBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glTexBuffer");
|
||||
glUniform1fv = (PFNGLUNIFORM1FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform1fv");
|
||||
glUniform4fv = (PFNGLUNIFORM4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform4fv");
|
||||
glBufferSubData = (PFNGLBUFFERSUBDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferSubData");
|
||||
glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribIPointer");
|
||||
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenFramebuffers");
|
||||
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteFramebuffers");
|
||||
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindFramebuffer");
|
||||
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)IRR_OGL_LOAD_EXTENSION("glFramebufferTexture2D");
|
||||
glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glFramebufferTexture");
|
||||
glTexImage3D = (PFNGLTEXIMAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexImage3D");
|
||||
glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)IRR_OGL_LOAD_EXTENSION("glGenerateMipmap");
|
||||
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)IRR_OGL_LOAD_EXTENSION("glCheckFramebufferStatus");
|
||||
glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)IRR_OGL_LOAD_EXTENSION("glTexImage2DMultisample");
|
||||
glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBlitFramebuffer");
|
||||
glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformBlockIndex");
|
||||
glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)IRR_OGL_LOAD_EXTENSION("glUniformBlockBinding");
|
||||
glBlendColor = (PFNGLBLENDCOLORPROC)IRR_OGL_LOAD_EXTENSION("glBlendColor");
|
||||
glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D");
|
||||
glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)IRR_OGL_LOAD_EXTENSION("glGetCompressedTexImage");
|
||||
glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage1D");
|
||||
glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage2D");
|
||||
glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage3D");
|
||||
glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glBindImageTexture");
|
||||
glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)IRR_OGL_LOAD_EXTENSION("glDispatchCompute");
|
||||
#ifdef DEBUG
|
||||
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB");
|
||||
#endif
|
||||
#endif
|
||||
glewExperimental = GL_TRUE;
|
||||
GLenum err = glewInit();
|
||||
if (GLEW_OK != err)
|
||||
Log::fatal("GLEW", "Glew initialisation failed with error %s", glewGetErrorString(err));
|
||||
#ifdef ARB_DEBUG_OUTPUT
|
||||
if (glDebugMessageCallbackARB)
|
||||
glDebugMessageCallbackARB((GLDEBUGPROCARB)debugCallback, NULL);
|
||||
@ -282,12 +131,21 @@ GLuint LoadShader(const char * file, unsigned type)
|
||||
char versionString[20];
|
||||
sprintf(versionString, "#version %d\n", irr_driver->getGLSLVersion());
|
||||
std::string Code = versionString;
|
||||
if (UserConfigParams::m_azdo)
|
||||
Code += "#extension GL_ARB_bindless_texture : enable\n";
|
||||
else
|
||||
{
|
||||
Code += "#extension GL_ARB_bindless_texture : disable\n";
|
||||
Code += "#undef GL_ARB_bindless_texture\n";
|
||||
}
|
||||
std::ifstream Stream(file, std::ios::in);
|
||||
Code += "//" + std::string(file) + "\n";
|
||||
if (irr_driver->needUBOWorkaround())
|
||||
Code += "#define UBO_DISABLED\n";
|
||||
if (irr_driver->hasVSLayerExtension())
|
||||
Code += "#define VSLayer\n";
|
||||
if (irr_driver->needsRGBBindlessWorkaround())
|
||||
Code += "#define SRGBBindlessFix\n";
|
||||
Code += LoadHeader();
|
||||
if (Stream.is_open())
|
||||
{
|
||||
@ -539,40 +397,7 @@ void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum
|
||||
glGetError();
|
||||
}
|
||||
|
||||
class VBOGatherer
|
||||
{
|
||||
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
|
||||
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
|
||||
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
|
||||
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
|
||||
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
|
||||
std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
|
||||
|
||||
void regenerateBuffer(enum VTXTYPE);
|
||||
void regenerateVAO(enum VTXTYPE);
|
||||
size_t getVertexPitch(enum VTXTYPE) const;
|
||||
VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type);
|
||||
void append(scene::IMeshBuffer *, VBOGatherer::VTXTYPE tp);
|
||||
public:
|
||||
VBOGatherer();
|
||||
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
|
||||
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
|
||||
unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; }
|
||||
~VBOGatherer()
|
||||
{
|
||||
for (unsigned i = 0; i < VTXTYPE_COUNT; i++)
|
||||
{
|
||||
if (vbo[i])
|
||||
glDeleteBuffers(1, &vbo[i]);
|
||||
if (ibo[i])
|
||||
glDeleteBuffers(1, &ibo[i]);
|
||||
if (vao[i])
|
||||
glDeleteVertexArrays(1, &vao[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
VBOGatherer::VBOGatherer()
|
||||
VAOManager::VAOManager()
|
||||
{
|
||||
vao[0] = vao[1] = vao[2] = 0;
|
||||
vbo[0] = vbo[1] = vbo[2] = 0;
|
||||
@ -581,16 +406,81 @@ VBOGatherer::VBOGatherer()
|
||||
idx_cnt[0] = idx_cnt[1] = idx_cnt[2] = 0;
|
||||
vtx_mirror[0] = vtx_mirror[1] = vtx_mirror[2] = NULL;
|
||||
idx_mirror[0] = idx_mirror[1] = idx_mirror[2] = NULL;
|
||||
instance_count[0] = 0;
|
||||
|
||||
for (unsigned i = 0; i < InstanceTypeCount; i++)
|
||||
{
|
||||
glGenBuffers(1, &instance_vbo[i]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[i]);
|
||||
#ifdef Buffer_Storage
|
||||
if (irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBufferStorage(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
Ptr[i] = glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_STREAM_DRAW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VBOGatherer::regenerateBuffer(enum VTXTYPE tp)
|
||||
static void cleanVAOMap(std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> Map)
|
||||
{
|
||||
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint>::iterator It = Map.begin(), E = Map.end();
|
||||
for (; It != E; It++)
|
||||
{
|
||||
glDeleteVertexArrays(1, &(It->second));
|
||||
}
|
||||
}
|
||||
|
||||
void VAOManager::cleanInstanceVAOs()
|
||||
{
|
||||
cleanVAOMap(InstanceVAO);
|
||||
InstanceVAO.clear();
|
||||
}
|
||||
|
||||
VAOManager::~VAOManager()
|
||||
{
|
||||
cleanInstanceVAOs();
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
{
|
||||
if (vtx_mirror[i])
|
||||
free(vtx_mirror[i]);
|
||||
if (idx_mirror[i])
|
||||
free(idx_mirror[i]);
|
||||
if (vbo[i])
|
||||
glDeleteBuffers(1, &vbo[i]);
|
||||
if (ibo[i])
|
||||
glDeleteBuffers(1, &ibo[i]);
|
||||
if (vao[i])
|
||||
glDeleteVertexArrays(1, &vao[i]);
|
||||
}
|
||||
for (unsigned i = 0; i < InstanceTypeCount; i++)
|
||||
{
|
||||
glDeleteBuffers(1, &instance_vbo[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void VAOManager::regenerateBuffer(enum VTXTYPE tp)
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
if (vbo[tp])
|
||||
glDeleteBuffers(1, &vbo[tp]);
|
||||
glGenBuffers(1, &vbo[tp]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
|
||||
glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW);
|
||||
#ifdef Buffer_Storage
|
||||
if (irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBufferStorage(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
VBOPtr[tp] = glMapBufferRange(GL_ARRAY_BUFFER, 0, vtx_cnt[tp] * getVertexPitch(tp), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW);
|
||||
|
||||
|
||||
if (ibo[tp])
|
||||
glDeleteBuffers(1, &ibo[tp]);
|
||||
@ -602,7 +492,7 @@ void VBOGatherer::regenerateBuffer(enum VTXTYPE tp)
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void VBOGatherer::regenerateVAO(enum VTXTYPE tp)
|
||||
void VAOManager::regenerateVAO(enum VTXTYPE tp)
|
||||
{
|
||||
if (vao[tp])
|
||||
glDeleteVertexArrays(1, &vao[tp]);
|
||||
@ -668,7 +558,100 @@ void VBOGatherer::regenerateVAO(enum VTXTYPE tp)
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
size_t VBOGatherer::getVertexPitch(enum VTXTYPE tp) const
|
||||
void VAOManager::regenerateInstancedVAO()
|
||||
{
|
||||
cleanInstanceVAOs();
|
||||
|
||||
enum video::E_VERTEX_TYPE IrrVT[] = { video::EVT_STANDARD, video::EVT_2TCOORDS, video::EVT_TANGENTS };
|
||||
for (unsigned i = 0; i < VTXTYPE_COUNT; i++)
|
||||
{
|
||||
video::E_VERTEX_TYPE tp = IrrVT[i];
|
||||
if (!vbo[tp] || !ibo[tp])
|
||||
continue;
|
||||
GLuint vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeDefault]);
|
||||
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||
glVertexAttribDivisor(7, 1);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 1);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 1);
|
||||
glEnableVertexAttribArray(10);
|
||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(10, 1);
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||
glVertexAttribDivisor(11, 1);
|
||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeDefault)] = vao;
|
||||
|
||||
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeShadow]);
|
||||
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||
glVertexAttribDivisor(7, 1);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 1);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 1);
|
||||
glEnableVertexAttribArray(10);
|
||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(10, 1);
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||
glVertexAttribDivisor(11, 1);
|
||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeShadow)] = vao;
|
||||
|
||||
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeRSM]);
|
||||
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||
glVertexAttribDivisor(7, 1);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 1);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 1);
|
||||
glEnableVertexAttribArray(10);
|
||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(10, 1);
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||
glVertexAttribDivisor(11, 1);
|
||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeRSM)] = vao;
|
||||
|
||||
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeGlow]);
|
||||
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), 0);
|
||||
glVertexAttribDivisor(7, 1);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 1);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 1);
|
||||
glEnableVertexAttribArray(12);
|
||||
glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GlowInstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(12, 1);
|
||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeGlow)] = vao;
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const
|
||||
{
|
||||
switch (tp)
|
||||
{
|
||||
@ -684,22 +667,22 @@ size_t VBOGatherer::getVertexPitch(enum VTXTYPE tp) const
|
||||
}
|
||||
}
|
||||
|
||||
VBOGatherer::VTXTYPE VBOGatherer::getVTXTYPE(video::E_VERTEX_TYPE type)
|
||||
VAOManager::VTXTYPE VAOManager::getVTXTYPE(video::E_VERTEX_TYPE type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
assert(0 && "Wrong vtxtype");
|
||||
case video::EVT_STANDARD:
|
||||
return VTXTYPE_STANDARD;
|
||||
case video::EVT_2TCOORDS:
|
||||
return VTXTYPE_TCOORD;
|
||||
case video::EVT_TANGENTS:
|
||||
return VTXTYPE_TANGENT;
|
||||
default:
|
||||
assert(0 && "Wrong vtxtype");
|
||||
}
|
||||
};
|
||||
|
||||
void VBOGatherer::append(scene::IMeshBuffer *mb, VBOGatherer::VTXTYPE tp)
|
||||
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
|
||||
{
|
||||
size_t old_vtx_cnt = vtx_cnt[tp];
|
||||
vtx_cnt[tp] += mb->getVertexCount();
|
||||
@ -717,7 +700,7 @@ void VBOGatherer::append(scene::IMeshBuffer *mb, VBOGatherer::VTXTYPE tp)
|
||||
mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16);
|
||||
}
|
||||
|
||||
std::pair<unsigned, unsigned> VBOGatherer::getBase(scene::IMeshBuffer *mb)
|
||||
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
|
||||
{
|
||||
VTXTYPE tp = getVTXTYPE(mb->getVertexType());
|
||||
if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end())
|
||||
@ -727,6 +710,7 @@ std::pair<unsigned, unsigned> VBOGatherer::getBase(scene::IMeshBuffer *mb)
|
||||
append(mb, tp);
|
||||
regenerateBuffer(tp);
|
||||
regenerateVAO(tp);
|
||||
regenerateInstancedVAO();
|
||||
}
|
||||
|
||||
std::map<scene::IMeshBuffer*, unsigned>::iterator It;
|
||||
@ -738,63 +722,41 @@ std::pair<unsigned, unsigned> VBOGatherer::getBase(scene::IMeshBuffer *mb)
|
||||
return std::pair<unsigned, unsigned>(vtx, It->second);
|
||||
}
|
||||
|
||||
static VBOGatherer *gatherersingleton = 0;
|
||||
|
||||
std::pair<unsigned, unsigned> getVAOOffsetAndBase(scene::IMeshBuffer *mb)
|
||||
size_t VAOManager::appendInstance(enum InstanceType, const std::vector<InstanceData> &instance_data)
|
||||
{
|
||||
if (!gatherersingleton)
|
||||
gatherersingleton = new VBOGatherer();
|
||||
return gatherersingleton->getBase(mb);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[0]);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, instance_count[0] * sizeof(InstanceData), instance_data.size() * sizeof(InstanceData), instance_data.data());
|
||||
size_t result = instance_count[0];
|
||||
instance_count[0] += instance_data.size();
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned getVBO(video::E_VERTEX_TYPE type)
|
||||
{
|
||||
if (gatherersingleton)
|
||||
return gatherersingleton->getVBO(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned getVAO(video::E_VERTEX_TYPE type)
|
||||
{
|
||||
if (gatherersingleton)
|
||||
return gatherersingleton->getVAO(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void resetVAO()
|
||||
{
|
||||
if (gatherersingleton)
|
||||
delete gatherersingleton;
|
||||
gatherersingleton = 0;
|
||||
}
|
||||
|
||||
ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer)
|
||||
ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t)
|
||||
{
|
||||
if (!UserConfigParams::m_profiler_enabled) return;
|
||||
if (profiler.isFrozen()) return;
|
||||
|
||||
if (!timer.canSubmitQuery) return;
|
||||
#ifdef GL_TIME_ELAPSED
|
||||
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
|
||||
if (!timer.initialised)
|
||||
{
|
||||
gl_driver->extGlGenQueries(1, &timer.query);
|
||||
glGenQueries(1, &timer.query);
|
||||
timer.initialised = true;
|
||||
}
|
||||
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, timer.query);
|
||||
glBeginQuery(GL_TIME_ELAPSED, timer.query);
|
||||
#endif
|
||||
}
|
||||
ScopedGPUTimer::~ScopedGPUTimer()
|
||||
{
|
||||
if (!UserConfigParams::m_profiler_enabled) return;
|
||||
if (profiler.isFrozen()) return;
|
||||
|
||||
if (!timer.canSubmitQuery) return;
|
||||
#ifdef GL_TIME_ELAPSED
|
||||
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
|
||||
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
|
||||
glEndQuery(GL_TIME_ELAPSED);
|
||||
timer.canSubmitQuery = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
GPUTimer::GPUTimer() : initialised(false)
|
||||
GPUTimer::GPUTimer() : initialised(false), lastResult(0), canSubmitQuery(true)
|
||||
{
|
||||
}
|
||||
|
||||
@ -803,8 +765,12 @@ unsigned GPUTimer::elapsedTimeus()
|
||||
if (!initialised)
|
||||
return 0;
|
||||
GLuint result;
|
||||
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
|
||||
gl_driver->extGlGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
|
||||
glGetQueryObjectuiv(query, GL_QUERY_RESULT_AVAILABLE, &result);
|
||||
if (result == GL_FALSE)
|
||||
return lastResult;
|
||||
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
|
||||
lastResult = result / 1000;
|
||||
canSubmitQuery = true;
|
||||
return result / 1000;
|
||||
}
|
||||
|
||||
@ -861,7 +827,7 @@ void FrameBuffer::Bind()
|
||||
glViewport(0, 0, width, height);
|
||||
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver*)irr_driver->getDevice()->getVideoDriver();
|
||||
GLenum bufs[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
|
||||
gl_driver->extGlDrawBuffers(RenderTargets.size(), bufs);
|
||||
glDrawBuffers(RenderTargets.size(), bufs);
|
||||
}
|
||||
|
||||
void FrameBuffer::Blit(const FrameBuffer &Src, FrameBuffer &Dst, GLbitfield mask, GLenum filter)
|
||||
@ -924,7 +890,7 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol
|
||||
glUseProgram(UIShader::ColoredTextureRectShader::getInstance()->Program);
|
||||
glBindVertexArray(UIShader::ColoredTextureRectShader::getInstance()->vao);
|
||||
|
||||
setTexture(UIShader::ColoredTextureRectShader::getInstance()->TU_tex, static_cast<const irr::video::COpenGLTexture*>(texture)->getOpenGLTextureName(), GL_LINEAR, GL_LINEAR);
|
||||
UIShader::ColoredTextureRectShader::getInstance()->SetTextureUnits(createVector<GLuint>(static_cast<const irr::video::COpenGLTexture*>(texture)->getOpenGLTextureName()));
|
||||
UIShader::ColoredTextureRectShader::getInstance()->setUniforms(
|
||||
core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height),
|
||||
core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height));
|
||||
@ -944,7 +910,7 @@ void drawTexQuad(GLuint texture, float width, float height,
|
||||
glUseProgram(UIShader::TextureRectShader::getInstance()->Program);
|
||||
glBindVertexArray(SharedObject::UIVAO);
|
||||
|
||||
setTexture(UIShader::TextureRectShader::getInstance()->TU_tex, texture, GL_LINEAR, GL_LINEAR);
|
||||
UIShader::TextureRectShader::getInstance()->SetTextureUnits(createVector<GLuint>(texture));
|
||||
UIShader::TextureRectShader::getInstance()->setUniforms(
|
||||
core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height),
|
||||
core::vector2df(tex_center_pos_x, tex_center_pos_y),
|
||||
@ -1047,7 +1013,7 @@ void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect
|
||||
glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program);
|
||||
glBindVertexArray(SharedObject::UIVAO);
|
||||
|
||||
setTexture(UIShader::UniformColoredTextureRectShader::getInstance()->TU_tex, static_cast<const irr::video::COpenGLTexture*>(texture)->getOpenGLTextureName(), GL_LINEAR, GL_LINEAR);
|
||||
UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector<GLuint>(static_cast<const irr::video::COpenGLTexture*>(texture)->getOpenGLTextureName()));
|
||||
UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms(
|
||||
core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), colors);
|
||||
|
||||
@ -1083,7 +1049,7 @@ void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h,
|
||||
glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program);
|
||||
glBindVertexArray(SharedObject::UIVAO);
|
||||
|
||||
setTexture(UIShader::UniformColoredTextureRectShader::getInstance()->TU_tex, texture, GL_LINEAR, GL_LINEAR);
|
||||
UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector<GLuint>(texture));
|
||||
UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms(
|
||||
core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height),
|
||||
core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height),
|
||||
@ -1204,3 +1170,30 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect<s32>& position,
|
||||
|
||||
glGetError();
|
||||
}
|
||||
|
||||
bool hasGLExtension(const char* extension)
|
||||
{
|
||||
if (glGetStringi != NULL)
|
||||
{
|
||||
GLint numExtensions = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
|
||||
for (GLint i = 0; i < numExtensions; i++)
|
||||
{
|
||||
const char* foundExtension =
|
||||
(const char*) glGetStringi(GL_EXTENSIONS, i);
|
||||
if (foundExtension && strcmp(foundExtension, extension) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* extensions = (const char*) glGetString(GL_EXTENSIONS);
|
||||
if (extensions && strstr(extensions, extension) != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,118 +1,12 @@
|
||||
#ifndef GLWRAP_HEADER_H
|
||||
#define GLWRAP_HEADER_H
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <OpenGL/gl.h>
|
||||
# include <OpenGL/gl3.h>
|
||||
# define OGL32CTX
|
||||
# ifdef GL_ARB_instanced_arrays
|
||||
# define glVertexAttribDivisor glVertexAttribDivisorARB
|
||||
# endif
|
||||
# ifndef GL_TEXTURE_SWIZZLE_RGBA
|
||||
# define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
|
||||
# endif
|
||||
#elif defined(ANDROID)
|
||||
# include <GLES/gl.h>
|
||||
#elif defined(WIN32)
|
||||
# define _WINSOCKAPI_
|
||||
// has to be included before gl.h because of WINGDIAPI and APIENTRY definitions
|
||||
# include <windows.h>
|
||||
# include <GL/gl.h>
|
||||
#else
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#define DEBUG_OUTPUT_DECLARED
|
||||
# include <GL/gl.h>
|
||||
#endif
|
||||
#include "gl_headers.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include "irr_driver.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
// already includes glext.h, which defines useful GL constants.
|
||||
// COpenGLDriver has already loaded the extension GL functions we use (e.g glBeginQuery)
|
||||
#include "../../lib/irrlicht/source/Irrlicht/COpenGLDriver.h"
|
||||
#ifdef WIN32
|
||||
extern PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks;
|
||||
extern PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback;
|
||||
extern PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback;
|
||||
extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
|
||||
extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
|
||||
extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
|
||||
extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
|
||||
extern PFNGLGENBUFFERSPROC glGenBuffers;
|
||||
extern PFNGLBINDBUFFERPROC glBindBuffer;
|
||||
extern PFNGLBUFFERDATAPROC glBufferData;
|
||||
extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
|
||||
extern PFNGLCREATESHADERPROC glCreateShader;
|
||||
extern PFNGLCOMPILESHADERPROC glCompileShader;
|
||||
extern PFNGLSHADERSOURCEPROC glShaderSource;
|
||||
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||
extern PFNGLATTACHSHADERPROC glAttachShader;
|
||||
extern PFNGLLINKPROGRAMPROC glLinkProgram;
|
||||
extern PFNGLUSEPROGRAMPROC glUseProgram;
|
||||
extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||
extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||
extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
|
||||
extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
|
||||
extern PFNGLUNIFORM1FPROC glUniform1f;
|
||||
extern PFNGLUNIFORM3FPROC glUniform3f;
|
||||
extern PFNGLUNIFORM1FVPROC glUniform1fv;
|
||||
extern PFNGLUNIFORM4FVPROC glUniform4fv;
|
||||
extern PFNGLDELETESHADERPROC glDeleteShader;
|
||||
extern PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||
extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
|
||||
extern PFNGLACTIVETEXTUREPROC glActiveTexture;
|
||||
extern PFNGLUNIFORM2FPROC glUniform2f;
|
||||
extern PFNGLUNIFORM1IPROC glUniform1i;
|
||||
extern PFNGLUNIFORM3IPROC glUniform3i;
|
||||
extern PFNGLUNIFORM4IPROC glUniform4i;
|
||||
extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
|
||||
extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
|
||||
extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
|
||||
extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
||||
extern PFNGLBLENDEQUATIONPROC glBlendEquation;
|
||||
extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
|
||||
extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
|
||||
extern PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
|
||||
extern PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
|
||||
extern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
|
||||
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||
extern PFNGLTEXBUFFERPROC glTexBuffer;
|
||||
extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
|
||||
extern PFNGLMAPBUFFERPROC glMapBuffer;
|
||||
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
||||
extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
|
||||
extern PFNGLFENCESYNCPROC glFenceSync;
|
||||
extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
|
||||
extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
|
||||
extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
||||
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
||||
extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||
extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
||||
extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
|
||||
extern PFNGLTEXIMAGE3DPROC glTexImage3D;
|
||||
extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
|
||||
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
||||
extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
|
||||
extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
|
||||
extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
|
||||
extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
|
||||
extern PFNGLBLENDCOLORPROC glBlendColor;
|
||||
extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
|
||||
extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
|
||||
extern PFNGLTEXSTORAGE1DPROC glTexStorage1D;
|
||||
extern PFNGLTEXSTORAGE2DPROC glTexStorage2D;
|
||||
extern PFNGLTEXSTORAGE3DPROC glTexStorage3D;
|
||||
extern PFNGLBINDIMAGETEXTUREPROC glBindImageTexture;
|
||||
extern PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
|
||||
#ifdef DEBUG
|
||||
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
void initGL();
|
||||
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount);
|
||||
@ -194,6 +88,8 @@ class GPUTimer;
|
||||
|
||||
class ScopedGPUTimer
|
||||
{
|
||||
protected:
|
||||
GPUTimer &timer;
|
||||
public:
|
||||
ScopedGPUTimer(GPUTimer &);
|
||||
~ScopedGPUTimer();
|
||||
@ -204,6 +100,8 @@ class GPUTimer
|
||||
friend class ScopedGPUTimer;
|
||||
GLuint query;
|
||||
bool initialised;
|
||||
unsigned lastResult;
|
||||
bool canSubmitQuery;
|
||||
public:
|
||||
GPUTimer();
|
||||
unsigned elapsedTimeus();
|
||||
@ -241,10 +139,109 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = f
|
||||
bool loadCompressedTexture(const std::string& compressed_tex);
|
||||
void saveCompressedTexture(const std::string& compressed_tex);
|
||||
|
||||
std::pair<unsigned, unsigned> getVAOOffsetAndBase(scene::IMeshBuffer *mb);
|
||||
unsigned getVAO(video::E_VERTEX_TYPE type);
|
||||
unsigned getVBO(video::E_VERTEX_TYPE type);
|
||||
void resetVAO();
|
||||
enum InstanceType
|
||||
{
|
||||
InstanceTypeDefault,
|
||||
InstanceTypeShadow,
|
||||
InstanceTypeRSM,
|
||||
InstanceTypeGlow,
|
||||
InstanceTypeCount,
|
||||
};
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma pack(push, 1)
|
||||
#endif
|
||||
struct InstanceData
|
||||
{
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Origin;
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Orientation;
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Scale;
|
||||
uint64_t Texture;
|
||||
uint64_t SecondTexture;
|
||||
#ifdef WIN32
|
||||
};
|
||||
#else
|
||||
} __attribute__((packed));
|
||||
#endif
|
||||
|
||||
struct GlowInstanceData
|
||||
{
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Origin;
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Orientation;
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Scale;
|
||||
unsigned Color;
|
||||
#ifdef WIN32
|
||||
};
|
||||
#else
|
||||
} __attribute__((packed));
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
class VAOManager : public Singleton<VAOManager>
|
||||
{
|
||||
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
|
||||
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
|
||||
GLuint instance_vbo[InstanceTypeCount];
|
||||
size_t instance_count[InstanceTypeCount];
|
||||
void *Ptr[InstanceTypeCount];
|
||||
void *VBOPtr[VTXTYPE_COUNT];
|
||||
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
|
||||
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
|
||||
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
|
||||
std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
|
||||
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO;
|
||||
|
||||
void cleanInstanceVAOs();
|
||||
void regenerateBuffer(enum VTXTYPE);
|
||||
void regenerateVAO(enum VTXTYPE);
|
||||
void regenerateInstancedVAO();
|
||||
size_t getVertexPitch(enum VTXTYPE) const;
|
||||
VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type);
|
||||
void append(scene::IMeshBuffer *, VTXTYPE tp);
|
||||
public:
|
||||
VAOManager();
|
||||
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
|
||||
size_t appendInstance(enum InstanceType, const std::vector<InstanceData> &instance_data);
|
||||
GLuint getInstanceBuffer(InstanceType it) { return instance_vbo[it]; }
|
||||
void *getInstanceBufferPtr(InstanceType it) { return Ptr[it]; }
|
||||
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
|
||||
void *getVBOPtr(video::E_VERTEX_TYPE type) { return VBOPtr[getVTXTYPE(type)]; }
|
||||
unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; }
|
||||
unsigned getInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
|
||||
~VAOManager();
|
||||
};
|
||||
|
||||
void draw3DLine(const core::vector3df& start,
|
||||
const core::vector3df& end, irr::video::SColor color);
|
||||
@ -264,4 +261,7 @@ void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect<s32>
|
||||
|
||||
void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect<s32>& position,
|
||||
const irr::core::rect<s32>* clip = 0);
|
||||
|
||||
bool hasGLExtension(const char* extension);
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <IParticleSystemSceneNode.h>
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "graphics/particle_emitter.hpp"
|
||||
#include "../../lib/irrlicht/source/Irrlicht/os.h"
|
||||
#define COMPONENTCOUNT 8
|
||||
|
||||
scene::IParticleSystemSceneNode *ParticleSystemProxy::addParticleNode(
|
||||
@ -88,7 +89,7 @@ void ParticleSystemProxy::setHeightmap(const std::vector<std::vector<float> > &h
|
||||
has_height_map = true;
|
||||
glGenBuffers(1, &heighmapbuffer);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, heighmapbuffer);
|
||||
glBufferData(GL_TEXTURE_BUFFER, width * height * sizeof(float), hm_array, GL_STATIC_DRAW);
|
||||
glBufferData(GL_TEXTURE_BUFFER, width * height * sizeof(float), hm_array, GL_STREAM_COPY);
|
||||
glGenTextures(1, &heightmaptexture);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, heighmapbuffer);
|
||||
@ -348,9 +349,7 @@ void ParticleSystemProxy::drawFlip()
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glUseProgram(ParticleShader::FlipParticleRender::getInstance()->Program);
|
||||
|
||||
setTexture(ParticleShader::FlipParticleRender::getInstance()->TU_tex, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
|
||||
setTexture(ParticleShader::FlipParticleRender::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
|
||||
ParticleShader::FlipParticleRender::getInstance()->SetTextureUnits(std::vector<GLuint>{ texture, irr_driver->getDepthStencilTexture() });
|
||||
ParticleShader::FlipParticleRender::getInstance()->setUniforms();
|
||||
|
||||
glBindVertexArray(current_rendering_vao);
|
||||
@ -365,8 +364,7 @@ void ParticleSystemProxy::drawNotFlip()
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glUseProgram(ParticleShader::SimpleParticleRender::getInstance()->Program);
|
||||
|
||||
setTexture(ParticleShader::SimpleParticleRender::getInstance()->TU_tex, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
|
||||
setTexture(ParticleShader::SimpleParticleRender::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
ParticleShader::SimpleParticleRender::getInstance()->SetTextureUnits(std::vector<GLuint>{ texture, irr_driver->getDepthStencilTexture() });
|
||||
video::SColorf ColorFrom = video::SColorf(getColorFrom()[0], getColorFrom()[1], getColorFrom()[2]);
|
||||
video::SColorf ColorTo = video::SColorf(getColorTo()[0], getColorTo()[1], getColorTo()[2]);
|
||||
|
||||
@ -389,12 +387,12 @@ void ParticleSystemProxy::generateVAOs()
|
||||
glBindVertexArray(0);
|
||||
glGenBuffers(1, &initial_values_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), ParticleParams, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), ParticleParams, GL_STREAM_COPY);
|
||||
glGenBuffers(2, tfb_buffers);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), InitialValues, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), InitialValues, GL_STREAM_COPY);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), 0, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), 0, GL_STREAM_COPY);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glGenVertexArrays(1, ¤t_rendering_vao);
|
||||
@ -423,7 +421,7 @@ void ParticleSystemProxy::generateVAOs()
|
||||
}
|
||||
glGenBuffers(1, &quaternionsbuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quaternionsbuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, 4 * count * sizeof(float), quaternions, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, 4 * count * sizeof(float), quaternions, GL_STREAM_COPY);
|
||||
delete[] quaternions;
|
||||
}
|
||||
|
||||
@ -452,6 +450,12 @@ void ParticleSystemProxy::render() {
|
||||
draw();
|
||||
}
|
||||
|
||||
bool ParticleSystemProxy::update()
|
||||
{
|
||||
doParticleSystem(os::Timer::getTime());
|
||||
return (IsVisible && (Particles.size() != 0));
|
||||
}
|
||||
|
||||
void ParticleSystemProxy::OnRegisterSceneNode()
|
||||
{
|
||||
doParticleSystem(os::Timer::getTime());
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
const float* getColorTo() const { return m_color_to; }
|
||||
void setHeightmap(const std::vector<std::vector<float> >&, float, float, float, float);
|
||||
void setFlip();
|
||||
bool update();
|
||||
};
|
||||
|
||||
#endif // GPUPARTICLES_H
|
||||
|
@ -112,6 +112,10 @@ IrrDriver::IrrDriver()
|
||||
m_mipviz = m_wireframe = m_normals = m_ssaoviz = \
|
||||
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = false;
|
||||
SkyboxCubeMap = m_last_light_bucket_distance = 0;
|
||||
m_shadow_camnodes[0] = NULL;
|
||||
m_shadow_camnodes[1] = NULL;
|
||||
m_shadow_camnodes[2] = NULL;
|
||||
m_shadow_camnodes[3] = NULL;
|
||||
memset(object_count, 0, sizeof(object_count));
|
||||
} // IrrDriver
|
||||
|
||||
@ -166,6 +170,11 @@ void IrrDriver::IncreaseObjectCount()
|
||||
object_count[m_phase]++;
|
||||
}
|
||||
|
||||
void IrrDriver::IncreasePolyCount(unsigned Polys)
|
||||
{
|
||||
poly_count[m_phase] += Polys;
|
||||
}
|
||||
|
||||
core::array<video::IRenderTarget> &IrrDriver::getMainSetup()
|
||||
{
|
||||
return m_mrt;
|
||||
@ -328,8 +337,8 @@ void IrrDriver::initDevice()
|
||||
|
||||
} // end if firstTime
|
||||
|
||||
const core::dimension2d<u32> ssize = m_device->getVideoModeList()
|
||||
->getDesktopResolution();
|
||||
video::IVideoModeList* modes = m_device->getVideoModeList();
|
||||
const core::dimension2d<u32> ssize = modes->getDesktopResolution();
|
||||
if (UserConfigParams::m_width > (int)ssize.Width ||
|
||||
UserConfigParams::m_height > (int)ssize.Height)
|
||||
{
|
||||
@ -339,11 +348,14 @@ void IrrDriver::initDevice()
|
||||
UserConfigParams::m_height = (int)ssize.Height;
|
||||
}
|
||||
|
||||
core::dimension2d<u32> res = core::dimension2du(UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
res = m_device->getVideoModeList()->getVideoModeResolution(res, res);
|
||||
|
||||
if (res.Width > 0 && res.Height > 0)
|
||||
core::dimension2d<u32> res = core::dimension2du(UserConfigParams::m_width,
|
||||
UserConfigParams::m_height);
|
||||
|
||||
|
||||
if (modes->getVideoModeCount() > 0)
|
||||
{
|
||||
res = modes->getVideoModeResolution(res, res);
|
||||
|
||||
UserConfigParams::m_width = res.Width;
|
||||
UserConfigParams::m_height = res.Height;
|
||||
}
|
||||
@ -467,25 +479,57 @@ void IrrDriver::initDevice()
|
||||
|
||||
m_need_ubo_workaround = false;
|
||||
m_need_rh_workaround = false;
|
||||
m_need_srgb_workaround = false;
|
||||
#ifdef WIN32
|
||||
// Fix for Intel Sandy Bridge on Windows which supports GL up to 3.1 only
|
||||
if (strstr((const char *)glGetString(GL_VENDOR), "Intel") != nullptr && (GLMajorVersion == 3 && GLMinorVersion == 1))
|
||||
if (strstr((const char *)glGetString(GL_VENDOR), "Intel") != NULL && (GLMajorVersion == 3 && GLMinorVersion == 1))
|
||||
m_need_ubo_workaround = true;
|
||||
#endif
|
||||
// Fix for Nvidia and instanced RH
|
||||
if (strstr((const char *)glGetString(GL_VENDOR), "NVIDIA") != nullptr)
|
||||
if (strstr((const char *)glGetString(GL_VENDOR), "NVIDIA") != NULL)
|
||||
m_need_rh_workaround = true;
|
||||
|
||||
// Fix for AMD and bindless sRGB textures
|
||||
if (strstr((const char *)glGetString(GL_VENDOR), "ATI") != NULL)
|
||||
m_need_srgb_workaround = true;
|
||||
}
|
||||
m_glsl = (GLMajorVersion > 3 || (GLMajorVersion == 3 && GLMinorVersion >= 1));
|
||||
initGL();
|
||||
|
||||
// Parse extensions
|
||||
hasVSLayer = false;
|
||||
hasBaseInstance = false;
|
||||
hasBuffserStorage = false;
|
||||
hasDrawIndirect = false;
|
||||
hasComputeShaders = false;
|
||||
hasTextureStorage = false;
|
||||
// Default false value for hasVSLayer if --no-graphics argument is used
|
||||
if (!ProfileWorld::isNoGraphics())
|
||||
{
|
||||
const GLubyte *extensions = glGetString(GL_EXTENSIONS);
|
||||
if (extensions && strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL)
|
||||
hasVSLayer = true;
|
||||
if (GLEW_AMD_vertex_shader_layer) {
|
||||
hasVSLayer = true;
|
||||
Log::info("GLDriver", "AMD Vertex Shader Layer enabled");
|
||||
}
|
||||
if (GLEW_ARB_buffer_storage) {
|
||||
hasBuffserStorage = true;
|
||||
Log::info("GLDriver", "ARB Buffer Storage enabled");
|
||||
}
|
||||
if (GLEW_ARB_base_instance) {
|
||||
hasBaseInstance = true;
|
||||
Log::info("GLDriver", "ARB Base Instance enabled");
|
||||
}
|
||||
if (GLEW_ARB_draw_indirect) {
|
||||
hasDrawIndirect = true;
|
||||
Log::info("GLDriver", "ARB Draw Indirect enabled");
|
||||
}
|
||||
if (GLEW_ARB_compute_shader) {
|
||||
hasComputeShaders = true;
|
||||
Log::info("GLDriver", "ARB Compute Shader enabled");
|
||||
}
|
||||
if (GLEW_ARB_texture_storage) {
|
||||
hasTextureStorage = true;
|
||||
Log::info("GLDriver", "ARB Texture Storage enabled");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -513,8 +557,7 @@ void IrrDriver::initDevice()
|
||||
m_mrt.clear();
|
||||
m_mrt.reallocate(2);
|
||||
|
||||
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
|
||||
gl_driver->extGlGenQueries(1, &m_lensflare_query);
|
||||
glGenQueries(1, &m_lensflare_query);
|
||||
m_query_issued = false;
|
||||
|
||||
scene::IMesh * const sphere = m_scene_manager->getGeometryCreator()->createSphereMesh(1, 16, 16);
|
||||
@ -733,7 +776,7 @@ void IrrDriver::applyResolutionSettings()
|
||||
// FIXME: this load sequence is (mostly) duplicated from main.cpp!!
|
||||
// That's just error prone
|
||||
// (we're sure to update main.cpp at some point and forget this one...)
|
||||
|
||||
m_shaders->killShaders();
|
||||
// initDevice will drop the current device.
|
||||
initDevice();
|
||||
|
||||
@ -1601,6 +1644,7 @@ video::ITexture* IrrDriver::applyMask(video::ITexture* texture,
|
||||
// ----------------------------------------------------------------------------
|
||||
void IrrDriver::setRTT(RTT* rtt)
|
||||
{
|
||||
memset(m_shadow_camnodes, 0, 4 * sizeof(void*));
|
||||
m_rtts = rtt;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -1703,13 +1747,14 @@ void IrrDriver::displayFPS()
|
||||
if (UserConfigParams::m_artist_debug_mode)
|
||||
{
|
||||
sprintf(
|
||||
buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) - LightDst : ~%d",
|
||||
buffer, "FPS: %i/%i/%i - PolyCount (Solid:%d Shadows:%d) - LightDst : ~%d",
|
||||
min, fps, max,
|
||||
object_count[SOLID_NORMAL_AND_DEPTH_PASS],
|
||||
object_count[SOLID_NORMAL_AND_DEPTH_PASS],
|
||||
object_count[TRANSPARENT_PASS],
|
||||
poly_count[SOLID_NORMAL_AND_DEPTH_PASS],
|
||||
poly_count[SHADOW_PASS],
|
||||
m_last_light_bucket_distance
|
||||
);
|
||||
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
|
||||
poly_count[SHADOW_PASS] = 0;
|
||||
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
|
||||
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
|
||||
object_count[TRANSPARENT_PASS] = 0;
|
||||
@ -2414,8 +2459,8 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy,
|
||||
|
||||
if (sun)
|
||||
{
|
||||
m_sun_interposer->setPosition(pos);
|
||||
m_sun_interposer->updateAbsolutePosition();
|
||||
//m_sun_interposer->setPosition(pos);
|
||||
//m_sun_interposer->updateAbsolutePosition();
|
||||
|
||||
m_lensflare->setPosition(pos);
|
||||
m_lensflare->updateAbsolutePosition();
|
||||
|
@ -78,9 +78,10 @@ enum TypeFBO
|
||||
{
|
||||
FBO_SSAO,
|
||||
FBO_NORMAL_AND_DEPTHS,
|
||||
FBO_COMBINED_TMP1_TMP2,
|
||||
FBO_COMBINED_DIFFUSE_SPECULAR,
|
||||
FBO_COLORS,
|
||||
FBO_LOG_LUMINANCE,
|
||||
FBO_DIFFUSE,
|
||||
FBO_SPECULAR,
|
||||
FBO_MLAA_COLORS,
|
||||
FBO_MLAA_BLEND,
|
||||
FBO_MLAA_TMP,
|
||||
@ -111,6 +112,7 @@ enum QueryPerf
|
||||
{
|
||||
Q_SOLID_PASS1,
|
||||
Q_SHADOWS,
|
||||
Q_RSM,
|
||||
Q_RH,
|
||||
Q_GI,
|
||||
Q_ENVMAP,
|
||||
@ -140,7 +142,9 @@ enum TypeRTT
|
||||
RTT_LINEAR_DEPTH,
|
||||
RTT_NORMAL_AND_DEPTH,
|
||||
RTT_COLOR,
|
||||
RTT_LOG_LUMINANCE,
|
||||
RTT_DIFFUSE,
|
||||
RTT_SPECULAR,
|
||||
|
||||
|
||||
RTT_HALF1,
|
||||
RTT_HALF2,
|
||||
@ -196,8 +200,15 @@ class IrrDriver : public IEventReceiver, public NoCopy
|
||||
private:
|
||||
int GLMajorVersion, GLMinorVersion;
|
||||
bool hasVSLayer;
|
||||
bool hasBaseInstance;
|
||||
bool hasDrawIndirect;
|
||||
bool hasBuffserStorage;
|
||||
bool hasComputeShaders;
|
||||
bool hasTextureStorage;
|
||||
bool m_need_ubo_workaround;
|
||||
bool m_need_rh_workaround;
|
||||
bool m_need_srgb_workaround;
|
||||
GLsync m_sync;
|
||||
/** The irrlicht device. */
|
||||
IrrlichtDevice *m_device;
|
||||
/** Irrlicht scene manager. */
|
||||
@ -290,11 +301,41 @@ public:
|
||||
return m_need_rh_workaround;
|
||||
}
|
||||
|
||||
bool needsRGBBindlessWorkaround() const
|
||||
{
|
||||
return m_need_srgb_workaround;
|
||||
}
|
||||
|
||||
bool hasARB_base_instance() const
|
||||
{
|
||||
return hasBaseInstance;
|
||||
}
|
||||
|
||||
bool hasARB_draw_indirect() const
|
||||
{
|
||||
return hasDrawIndirect;
|
||||
}
|
||||
|
||||
bool hasVSLayerExtension() const
|
||||
{
|
||||
return hasVSLayer;
|
||||
}
|
||||
|
||||
bool hasBufferStorageExtension() const
|
||||
{
|
||||
return hasBuffserStorage;
|
||||
}
|
||||
|
||||
bool hasARBComputeShaders() const
|
||||
{
|
||||
return hasComputeShaders;
|
||||
}
|
||||
|
||||
bool hasARBTextureStorage() const
|
||||
{
|
||||
return hasTextureStorage;
|
||||
}
|
||||
|
||||
video::SColorf getAmbientLight() const;
|
||||
|
||||
struct GlowData {
|
||||
@ -332,12 +373,14 @@ private:
|
||||
/** Performance stats */
|
||||
unsigned m_last_light_bucket_distance;
|
||||
unsigned object_count[PASS_COUNT];
|
||||
unsigned poly_count[PASS_COUNT];
|
||||
u32 m_renderpass;
|
||||
u32 m_lensflare_query;
|
||||
bool m_query_issued;
|
||||
class STKMeshSceneNode *m_sun_interposer;
|
||||
scene::CLensFlareSceneNode *m_lensflare;
|
||||
scene::ICameraSceneNode *m_suncam;
|
||||
scene::ICameraSceneNode *m_shadow_camnodes[4];
|
||||
float m_shadows_cam[4][24];
|
||||
|
||||
std::vector<GlowData> m_glowing;
|
||||
@ -379,6 +422,7 @@ private:
|
||||
void renderLights(unsigned pointlightCount);
|
||||
void renderShadowsDebug();
|
||||
void doScreenShot();
|
||||
void PrepareDrawCalls(scene::ICameraSceneNode *camnode);
|
||||
public:
|
||||
IrrDriver();
|
||||
~IrrDriver();
|
||||
@ -394,6 +438,7 @@ public:
|
||||
return sun_ortho_matrix;
|
||||
}
|
||||
void IncreaseObjectCount();
|
||||
void IncreasePolyCount(unsigned);
|
||||
core::array<video::IRenderTarget> &getMainSetup();
|
||||
void updateConfigIfRelevant();
|
||||
void setAllMaterialFlags(scene::IMesh *mesh) const;
|
||||
@ -570,7 +615,7 @@ public:
|
||||
// -----------------------------------------------------------------------
|
||||
inline video::E_MATERIAL_TYPE getShader(const ShaderType num) {return m_shaders->getShader(num);}
|
||||
// -----------------------------------------------------------------------
|
||||
inline void updateShaders() {m_shaders->loadShaders();}
|
||||
inline void updateShaders() {m_shaders->killShaders();}
|
||||
// ------------------------------------------------------------------------
|
||||
inline video::IShaderConstantSetCallBack* getCallback(const ShaderType num)
|
||||
{
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
float getEnergy() const { return m_energy; }
|
||||
float getEffectiveEnergy() const { return m_energy_multiplier * m_energy; }
|
||||
core::vector3df getColor() const { return core::vector3df(m_color[0], m_color[1], m_color[2]); }
|
||||
void setColor(float r, float g, float b) { m_color[0] = r; m_color[1] = g; m_color[2] = b; }
|
||||
|
||||
float getEnergyMultiplier() const { return m_energy_multiplier; }
|
||||
void setEnergyMultiplier(float newval) { m_energy_multiplier = newval; }
|
||||
|
@ -137,19 +137,24 @@ void LODNode::OnAnimate(u32 timeMs)
|
||||
}
|
||||
}
|
||||
|
||||
void LODNode::OnRegisterSceneNode()
|
||||
void LODNode::updateVisibility(bool* shown)
|
||||
{
|
||||
if (!isVisible()) return;
|
||||
if (m_nodes.size() == 0) return;
|
||||
|
||||
bool shown = false;
|
||||
int level = getLevel();
|
||||
if (level>=0)
|
||||
for (size_t i = 0; i < m_nodes.size(); i++)
|
||||
{
|
||||
m_nodes[level]->updateAbsolutePosition();
|
||||
m_nodes[level]->OnRegisterSceneNode();
|
||||
shown = true;
|
||||
m_nodes[i]->setVisible(i == level);
|
||||
if (i == level && shown != NULL)
|
||||
*shown = (i > 0);
|
||||
}
|
||||
}
|
||||
|
||||
void LODNode::OnRegisterSceneNode()
|
||||
{
|
||||
bool shown;
|
||||
updateVisibility(&shown);
|
||||
|
||||
const u32 now = irr_driver->getDevice()->getTimer()->getTime();
|
||||
|
||||
@ -158,6 +163,7 @@ void LODNode::OnRegisterSceneNode()
|
||||
m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH) &&
|
||||
now > m_last_tick)
|
||||
{
|
||||
int level = getLevel();
|
||||
if (m_previous_visibility == WAS_HIDDEN && shown)
|
||||
{
|
||||
scene::IMesh* mesh;
|
||||
@ -254,20 +260,7 @@ void LODNode::OnRegisterSceneNode()
|
||||
m_previous_visibility = (shown ? WAS_SHOWN : WAS_HIDDEN);
|
||||
m_last_tick = now;
|
||||
|
||||
// If this node has children other than the LOD nodes, draw them
|
||||
core::list<ISceneNode*>::Iterator it;
|
||||
|
||||
for (it = Children.begin(); it != Children.end(); it++)
|
||||
{
|
||||
if (m_nodes_set.find(*it) == m_nodes_set.end())
|
||||
{
|
||||
assert(*it != NULL);
|
||||
if ((*it)->isVisible())
|
||||
{
|
||||
(*it)->OnRegisterSceneNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
scene::ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
|
||||
void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
|
||||
|
@ -83,6 +83,8 @@ public:
|
||||
|
||||
int getLevel();
|
||||
|
||||
void updateVisibility(bool* shown = NULL);
|
||||
|
||||
/*
|
||||
//! Returns a reference to the current relative transformation matrix.
|
||||
//! This is the matrix, this scene node uses instead of scale, translation
|
||||
|
@ -450,7 +450,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
||||
else
|
||||
{
|
||||
if (m_is_glsl)
|
||||
m_node = ParticleSystemProxy::addParticleNode(m_is_glsl, true);
|
||||
m_node = ParticleSystemProxy::addParticleNode(m_is_glsl, false);
|
||||
else
|
||||
m_node = irr_driver->addParticleNode();
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
#include <SViewFrustum.h>
|
||||
|
||||
@ -216,7 +217,7 @@ static void DrawFullScreenEffect(Args...args)
|
||||
static
|
||||
void renderBloom(GLuint in)
|
||||
{
|
||||
setTexture(FullScreenShader::BloomShader::getInstance()->TU_tex, in, GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::BloomShader::getInstance()->SetTextureUnits(createVector<GLuint>(in));
|
||||
DrawFullScreenEffect<FullScreenShader::BloomShader>();
|
||||
}
|
||||
|
||||
@ -227,12 +228,12 @@ void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSH
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
glUseProgram(FullScreenShader::DiffuseEnvMapShader::Program);
|
||||
glUseProgram(FullScreenShader::DiffuseEnvMapShader::getInstance()->Program);
|
||||
glBindVertexArray(SharedObject::FullScreenQuadVAO);
|
||||
|
||||
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::DiffuseEnvMapShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH)));
|
||||
core::matrix4 TVM = irr_driver->getViewMatrix().getTransposed();
|
||||
FullScreenShader::DiffuseEnvMapShader::setUniforms(TVM, bSHCoeff, gSHCoeff, rSHCoeff, 0);
|
||||
FullScreenShader::DiffuseEnvMapShader::getInstance()->setUniforms(TVM, std::vector<float>(bSHCoeff, bSHCoeff + 9), std::vector<float>(gSHCoeff, gSHCoeff + 9), std::vector<float>(rSHCoeff, rSHCoeff + 9));
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
@ -263,26 +264,8 @@ void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3
|
||||
core::matrix4 InvRHMatrix;
|
||||
RHMatrix.getInverse(InvRHMatrix);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glActiveTexture(GL_TEXTURE0 + FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_SHR);
|
||||
glBindTexture(GL_TEXTURE_3D, shr);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0 + FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_SHG);
|
||||
glBindTexture(GL_TEXTURE_3D, shg);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0 + FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_SHB);
|
||||
glBindTexture(GL_TEXTURE_3D, shb);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
setTexture(FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_ntex, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->SetTextureUnits(createVector<GLuint>(
|
||||
irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), shr, shg, shb));
|
||||
DrawFullScreenEffect<FullScreenShader::GlobalIlluminationReconstructionShader>(RHMatrix, InvRHMatrix, rh_extend);
|
||||
}
|
||||
|
||||
@ -295,8 +278,7 @@ void PostProcessing::renderSunlight()
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
setTexture(FullScreenShader::SunLightShader::getInstance()->TU_ntex, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(FullScreenShader::SunLightShader::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::SunLightShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture()));
|
||||
DrawFullScreenEffect<FullScreenShader::SunLightShader>(cb->getPosition(), video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue()));
|
||||
}
|
||||
|
||||
@ -309,17 +291,7 @@ void PostProcessing::renderShadowedSunlight(const std::vector<core::matrix4> &su
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
setTexture(FullScreenShader::ShadowedSunLightShader::getInstance()->TU_ntex, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(FullScreenShader::ShadowedSunLightShader::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
glActiveTexture(GL_TEXTURE0 + FullScreenShader::ShadowedSunLightShader::getInstance()->TU_shadowtex);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, depthtex);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
||||
|
||||
FullScreenShader::ShadowedSunLightShader::getInstance()->SetTextureUnits(createVector<GLuint>( irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), depthtex ));
|
||||
DrawFullScreenEffect<FullScreenShader::ShadowedSunLightShader>(cb->getPosition(), video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue()));
|
||||
}
|
||||
|
||||
@ -331,17 +303,13 @@ void PostProcessing::renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
|
||||
{
|
||||
auxiliary.Bind();
|
||||
|
||||
setTexture(FullScreenShader::Gaussian3VBlurShader::getInstance()->TU_tex, in_fbo.getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
FullScreenShader::Gaussian3VBlurShader::getInstance()->SetTextureUnits(createVector<GLuint>(in_fbo.getRTT()[0]));
|
||||
DrawFullScreenEffect<FullScreenShader::Gaussian3VBlurShader>(core::vector2df(inv_width, inv_height));
|
||||
}
|
||||
{
|
||||
in_fbo.Bind();
|
||||
|
||||
setTexture(FullScreenShader::Gaussian3HBlurShader::getInstance()->TU_tex, auxiliary.getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
FullScreenShader::Gaussian3HBlurShader::getInstance()->SetTextureUnits(createVector<GLuint>(auxiliary.getRTT()[0]));
|
||||
DrawFullScreenEffect<FullScreenShader::Gaussian3HBlurShader>(core::vector2df(inv_width, inv_height));
|
||||
}
|
||||
}
|
||||
@ -353,17 +321,13 @@ void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
|
||||
{
|
||||
auxiliary.Bind();
|
||||
|
||||
setTexture(FullScreenShader::Gaussian6VBlurShader::getInstance()->TU_tex, in_fbo.getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(createVector<GLuint>(in_fbo.getRTT()[0]));
|
||||
DrawFullScreenEffect<FullScreenShader::Gaussian6VBlurShader>(core::vector2df(inv_width, inv_height));
|
||||
}
|
||||
{
|
||||
in_fbo.Bind();
|
||||
|
||||
setTexture(FullScreenShader::Gaussian6HBlurShader::getInstance()->TU_tex, auxiliary.getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(createVector<GLuint>(auxiliary.getRTT()[0]));
|
||||
DrawFullScreenEffect<FullScreenShader::Gaussian6HBlurShader>(core::vector2df(inv_width, inv_height));
|
||||
}
|
||||
}
|
||||
@ -373,21 +337,12 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
|
||||
assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight());
|
||||
float inv_width = 1.0f / in_fbo.getWidth(), inv_height = 1.0f / in_fbo.getHeight();
|
||||
{
|
||||
#if WIN32
|
||||
if (irr_driver->getGLSLVersion() < 430)
|
||||
#endif
|
||||
if (irr_driver->hasARBComputeShaders())
|
||||
{
|
||||
auxiliary.Bind();
|
||||
|
||||
setTexture(FullScreenShader::Gaussian17TapHShader::getInstance()->TU_tex, in_fbo.getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
setTexture(FullScreenShader::Gaussian17TapHShader::getInstance()->TU_depth, irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
FullScreenShader::Gaussian17TapHShader::getInstance()->SetTextureUnits(createVector<GLuint>(in_fbo.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]));
|
||||
DrawFullScreenEffect<FullScreenShader::Gaussian17TapHShader>(core::vector2df(inv_width, inv_height));
|
||||
}
|
||||
#if WIN32
|
||||
else
|
||||
{
|
||||
|
||||
@ -398,24 +353,15 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
|
||||
FullScreenShader::ComputeGaussian17TapHShader::getInstance()->setUniforms();
|
||||
glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
{
|
||||
#if WIN32
|
||||
if (irr_driver->getGLSLVersion() < 430)
|
||||
#endif
|
||||
if (irr_driver->hasARBComputeShaders())
|
||||
{
|
||||
in_fbo.Bind();
|
||||
|
||||
setTexture(FullScreenShader::Gaussian17TapVShader::getInstance()->TU_tex, auxiliary.getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
setTexture(FullScreenShader::Gaussian17TapVShader::getInstance()->TU_depth, irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
FullScreenShader::Gaussian17TapVShader::getInstance()->SetTextureUnits(createVector<GLuint>(auxiliary.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]));
|
||||
DrawFullScreenEffect<FullScreenShader::Gaussian17TapVShader>(core::vector2df(inv_width, inv_height));
|
||||
}
|
||||
#if WIN32
|
||||
else
|
||||
{
|
||||
glUseProgram(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->Program);
|
||||
@ -425,7 +371,6 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
|
||||
FullScreenShader::ComputeGaussian17TapVShader::getInstance()->setUniforms();
|
||||
glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,7 +379,7 @@ void PostProcessing::renderPassThrough(GLuint tex)
|
||||
glUseProgram(FullScreenShader::PassThroughShader::getInstance()->Program);
|
||||
glBindVertexArray(FullScreenShader::PassThroughShader::getInstance()->vao);
|
||||
|
||||
setTexture(FullScreenShader::PassThroughShader::getInstance()->TU_tex, tex, GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::PassThroughShader::getInstance()->SetTextureUnits(createVector<GLuint>(tex));
|
||||
FullScreenShader::PassThroughShader::getInstance()->setUniforms();
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
@ -459,7 +404,7 @@ void PostProcessing::renderGlow(unsigned tex)
|
||||
glUseProgram(FullScreenShader::GlowShader::getInstance()->Program);
|
||||
glBindVertexArray(FullScreenShader::GlowShader::getInstance()->vao);
|
||||
|
||||
setTexture(FullScreenShader::GlowShader::getInstance()->TU_tex, tex, GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::GlowShader::getInstance()->SetTextureUnits(createVector<GLuint>(tex));
|
||||
FullScreenShader::GlowShader::getInstance()->setUniforms();
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
@ -473,11 +418,11 @@ void PostProcessing::renderSSAO()
|
||||
|
||||
// Generate linear depth buffer
|
||||
irr_driver->getFBO(FBO_LINEAR_DEPTH).Bind();
|
||||
setTexture(FullScreenShader::LinearizeDepthShader::getInstance()->TU_tex, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::LinearizeDepthShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getDepthStencilTexture()));
|
||||
DrawFullScreenEffect<FullScreenShader::LinearizeDepthShader>(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue());
|
||||
irr_driver->getFBO(FBO_SSAO).Bind();
|
||||
|
||||
setTexture(FullScreenShader::SSAOShader::getInstance()->TU_dtex, irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH), GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST);
|
||||
FullScreenShader::SSAOShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH)));
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
DrawFullScreenEffect<FullScreenShader::SSAOShader>(irr_driver->getSSAORadius(), irr_driver->getSSAOK(), irr_driver->getSSAOSigma());
|
||||
@ -505,8 +450,8 @@ void PostProcessing::renderFog()
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
setTexture(FullScreenShader::FogShader::getInstance()->TU_tex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
DrawFullScreenEffect<FullScreenShader::FogShader>(fogmax, startH, endH, start, end, col);
|
||||
FullScreenShader::FogShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getDepthStencilTexture()));
|
||||
DrawFullScreenEffect<FullScreenShader::FogShader>(fogmax, startH, endH, start, end, col);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
@ -533,10 +478,7 @@ void PostProcessing::renderMotionBlur(unsigned cam, FrameBuffer &in_fbo, FrameBu
|
||||
out_fbo.Bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
setTexture(FullScreenShader::MotionBlurShader::getInstance()->TU_cb, in_fbo.getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
setTexture(FullScreenShader::MotionBlurShader::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::MotionBlurShader::getInstance()->SetTextureUnits(createVector<GLuint>(in_fbo.getRTT()[0], irr_driver->getDepthStencilTexture()));
|
||||
DrawFullScreenEffect<FullScreenShader::MotionBlurShader>(
|
||||
// Todo : use a previousPVMatrix per cam, not global
|
||||
irr_driver->getPreviousPVMatrix(),
|
||||
@ -549,7 +491,7 @@ static void renderGodFade(GLuint tex, const SColor &col)
|
||||
{
|
||||
glUseProgram(FullScreenShader::GodFadeShader::getInstance()->Program);
|
||||
glBindVertexArray(FullScreenShader::GodFadeShader::getInstance()->vao);
|
||||
setTexture(FullScreenShader::GodFadeShader::getInstance()->TU_tex, tex, GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::GodFadeShader::getInstance()->SetTextureUnits(createVector<GLuint>(tex));
|
||||
FullScreenShader::GodFadeShader::getInstance()->setUniforms(col);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
@ -559,7 +501,7 @@ static void renderGodRay(GLuint tex, const core::vector2df &sunpos)
|
||||
{
|
||||
glUseProgram(FullScreenShader::GodRayShader::getInstance()->Program);
|
||||
glBindVertexArray(FullScreenShader::GodRayShader::getInstance()->vao);
|
||||
setTexture(FullScreenShader::GodRayShader::getInstance()->TU_tex, tex, GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::GodRayShader::getInstance()->SetTextureUnits(createVector<GLuint>(tex));
|
||||
FullScreenShader::GodRayShader::getInstance()->setUniforms(sunpos);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
@ -568,15 +510,14 @@ static void renderGodRay(GLuint tex, const core::vector2df &sunpos)
|
||||
static void toneMap(FrameBuffer &fbo, GLuint rtt)
|
||||
{
|
||||
fbo.Bind();
|
||||
setTexture(FullScreenShader::ToneMapShader::getInstance()->TU_tex, rtt, GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::ToneMapShader::getInstance()->SetTextureUnits(createVector<GLuint>(rtt));
|
||||
DrawFullScreenEffect<FullScreenShader::ToneMapShader>();
|
||||
}
|
||||
|
||||
static void renderDoF(FrameBuffer &fbo, GLuint rtt)
|
||||
{
|
||||
fbo.Bind();
|
||||
setTexture(FullScreenShader::DepthOfFieldShader::getInstance()->TU_tex, rtt, GL_LINEAR, GL_LINEAR);
|
||||
setTexture(FullScreenShader::DepthOfFieldShader::getInstance()->TU_depth, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::DepthOfFieldShader::getInstance()->SetTextureUnits(createVector<GLuint>(rtt, irr_driver->getDepthStencilTexture()));
|
||||
DrawFullScreenEffect<FullScreenShader::DepthOfFieldShader>();
|
||||
}
|
||||
|
||||
@ -592,8 +533,8 @@ void PostProcessing::applyMLAA()
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
// Pass 1: color edge detection
|
||||
setTexture(FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->TU_colorMapG, irr_driver->getRenderTargetTexture(RTT_MLAA_COLORS), GL_NEAREST, GL_NEAREST);
|
||||
glUseProgram(FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->Program);
|
||||
FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_MLAA_COLORS)));
|
||||
FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->setUniforms(PIXEL_SIZE);
|
||||
|
||||
glBindVertexArray(FullScreenShader::MLAAColorEdgeDetectionSHader::getInstance()->vao);
|
||||
@ -607,8 +548,7 @@ void PostProcessing::applyMLAA()
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glUseProgram(FullScreenShader::MLAABlendWeightSHader::getInstance()->Program);
|
||||
setTexture(FullScreenShader::MLAABlendWeightSHader::getInstance()->TU_edgesMap, irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), GL_LINEAR, GL_LINEAR);
|
||||
setTexture(FullScreenShader::MLAABlendWeightSHader::getInstance()->TU_areaMap, getTextureGLuint(m_areamap), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::MLAABlendWeightSHader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), getTextureGLuint(m_areamap)));
|
||||
FullScreenShader::MLAABlendWeightSHader::getInstance()->setUniforms(PIXEL_SIZE);
|
||||
|
||||
glBindVertexArray(FullScreenShader::MLAABlendWeightSHader::getInstance()->vao);
|
||||
@ -621,8 +561,7 @@ void PostProcessing::applyMLAA()
|
||||
irr_driver->getFBO(FBO_MLAA_COLORS).Bind();
|
||||
|
||||
glUseProgram(FullScreenShader::MLAAGatherSHader::getInstance()->Program);
|
||||
setTexture(FullScreenShader::MLAAGatherSHader::getInstance()->TU_colorMap, irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(FullScreenShader::MLAAGatherSHader::getInstance()->TU_blendMap, irr_driver->getRenderTargetTexture(RTT_MLAA_BLEND), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::MLAAGatherSHader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_MLAA_BLEND), irr_driver->getRenderTargetTexture(RTT_MLAA_TMP)));
|
||||
FullScreenShader::MLAAGatherSHader::getInstance()->setUniforms(PIXEL_SIZE);
|
||||
|
||||
glBindVertexArray(FullScreenShader::MLAAGatherSHader::getInstance()->vao);
|
||||
@ -661,8 +600,10 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
|
||||
if (World::getWorld() != NULL)
|
||||
hasgodrays = World::getWorld()->getTrack()->hasGodRays();
|
||||
|
||||
if (isRace && UserConfigParams::m_light_shaft && m_sunpixels > 30 && hasgodrays)
|
||||
if (isRace && UserConfigParams::m_light_shaft && hasgodrays)
|
||||
{
|
||||
Track* track = World::getWorld()->getTrack();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
// Grab the sky
|
||||
out_fbo->Bind();
|
||||
@ -670,12 +611,14 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
|
||||
irr_driver->renderSkybox(camnode);
|
||||
|
||||
// Set the sun's color
|
||||
const SColor col = World::getWorld()->getTrack()->getSunColor();
|
||||
const SColor col = track->getGodRaysColor();
|
||||
ColorizeProvider * const colcb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
|
||||
colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f);
|
||||
|
||||
// The sun interposer
|
||||
STKMeshSceneNode *sun = irr_driver->getSunInterposer();
|
||||
sun->setPosition(track->getGodRaysPosition());
|
||||
sun->updateAbsolutePosition();
|
||||
irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA);
|
||||
irr_driver->setPhase(GLOW_PASS);
|
||||
sun->render();
|
||||
@ -690,7 +633,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
|
||||
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getFBO(FBO_QUARTER2));
|
||||
|
||||
// Calculate the sun's position in texcoords
|
||||
const core::vector3df pos = sun->getPosition();
|
||||
const core::vector3df pos = track->getGodRaysPosition();
|
||||
float ndc[4];
|
||||
core::matrix4 trans = camnode->getProjectionMatrix();
|
||||
trans *= camnode->getViewMatrix();
|
||||
@ -753,9 +696,8 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
setTexture(FullScreenShader::BloomBlendShader::getInstance()->TU_tex_128, irr_driver->getRenderTargetTexture(RTT_BLOOM_128), GL_LINEAR, GL_LINEAR);
|
||||
setTexture(FullScreenShader::BloomBlendShader::getInstance()->TU_tex_256, irr_driver->getRenderTargetTexture(RTT_BLOOM_256), GL_LINEAR, GL_LINEAR);
|
||||
setTexture(FullScreenShader::BloomBlendShader::getInstance()->TU_tex_512, irr_driver->getRenderTargetTexture(RTT_BLOOM_512), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::BloomBlendShader::getInstance()->SetTextureUnits(createVector<GLuint>(
|
||||
irr_driver->getRenderTargetTexture(RTT_BLOOM_128), irr_driver->getRenderTargetTexture(RTT_BLOOM_256), irr_driver->getRenderTargetTexture(RTT_BLOOM_512) ));
|
||||
DrawFullScreenEffect<FullScreenShader::BloomBlendShader>();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
@ -784,6 +726,10 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
// Workaround a bug with srgb fbo on sandy bridge windows
|
||||
if (irr_driver->needUBOWorkaround())
|
||||
return in_fbo;
|
||||
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
irr_driver->getFBO(FBO_MLAA_COLORS).Bind();
|
||||
renderPassThrough(in_fbo->getRTT()[0]);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "graphics/referee.hpp"
|
||||
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/light.hpp"
|
||||
#include "graphics/mesh_tools.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
@ -36,7 +37,6 @@ Vec3 Referee::m_st_start_offset = Vec3(-2, 2, 2);
|
||||
Vec3 Referee::m_st_start_rotation = Vec3(0, 180, 0);
|
||||
Vec3 Referee::m_st_scale = Vec3(1, 1, 1);
|
||||
scene::IAnimatedMesh *Referee::m_st_referee_mesh = NULL;
|
||||
video::ITexture *Referee::m_st_traffic_lights[3] = {NULL, NULL, NULL};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads the static mesh.
|
||||
@ -93,23 +93,6 @@ void Referee::init()
|
||||
* RAD_TO_DEGREE;
|
||||
m_st_start_rotation.setY(m_st_start_rotation.getY()+angle_to_kart);
|
||||
|
||||
std::vector<std::string> colors;
|
||||
node->get("colors", &colors);
|
||||
|
||||
if(colors.size()>3)
|
||||
Log::warn("referee", "Too many colors for referee defined, "
|
||||
"only first three will be used.");
|
||||
if(colors.size()<3)
|
||||
{
|
||||
Log::fatal("referee",
|
||||
"Not enough colors for referee defined, aborting.");
|
||||
}
|
||||
for(unsigned int i=0; i<3; i++)
|
||||
{
|
||||
m_st_traffic_lights[i] = irr_driver->getTexture(FileManager::MODEL, colors[i]);
|
||||
}
|
||||
|
||||
|
||||
for(unsigned int i=0; i<m_st_referee_mesh->getMeshBufferCount(); i++)
|
||||
{
|
||||
scene::IMeshBuffer *mb = m_st_referee_mesh->getMeshBuffer(i);
|
||||
@ -119,7 +102,7 @@ void Referee::init()
|
||||
|
||||
std::string name=StringUtils::getBasename(t->getName()
|
||||
.getInternalName().c_str());
|
||||
if(name==colors[0] || name==colors[1] ||name==colors[2] )
|
||||
if (name == "traffic_light.png")
|
||||
{
|
||||
m_st_traffic_buffer = i;
|
||||
break;
|
||||
@ -166,6 +149,16 @@ Referee::Referee()
|
||||
m_st_last_start_frame);
|
||||
|
||||
irr_driver->applyObjectPassShader(m_scene_node);
|
||||
|
||||
if (irr_driver->isGLSL() && UserConfigParams::m_dynamic_lights)
|
||||
{
|
||||
m_light = irr_driver->addLight(core::vector3df(0.0f, 0.0f, 0.6f), 0.7f, 2.0f,
|
||||
0.7f /* r */, 0.0 /* g */, 0.0f /* b */, false /* sun */, m_scene_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_light = NULL;
|
||||
}
|
||||
} // Referee
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -212,6 +205,9 @@ void Referee::attachToSceneNode()
|
||||
if(!m_scene_node->getParent())
|
||||
m_scene_node->setParent(irr_driver->getSceneManager()
|
||||
->getRootSceneNode());
|
||||
|
||||
if (m_light != NULL)
|
||||
m_light->setVisible(true);
|
||||
} // attachToSceneNode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -223,6 +219,8 @@ void Referee::removeFromSceneGraph()
|
||||
{
|
||||
if(isAttached())
|
||||
irr_driver->removeNode(m_scene_node);
|
||||
if (m_light != NULL)
|
||||
m_light->setVisible(false);
|
||||
} // removeFromSceneGraph
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -232,9 +230,31 @@ void Referee::removeFromSceneGraph()
|
||||
*/
|
||||
void Referee::selectReadySetGo(int rsg)
|
||||
{
|
||||
if(m_st_traffic_buffer<0) return;
|
||||
video::SMaterial &m = m_scene_node->getMesh()->getMeshBuffer(m_st_traffic_buffer)->getMaterial();
|
||||
m.setTexture(0, m_st_traffic_lights[rsg]);
|
||||
if (m_st_traffic_buffer < 0)
|
||||
return;
|
||||
video::SMaterial &m = m_scene_node->getMaterial(m_st_traffic_buffer); // m_scene_node->getMesh()->getMeshBuffer(m_st_traffic_buffer)->getMaterial();
|
||||
|
||||
//if (irr_driver->isGLSL() && UserConfigParams::m_dynamic_lights)
|
||||
// m.MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
|
||||
|
||||
core::matrix4* matrix = &m.getTextureMatrix(0);
|
||||
matrix->setTextureTranslate(0.0f, rsg*0.333f);
|
||||
|
||||
if (m_light != NULL)
|
||||
{
|
||||
if (rsg == 0)
|
||||
{
|
||||
((LightNode*)m_light)->setColor(0.6f, 0.0f, 0.0f);
|
||||
}
|
||||
else if (rsg == 1)
|
||||
{
|
||||
((LightNode*)m_light)->setColor(0.7f, 0.23f, 0.0f);
|
||||
}
|
||||
else if (rsg == 2)
|
||||
{
|
||||
((LightNode*)m_light)->setColor(0.0f, 0.6f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// disable lighting, we need to see the traffic light even if facing away
|
||||
// from the sun
|
||||
|
@ -79,6 +79,8 @@ private:
|
||||
/** The scene node for an instance of the referee. */
|
||||
scene::IAnimatedMeshSceneNode *m_scene_node;
|
||||
|
||||
scene::ISceneNode* m_light;
|
||||
|
||||
public:
|
||||
Referee();
|
||||
Referee(const AbstractKart &kart);
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "graphics/screenquad.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "graphics/stkinstancedscenenode.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "items/item.hpp"
|
||||
@ -47,6 +46,7 @@
|
||||
#include "utils/helpers.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
#include "stkscenemanager.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
@ -148,8 +148,12 @@ void IrrDriver::renderGLSL(float dt)
|
||||
// TODO: put this outside of the rendering loop
|
||||
generateDiffuseCoefficients();
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("Update Light Info", 0xFF, 0x0, 0x0);
|
||||
unsigned plc = UpdateLightsInfo(camnode, dt);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
PROFILER_PUSH_CPU_MARKER("Compute camera matrix", 0x0, 0xFF, 0x0);
|
||||
computeCameraMatrix(camnode, viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
renderScene(camnode, plc, glows, dt, track->hasShadows(), false);
|
||||
|
||||
// Debug physic
|
||||
@ -272,22 +276,30 @@ void IrrDriver::renderGLSL(float dt)
|
||||
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow, bool forceRTT)
|
||||
{
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
|
||||
m_scene_manager->setActiveCamera(camnode);
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Draw Call Generation", 0xFF, 0xFF, 0xFF);
|
||||
PrepareDrawCalls(camnode);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
// Shadows
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
|
||||
ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS));
|
||||
// To avoid wrong culling, use the largest view possible
|
||||
m_scene_manager->setActiveCamera(m_suncam);
|
||||
if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights &&
|
||||
UserConfigParams::m_shadows && !irr_driver->needUBOWorkaround() && hasShadow)
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
|
||||
renderShadows();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- RSM", 0xFF, 0x0, 0xFF);
|
||||
renderRSM();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
}
|
||||
m_scene_manager->setActiveCamera(camnode);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00);
|
||||
@ -323,6 +335,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
|
||||
renderSolidSecondPass();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
|
||||
if (getNormals())
|
||||
{
|
||||
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind();
|
||||
@ -480,29 +494,25 @@ void IrrDriver::computeSunVisibility()
|
||||
hasgodrays = World::getWorld()->getTrack()->hasGodRays();
|
||||
}
|
||||
|
||||
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
|
||||
if (UserConfigParams::m_light_shaft && hasgodrays)//hasflare || hasgodrays)
|
||||
if (UserConfigParams::m_light_shaft && hasgodrays)
|
||||
{
|
||||
GLuint res = 0;
|
||||
if (m_query_issued)
|
||||
gl_driver->extGlGetQueryObjectuiv(m_lensflare_query, GL_QUERY_RESULT, &res);
|
||||
glGetQueryObjectuiv(m_lensflare_query, GL_QUERY_RESULT, &res);
|
||||
m_post_processing->setSunPixels(res);
|
||||
|
||||
// Prepare the query for the next frame.
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
gl_driver->extGlBeginQuery(GL_SAMPLES_PASSED_ARB, m_lensflare_query);
|
||||
glBeginQuery(GL_SAMPLES_PASSED_ARB, m_lensflare_query);
|
||||
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
|
||||
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
|
||||
irr_driver->setPhase(GLOW_PASS);
|
||||
m_sun_interposer->render();
|
||||
gl_driver->extGlEndQuery(GL_SAMPLES_PASSED_ARB);
|
||||
glEndQuery(GL_SAMPLES_PASSED_ARB);
|
||||
m_query_issued = true;
|
||||
|
||||
m_lensflare->setStrength(res / 4000.0f);
|
||||
|
||||
if (hasflare)
|
||||
m_lensflare->OnRegisterSceneNode();
|
||||
|
||||
// Make sure the color mask is reset
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
}
|
||||
@ -514,7 +524,9 @@ void IrrDriver::renderParticles()
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
|
||||
for (unsigned i = 0; i < ParticlesList::getInstance()->size(); ++i)
|
||||
ParticlesList::getInstance()->at(i)->render();
|
||||
// m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
|
||||
}
|
||||
|
||||
/** Given a matrix transform and a set of points returns an orthogonal projection matrix that maps coordinates of
|
||||
@ -584,14 +596,20 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
|
||||
50.,
|
||||
};
|
||||
|
||||
float *tmp = new float[18 * 8];
|
||||
|
||||
float tmp[16 * 9 + 2];
|
||||
memcpy(tmp, irr_driver->getViewMatrix().pointer(), 16 * sizeof(float));
|
||||
memcpy(&tmp[16], irr_driver->getProjMatrix().pointer(), 16 * sizeof(float));
|
||||
memcpy(&tmp[32], irr_driver->getInvViewMatrix().pointer(), 16 * sizeof(float));
|
||||
memcpy(&tmp[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float));
|
||||
memcpy(&tmp[64], irr_driver->getProjViewMatrix().pointer(), 16 * sizeof(float));
|
||||
|
||||
const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix();
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
{
|
||||
if (!m_shadow_camnodes[i])
|
||||
m_shadow_camnodes[i] = (scene::ICameraSceneNode *) m_suncam->clone();
|
||||
}
|
||||
sun_ortho_matrix.clear();
|
||||
|
||||
if (World::getWorld() && World::getWorld()->getTrack())
|
||||
@ -669,8 +687,8 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
|
||||
const float units_per_w = w / 1024;
|
||||
const float units_per_h = h / 1024;*/
|
||||
|
||||
m_suncam->setProjectionMatrix(getTighestFitOrthoProj(SunCamViewMatrix, vectors) , true);
|
||||
m_suncam->render();
|
||||
m_shadow_camnodes[i]->setProjectionMatrix(getTighestFitOrthoProj(SunCamViewMatrix, vectors) , true);
|
||||
m_shadow_camnodes[i]->render();
|
||||
|
||||
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||
}
|
||||
@ -702,18 +720,17 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
|
||||
assert(sun_ortho_matrix.size() == 4);
|
||||
camnode->setNearValue(oldnear);
|
||||
camnode->setFarValue(oldfar);
|
||||
camnode->render();
|
||||
|
||||
size_t size = irr_driver->getShadowViewProj().size();
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
memcpy(&tmp[16 * i + 64], irr_driver->getShadowViewProj()[i].pointer(), 16 * sizeof(float));
|
||||
memcpy(&tmp[16 * i + 80], irr_driver->getShadowViewProj()[i].pointer(), 16 * sizeof(float));
|
||||
}
|
||||
|
||||
tmp[128] = float(width);
|
||||
tmp[129] = float(height);
|
||||
|
||||
tmp[144] = float(width);
|
||||
tmp[145] = float(height);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 8 + 2) * sizeof(float), tmp);
|
||||
delete []tmp;
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 9 + 2) * sizeof(float), tmp);
|
||||
}
|
||||
|
||||
|
||||
@ -770,20 +787,40 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glBindVertexArray(getVAO(EVT_STANDARD));
|
||||
if (irr_driver->hasARB_base_instance())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
|
||||
for (u32 i = 0; i < glowcount; i++)
|
||||
{
|
||||
const GlowData &dat = glows[i];
|
||||
scene::ISceneNode * const cur = dat.node;
|
||||
scene::ISceneNode * cur = dat.node;
|
||||
|
||||
//TODO : implement culling on gpu
|
||||
// Quick box-based culling
|
||||
// const core::aabbox3df nodebox = cur->getTransformedBoundingBox();
|
||||
// if (!nodebox.intersectsWithBox(cambox))
|
||||
// continue;
|
||||
STKMeshSceneNode *node = static_cast<STKMeshSceneNode *>(cur);
|
||||
node->setGlowColors(SColor(0, (unsigned) (dat.b * 255.f), (unsigned)(dat.g * 255.f), (unsigned)(dat.r * 255.f)));
|
||||
if (!irr_driver->hasARB_draw_indirect())
|
||||
node->render();
|
||||
}
|
||||
|
||||
cb->setColor(dat.r, dat.g, dat.b);
|
||||
cur->render();
|
||||
if (irr_driver->hasARB_draw_indirect())
|
||||
{
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
|
||||
glUseProgram(MeshShader::InstancedColorizeShader::getInstance()->Program);
|
||||
|
||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeGlow));
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
if (GlowPassCmd::getInstance()->Size)
|
||||
{
|
||||
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
|
||||
(const void*)(GlowPassCmd::getInstance()->Offset * sizeof(DrawElementsIndirectCommand)),
|
||||
GlowPassCmd::getInstance()->Size,
|
||||
sizeof(DrawElementsIndirectCommand));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned i = 0; i < ListInstancedGlow::getInstance()->size(); i++)
|
||||
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((GlowPassCmd::getInstance()->Offset + i) * sizeof(DrawElementsIndirectCommand)));
|
||||
}
|
||||
}
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,6 @@
|
||||
#include "graphics/screenquad.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "graphics/stkinstancedscenenode.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "items/item.hpp"
|
||||
@ -45,17 +44,13 @@ static void renderPointLights(unsigned count)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
glUseProgram(LightShader::PointLightShader::Program);
|
||||
glBindVertexArray(LightShader::PointLightShader::vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, LightShader::PointLightShader::vbo);
|
||||
glUseProgram(LightShader::PointLightShader::getInstance()->Program);
|
||||
glBindVertexArray(LightShader::PointLightShader::getInstance()->vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, LightShader::PointLightShader::getInstance()->vbo);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(LightShader::PointLightInfo), PointLightsInfo);
|
||||
|
||||
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
LightShader::PointLightShader
|
||||
::setUniforms(core::vector2df(float(UserConfigParams::m_width),
|
||||
float(UserConfigParams::m_height)),
|
||||
200, 0, 1);
|
||||
LightShader::PointLightShader::getInstance()->SetTextureUnits(createVector<GLuint>(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture()));
|
||||
LightShader::PointLightShader::getInstance()->setUniforms();
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
|
||||
}
|
||||
@ -68,6 +63,9 @@ unsigned IrrDriver::UpdateLightsInfo(scene::ICameraSceneNode * const camnode, fl
|
||||
std::vector<LightNode *> BucketedLN[15];
|
||||
for (unsigned int i = 0; i < lightcount; i++)
|
||||
{
|
||||
if (!m_lights[i]->isVisible())
|
||||
continue;
|
||||
|
||||
if (!m_lights[i]->isPointLight())
|
||||
{
|
||||
m_lights[i]->render();
|
||||
@ -140,9 +138,8 @@ void IrrDriver::renderLights(unsigned pointlightcount)
|
||||
if (irr_driver->needRHWorkaround())
|
||||
{
|
||||
glUseProgram(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->Program);
|
||||
setTexture(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->TU_ctex, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->TU_ntex, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->TU_dtex, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->SetTextureUnits(
|
||||
createVector<GLuint>(m_rtts->getRSM().getRTT()[0], m_rtts->getRSM().getRTT()[1], m_rtts->getRSM().getDepthTexture()));
|
||||
for (unsigned i = 0; i < 32; i++)
|
||||
{
|
||||
FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend, i);
|
||||
@ -152,9 +149,13 @@ void IrrDriver::renderLights(unsigned pointlightcount)
|
||||
else
|
||||
{
|
||||
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::getInstance()->Program);
|
||||
setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_ctex, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_ntex, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_dtex, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::RadianceHintsConstructionShader::getInstance()->SetTextureUnits(
|
||||
createVector<GLuint>(
|
||||
m_rtts->getRSM().getRTT()[0],
|
||||
m_rtts->getRSM().getRTT()[1],
|
||||
m_rtts->getRSM().getDepthTexture()
|
||||
)
|
||||
);
|
||||
FullScreenShader::RadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
|
||||
}
|
||||
@ -162,14 +163,14 @@ void IrrDriver::renderLights(unsigned pointlightcount)
|
||||
|
||||
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
|
||||
sun_ortho_matrix[i] *= getInvViewMatrix();
|
||||
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
|
||||
m_rtts->getFBO(FBO_COMBINED_DIFFUSE_SPECULAR).Bind();
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
glClearColor(.5, .5, .5, .5);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
return;
|
||||
|
||||
m_rtts->getFBO(FBO_TMP1_WITH_DS).Bind();
|
||||
m_rtts->getFBO(FBO_DIFFUSE).Bind();
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI));
|
||||
@ -181,7 +182,7 @@ void IrrDriver::renderLights(unsigned pointlightcount)
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
}
|
||||
|
||||
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
|
||||
m_rtts->getFBO(FBO_COMBINED_DIFFUSE_SPECULAR).Bind();
|
||||
|
||||
// Render sunlight if and only if track supports shadow
|
||||
if (!World::getWorld() || World::getWorld()->getTrack()->hasShadows())
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "graphics/screenquad.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "graphics/stkinstancedscenenode.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "items/item.hpp"
|
||||
@ -440,6 +439,7 @@ GLuint generateCubeMapFromTextures(const std::vector<video::ITexture *> &texture
|
||||
swapPixels(tmp, rgba[i], size, x, y, (size - y - 1), x);
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, result);
|
||||
@ -448,6 +448,7 @@ GLuint generateCubeMapFromTextures(const std::vector<video::ITexture *> &texture
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, size, size, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||
}
|
||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
delete[] rgba[i];
|
||||
return result;
|
||||
@ -552,7 +553,7 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
|
||||
return;
|
||||
if (!SkyboxCubeMap)
|
||||
generateSkyboxCubemap();
|
||||
glBindVertexArray(MeshShader::SkyboxShader::cubevao);
|
||||
glBindVertexArray(MeshShader::SkyboxShader::getInstance()->cubevao);
|
||||
glDisable(GL_CULL_FACE);
|
||||
assert(SkyboxTextures.size() == 6);
|
||||
|
||||
@ -567,15 +568,10 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
|
||||
core::matrix4 invtransform;
|
||||
transform.getInverse(invtransform);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glUseProgram(MeshShader::SkyboxShader::Program);
|
||||
MeshShader::SkyboxShader::setUniforms(transform,
|
||||
core::vector2df(float(UserConfigParams::m_width),
|
||||
float(UserConfigParams::m_height)),
|
||||
0);
|
||||
glUseProgram(MeshShader::SkyboxShader::getInstance()->Program);
|
||||
MeshShader::SkyboxShader::getInstance()->setUniforms(transform);
|
||||
MeshShader::SkyboxShader::getInstance()->SetTextureUnits(createVector<GLuint>(SkyboxCubeMap));
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 6 * 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
@ -29,11 +29,9 @@ static GLuint generateRTT3D(GLenum target, size_t w, size_t h, size_t d, GLint i
|
||||
GLuint result;
|
||||
glGenTextures(1, &result);
|
||||
glBindTexture(target, result);
|
||||
#if WIN32
|
||||
if (irr_driver->getGLSLVersion() >= 420)
|
||||
if (irr_driver->hasARBTextureStorage())
|
||||
glTexStorage3D(target, 1, internalFormat, w, h, d);
|
||||
else
|
||||
#endif
|
||||
glTexImage3D(target, 0, internalFormat, w, h, d, 0, format, type, 0);
|
||||
return result;
|
||||
}
|
||||
@ -43,11 +41,9 @@ static GLuint generateRTT(const core::dimension2du &res, GLint internalFormat, G
|
||||
GLuint result;
|
||||
glGenTextures(1, &result);
|
||||
glBindTexture(GL_TEXTURE_2D, result);
|
||||
#if WIN32
|
||||
if (irr_driver->getGLSLVersion() >= 420)
|
||||
if (irr_driver->hasARBTextureStorage())
|
||||
glTexStorage2D(GL_TEXTURE_2D, mipmaplevel, internalFormat, res.Width, res.Height);
|
||||
else
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, res.Width, res.Height, 0, format, type, 0);
|
||||
return result;
|
||||
}
|
||||
@ -115,6 +111,8 @@ RTT::RTT(size_t width, size_t height)
|
||||
RenderTargetTextures[RTT_MLAA_BLEND] = generateRTT(res, GL_SRGB8_ALPHA8, GL_BGR, GL_UNSIGNED_BYTE);
|
||||
RenderTargetTextures[RTT_SSAO] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_DIFFUSE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_SPECULAR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
|
||||
RenderTargetTextures[RTT_HALF1] = generateRTT(half, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_QUARTER1] = generateRTT(quarter, GL_RGBA16F, GL_BGRA, GL_FLOAT);
|
||||
@ -133,7 +131,6 @@ RTT::RTT(size_t width, size_t height)
|
||||
RenderTargetTextures[RTT_TMP_256] = generateRTT(shadowsize2, GL_RGBA16F, GL_BGR, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_BLOOM_128] = generateRTT(shadowsize3, GL_RGBA16F, GL_BGR, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_TMP_128] = generateRTT(shadowsize3, GL_RGBA16F, GL_BGR, GL_FLOAT);
|
||||
RenderTargetTextures[RTT_LOG_LUMINANCE] = generateRTT(shadowsize0, GL_R16F, GL_RED, GL_FLOAT);
|
||||
|
||||
std::vector<GLuint> somevector;
|
||||
somevector.push_back(RenderTargetTextures[RTT_SSAO]);
|
||||
@ -143,14 +140,17 @@ RTT::RTT(size_t width, size_t height)
|
||||
somevector.push_back(RenderTargetTextures[RTT_NORMAL_AND_DEPTH]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_TMP1]);
|
||||
somevector.push_back(RenderTargetTextures[RTT_TMP2]);
|
||||
somevector.push_back(RenderTargetTextures[RTT_DIFFUSE]);
|
||||
somevector.push_back(RenderTargetTextures[RTT_SPECULAR]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_COLOR]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_LOG_LUMINANCE]);
|
||||
somevector.push_back(RenderTargetTextures[RTT_DIFFUSE]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_SPECULAR]);
|
||||
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
|
||||
somevector.clear();
|
||||
somevector.push_back(RenderTargetTextures[RTT_MLAA_COLORS]);
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,9 @@
|
||||
#include <IMeshSceneNode.h>
|
||||
#include <ISceneNode.h>
|
||||
|
||||
Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node, float scale = 1.0, float xOffset = 0.0, float yOffset = 0.0)
|
||||
Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node,
|
||||
float scale = 1.0, float x_offset = 0.0, float y_offset = 0.0,
|
||||
float z_offset = 0.0)
|
||||
{
|
||||
video::SMaterial m;
|
||||
m.setTexture(0, texture);
|
||||
@ -33,10 +35,10 @@ Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node, float scale =
|
||||
m_mesh = irr_driver->createQuadMesh(&m, /*create_one_quad*/true);
|
||||
scene::IMeshBuffer *buffer = m_mesh->getMeshBuffer(0);
|
||||
irr::video::S3DVertex* v=(video::S3DVertex*)buffer->getVertices();
|
||||
v[0].Pos.X = -scale+xOffset; v[0].Pos.Z = scale+yOffset; v[0].Pos.Y = 0.01f;
|
||||
v[1].Pos.X = scale+xOffset; v[1].Pos.Z = scale+yOffset; v[1].Pos.Y = 0.01f;
|
||||
v[2].Pos.X = scale+xOffset; v[2].Pos.Z = -scale+yOffset; v[2].Pos.Y = 0.01f;
|
||||
v[3].Pos.X = -scale+xOffset; v[3].Pos.Z = -scale+yOffset; v[3].Pos.Y = 0.01f;
|
||||
v[0].Pos.X = -scale+x_offset; v[0].Pos.Z = scale+z_offset; v[0].Pos.Y = 0.01f-y_offset;
|
||||
v[1].Pos.X = scale+x_offset; v[1].Pos.Z = scale+z_offset; v[1].Pos.Y = 0.01f-y_offset;
|
||||
v[2].Pos.X = scale+x_offset; v[2].Pos.Z = -scale+z_offset; v[2].Pos.Y = 0.01f-y_offset;
|
||||
v[3].Pos.X = -scale+x_offset; v[3].Pos.Z = -scale+z_offset; v[3].Pos.Y = 0.01f-y_offset;
|
||||
v[0].TCoords = core::vector2df(0,0);
|
||||
v[1].TCoords = core::vector2df(1,0);
|
||||
v[2].TCoords = core::vector2df(1,1);
|
||||
|
@ -46,9 +46,8 @@ private:
|
||||
/** The scene node of the kart to which this shadow belongs. */
|
||||
scene::ISceneNode *m_parent_kart_node;
|
||||
public:
|
||||
Shadow(video::ITexture *texture,
|
||||
scene::ISceneNode *node,
|
||||
float scale, float xOffset, float yOffset);
|
||||
Shadow(video::ITexture *texture, scene::ISceneNode *node,
|
||||
float scale, float x_offset, float y_offset,float z_offset);
|
||||
~Shadow();
|
||||
void enableShadow();
|
||||
void disableShadow();
|
||||
|
@ -75,12 +75,12 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFon
|
||||
|
||||
for (unsigned int i = 0; i < m_chars.size(); i++)
|
||||
{
|
||||
core::vector3df char_pos(m_chars[i].m_destRect.UpperLeftCorner.X,
|
||||
m_chars[i].m_destRect.UpperLeftCorner.Y, 0);
|
||||
core::vector3df char_pos((float) m_chars[i].m_destRect.UpperLeftCorner.X,
|
||||
(float) m_chars[i].m_destRect.UpperLeftCorner.Y, 0);
|
||||
char_pos *= scale;
|
||||
|
||||
core::vector3df char_pos2(m_chars[i].m_destRect.LowerRightCorner.X,
|
||||
m_chars[i].m_destRect.LowerRightCorner.Y, 0);
|
||||
core::vector3df char_pos2((float)m_chars[i].m_destRect.LowerRightCorner.X,
|
||||
(float) m_chars[i].m_destRect.LowerRightCorner.Y, 0);
|
||||
char_pos2 *= scale;
|
||||
|
||||
core::dimension2di char_size_i = m_chars[i].m_destRect.getSize();
|
||||
@ -100,8 +100,8 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFon
|
||||
buffer = map_itr->second;
|
||||
}
|
||||
|
||||
float tex_width = m_chars[i].m_texture->getSize().Width;
|
||||
float tex_height = m_chars[i].m_texture->getSize().Height;
|
||||
float tex_width = (float) m_chars[i].m_texture->getSize().Width;
|
||||
float tex_height = (float)m_chars[i].m_texture->getSize().Height;
|
||||
|
||||
|
||||
video::S3DVertex vertices[] =
|
||||
|
@ -33,6 +33,15 @@ void STKAnimatedMesh::cleanGLMeshes()
|
||||
glDeleteVertexArrays(1, &(mesh.vao));
|
||||
glDeleteBuffers(1, &(mesh.vertex_buffer));
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
if (mesh.instance_buffer)
|
||||
glDeleteBuffers(1, &(mesh.instance_buffer));
|
||||
#ifdef Bindless_Texture_Support
|
||||
for (unsigned j = 0; j < 6; j++)
|
||||
{
|
||||
if (mesh.TextureHandles[j] && glIsTextureHandleResidentARB(mesh.TextureHandles[j]))
|
||||
glMakeTextureHandleNonResidentARB(mesh.TextureHandles[j]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,21 +54,13 @@ void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh)
|
||||
CAnimatedMeshSceneNode::setMesh(mesh);
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::render()
|
||||
void STKAnimatedMesh::update()
|
||||
{
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
|
||||
bool isTransparentPass =
|
||||
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
|
||||
|
||||
++PassCount;
|
||||
|
||||
scene::IMesh* m = getMeshForCurrentFrame();
|
||||
|
||||
if (m)
|
||||
{
|
||||
Box = m->getBoundingBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("animated mesh", "Animated Mesh returned no mesh to render.");
|
||||
@ -99,11 +100,21 @@ void STKAnimatedMesh::render()
|
||||
{
|
||||
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
|
||||
MeshSolidMaterial[MatType].push_back(&mesh);
|
||||
InitTextures(mesh, MatType);
|
||||
}
|
||||
|
||||
if (irr_driver->hasARB_base_instance())
|
||||
{
|
||||
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
|
||||
mesh.vaoBaseVertex = p.first;
|
||||
mesh.vaoOffset = p.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
fillLocalBuffer(mesh, mb);
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
std::pair<unsigned, unsigned> p = getVAOOffsetAndBase(mb);
|
||||
mesh.vaoBaseVertex = p.first;
|
||||
mesh.vaoOffset = p.second;
|
||||
mesh.VAOType = mb->getVertexType();
|
||||
}
|
||||
}
|
||||
firstTime = false;
|
||||
@ -114,31 +125,47 @@ void STKAnimatedMesh::render()
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
||||
if (isObject(material.MaterialType))
|
||||
{
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == TRANSPARENT_PASS)
|
||||
|
||||
size_t size = mb->getVertexCount() * GLmeshes[i].Stride, offset = GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride;
|
||||
void *buf;
|
||||
if (irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
buf = VAOManager::getInstance()->getVBOPtr(mb->getVertexType());
|
||||
buf = (char *)buf + offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
size_t size = mb->getVertexCount() * GLmeshes[i].Stride;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, getVBO(mb->getVertexType()));
|
||||
if (irr_driver->hasARB_base_instance())
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getVBO(mb->getVertexType()));
|
||||
else
|
||||
glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer);
|
||||
GLbitfield bitfield = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
|
||||
void * buf = glMapBufferRange(GL_ARRAY_BUFFER, GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride, size, bitfield);
|
||||
memcpy(buf, mb->getVertices(), size);
|
||||
buf = glMapBufferRange(GL_ARRAY_BUFFER, offset, size, bitfield);
|
||||
}
|
||||
memcpy(buf, mb->getVertices(), size);
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
if (mb)
|
||||
GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);
|
||||
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
bool transparent = (rnd && rnd->isTransparent());
|
||||
|
||||
// only render transparent buffer if this is the transparent render pass
|
||||
// and solid only in solid pass
|
||||
if (transparent != isTransparentPass)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::render()
|
||||
{
|
||||
bool isTransparentPass =
|
||||
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
|
||||
|
||||
++PassCount;
|
||||
|
||||
update();
|
||||
|
||||
/* if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
|
||||
{
|
||||
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
|
||||
core::matrix4 invmodel;
|
||||
@ -158,7 +185,7 @@ void STKAnimatedMesh::render()
|
||||
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
|
||||
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (irr_driver->getPhase() == TRANSPARENT_PASS)
|
||||
{
|
||||
|
@ -7,16 +7,15 @@
|
||||
#include "graphics/stkmesh.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
|
||||
class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode
|
||||
class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode, public STKMeshCommon
|
||||
{
|
||||
protected:
|
||||
bool firstTime;
|
||||
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
|
||||
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
core::matrix4 ModelViewProjectionMatrix;
|
||||
void cleanGLMeshes();
|
||||
public:
|
||||
virtual void update();
|
||||
STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent,
|
||||
irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position = irr::core::vector3df(0,0,0),
|
||||
@ -25,6 +24,7 @@ public:
|
||||
|
||||
virtual void render();
|
||||
virtual void setMesh(irr::scene::IAnimatedMesh* mesh);
|
||||
virtual bool glow() const { return false; }
|
||||
};
|
||||
|
||||
#endif // STKANIMATEDMESH_HPP
|
||||
|
@ -47,10 +47,12 @@ void STKBillboard::render()
|
||||
core::vector3df pos = getAbsolutePosition();
|
||||
glBindVertexArray(billboardvao);
|
||||
video::ITexture *tex = Material.getTexture(0);
|
||||
if (tex == NULL)
|
||||
return;
|
||||
compressTexture(tex, true, true);
|
||||
GLuint texid = getTextureGLuint(tex);
|
||||
setTexture(0, texid, GL_LINEAR, GL_LINEAR);
|
||||
glUseProgram(MeshShader::BillboardShader::getInstance()->Program);
|
||||
MeshShader::BillboardShader::getInstance()->SetTextureUnits(createVector<GLuint>(texid));
|
||||
MeshShader::BillboardShader::getInstance()->setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), pos, Size);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindVertexArray(0);
|
||||
|
@ -1,179 +0,0 @@
|
||||
#include "stkinstancedscenenode.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/callbacks.hpp"
|
||||
|
||||
STKInstancedSceneNode::STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position,
|
||||
const irr::core::vector3df& rotation,
|
||||
const irr::core::vector3df& scale) :
|
||||
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
|
||||
{
|
||||
m_ref_count = 0;
|
||||
irr_driver->grabAllTextures(mesh);
|
||||
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
createGLMeshes();
|
||||
setAutomaticCulling(0);
|
||||
}
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::cleanGL()
|
||||
{
|
||||
for (u32 i = 0; i < GLmeshes.size(); ++i)
|
||||
{
|
||||
GLMesh mesh = GLmeshes[i];
|
||||
if (!mesh.vertex_buffer)
|
||||
continue;
|
||||
if (mesh.vao)
|
||||
glDeleteVertexArrays(1, &(mesh.vao));
|
||||
if (mesh.vao_shadow_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_shadow_pass));
|
||||
glDeleteBuffers(1, &(mesh.vertex_buffer));
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
}
|
||||
glDeleteBuffers(1, &instances_vbo);
|
||||
}
|
||||
|
||||
STKInstancedSceneNode::~STKInstancedSceneNode()
|
||||
{
|
||||
irr_driver->dropAllTextures(getMesh());
|
||||
irr_driver->removeMeshFromCache(getMesh());
|
||||
|
||||
if (irr_driver->isGLSL())
|
||||
cleanGL();
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::createGLMeshes()
|
||||
{
|
||||
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
GLmeshes.push_back(allocateMeshBuffer(mb));
|
||||
fillLocalBuffer(GLmeshes.back(), mb);
|
||||
}
|
||||
isMaterialInitialized = false;
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh)
|
||||
{
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride));
|
||||
glGenBuffers(1, &instances_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0);
|
||||
glVertexAttribDivisor(7, 1);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 1);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 1);
|
||||
|
||||
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride));
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0);
|
||||
glVertexAttribDivisor(7, 4);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 4);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 4);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::setFirstTimeMaterial()
|
||||
{
|
||||
if (isMaterialInitialized)
|
||||
return;
|
||||
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
|
||||
initinstancedvaostate(mesh);
|
||||
MeshSolidMaterial[MatType].push_back(&mesh);
|
||||
}
|
||||
isMaterialInitialized = true;
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale)
|
||||
{
|
||||
instance_pos.push_back(origin.X);
|
||||
instance_pos.push_back(origin.Y);
|
||||
instance_pos.push_back(origin.Z);
|
||||
instance_pos.push_back(orientation.X);
|
||||
instance_pos.push_back(orientation.Y);
|
||||
instance_pos.push_back(orientation.Z);
|
||||
instance_pos.push_back(scale.X);
|
||||
instance_pos.push_back(scale.Y);
|
||||
instance_pos.push_back(scale.Z);
|
||||
}
|
||||
|
||||
core::matrix4 STKInstancedSceneNode::getInstanceTransform(int id)
|
||||
{
|
||||
core::matrix4 mat;
|
||||
|
||||
int offset = id * 9;
|
||||
mat.setTranslation(core::vector3df(
|
||||
instance_pos[offset],
|
||||
instance_pos[offset + 1],
|
||||
instance_pos[offset + 2]));
|
||||
mat.setRotationDegrees(core::vector3df(
|
||||
instance_pos[offset + 3],
|
||||
instance_pos[offset + 4],
|
||||
instance_pos[offset + 5]));
|
||||
mat.setScale(core::vector3df(
|
||||
instance_pos[offset + 6],
|
||||
instance_pos[offset + 7],
|
||||
instance_pos[offset + 8]));
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
void STKInstancedSceneNode::render()
|
||||
{
|
||||
if (!irr_driver->isGLSL())
|
||||
{
|
||||
CMeshSceneNode::render();
|
||||
return;
|
||||
}
|
||||
|
||||
setFirstTimeMaterial();
|
||||
|
||||
|
||||
for(unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++)
|
||||
{
|
||||
GLMesh *mesh = MeshSolidMaterial[MAT_DEFAULT][i];
|
||||
ListInstancedMatDefault::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9));
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++)
|
||||
{
|
||||
GLMesh *mesh = MeshSolidMaterial[MAT_ALPHA_REF][i];
|
||||
ListInstancedMatAlphaRef::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9));
|
||||
}
|
||||
|
||||
windDir = getWind();
|
||||
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
|
||||
for(unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++)
|
||||
{
|
||||
GLMesh *mesh = MeshSolidMaterial[MAT_GRASS][i];
|
||||
ListInstancedMatGrass::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9, windDir, cb->getPosition()));
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < MeshSolidMaterial[MAT_NORMAL_MAP].size(); i++)
|
||||
{
|
||||
GLMesh *mesh = MeshSolidMaterial[MAT_NORMAL_MAP][i];
|
||||
ListInstancedMatNormalMap::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9));
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
#ifndef STKINSTANCEDSCENENODE_HPP
|
||||
#define STKINSTANCEDSCENENODE_HPP
|
||||
|
||||
#include "stkmesh.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
|
||||
class ListInstancedMatDefault : public MeshList<ListInstancedMatDefault, GLMesh *, size_t>
|
||||
{};
|
||||
|
||||
class ListInstancedMatAlphaRef : public MeshList<ListInstancedMatAlphaRef, GLMesh *, size_t>
|
||||
{};
|
||||
|
||||
class ListInstancedMatGrass : public MeshList<ListInstancedMatGrass, GLMesh *, size_t, core::vector3df, core::vector3df>
|
||||
{};
|
||||
|
||||
class ListInstancedMatNormalMap : public MeshList<ListInstancedMatNormalMap, GLMesh *, size_t>
|
||||
{};
|
||||
|
||||
class STKInstancedSceneNode : public irr::scene::CMeshSceneNode
|
||||
{
|
||||
protected:
|
||||
int m_ref_count;
|
||||
std::vector<GLMesh *> MeshSolidMaterial[MAT_COUNT];
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
std::vector<float> instance_pos;
|
||||
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
|
||||
GLuint instances_vbo;
|
||||
void createGLMeshes();
|
||||
bool isMaterialInitialized;
|
||||
void setFirstTimeMaterial();
|
||||
void initinstancedvaostate(GLMesh &mesh);
|
||||
void cleanGL();
|
||||
core::vector3df windDir;
|
||||
public:
|
||||
STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
|
||||
const irr::core::vector3df& rotation = irr::core::vector3df(0, 0, 0),
|
||||
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f));
|
||||
~STKInstancedSceneNode();
|
||||
virtual void render();
|
||||
void addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale);
|
||||
|
||||
int getInstanceCount() const { return instance_pos.size() / 9; }
|
||||
|
||||
core::matrix4 getInstanceTransform(int id);
|
||||
|
||||
void instanceGrab() { m_ref_count++; }
|
||||
void instanceDrop()
|
||||
{
|
||||
m_ref_count--;
|
||||
if (m_ref_count <= 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
LEAK_CHECK();
|
||||
};
|
||||
|
||||
#endif
|
@ -126,6 +126,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
|
||||
GLMesh result = {};
|
||||
if (!mb)
|
||||
return result;
|
||||
result.mb = mb;
|
||||
|
||||
result.IndexCount = mb->getIndexCount();
|
||||
switch (mb->getIndexType())
|
||||
@ -178,6 +179,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
result.textures[i] = mb->getMaterial().getTexture(i);
|
||||
result.TextureMatrix = 0;
|
||||
result.VAOType = mb->getVertexType();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -229,7 +231,7 @@ core::matrix4 computeMVP(const core::matrix4 &ModelMatrix)
|
||||
return ModelViewProjectionMatrix;
|
||||
}
|
||||
|
||||
core::vector3df getWind()
|
||||
core::vector3df getWindDir()
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS);
|
||||
@ -292,4 +294,48 @@ bool isObject(video::E_MATERIAL_TYPE type)
|
||||
if (type == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
SetTexture(GLMesh &mesh, unsigned i, bool isSrgb)
|
||||
{
|
||||
if (!mesh.textures[i])
|
||||
mesh.textures[i] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
compressTexture(mesh.textures[i], isSrgb);
|
||||
#ifdef Bindless_Texture_Support
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
if (!mesh.TextureHandles[i])
|
||||
mesh.TextureHandles[i] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[i]), MeshShader::ObjectPass1Shader::getInstance()->SamplersId[0]);
|
||||
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[i]))
|
||||
glMakeTextureHandleResidentARB(mesh.TextureHandles[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void InitTextures(GLMesh &mesh, MeshMaterial Mat)
|
||||
{
|
||||
switch (Mat)
|
||||
{
|
||||
default:
|
||||
case MAT_DEFAULT:
|
||||
case MAT_ALPHA_REF:
|
||||
case MAT_GRASS:
|
||||
case MAT_SPHEREMAP:
|
||||
case MAT_UNLIT:
|
||||
SetTexture(mesh, 0, true);
|
||||
break;
|
||||
case MAT_DETAIL:
|
||||
case MAT_NORMAL_MAP:
|
||||
SetTexture(mesh, 0, true);
|
||||
SetTexture(mesh, 1, false);
|
||||
break;
|
||||
case MAT_SPLATTING:
|
||||
SetTexture(mesh, 0, true);
|
||||
SetTexture(mesh, 1, true);
|
||||
SetTexture(mesh, 2, true);
|
||||
SetTexture(mesh, 3, true);
|
||||
SetTexture(mesh, 4, true);
|
||||
break;
|
||||
}
|
||||
}
|
@ -35,9 +35,9 @@ enum TransparentMaterial
|
||||
|
||||
struct GLMesh {
|
||||
GLuint vao;
|
||||
GLuint vao_shadow_pass;
|
||||
GLuint vertex_buffer;
|
||||
GLuint index_buffer;
|
||||
GLuint instance_buffer;
|
||||
video::ITexture *textures[6];
|
||||
GLenum PrimitiveType;
|
||||
GLenum IndexType;
|
||||
@ -47,6 +47,8 @@ struct GLMesh {
|
||||
size_t vaoBaseVertex;
|
||||
size_t vaoOffset;
|
||||
video::E_VERTEX_TYPE VAOType;
|
||||
uint64_t TextureHandles[6];
|
||||
scene::IMeshBuffer *mb;
|
||||
};
|
||||
|
||||
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb);
|
||||
@ -56,50 +58,132 @@ GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type);
|
||||
core::matrix4 computeMVP(const core::matrix4 &ModelViewProjectionMatrix);
|
||||
bool isObject(video::E_MATERIAL_TYPE type);
|
||||
|
||||
core::vector3df getWind();
|
||||
core::vector3df getWindDir();
|
||||
|
||||
|
||||
class STKMeshCommon
|
||||
{
|
||||
protected:
|
||||
bool m_culledForPlayerCam;
|
||||
bool m_culledForShadowCam[4];
|
||||
bool m_culledForRSMCam;
|
||||
public:
|
||||
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
|
||||
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
|
||||
virtual void update() = 0;
|
||||
virtual bool glow() const = 0;
|
||||
virtual bool isImmediateDraw() const { return false; }
|
||||
bool isCulledForPlayerCam() const { return m_culledForPlayerCam; }
|
||||
void setCulledForPlayerCam(bool v) { m_culledForPlayerCam = v; }
|
||||
bool isCulledForShadowCam(unsigned cascade) const { return m_culledForShadowCam[cascade]; }
|
||||
void setCulledForShadowCam(unsigned cascade, bool v) { m_culledForShadowCam[cascade] = v; }
|
||||
bool isCulledForRSMCam() const { return m_culledForRSMCam; }
|
||||
void setCulledForRSMCam(bool v) { m_culledForRSMCam = v; }
|
||||
};
|
||||
|
||||
template<typename T, typename... Args>
|
||||
class MeshList : public Singleton<T>, public std::vector<STK::Tuple<Args...> >
|
||||
{};
|
||||
class MeshList : public Singleton<T>
|
||||
{
|
||||
public:
|
||||
std::vector<STK::Tuple<Args...> > SolidPass, Shadows[4], RSM;
|
||||
void clear()
|
||||
{
|
||||
SolidPass.clear();
|
||||
RSM.clear();
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
Shadows[i].clear();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class InstancedMeshList : public Singleton<T>
|
||||
{
|
||||
public:
|
||||
std::vector<GLMesh *> SolidPass, Shadows[4], RSM;
|
||||
void clear()
|
||||
{
|
||||
SolidPass.clear();
|
||||
RSM.clear();
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
Shadows[i].clear();
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------Mat Default---------------------------------------------------- //
|
||||
class ListMatDefault : public MeshList<ListMatDefault, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||
{};
|
||||
|
||||
class ListInstancedMatDefault : public InstancedMeshList<ListInstancedMatDefault>
|
||||
{};
|
||||
|
||||
|
||||
// -----------------------------------------Mat Alpha Ref---------------------------------------------------- //
|
||||
class ListMatAlphaRef : public MeshList<ListMatAlphaRef, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||
{};
|
||||
|
||||
class ListInstancedMatAlphaRef : public InstancedMeshList<ListInstancedMatAlphaRef>
|
||||
{};
|
||||
|
||||
// -----------------------------------------Mat Normap Map---------------------------------------------------- //
|
||||
class ListMatNormalMap : public MeshList<ListMatNormalMap, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||
{};
|
||||
|
||||
class ListInstancedMatNormalMap : public InstancedMeshList<ListInstancedMatNormalMap>
|
||||
{};
|
||||
|
||||
// -----------------------------------------Mat Grass---------------------------------------------------- //
|
||||
class ListMatGrass : public MeshList<ListMatGrass, GLMesh *, core::matrix4, core::matrix4, core::vector3df>
|
||||
{};
|
||||
|
||||
class ListInstancedMatGrass : public InstancedMeshList<ListInstancedMatGrass>
|
||||
{};
|
||||
|
||||
// -----------------------------------------Mat Sphere Map---------------------------------------------------- //
|
||||
class ListMatSphereMap : public MeshList<ListMatSphereMap, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||
{};
|
||||
|
||||
class ListInstancedMatSphereMap : public InstancedMeshList<ListInstancedMatSphereMap>
|
||||
{};
|
||||
|
||||
// -----------------------------------------Mat Splatting---------------------------------------------------- //
|
||||
class ListMatSplatting : public MeshList<ListMatSplatting, GLMesh *, core::matrix4, core::matrix4>
|
||||
{};
|
||||
|
||||
// -----------------------------------------Mat Unlit---------------------------------------------------- //
|
||||
class ListMatUnlit : public MeshList<ListMatUnlit, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||
{};
|
||||
|
||||
class ListInstancedMatUnlit : public InstancedMeshList<ListInstancedMatUnlit>
|
||||
{};
|
||||
|
||||
// -----------------------------------------Mat Details---------------------------------------------------- //
|
||||
class ListMatDetails : public MeshList<ListMatDetails, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
|
||||
{};
|
||||
|
||||
|
||||
class ListBlendTransparent : public MeshList<ListBlendTransparent, GLMesh *, core::matrix4, core::matrix4>
|
||||
class ListInstancedMatDetails : public InstancedMeshList<ListInstancedMatDetails>
|
||||
{};
|
||||
|
||||
class ListAdditiveTransparent : public MeshList<ListAdditiveTransparent, GLMesh *, core::matrix4, core::matrix4>
|
||||
// Transparent
|
||||
template <typename T, typename ...Args>
|
||||
class MiscList : public Singleton<T>, public std::vector<STK::Tuple<Args...> >
|
||||
{};
|
||||
|
||||
class ListBlendTransparentFog : public MeshList<ListBlendTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
|
||||
class ListBlendTransparent : public MiscList<ListBlendTransparent, GLMesh *, core::matrix4, core::matrix4>
|
||||
{};
|
||||
|
||||
class ListAdditiveTransparentFog : public MeshList<ListAdditiveTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
|
||||
class ListAdditiveTransparent : public MiscList<ListAdditiveTransparent, GLMesh *, core::matrix4, core::matrix4>
|
||||
{};
|
||||
|
||||
class ListDisplacement : public MeshList<ListDisplacement, GLMesh *, core::matrix4>
|
||||
class ListBlendTransparentFog : public MiscList<ListBlendTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
|
||||
{};
|
||||
|
||||
class ListAdditiveTransparentFog : public MiscList<ListAdditiveTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
|
||||
{};
|
||||
|
||||
class ListDisplacement : public MiscList<ListDisplacement, GLMesh *, core::matrix4>
|
||||
{};
|
||||
|
||||
class ListInstancedGlow : public Singleton<ListInstancedGlow>, public std::vector<GLMesh *>
|
||||
{};
|
||||
|
||||
// Forward pass (for transparents meshes)
|
||||
@ -108,4 +192,6 @@ void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatr
|
||||
MeshMaterial MaterialTypeToMeshMaterial(video::E_MATERIAL_TYPE, video::E_VERTEX_TYPE);
|
||||
TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE, f32 MaterialTypeParam);
|
||||
|
||||
void InitTextures(GLMesh &mesh, MeshMaterial);
|
||||
|
||||
#endif // STKMESH_H
|
||||
|
@ -21,6 +21,7 @@ STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent,
|
||||
isDisplacement = false;
|
||||
immediate_draw = false;
|
||||
update_each_frame = false;
|
||||
isGlow = false;
|
||||
|
||||
if (createGLMeshes)
|
||||
this->createGLMeshes();
|
||||
@ -70,35 +71,31 @@ void STKMeshSceneNode::setFirstTimeMaterial()
|
||||
if (rnd->isTransparent())
|
||||
{
|
||||
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam);
|
||||
if (immediate_draw)
|
||||
{
|
||||
fillLocalBuffer(mesh, mb);
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
else
|
||||
if (!immediate_draw)
|
||||
TransparentMesh[TranspMat].push_back(&mesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!isDisplacement);
|
||||
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
|
||||
if (immediate_draw)
|
||||
if (!immediate_draw)
|
||||
{
|
||||
fillLocalBuffer(mesh, mb);
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
|
||||
glBindVertexArray(0);
|
||||
InitTextures(mesh, MatType);
|
||||
MeshSolidMaterial[MatType].push_back(&mesh);
|
||||
}
|
||||
else
|
||||
MeshSolidMaterials[MatType].push_back(&mesh);
|
||||
}
|
||||
|
||||
if (!immediate_draw)
|
||||
if (!immediate_draw && irr_driver->hasARB_base_instance())
|
||||
{
|
||||
std::pair<unsigned, unsigned> p = getVAOOffsetAndBase(mb);
|
||||
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
|
||||
mesh.vaoBaseVertex = p.first;
|
||||
mesh.vaoOffset = p.second;
|
||||
mesh.VAOType = mb->getVertexType();
|
||||
}
|
||||
else
|
||||
{
|
||||
fillLocalBuffer(mesh, mb);
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
isMaterialInitialized = true;
|
||||
@ -113,12 +110,23 @@ void STKMeshSceneNode::cleanGLMeshes()
|
||||
continue;
|
||||
if (mesh.vao)
|
||||
glDeleteVertexArrays(1, &(mesh.vao));
|
||||
glDeleteBuffers(1, &(mesh.vertex_buffer));
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
if (mesh.vertex_buffer)
|
||||
glDeleteBuffers(1, &(mesh.vertex_buffer));
|
||||
if (mesh.index_buffer)
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
if (mesh.instance_buffer)
|
||||
glDeleteBuffers(1, &(mesh.instance_buffer));
|
||||
#ifdef Bindless_Texture_Support
|
||||
for (unsigned j = 0; j < 6; j++)
|
||||
{
|
||||
if (mesh.TextureHandles[j] && glIsTextureHandleResidentARB(mesh.TextureHandles[j]))
|
||||
glMakeTextureHandleNonResidentARB(mesh.TextureHandles[j]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
GLmeshes.clear();
|
||||
for (unsigned i = 0; i < MAT_COUNT; i++)
|
||||
MeshSolidMaterials[i].clearWithoutDeleting();
|
||||
MeshSolidMaterial[i].clearWithoutDeleting();
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::setMesh(irr::scene::IMesh* mesh)
|
||||
@ -135,14 +143,12 @@ STKMeshSceneNode::~STKMeshSceneNode()
|
||||
|
||||
void STKMeshSceneNode::drawGlow(const GLMesh &mesh)
|
||||
{
|
||||
ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
|
||||
assert(mesh.VAOType == video::EVT_STANDARD);
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
MeshShader::ColorizeShader::getInstance()->setUniforms(AbsoluteTransformation, video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue()));
|
||||
MeshShader::ColorizeShader::getInstance()->setUniforms(AbsoluteTransformation, video::SColorf(glowcolor.getRed() / 255.f, glowcolor.getGreen() / 255.f, glowcolor.getBlue() / 255.f));
|
||||
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
|
||||
}
|
||||
|
||||
@ -163,26 +169,8 @@ void STKMeshSceneNode::updatevbo()
|
||||
}
|
||||
}
|
||||
|
||||
static video::ITexture *spareWhiteTex = 0;
|
||||
|
||||
|
||||
void STKMeshSceneNode::OnRegisterSceneNode()
|
||||
void STKMeshSceneNode::update()
|
||||
{
|
||||
if (isDisplacement)
|
||||
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
|
||||
else
|
||||
CMeshSceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::render()
|
||||
{
|
||||
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
|
||||
if (!Mesh || !driver)
|
||||
return;
|
||||
|
||||
++PassCount;
|
||||
|
||||
Box = Mesh->getBoundingBox();
|
||||
|
||||
setFirstTimeMaterial();
|
||||
@ -194,13 +182,50 @@ void STKMeshSceneNode::render()
|
||||
continue;
|
||||
GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS && immediate_draw)
|
||||
|
||||
void STKMeshSceneNode::OnRegisterSceneNode()
|
||||
{
|
||||
if (isDisplacement)
|
||||
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
|
||||
else
|
||||
CMeshSceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
|
||||
static video::ITexture *spareWhiteTex = 0;
|
||||
|
||||
void STKMeshSceneNode::render()
|
||||
{
|
||||
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
|
||||
if (!Mesh || !driver)
|
||||
return;
|
||||
|
||||
++PassCount;
|
||||
|
||||
update();
|
||||
|
||||
bool isTransparent;
|
||||
|
||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
|
||||
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
|
||||
|
||||
isTransparent = rnd->isTransparent();
|
||||
break;
|
||||
}
|
||||
|
||||
if ((irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) && immediate_draw && !isTransparent)
|
||||
{
|
||||
core::matrix4 invmodel;
|
||||
AbsoluteTransformation.getInverse(invmodel);
|
||||
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
if (update_each_frame)
|
||||
updatevbo();
|
||||
@ -214,6 +239,21 @@ void STKMeshSceneNode::render()
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
if (!mesh.textures[0])
|
||||
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
compressTexture(mesh.textures[0], true);
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
#ifdef Bindless_Texture_Support
|
||||
if (!mesh.TextureHandles[0])
|
||||
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
|
||||
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
|
||||
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
|
||||
MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(std::vector < GLuint > { getTextureGLuint(mesh.textures[0]) });
|
||||
MeshShader::ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel);
|
||||
assert(mesh.vao);
|
||||
glBindVertexArray(mesh.vao);
|
||||
@ -224,53 +264,25 @@ void STKMeshSceneNode::render()
|
||||
return;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
|
||||
if (irr_driver->getPhase() == SOLID_LIT_PASS && immediate_draw && !isTransparent)
|
||||
{
|
||||
core::matrix4 invmodel;
|
||||
AbsoluteTransformation.getInverse(invmodel);
|
||||
|
||||
GLMesh* mesh;
|
||||
for_in(mesh, MeshSolidMaterials[MAT_DEFAULT])
|
||||
pushVector(ListMatDefault::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
||||
|
||||
for_in(mesh, MeshSolidMaterials[MAT_ALPHA_REF])
|
||||
pushVector(ListMatAlphaRef::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
||||
|
||||
for_in(mesh, MeshSolidMaterials[MAT_SPHEREMAP])
|
||||
pushVector(ListMatSphereMap::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
||||
|
||||
for_in(mesh, MeshSolidMaterials[MAT_DETAIL])
|
||||
pushVector(ListMatDetails::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
|
||||
|
||||
windDir = getWind();
|
||||
for_in(mesh, MeshSolidMaterials[MAT_GRASS])
|
||||
pushVector(ListMatGrass::getInstance(), mesh, AbsoluteTransformation, invmodel, windDir);
|
||||
|
||||
for_in(mesh, MeshSolidMaterials[MAT_UNLIT])
|
||||
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
|
||||
|
||||
for_in(mesh, MeshSolidMaterials[MAT_SPLATTING])
|
||||
pushVector(ListMatSplatting::getInstance(), mesh, AbsoluteTransformation, invmodel);
|
||||
|
||||
for_in(mesh, MeshSolidMaterials[MAT_NORMAL_MAP])
|
||||
pushVector(ListMatNormalMap::getInstance(), mesh, AbsoluteTransformation, invmodel, core::matrix4::EM4CONST_IDENTITY);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SOLID_LIT_PASS)
|
||||
{
|
||||
core::matrix4 invmodel;
|
||||
AbsoluteTransformation.getInverse(invmodel);
|
||||
|
||||
if (immediate_draw)
|
||||
glDisable(GL_CULL_FACE);
|
||||
if (!spareWhiteTex)
|
||||
spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program);
|
||||
// Only untextured
|
||||
for (unsigned i = 0; i < GLmeshes.size(); i++)
|
||||
{
|
||||
glDisable(GL_CULL_FACE);
|
||||
if (!spareWhiteTex)
|
||||
spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program);
|
||||
// Only untextured
|
||||
for (unsigned i = 0; i < GLmeshes.size(); i++)
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
@ -278,17 +290,54 @@ void STKMeshSceneNode::render()
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
setTexture(MeshShader::ObjectPass2Shader::getInstance()->TU_Albedo, getTextureGLuint(spareWhiteTex), GL_NEAREST, GL_NEAREST, false);
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
#ifdef Bindless_Texture_Support
|
||||
GLuint64 DiffuseHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]);
|
||||
if (!glIsTextureHandleResidentARB(DiffuseHandle))
|
||||
glMakeTextureHandleResidentARB(DiffuseHandle);
|
||||
|
||||
GLuint64 SpecularHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_SPECULAR), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[1]);
|
||||
if (!glIsTextureHandleResidentARB(SpecularHandle))
|
||||
glMakeTextureHandleResidentARB(SpecularHandle);
|
||||
|
||||
GLuint64 SSAOHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_HALF1_R), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[2]);
|
||||
if (!glIsTextureHandleResidentARB(SSAOHandle))
|
||||
glMakeTextureHandleResidentARB(SSAOHandle);
|
||||
|
||||
if (!mesh.TextureHandles[0])
|
||||
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(spareWhiteTex), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
|
||||
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
|
||||
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
|
||||
MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0]));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>(
|
||||
irr_driver->getRenderTargetTexture(RTT_DIFFUSE),
|
||||
irr_driver->getRenderTargetTexture(RTT_SPECULAR),
|
||||
irr_driver->getRenderTargetTexture(RTT_HALF1_R),
|
||||
getTextureGLuint(spareWhiteTex)));
|
||||
|
||||
MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
|
||||
assert(mesh.vao);
|
||||
glBindVertexArray(mesh.vao);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
glEnable(GL_CULL_FACE);
|
||||
return;
|
||||
else
|
||||
MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>(
|
||||
irr_driver->getRenderTargetTexture(RTT_DIFFUSE),
|
||||
irr_driver->getRenderTargetTexture(RTT_SPECULAR),
|
||||
irr_driver->getRenderTargetTexture(RTT_HALF1_R),
|
||||
getTextureGLuint(mesh.textures[0])));
|
||||
MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
|
||||
assert(mesh.vao);
|
||||
glBindVertexArray(mesh.vao);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -300,12 +349,15 @@ void STKMeshSceneNode::render()
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
glBindVertexArray(getVAO(video::EVT_STANDARD));
|
||||
if (irr_driver->hasARB_base_instance())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD));
|
||||
else
|
||||
glBindVertexArray(GLmeshes[i].vao);
|
||||
drawGlow(GLmeshes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == TRANSPARENT_PASS)
|
||||
if (irr_driver->getPhase() == TRANSPARENT_PASS && isTransparent)
|
||||
{
|
||||
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
|
||||
|
||||
@ -340,8 +392,21 @@ void STKMeshSceneNode::render()
|
||||
tmpcol.getGreen() / 255.0f,
|
||||
tmpcol.getBlue() / 255.0f);
|
||||
|
||||
if (!mesh.textures[0])
|
||||
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(MeshShader::TransparentFogShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
#ifdef Bindless_Texture_Support
|
||||
if (!mesh.TextureHandles[0])
|
||||
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
|
||||
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
|
||||
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
|
||||
MeshShader::TransparentFogShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
MeshShader::TransparentFogShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) });
|
||||
MeshShader::TransparentFogShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col);
|
||||
|
||||
assert(mesh.vao);
|
||||
@ -360,9 +425,21 @@ void STKMeshSceneNode::render()
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
if (!mesh.textures[0])
|
||||
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(MeshShader::TransparentShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
#ifdef Bindless_Texture_Support
|
||||
if (!mesh.TextureHandles[0])
|
||||
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentShader::getInstance()->SamplersId[0]);
|
||||
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
|
||||
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
|
||||
MeshShader::TransparentShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
MeshShader::TransparentShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) });
|
||||
|
||||
MeshShader::TransparentShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
|
||||
assert(mesh.vao);
|
||||
@ -375,47 +452,16 @@ void STKMeshSceneNode::render()
|
||||
}
|
||||
|
||||
GLMesh* mesh;
|
||||
|
||||
if (World::getWorld() && World::getWorld()->isFogEnabled())
|
||||
{
|
||||
const Track * const track = World::getWorld()->getTrack();
|
||||
|
||||
// Todo : put everything in a ubo
|
||||
const float fogmax = track->getFogMax();
|
||||
const float startH = track->getFogStartHeight();
|
||||
const float endH = track->getFogEndHeight();
|
||||
const float start = track->getFogStart();
|
||||
const float end = track->getFogEnd();
|
||||
const video::SColor tmpcol = track->getFogColor();
|
||||
|
||||
video::SColorf col(tmpcol.getRed() / 255.0f,
|
||||
tmpcol.getGreen() / 255.0f,
|
||||
tmpcol.getBlue() / 255.0f);
|
||||
|
||||
for_in(mesh, TransparentMesh[TM_DEFAULT])
|
||||
pushVector(ListBlendTransparentFog::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix,
|
||||
fogmax, startH, endH, start, end, col);
|
||||
for_in(mesh, TransparentMesh[TM_ADDITIVE])
|
||||
pushVector(ListAdditiveTransparentFog::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix,
|
||||
fogmax, startH, endH, start, end, col);
|
||||
}
|
||||
else
|
||||
{
|
||||
for_in(mesh, TransparentMesh[TM_DEFAULT])
|
||||
pushVector(ListBlendTransparent::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix);
|
||||
|
||||
for_in(mesh, TransparentMesh[TM_ADDITIVE])
|
||||
pushVector(ListAdditiveTransparent::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix);
|
||||
}
|
||||
|
||||
for_in(mesh, TransparentMesh[TM_DISPLACEMENT])
|
||||
pushVector(ListDisplacement::getInstance(), mesh, AbsoluteTransformation);
|
||||
|
||||
if (!TransparentMesh[TM_BUBBLE].empty())
|
||||
glUseProgram(MeshShader::BubbleShader::Program);
|
||||
glBindVertexArray(getVAO(video::EVT_STANDARD));
|
||||
if (irr_driver->hasARB_base_instance())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD));
|
||||
for_in(mesh, TransparentMesh[TM_BUBBLE])
|
||||
{
|
||||
if (irr_driver->hasARB_base_instance())
|
||||
glBindVertexArray(mesh->vao);
|
||||
drawBubble(*mesh, ModelViewProjectionMatrix);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,9 @@
|
||||
#include "stkmesh.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
|
||||
class STKMeshSceneNode : public irr::scene::CMeshSceneNode
|
||||
class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon
|
||||
{
|
||||
protected:
|
||||
PtrVector<GLMesh, REF> MeshSolidMaterials[MAT_COUNT];
|
||||
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
core::matrix4 ModelViewProjectionMatrix;
|
||||
core::vector3df windDir;
|
||||
@ -24,7 +22,10 @@ protected:
|
||||
bool immediate_draw;
|
||||
bool update_each_frame;
|
||||
bool isDisplacement;
|
||||
bool isGlow;
|
||||
video::SColor glowcolor;
|
||||
public:
|
||||
virtual void update();
|
||||
void setReloadEachFrame(bool);
|
||||
STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
|
||||
@ -35,6 +36,7 @@ public:
|
||||
virtual void setMesh(irr::scene::IMesh* mesh);
|
||||
virtual void OnRegisterSceneNode();
|
||||
virtual ~STKMeshSceneNode();
|
||||
virtual bool isImmediateDraw() const { return immediate_draw; }
|
||||
void setIsDisplacement(bool v) {
|
||||
isDisplacement = v;
|
||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
|
||||
@ -46,6 +48,9 @@ public:
|
||||
mb->getMaterial().MaterialType = irr_driver->getShader(ES_DISPLACE);
|
||||
}
|
||||
}
|
||||
virtual bool glow() const { return isGlow; }
|
||||
void setGlowColors(const video::SColor &c) { isGlow = true; glowcolor = c; }
|
||||
video::SColor getGlowColor() const { return glowcolor; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
710
src/graphics/stkscenemanager.cpp
Normal file
710
src/graphics/stkscenemanager.cpp
Normal file
@ -0,0 +1,710 @@
|
||||
#include "stkscenemanager.hpp"
|
||||
#include "stkmesh.hpp"
|
||||
#include "irr_driver.hpp"
|
||||
#include <ISceneManager.h>
|
||||
#include <ISceneNode.h>
|
||||
#include "stkanimatedmesh.hpp"
|
||||
#include "stkmeshscenenode.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include <ICameraSceneNode.h>
|
||||
#include <SViewFrustum.h>
|
||||
#include "callbacks.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
#include <omp.h>
|
||||
#include "modes/world.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "lod_node.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
#include <unordered_map>
|
||||
#include <SViewFrustum.h>
|
||||
#include <functional>
|
||||
|
||||
static void
|
||||
FillInstances_impl(std::vector<std::pair<GLMesh *, scene::ISceneNode *> > InstanceList, InstanceData * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
|
||||
size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &PolyCount, std::function<bool (const scene::ISceneNode *)> cull_func)
|
||||
{
|
||||
// Should never be empty
|
||||
GLMesh *mesh = InstanceList.front().first;
|
||||
size_t InitialOffset = InstanceBufferOffset;
|
||||
|
||||
for (unsigned i = 0; i < InstanceList.size(); i++)
|
||||
{
|
||||
auto &Tp = InstanceList[i];
|
||||
scene::ISceneNode *node = Tp.second;
|
||||
if (cull_func(node))
|
||||
continue;
|
||||
InstanceData &Instance = InstanceBuffer[InstanceBufferOffset++];
|
||||
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||
const core::vector3df &Origin = mat.getTranslation();
|
||||
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||
const core::vector3df &Scale = mat.getScale();
|
||||
Instance.Origin.X = Origin.X;
|
||||
Instance.Origin.Y = Origin.Y;
|
||||
Instance.Origin.Z = Origin.Z;
|
||||
Instance.Orientation.X = Orientation.X;
|
||||
Instance.Orientation.Y = Orientation.Y;
|
||||
Instance.Orientation.Z = Orientation.Z;
|
||||
Instance.Scale.X = Scale.X;
|
||||
Instance.Scale.Y = Scale.Y;
|
||||
Instance.Scale.Z = Scale.Z;
|
||||
Instance.Texture = mesh->TextureHandles[0];
|
||||
Instance.SecondTexture = mesh->TextureHandles[1];
|
||||
}
|
||||
|
||||
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
|
||||
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
|
||||
CurrentCommand.count = mesh->IndexCount;
|
||||
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
|
||||
CurrentCommand.baseInstance = InitialOffset;
|
||||
CurrentCommand.instanceCount = InstanceBufferOffset - InitialOffset;
|
||||
|
||||
PolyCount += (InstanceBufferOffset - InitialOffset) * mesh->IndexCount / 3;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
FillInstancesGlow_impl(std::vector<std::pair<GLMesh *, STKMeshCommon *> > InstanceList, GlowInstanceData * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
|
||||
size_t &InstanceBufferOffset, size_t &CommandBufferOffset, std::function<bool (const scene::ISceneNode *)> cull_func)
|
||||
{
|
||||
// Should never be empty
|
||||
GLMesh *mesh = InstanceList.front().first;
|
||||
size_t InitialOffset = InstanceBufferOffset;
|
||||
|
||||
for (unsigned i = 0; i < InstanceList.size(); i++)
|
||||
{
|
||||
STKMeshSceneNode *node = dynamic_cast<STKMeshSceneNode*>(InstanceList[i].second);
|
||||
if (cull_func(node))
|
||||
continue;
|
||||
GlowInstanceData &Instance = InstanceBuffer[InstanceBufferOffset++];
|
||||
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||
const core::vector3df &Origin = mat.getTranslation();
|
||||
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||
const core::vector3df &Scale = mat.getScale();
|
||||
Instance.Color = node->getGlowColor().color;
|
||||
Instance.Origin.X = Origin.X;
|
||||
Instance.Origin.Y = Origin.Y;
|
||||
Instance.Origin.Z = Origin.Z;
|
||||
Instance.Orientation.X = Orientation.X;
|
||||
Instance.Orientation.Y = Orientation.Y;
|
||||
Instance.Orientation.Z = Orientation.Z;
|
||||
Instance.Scale.X = Scale.X;
|
||||
Instance.Scale.Y = Scale.Y;
|
||||
Instance.Scale.Z = Scale.Z;
|
||||
}
|
||||
|
||||
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
|
||||
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
|
||||
CurrentCommand.count = mesh->IndexCount;
|
||||
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
|
||||
CurrentCommand.baseInstance = InitialOffset;
|
||||
CurrentCommand.instanceCount = InstanceBufferOffset - InitialOffset;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void FillInstances(const std::unordered_map<scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,
|
||||
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &Polycount,
|
||||
std::function<bool (const scene::ISceneNode *)> cull_func)
|
||||
{
|
||||
auto It = GatheredGLMesh.begin(), E = GatheredGLMesh.end();
|
||||
for (; It != E; ++It)
|
||||
{
|
||||
FillInstances_impl(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, Polycount, cull_func);
|
||||
if (!UserConfigParams::m_azdo)
|
||||
InstancedList.push_back(It->second.front().first);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void FillInstancesGrass(const std::unordered_map<scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,
|
||||
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, const core::vector3df &dir, size_t &PolyCount,
|
||||
std::function<bool (const scene::ISceneNode *)> cull_func)
|
||||
{
|
||||
auto It = GatheredGLMesh.begin(), E = GatheredGLMesh.end();
|
||||
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
|
||||
for (; It != E; ++It)
|
||||
{
|
||||
FillInstances_impl(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount, cull_func);
|
||||
if (!UserConfigParams::m_azdo)
|
||||
InstancedList.push_back(It->second.front().first);
|
||||
}
|
||||
}
|
||||
|
||||
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForSolidPass[MAT_COUNT];
|
||||
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForShadowPass[4][MAT_COUNT];
|
||||
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForRSMPass[MAT_COUNT];
|
||||
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, STKMeshCommon *> > > MeshForGlowPass;
|
||||
static std::vector <STKMeshCommon *> DeferredUpdate;
|
||||
|
||||
static core::vector3df windDir;
|
||||
|
||||
// From irrlicht code
|
||||
static
|
||||
bool isBoxInFrontOfPlane(const core::plane3df &plane, const core::vector3df edges[8])
|
||||
{
|
||||
for (u32 j = 0; j<8; ++j)
|
||||
if (plane.classifyPointRelation(edges[j]) != core::ISREL3D_FRONT)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool isCulled(const scene::ICameraSceneNode *cam, const scene::ISceneNode *node)
|
||||
{
|
||||
if (!node->getAutomaticCulling())
|
||||
return false;
|
||||
|
||||
scene::SViewFrustum frust = *cam->getViewFrustum();
|
||||
|
||||
//transform the frustum to the node's current absolute transformation
|
||||
core::matrix4 invTrans(node->getAbsoluteTransformation(), core::matrix4::EM4CONST_INVERSE);
|
||||
//invTrans.makeInverse();
|
||||
frust.transform(invTrans);
|
||||
|
||||
core::vector3df edges[8];
|
||||
node->getBoundingBox().getEdges(edges);
|
||||
|
||||
for (s32 i = 0; i < scene::SViewFrustum::VF_PLANE_COUNT; ++i)
|
||||
if (isBoxInFrontOfPlane(frust.planes[i], edges))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *ImmediateDraw)
|
||||
{
|
||||
STKMeshCommon *node = dynamic_cast<STKMeshCommon*>(Node);
|
||||
if (!node)
|
||||
return;
|
||||
DeferredUpdate.push_back(node);
|
||||
|
||||
if (node->isImmediateDraw())
|
||||
{
|
||||
ImmediateDraw->push_back(Node);
|
||||
return;
|
||||
}
|
||||
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
|
||||
{
|
||||
GLMesh *mesh;
|
||||
if (irr_driver->hasARB_draw_indirect())
|
||||
{
|
||||
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||
{
|
||||
if (node->glow())
|
||||
MeshForGlowPass[mesh->mb].emplace_back(mesh, node);
|
||||
|
||||
if (Mat != MAT_SPLATTING && mesh->TextureMatrix.isIdentity())
|
||||
MeshForSolidPass[Mat][mesh->mb].emplace_back(mesh, Node);
|
||||
else
|
||||
{
|
||||
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
|
||||
ModelMatrix.getInverse(InvModelMatrix);
|
||||
switch (Mat)
|
||||
{
|
||||
case MAT_DEFAULT:
|
||||
ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_ALPHA_REF:
|
||||
ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_UNLIT:
|
||||
ListMatUnlit::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_SPLATTING:
|
||||
ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
|
||||
ModelMatrix.getInverse(InvModelMatrix);
|
||||
|
||||
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||
{
|
||||
switch (Mat)
|
||||
{
|
||||
case MAT_DEFAULT:
|
||||
ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_ALPHA_REF:
|
||||
ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_NORMAL_MAP:
|
||||
ListMatNormalMap::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_DETAIL:
|
||||
ListMatDetails::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_UNLIT:
|
||||
ListMatUnlit::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_SPHEREMAP:
|
||||
ListMatSphereMap::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_SPLATTING:
|
||||
ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix);
|
||||
break;
|
||||
case MAT_GRASS:
|
||||
ListMatGrass::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, windDir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!UserConfigParams::m_shadows)
|
||||
return;
|
||||
for (unsigned cascade = 0; cascade < 4; ++cascade)
|
||||
{
|
||||
if (irr_driver->hasARB_draw_indirect())
|
||||
{
|
||||
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||
MeshForShadowPass[cascade][Mat][mesh->mb].emplace_back(mesh, Node);
|
||||
}
|
||||
else
|
||||
{
|
||||
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
|
||||
ModelMatrix.getInverse(InvModelMatrix);
|
||||
|
||||
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||
{
|
||||
switch (Mat)
|
||||
{
|
||||
case MAT_DEFAULT:
|
||||
ListMatDefault::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_ALPHA_REF:
|
||||
ListMatAlphaRef::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_NORMAL_MAP:
|
||||
ListMatNormalMap::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_DETAIL:
|
||||
ListMatDetails::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_UNLIT:
|
||||
ListMatUnlit::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_SPHEREMAP:
|
||||
ListMatSphereMap::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_SPLATTING:
|
||||
ListMatSplatting::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix);
|
||||
break;
|
||||
case MAT_GRASS:
|
||||
ListMatGrass::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, windDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!UserConfigParams::m_gi)
|
||||
return;
|
||||
if (irr_driver->hasARB_draw_indirect())
|
||||
{
|
||||
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||
if (Mat != MAT_SPLATTING)
|
||||
MeshForRSMPass[Mat][mesh->mb].emplace_back(mesh, Node);
|
||||
else
|
||||
{
|
||||
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
|
||||
ModelMatrix.getInverse(InvModelMatrix);
|
||||
ListMatSplatting::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
|
||||
ModelMatrix.getInverse(InvModelMatrix);
|
||||
|
||||
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||
{
|
||||
switch (Mat)
|
||||
{
|
||||
case MAT_DEFAULT:
|
||||
ListMatDefault::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_ALPHA_REF:
|
||||
ListMatAlphaRef::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_NORMAL_MAP:
|
||||
ListMatNormalMap::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_DETAIL:
|
||||
ListMatDetails::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_UNLIT:
|
||||
ListMatUnlit::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_SPHEREMAP:
|
||||
ListMatSphereMap::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix);
|
||||
break;
|
||||
case MAT_SPLATTING:
|
||||
ListMatSplatting::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix);
|
||||
break;
|
||||
case MAT_GRASS:
|
||||
ListMatGrass::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, windDir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Transparent
|
||||
GLMesh *mesh;
|
||||
if (World::getWorld() && World::getWorld()->isFogEnabled())
|
||||
{
|
||||
const Track * const track = World::getWorld()->getTrack();
|
||||
|
||||
// Todo : put everything in a ubo
|
||||
const float fogmax = track->getFogMax();
|
||||
const float startH = track->getFogStartHeight();
|
||||
const float endH = track->getFogEndHeight();
|
||||
const float start = track->getFogStart();
|
||||
const float end = track->getFogEnd();
|
||||
const video::SColor tmpcol = track->getFogColor();
|
||||
|
||||
video::SColorf col(tmpcol.getRed() / 255.0f,
|
||||
tmpcol.getGreen() / 255.0f,
|
||||
tmpcol.getBlue() / 255.0f);
|
||||
|
||||
for_in(mesh, node->TransparentMesh[TM_DEFAULT])
|
||||
pushVector(ListBlendTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
|
||||
fogmax, startH, endH, start, end, col);
|
||||
for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
|
||||
pushVector(ListAdditiveTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
|
||||
fogmax, startH, endH, start, end, col);
|
||||
}
|
||||
else
|
||||
{
|
||||
for_in(mesh, node->TransparentMesh[TM_DEFAULT])
|
||||
pushVector(ListBlendTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
|
||||
for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
|
||||
pushVector(ListAdditiveTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
|
||||
}
|
||||
for_in(mesh, node->TransparentMesh[TM_DISPLACEMENT])
|
||||
pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
|
||||
}
|
||||
|
||||
static void
|
||||
parseSceneManager(core::list<scene::ISceneNode*> List, std::vector<scene::ISceneNode *> *ImmediateDraw,
|
||||
scene::ICameraSceneNode* cam)
|
||||
{
|
||||
core::list<scene::ISceneNode*>::Iterator I = List.begin(), E = List.end();
|
||||
for (; I != E; ++I)
|
||||
{
|
||||
if (LODNode *node = dynamic_cast<LODNode *>(*I))
|
||||
node->updateVisibility();
|
||||
if (!(*I)->isVisible())
|
||||
continue;
|
||||
(*I)->updateAbsolutePosition();
|
||||
|
||||
if (ParticleSystemProxy *node = dynamic_cast<ParticleSystemProxy *>(*I))
|
||||
{
|
||||
if (!isCulled(cam, *I) && node->update())
|
||||
ParticlesList::getInstance()->push_back(node);
|
||||
continue;
|
||||
}
|
||||
|
||||
handleSTKCommon(*I, ImmediateDraw);
|
||||
|
||||
parseSceneManager((*I)->getChildren(), ImmediateDraw, cam);
|
||||
}
|
||||
}
|
||||
|
||||
template<MeshMaterial Mat> static void
|
||||
GenDrawCalls(unsigned cascade, std::vector<GLMesh *> &InstancedList,
|
||||
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &PolyCount)
|
||||
{
|
||||
std::function<bool(const scene::ISceneNode *)> shadowculling = [&](const scene::ISceneNode *nd) {return dynamic_cast<const STKMeshCommon*>(nd)->isCulledForShadowCam(cascade); };
|
||||
if (irr_driver->hasARB_draw_indirect())
|
||||
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
|
||||
FillInstances(MeshForShadowPass[cascade][Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount, shadowculling);
|
||||
if (UserConfigParams::m_azdo)
|
||||
ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat];
|
||||
}
|
||||
|
||||
template<MeshMaterial Mat> static void
|
||||
GenDrawCallsGrass(unsigned cascade, std::vector<GLMesh *> &InstancedList,
|
||||
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, const core::vector3df &dir, size_t &PolyCount)
|
||||
{
|
||||
std::function<bool(const scene::ISceneNode *)> shadowculling = [&](const scene::ISceneNode *nd) {return dynamic_cast<const STKMeshCommon*>(nd)->isCulledForShadowCam(cascade); };
|
||||
if (irr_driver->hasARB_draw_indirect())
|
||||
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
|
||||
FillInstancesGrass(MeshForShadowPass[cascade][Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, dir, PolyCount, shadowculling);
|
||||
if (UserConfigParams::m_azdo)
|
||||
ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat];
|
||||
}
|
||||
|
||||
void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
|
||||
{
|
||||
windDir = getWindDir();
|
||||
ListBlendTransparent::getInstance()->clear();
|
||||
ListAdditiveTransparent::getInstance()->clear();
|
||||
ListBlendTransparentFog::getInstance()->clear();
|
||||
ListAdditiveTransparentFog::getInstance()->clear();
|
||||
ListDisplacement::getInstance()->clear();
|
||||
|
||||
ListMatDefault::getInstance()->clear();
|
||||
ListMatAlphaRef::getInstance()->clear();
|
||||
ListMatSphereMap::getInstance()->clear();
|
||||
ListMatDetails::getInstance()->clear();
|
||||
ListMatUnlit::getInstance()->clear();
|
||||
ListMatNormalMap::getInstance()->clear();
|
||||
ListMatGrass::getInstance()->clear();
|
||||
ListMatSplatting::getInstance()->clear();
|
||||
|
||||
ImmediateDrawList::getInstance()->clear();
|
||||
ParticlesList::getInstance()->clear();
|
||||
ListInstancedGlow::getInstance()->clear();
|
||||
|
||||
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
|
||||
{
|
||||
MeshForSolidPass[Mat].clear();
|
||||
MeshForRSMPass[Mat].clear();
|
||||
for (unsigned cascade = 0; cascade < 4; ++cascade)
|
||||
MeshForShadowPass[cascade][Mat].clear();
|
||||
}
|
||||
MeshForGlowPass.clear();
|
||||
DeferredUpdate.clear();
|
||||
core::list<scene::ISceneNode*> List = m_scene_manager->getRootSceneNode()->getChildren();
|
||||
|
||||
parseSceneManager(List, ImmediateDrawList::getInstance(), camnode);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < (int)DeferredUpdate.size(); i++)
|
||||
{
|
||||
scene::ISceneNode *node = dynamic_cast<scene::ISceneNode *>(DeferredUpdate[i]);
|
||||
DeferredUpdate[i]->setCulledForPlayerCam(isCulled(camnode, node));
|
||||
DeferredUpdate[i]->setCulledForRSMCam(isCulled(m_suncam, node));
|
||||
DeferredUpdate[i]->setCulledForShadowCam(0, isCulled(m_shadow_camnodes[0], node));
|
||||
DeferredUpdate[i]->setCulledForShadowCam(1, isCulled(m_shadow_camnodes[1], node));
|
||||
DeferredUpdate[i]->setCulledForShadowCam(2, isCulled(m_shadow_camnodes[2], node));
|
||||
DeferredUpdate[i]->setCulledForShadowCam(3, isCulled(m_shadow_camnodes[3], node));
|
||||
}
|
||||
|
||||
// Add a 1 s timeout
|
||||
if (!m_sync)
|
||||
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
PROFILER_PUSH_CPU_MARKER("- Sync Stall", 0xFF, 0x0, 0x0);
|
||||
GLenum reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
/* switch (reason)
|
||||
{
|
||||
case GL_ALREADY_SIGNALED:
|
||||
printf("Already Signaled\n");
|
||||
break;
|
||||
case GL_TIMEOUT_EXPIRED:
|
||||
printf("Timeout Expired\n");
|
||||
break;
|
||||
case GL_CONDITION_SATISFIED:
|
||||
printf("Condition Satisfied\n");
|
||||
break;
|
||||
case GL_WAIT_FAILED:
|
||||
printf("Wait Failed\n");
|
||||
break;
|
||||
}*/
|
||||
for (unsigned i = 0; i < DeferredUpdate.size(); i++)
|
||||
DeferredUpdate[i]->update();
|
||||
|
||||
if (!irr_driver->hasARB_draw_indirect())
|
||||
return;
|
||||
|
||||
InstanceData *InstanceBuffer;
|
||||
InstanceData *ShadowInstanceBuffer;
|
||||
InstanceData *RSMInstanceBuffer;
|
||||
GlowInstanceData *GlowInstanceBuffer;
|
||||
DrawElementsIndirectCommand *CmdBuffer;
|
||||
DrawElementsIndirectCommand *ShadowCmdBuffer;
|
||||
DrawElementsIndirectCommand *RSMCmdBuffer;
|
||||
DrawElementsIndirectCommand *GlowCmdBuffer;
|
||||
|
||||
if (irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
InstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeDefault);
|
||||
ShadowInstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeShadow);
|
||||
RSMInstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeRSM);
|
||||
GlowInstanceBuffer = (GlowInstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeGlow);
|
||||
CmdBuffer = SolidPassCmd::getInstance()->Ptr;
|
||||
ShadowCmdBuffer = ShadowPassCmd::getInstance()->Ptr;
|
||||
GlowCmdBuffer = GlowPassCmd::getInstance()->Ptr;
|
||||
RSMCmdBuffer = RSMPassCmd::getInstance()->Ptr;
|
||||
}
|
||||
|
||||
ListInstancedMatDefault::getInstance()->clear();
|
||||
ListInstancedMatAlphaRef::getInstance()->clear();
|
||||
ListInstancedMatGrass::getInstance()->clear();
|
||||
ListInstancedMatNormalMap::getInstance()->clear();
|
||||
ListInstancedMatSphereMap::getInstance()->clear();
|
||||
ListInstancedMatDetails::getInstance()->clear();
|
||||
ListInstancedMatUnlit::getInstance()->clear();
|
||||
|
||||
size_t SolidPoly = 0, ShadowPoly = 0, MiscPoly = 0;
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Draw Command upload", 0xFF, 0x0, 0xFF);
|
||||
|
||||
auto playercamculling = [](const scene::ISceneNode *nd) {return dynamic_cast<const STKMeshCommon*>(nd)->isCulledForPlayerCam(); };
|
||||
#pragma omp parallel sections
|
||||
{
|
||||
#pragma omp section
|
||||
{
|
||||
size_t offset = 0, current_cmd = 0;
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeDefault));
|
||||
InstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
|
||||
CmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
|
||||
// Default Material
|
||||
SolidPassCmd::getInstance()->Offset[MAT_DEFAULT] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_DEFAULT] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_DEFAULT];
|
||||
// Alpha Ref
|
||||
SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_ALPHA_REF] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF];
|
||||
// Unlit
|
||||
SolidPassCmd::getInstance()->Offset[MAT_UNLIT] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_UNLIT] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_UNLIT];
|
||||
// Spheremap
|
||||
SolidPassCmd::getInstance()->Offset[MAT_SPHEREMAP] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_SPHEREMAP], ListInstancedMatSphereMap::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_SPHEREMAP] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_SPHEREMAP];
|
||||
// Detail
|
||||
SolidPassCmd::getInstance()->Offset[MAT_DETAIL] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_DETAIL] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_DETAIL];
|
||||
// Normal Map
|
||||
SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP];
|
||||
|
||||
// Grass
|
||||
SolidPassCmd::getInstance()->Offset[MAT_GRASS] = current_cmd;
|
||||
FillInstancesGrass(MeshForSolidPass[MAT_GRASS], ListInstancedMatGrass::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, windDir, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_GRASS] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_GRASS];
|
||||
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
}
|
||||
}
|
||||
#pragma omp section
|
||||
{
|
||||
size_t offset = 0, current_cmd = 0;
|
||||
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeGlow));
|
||||
GlowInstanceBuffer = (GlowInstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
|
||||
GlowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
// Glow
|
||||
if (irr_driver->hasARB_draw_indirect())
|
||||
GlowPassCmd::getInstance()->Offset = offset; // Store command buffer offset
|
||||
|
||||
auto It = MeshForGlowPass.begin(), E = MeshForGlowPass.end();
|
||||
for (; It != E; ++It)
|
||||
{
|
||||
FillInstancesGlow_impl(It->second, GlowInstanceBuffer, GlowCmdBuffer, offset, current_cmd, playercamculling);
|
||||
if (!UserConfigParams::m_azdo)
|
||||
ListInstancedGlow::getInstance()->push_back(It->second.front().first);
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_azdo)
|
||||
GlowPassCmd::getInstance()->Size = current_cmd - GlowPassCmd::getInstance()->Offset;
|
||||
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
}
|
||||
}
|
||||
#pragma omp section
|
||||
{
|
||||
irr_driver->setPhase(SHADOW_PASS);
|
||||
|
||||
size_t offset = 0, current_cmd = 0;
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeShadow));
|
||||
ShadowInstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
|
||||
ShadowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
{
|
||||
// Mat default
|
||||
GenDrawCalls<MAT_DEFAULT>(i, ListInstancedMatDefault::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
|
||||
// Mat AlphaRef
|
||||
GenDrawCalls<MAT_ALPHA_REF>(i, ListInstancedMatAlphaRef::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
|
||||
// Mat Unlit
|
||||
GenDrawCalls<MAT_UNLIT>(i, ListInstancedMatUnlit::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
|
||||
// Mat NormalMap
|
||||
GenDrawCalls<MAT_NORMAL_MAP>(i, ListInstancedMatNormalMap::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
|
||||
// Mat Spheremap
|
||||
GenDrawCalls<MAT_SPHEREMAP>(i, ListInstancedMatSphereMap::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
|
||||
// Mat Detail
|
||||
GenDrawCalls<MAT_DETAIL>(i, ListInstancedMatDetails::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
|
||||
// Mat Grass
|
||||
GenDrawCallsGrass<MAT_GRASS>(i, ListInstancedMatGrass::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, windDir, ShadowPoly);
|
||||
}
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
}
|
||||
}
|
||||
#pragma omp section
|
||||
{
|
||||
auto rsmcamculling = [](const scene::ISceneNode *nd) {return dynamic_cast<const STKMeshCommon*>(nd)->isCulledForRSMCam(); };
|
||||
size_t offset = 0, current_cmd = 0;
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeRSM));
|
||||
RSMInstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, RSMPassCmd::getInstance()->drawindirectcmd);
|
||||
RSMCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
// Default Material
|
||||
RSMPassCmd::getInstance()->Offset[MAT_DEFAULT] = current_cmd;
|
||||
FillInstances(MeshForRSMPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling);
|
||||
RSMPassCmd::getInstance()->Size[MAT_DEFAULT] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_DEFAULT];
|
||||
// Alpha Ref
|
||||
RSMPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = current_cmd;
|
||||
FillInstances(MeshForRSMPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling);
|
||||
RSMPassCmd::getInstance()->Size[MAT_ALPHA_REF] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_ALPHA_REF];
|
||||
// Unlit
|
||||
RSMPassCmd::getInstance()->Offset[MAT_UNLIT] = current_cmd;
|
||||
FillInstances(MeshForRSMPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling);
|
||||
RSMPassCmd::getInstance()->Size[MAT_UNLIT] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_UNLIT];
|
||||
// Detail
|
||||
RSMPassCmd::getInstance()->Offset[MAT_DETAIL] = current_cmd;
|
||||
FillInstances(MeshForRSMPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling);
|
||||
RSMPassCmd::getInstance()->Size[MAT_DETAIL] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_DETAIL];
|
||||
// Normal Map
|
||||
RSMPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = current_cmd;
|
||||
FillInstances(MeshForRSMPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling);
|
||||
RSMPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_NORMAL_MAP];
|
||||
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
}
|
||||
}
|
||||
}
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] += SolidPoly;
|
||||
poly_count[SHADOW_PASS] += ShadowPoly;
|
||||
|
||||
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
|
||||
}
|
68
src/graphics/stkscenemanager.hpp
Normal file
68
src/graphics/stkscenemanager.hpp
Normal file
@ -0,0 +1,68 @@
|
||||
// Not really a scene manager yet but hold algorithm that
|
||||
// rework scene manager output
|
||||
|
||||
#ifndef HEADER_STKSCENEMANAGER_HPP
|
||||
#define HEADER_STKSCENEMANAGER_HPP
|
||||
|
||||
#include "utils/singleton.hpp"
|
||||
#include "gl_headers.hpp"
|
||||
#include "stkmesh.hpp"
|
||||
#include "gpuparticles.hpp"
|
||||
|
||||
template<typename T>
|
||||
class CommandBuffer : public Singleton<T>
|
||||
{
|
||||
public:
|
||||
GLuint drawindirectcmd;
|
||||
DrawElementsIndirectCommand *Ptr;
|
||||
CommandBuffer()
|
||||
{
|
||||
glGenBuffers(1, &drawindirectcmd);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd);
|
||||
#ifdef Buffer_Storage
|
||||
if (irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBufferStorage(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
|
||||
Ptr = (DrawElementsIndirectCommand *)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
glBufferData(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_STREAM_DRAW);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ImmediateDrawList : public Singleton<ImmediateDrawList>, public std::vector<scene::ISceneNode *>
|
||||
{};
|
||||
|
||||
class ParticlesList : public Singleton<ParticlesList>, public std::vector<ParticleSystemProxy *>
|
||||
{};
|
||||
|
||||
|
||||
class SolidPassCmd : public CommandBuffer<SolidPassCmd>
|
||||
{
|
||||
public:
|
||||
size_t Offset[MAT_COUNT], Size[MAT_COUNT];
|
||||
};
|
||||
|
||||
class ShadowPassCmd : public CommandBuffer<ShadowPassCmd>
|
||||
{
|
||||
public:
|
||||
size_t Offset[4][MAT_COUNT], Size[4][MAT_COUNT];
|
||||
};
|
||||
|
||||
class RSMPassCmd : public CommandBuffer<RSMPassCmd>
|
||||
{
|
||||
public:
|
||||
size_t Offset[MAT_COUNT], Size[MAT_COUNT];
|
||||
};
|
||||
|
||||
class GlowPassCmd : public CommandBuffer<GlowPassCmd>
|
||||
{
|
||||
public:
|
||||
size_t Offset, Size;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -18,92 +18,80 @@
|
||||
|
||||
#include "audio/sfx_base.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/gpuparticles.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/per_camera_node.hpp"
|
||||
#include "graphics/rain.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/weather.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "states_screens/race_gui.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
|
||||
|
||||
#include <ISceneManager.h>
|
||||
#include <SMeshBuffer.h>
|
||||
// The weather manager
|
||||
|
||||
using namespace video;
|
||||
using namespace scene;
|
||||
using namespace core;
|
||||
|
||||
// The rain manager
|
||||
|
||||
Rain::Rain(Camera *camera, irr::scene::ISceneNode* parent) : m_thunder_sound(0)
|
||||
Weather::Weather(bool lightning, std::string sound)
|
||||
{
|
||||
m_lightning = camera->getIndex()==0;
|
||||
|
||||
m_lightning = lightning;
|
||||
m_thunder_sound = NULL;
|
||||
m_weather_sound = NULL;
|
||||
|
||||
if (m_lightning)
|
||||
m_thunder_sound = sfx_manager->createSoundSource("thunder");
|
||||
{
|
||||
m_thunder_sound = sfx_manager->createSoundSource("thunder");
|
||||
}
|
||||
|
||||
Material* m = material_manager->getMaterial("rain.png");
|
||||
assert(m != NULL);
|
||||
if (sound != "")
|
||||
{
|
||||
m_weather_sound = sfx_manager->createSoundSource(sound);
|
||||
}
|
||||
|
||||
RandomGenerator g;
|
||||
m_next_lightning = (float)g.get(35);
|
||||
|
||||
// RainNode *node = new RainNode(irr_driver->getSceneManager(), m->getTexture());
|
||||
// m_node = irr_driver->addPerCameraNode(node, camera->getCameraSceneNode(), parent);
|
||||
// m_node->setAutomaticCulling(0);
|
||||
} // Rain
|
||||
} // Weather
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Rain::~Rain()
|
||||
Weather::~Weather()
|
||||
{
|
||||
// m_node->drop(); // drop STK's reference
|
||||
// m_node->remove(); // Then remove it from the scene graph.
|
||||
|
||||
if (m_lightning && m_thunder_sound != NULL) sfx_manager->deleteSFX(m_thunder_sound);
|
||||
if (m_thunder_sound != NULL)
|
||||
sfx_manager->deleteSFX(m_thunder_sound);
|
||||
|
||||
if (m_weather_sound != NULL)
|
||||
sfx_manager->deleteSFX(m_weather_sound);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Rain::update(float dt)
|
||||
void Weather::update(float dt)
|
||||
{
|
||||
if (m_lightning)
|
||||
{
|
||||
m_next_lightning -= dt;
|
||||
|
||||
|
||||
if (m_next_lightning < 0.0f)
|
||||
{
|
||||
RaceGUIBase* gui_base = World::getWorld()->getRaceGUI();
|
||||
|
||||
if (gui_base != NULL)
|
||||
{
|
||||
gui_base->doLightning();
|
||||
if (m_thunder_sound) m_thunder_sound->play();
|
||||
}
|
||||
|
||||
if (m_thunder_sound)
|
||||
{
|
||||
m_thunder_sound->play();
|
||||
}
|
||||
}
|
||||
|
||||
RandomGenerator g;
|
||||
m_next_lightning = 35 + (float)g.get(35);
|
||||
}
|
||||
}
|
||||
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Rain::setPosition(const core::vector3df& position)
|
||||
void Weather::playSound()
|
||||
{
|
||||
// m_node->getChild()->setPosition(position);
|
||||
} // setPosition
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Rain::setCamera(scene::ICameraSceneNode* camera)
|
||||
{
|
||||
// m_node->setCamera(camera);
|
||||
if (m_weather_sound)
|
||||
{
|
||||
m_weather_sound->setLoop(true);
|
||||
m_weather_sound->play();
|
||||
}
|
||||
}
|
@ -16,38 +16,25 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_RAIN_HPP
|
||||
#define HEADER_RAIN_HPP
|
||||
|
||||
class Camera;
|
||||
class PerCameraNode;
|
||||
|
||||
#include <vector3d.h>
|
||||
namespace irr
|
||||
{
|
||||
namespace video { class SMaterial; class ITexture; }
|
||||
namespace scene { class ICameraSceneNode; class ISceneNode; }
|
||||
}
|
||||
using namespace irr;
|
||||
#ifndef HEADER_WEATHER_HPP
|
||||
#define HEADER_WEATHER_HPP
|
||||
|
||||
class SFXBase;
|
||||
|
||||
class Rain
|
||||
class Weather
|
||||
{
|
||||
PerCameraNode* m_node;
|
||||
|
||||
float m_next_lightning;
|
||||
bool m_lightning;
|
||||
float m_next_lightning;
|
||||
|
||||
SFXBase* m_thunder_sound;
|
||||
SFXBase* m_weather_sound;
|
||||
|
||||
public:
|
||||
Rain(Camera* camera, irr::scene::ISceneNode* parent);
|
||||
virtual ~Rain();
|
||||
Weather(bool lightning, std::string sound);
|
||||
virtual ~Weather();
|
||||
|
||||
void update(float dt);
|
||||
void setPosition(const irr::core::vector3df& position);
|
||||
|
||||
void setCamera(scene::ICameraSceneNode* camera);
|
||||
void playSound();
|
||||
};
|
||||
|
||||
#endif
|
@ -170,7 +170,7 @@ namespace GUIEngine
|
||||
inline Skin* getSkin() { return Private::g_skin; }
|
||||
|
||||
Screen* getScreenNamed(const char* name);
|
||||
|
||||
|
||||
/** \return the height of the title font in pixels */
|
||||
int getTitleFontHeight();
|
||||
|
||||
|
@ -43,6 +43,8 @@ void ButtonWidget::add()
|
||||
m_id = m_element->getID();
|
||||
m_element->setTabOrder(m_id);
|
||||
m_element->setTabGroup(false);
|
||||
if (!m_is_visible)
|
||||
m_element->setVisible(false);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user