mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d344361087 |
No files matched your search
@@ -102,7 +102,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
os: [windows-2025, windows-11-arm]
|
||||
os: [windows-2022, windows-11-arm]
|
||||
arch: [Win32, x64, ARM64]
|
||||
simd: [SSE2, ""]
|
||||
exclude:
|
||||
@@ -111,8 +111,8 @@ jobs:
|
||||
- arch: x64
|
||||
os: windows-11-arm
|
||||
- arch: ARM64
|
||||
os: windows-2025
|
||||
- os: windows-2025
|
||||
os: windows-2022
|
||||
- os: windows-2022
|
||||
simd: ""
|
||||
- os: windows-11-arm
|
||||
simd: SSE2
|
||||
@@ -126,9 +126,6 @@ jobs:
|
||||
- name: Set workspace as safe
|
||||
# This appears to be broken in current actions, so do it manually
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: Install v143 ATL/MFC
|
||||
shell: pwsh
|
||||
run: ci/windows/install_v143_atlmfc.ps1
|
||||
# Tree A: static CRT (/MT) for FSO + FRED2 (no Qt dependency needed)
|
||||
- name: Configure CMake (static CRT /MT - FSO + FRED2)
|
||||
env:
|
||||
@@ -142,7 +139,7 @@ jobs:
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH=ON \
|
||||
-DFSO_USE_VOICEREC=ON -DFORCED_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_TESTS=ON -DFSO_INSTALL_DEBUG_FILES=ON -A "$ARCHITECTURE" \
|
||||
-DFSO_BUILD_QTFRED=OFF -G "Visual Studio 18 2026" -T "v143" \
|
||||
-DFSO_BUILD_QTFRED=OFF -G "Visual Studio 17 2022" -T "v143" \
|
||||
-DCMAKE_BUILD_TYPE=$CONFIGURATION ..
|
||||
- name: Compile (static CRT)
|
||||
working-directory: ./build-mt
|
||||
@@ -171,7 +168,7 @@ jobs:
|
||||
-DFSO_USE_VOICEREC=ON -DFORCED_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_TESTS=OFF -DFSO_INSTALL_DEBUG_FILES=ON -A "$ARCHITECTURE" \
|
||||
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_FRED2=OFF -DQT_USE_PRECOMPILED=ON \
|
||||
-G "Visual Studio 18 2026" -T "v143" -DCMAKE_BUILD_TYPE=$CONFIGURATION ..
|
||||
-G "Visual Studio 17 2022" -T "v143" -DCMAKE_BUILD_TYPE=$CONFIGURATION ..
|
||||
- name: Compile (dynamic CRT)
|
||||
if: matrix.arch != 'Win32'
|
||||
working-directory: ./build-md
|
||||
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
os: [windows-2025, windows-11-arm]
|
||||
os: [windows-2022, windows-11-arm]
|
||||
arch: [Win32, x64, ARM64]
|
||||
simd: [SSE2, AVX, ""]
|
||||
exclude:
|
||||
@@ -161,8 +161,8 @@ jobs:
|
||||
- arch: x64
|
||||
os: windows-11-arm
|
||||
- arch: ARM64
|
||||
os: windows-2025
|
||||
- os: windows-2025
|
||||
os: windows-2022
|
||||
- os: windows-2022
|
||||
simd: ""
|
||||
- os: windows-11-arm
|
||||
simd: SSE2
|
||||
@@ -181,9 +181,6 @@ jobs:
|
||||
- name: Set workspace as safe
|
||||
# This appears to be broken in current actions, so do it manually
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: Install v143 ATL/MFC
|
||||
shell: pwsh
|
||||
run: ci/windows/install_v143_atlmfc.ps1
|
||||
# Tree A: static CRT (/MT) for FSO + FRED2 (no Qt dependency needed)
|
||||
- name: Configure CMake (static CRT /MT - FSO + FRED2)
|
||||
env:
|
||||
@@ -197,7 +194,7 @@ jobs:
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH=ON \
|
||||
-DFSO_USE_VOICEREC=ON -DFORCED_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_TESTS=ON -DFSO_INSTALL_DEBUG_FILES=ON -A "$ARCHITECTURE" \
|
||||
-DFSO_BUILD_QTFRED=OFF -G "Visual Studio 18 2026" -T "v143" \
|
||||
-DFSO_BUILD_QTFRED=OFF -G "Visual Studio 17 2022" -T "v143" \
|
||||
-DCMAKE_BUILD_TYPE=$CONFIGURATION ..
|
||||
- name: Compile (static CRT)
|
||||
working-directory: ./build-mt
|
||||
@@ -226,7 +223,7 @@ jobs:
|
||||
-DFSO_USE_VOICEREC=ON -DFORCED_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_TESTS=OFF -DFSO_INSTALL_DEBUG_FILES=ON -A "$ARCHITECTURE" \
|
||||
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_FRED2=OFF -DQT_USE_PRECOMPILED=ON \
|
||||
-G "Visual Studio 18 2026" -T "v143" -DCMAKE_BUILD_TYPE=$CONFIGURATION ..
|
||||
-G "Visual Studio 17 2022" -T "v143" -DCMAKE_BUILD_TYPE=$CONFIGURATION ..
|
||||
- name: Compile (dynamic CRT)
|
||||
if: matrix.arch != 'Win32'
|
||||
working-directory: ./build-md
|
||||
|
||||
@@ -109,7 +109,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
os: [windows-2025, windows-11-arm]
|
||||
os: [windows-2022, windows-11-arm]
|
||||
arch: [Win32, x64, ARM64]
|
||||
simd: [SSE2, ""]
|
||||
exclude:
|
||||
@@ -118,8 +118,8 @@ jobs:
|
||||
- arch: x64
|
||||
os: windows-11-arm
|
||||
- arch: ARM64
|
||||
os: windows-2025
|
||||
- os: windows-2025
|
||||
os: windows-2022
|
||||
- os: windows-2022
|
||||
simd: ""
|
||||
- os: windows-11-arm
|
||||
simd: SSE2
|
||||
@@ -139,9 +139,6 @@ jobs:
|
||||
[[ "${{ github.ref }}" =~ ^refs\/heads\/test\/(.*)$ ]]
|
||||
# Override the revision string so that the builds are named correctly
|
||||
echo "set(FSO_VERSION_REVISION_STR ${BASH_REMATCH[1]})" > "version_override.cmake"
|
||||
- name: Install v143 ATL/MFC
|
||||
shell: pwsh
|
||||
run: ci/windows/install_v143_atlmfc.ps1
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
@@ -154,7 +151,7 @@ jobs:
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH=ON \
|
||||
-DFSO_USE_VOICEREC=ON -DFORCED_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_TESTS=ON -DFSO_INSTALL_DEBUG_FILES=ON -A "$ARCHITECTURE" \
|
||||
-DQT_USE_PRECOMPILED=ON -G "Visual Studio 18 2026" -T "v143" \
|
||||
-DQT_USE_PRECOMPILED=ON -G "Visual Studio 17 2022" -T "v143" \
|
||||
-DCMAKE_BUILD_TYPE=$CONFIGURATION ..
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
compiler: [MSVC]
|
||||
arch: [Win32, x64]
|
||||
name: Windows
|
||||
runs-on: windows-2025
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: Prepare Environment
|
||||
run: choco install ninja
|
||||
@@ -89,10 +89,6 @@ jobs:
|
||||
- name: Set workspace as safe
|
||||
# This appears to be broken in current actions, so do it manually
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: Install v143 ATL/MFC
|
||||
if: matrix.compiler == 'MSVC'
|
||||
shell: pwsh
|
||||
run: ci/windows/install_v143_atlmfc.ps1
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
@@ -108,7 +104,7 @@ jobs:
|
||||
-DFSO_BUILD_FRED2=OFF -DQT_USE_PRECOMPILED=ON -DCMAKE_BUILD_TYPE=$CONFIGURATION -G "Ninja" ..
|
||||
else
|
||||
cmake -DFSO_USE_SPEECH=ON -DFSO_FATAL_WARNINGS=ON -DFSO_USE_VOICEREC=OFF -DFSO_BUILD_TESTS=ON \
|
||||
-DFORCED_SIMD_INSTRUCTIONS=SSE2 -G "Visual Studio 18 2026" -T "v143" -A "$ARCHITECTURE" \
|
||||
-DFORCED_SIMD_INSTRUCTIONS=SSE2 -G "Visual Studio 17 2022" -T "v143" -A "$ARCHITECTURE" \
|
||||
-DQT_USE_PRECOMPILED=ON -DCMAKE_BUILD_TYPE=$CONFIGURATION ..
|
||||
fi
|
||||
- name: Compile
|
||||
|
||||
+15
-34
@@ -29,43 +29,24 @@ ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
SET(TARGET_COPY_FILES "" CACHE INTERNAL "" FORCE)
|
||||
SET(TARGET_COPY_DIRS "" CACHE INTERNAL "" FORCE)
|
||||
|
||||
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
|
||||
# Override standard CMake configurations
|
||||
set(FSO_BUILD_TYPES Debug Release FastDebug)
|
||||
|
||||
if(is_multi_config)
|
||||
set(CMAKE_CONFIGURATION_TYPES "${FSO_BUILD_TYPES}" CACHE STRING "Configuration types" FORCE)
|
||||
elseif(NOT CMAKE_BUILD_TYPE)
|
||||
### Define options and editable variables in the section below:
|
||||
# This is only needed for single configuration generators so don't annoy others
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Default build configuration used." FORCE)
|
||||
message(WARNING "CMAKE_BUILD_TYPE was not specified, defaulting to Release configuration.")
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${FSO_BUILD_TYPES}")
|
||||
endif()
|
||||
endif(NOT CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)
|
||||
|
||||
# Override standard CMake configurations
|
||||
set(CMAKE_CONFIGURATION_TYPES Debug Release FastDebug CACHE STRING "Available configurations" FORCE)
|
||||
|
||||
set(FSO_LANGUAGES C CXX)
|
||||
|
||||
if(APPLE)
|
||||
set(FSO_LANGUAGES ${FSO_LANGUAGES} OBJC OBJCXX)
|
||||
|
||||
# 10.15 for c++17 std::filesystem
|
||||
# NOTE: this must be set *before* the project() call to work properly!!
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "macOS deployment target")
|
||||
|
||||
# fix all targets in scheme (so it's not just qtfred)
|
||||
set(CMAKE_XCODE_GENERATE_SCHEME TRUE)
|
||||
endif()
|
||||
|
||||
PROJECT(FS2_Open LANGUAGES ${FSO_LANGUAGES})
|
||||
|
||||
if (ANDROID)
|
||||
message(STATUS "Building for Android (NDK)")
|
||||
set(FSO_BUILD_INCLUDED_LIBS ON CACHE BOOL "" FORCE)
|
||||
set(USING_PREBUILT_LIBS ON CACHE BOOL "" FORCE)
|
||||
set(SDL3_USE_PRECOMPILED ON CACHE BOOL "" FORCE)
|
||||
set(OPENAL_USE_PRECOMPILED ON CACHE BOOL "" FORCE)
|
||||
set(USING_PREBUILT_VULKAN ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
# Check if the external modules exists
|
||||
IF(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lib/libRocket/Build")
|
||||
message(FATAL_ERROR "External submodules could not be found. Please make sure you have updated your submodules.")
|
||||
@@ -118,8 +99,8 @@ OPTION(FSO_BUILD_TESTS "Build unit tests" OFF)
|
||||
|
||||
OPTION(FSO_DEVELOPMENT_MODE "Generate binaries in development mode, only use if you know what you're doing!" OFF)
|
||||
|
||||
IF(WIN32 OR APPLE OR ANDROID)
|
||||
# On windows, mac and android the default should be to always build the included libraries
|
||||
IF(WIN32 OR APPLE)
|
||||
# On windows and mac the default should be to always build the included libraries
|
||||
SET(FSO_BUILD_INCLUDED_LIBS_DEFAULT ON)
|
||||
ELSE()
|
||||
SET(FSO_BUILD_INCLUDED_LIBS_DEFAULT OFF)
|
||||
@@ -147,13 +128,13 @@ OPTION(FSO_BUILD_WITH_DISCORD "Build with Discord support" ON)
|
||||
|
||||
OPTION(FSO_BUILD_WITH_OPENGL "Enable compilation of the OpenGL renderer" ON)
|
||||
OPTION(FSO_BUILD_WITH_OPENGL_DEBUG "Enables debug option for OpenGL" OFF)
|
||||
OPTION(FSO_BUILD_WITH_OPENGL_ES "When building OpenGL, use OpenGL ES compatibility layer" OFF)
|
||||
OPTION(FSO_BUILD_WITH_OPENGL_ES "When building OpenGL, use OpenGL ES compatibility layer (External shaders only!)" OFF)
|
||||
|
||||
OPTION(FSO_BUILD_WITH_VULKAN "Enable compilation of the Vulkan renderer" ON)
|
||||
|
||||
if(NOT FSO_BUILD_WITH_OPENGL AND FSO_BUILD_WITH_OPENGL_ES)
|
||||
# Disable GLES if not building with OpenGL
|
||||
set(FSO_BUILD_WITH_OPENGL_ES OFF CACHE BOOL "" FORCE)
|
||||
set(FSO_BUILD_WITH_OPENGL_ES OFF FORCE)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -215,11 +196,11 @@ include(clang-tidy)
|
||||
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT LTO_AVAILABLE)
|
||||
if (FSO_USE_LTO AND LTO_AVAILABLE)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release" AND FSO_USE_LTO AND LTO_AVAILABLE)
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
|
||||
message("Enabled LTO for Release builds")
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
|
||||
endif (FSO_USE_LTO AND LTO_AVAILABLE)
|
||||
message("Enabled LTO")
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif (CMAKE_BUILD_TYPE STREQUAL "Release" AND FSO_USE_LTO AND LTO_AVAILABLE)
|
||||
|
||||
# This includes source code for some tools, either used in the build or also for something else
|
||||
ADD_SUBDIRECTORY(tools)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
Mako==1.4.2
|
||||
Mako==1.3.12
|
||||
requests==2.33.0
|
||||
semantic-version==2.8.5
|
||||
@@ -1,34 +0,0 @@
|
||||
# Installs ATL and MFC for the v143 toolset, which the Visual Studio 2026 runner images
|
||||
# only ship for the latest toolset. ATL is needed by SAPI speech (sphelper.h) and MFC by FRED2.
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$msvcVersion = '14.44'
|
||||
$component = 'Microsoft.VisualStudio.Component.VC.14.44.17.14'
|
||||
$suffix = if ($env:RUNNER_ARCH -eq 'ARM64') { '.ARM64' } else { '' }
|
||||
|
||||
$installerDir = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer"
|
||||
$installPath = & "$installerDir\vswhere.exe" -version '[18.0,19.0)' -latest -property installationPath
|
||||
if (-not $installPath) {
|
||||
Write-Error 'Visual Studio 2026 was not found'
|
||||
}
|
||||
|
||||
$arguments = @(
|
||||
'/c', 'vs_installer.exe', 'modify',
|
||||
'--installPath', "`"$installPath`"",
|
||||
'--add', "$component.ATL$suffix",
|
||||
'--add', "$component.MFC$suffix",
|
||||
'--quiet', '--norestart', '--nocache'
|
||||
)
|
||||
$process = Start-Process -FilePath cmd.exe -ArgumentList $arguments -WorkingDirectory $installerDir -Wait -PassThru -NoNewWindow
|
||||
# 3010 = success, reboot required
|
||||
if ($process.ExitCode -notin 0, 3010) {
|
||||
Write-Error "vs_installer exited with code $($process.ExitCode)"
|
||||
}
|
||||
|
||||
# fail here rather than with a confusing compile error if the components didn't install
|
||||
foreach ($header in 'atlbase.h', 'afxwin.h') {
|
||||
if (-not (Test-Path "$installPath\VC\Tools\MSVC\$msvcVersion.*\atlmfc\include\$header")) {
|
||||
Write-Error "$header for MSVC $msvcVersion is missing after install"
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,10 @@ endif()
|
||||
|
||||
target_link_libraries(platform INTERFACE ${COCOA_LIBRARY})
|
||||
|
||||
# To support C++17 we need to target at least 10.13. maybe 10.14 for some rare features
|
||||
# bump to 10.15 for c++17 std::filesystem usage in qtFRED
|
||||
SET(CMAKE_OSX_DEPLOYMENT_TARGET "10.15")
|
||||
|
||||
SET(CMAKE_SKIP_RPATH FALSE)
|
||||
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
SET(CMAKE_INSTALL_RPATH @loader_path/../Frameworks/)
|
||||
|
||||
@@ -13,13 +13,6 @@ option(MSVC_RELEASE_DEBUGGING "Set options that allow to debug release builds" O
|
||||
MARK_AS_ADVANCED(FORCE MSVC_USE_RUNTIME_DLL)
|
||||
MARK_AS_ADVANCED(FORCE MSVC_RELEASE_DEBUGGING)
|
||||
|
||||
# Qt is only available as DLL-runtime builds, so qtFRED forces the DLL runtime for the whole tree
|
||||
if(MSVC_USE_RUNTIME_DLL OR FSO_BUILD_QTFRED)
|
||||
set(FSO_MSVC_RUNTIME_DLL ON)
|
||||
else()
|
||||
set(FSO_MSVC_RUNTIME_DLL OFF)
|
||||
endif()
|
||||
|
||||
# These are the warnings we disable
|
||||
set(WARNING_FLAGS
|
||||
/wd4100 # unreferenced formal parameters
|
||||
@@ -78,12 +71,12 @@ if (MSVC_RELEASE_DEBUGGING)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# The debug runtime is not redistributable (statically linked or not), so only Debug may use it
|
||||
IF(FSO_MSVC_RUNTIME_DLL)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
# This should be kept in sync with the corresponding IF() in fred2/CMakeLists.txt
|
||||
IF(MSVC_USE_RUNTIME_DLL OR FSO_BUILD_QTFRED)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<NOT:$<CONFIG:Release>>:Debug>DLL")
|
||||
add_compile_definitions(_AFXDLL)
|
||||
ELSE()
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<NOT:$<CONFIG:Release>>:Debug>")
|
||||
ENDIF()
|
||||
|
||||
# Debug
|
||||
|
||||
+10
-7
@@ -3,13 +3,7 @@
|
||||
|
||||
add_library(compiler INTERFACE)
|
||||
|
||||
set(FSO_CONFIG_DEFINITIONS "$<$<CONFIG:Release>:NDEBUG>" "$<$<CONFIG:Debug>:_DEBUG>")
|
||||
if(NOT MSVC)
|
||||
# On MSVC the debug runtime flags (/MTd, /MDd) define _DEBUG themselves, and a FastDebug
|
||||
# build on the release runtime must not have it
|
||||
list(APPEND FSO_CONFIG_DEFINITIONS "$<$<CONFIG:FastDebug>:_DEBUG>")
|
||||
endif()
|
||||
target_compile_definitions(compiler INTERFACE ${FSO_CONFIG_DEFINITIONS})
|
||||
target_compile_definitions(compiler INTERFACE "$<$<CONFIG:Release>:NDEBUG>;$<$<CONFIG:Debug>:_DEBUG>;$<$<CONFIG:FastDebug>:_DEBUG>")
|
||||
|
||||
set(FORCED_NATIVE_SIMD_INSTRUCTIONS ON CACHE BOOL "Override instruction set detection and compile with the maximum possible instructions for the current system.")
|
||||
IF(IS_X86)
|
||||
@@ -80,3 +74,12 @@ set(CMAKE_C_FLAGS_FASTDEBUG "${CMAKE_C_FLAGS_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_FASTDEBUG "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_FASTDEBUG "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_FASTDEBUG "${CMAKE_STATIC_LINKER_FLAGS_RELEASE}")
|
||||
|
||||
if (MSVC)
|
||||
# Adjust runtime library
|
||||
string(REPLACE "/MD" "/MDd" CMAKE_C_FLAGS_FASTDEBUG "${CMAKE_C_FLAGS_FASTDEBUG}")
|
||||
string(REPLACE "/MT" "/MTd" CMAKE_C_FLAGS_FASTDEBUG "${CMAKE_C_FLAGS_FASTDEBUG}")
|
||||
|
||||
string(REPLACE "/MD" "/MDd" CMAKE_CXX_FLAGS_FASTDEBUG "${CMAKE_CXX_FLAGS_FASTDEBUG}")
|
||||
string(REPLACE "/MT" "/MTd" CMAKE_CXX_FLAGS_FASTDEBUG "${CMAKE_CXX_FLAGS_FASTDEBUG}")
|
||||
endif()
|
||||
@@ -241,17 +241,6 @@ function(suppress_file_warnings)
|
||||
endif()
|
||||
endfunction(suppress_file_warnings)
|
||||
|
||||
# Suppress no symbols warnings in static libraries (on Xcode)
|
||||
function(suppress_no_symbol_warnings _target)
|
||||
if(XCODE)
|
||||
get_target_property(target_type ${_target} TYPE)
|
||||
if(target_type STREQUAL "STATIC_LIBRARY")
|
||||
set_property(TARGET ${_target} APPEND PROPERTY
|
||||
STATIC_LIBRARY_OPTIONS "-no_warning_for_no_symbols"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endfunction(suppress_no_symbol_warnings)
|
||||
|
||||
function(list_target_dependencies _target _out_var)
|
||||
set(out_list)
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ if (EXISTS "${PROJECT_SOURCE_DIR}/version_override.cmake")
|
||||
endif()
|
||||
|
||||
set_if_not_defined(FSO_VERSION_MAJOR 26)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 3)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 1)
|
||||
set_if_not_defined(FSO_VERSION_BUILD 0)
|
||||
|
||||
# A numeric revision e.g. the CI build number
|
||||
|
||||
@@ -130,8 +130,5 @@ set_target_properties(code PROPERTIES XCODE_ATTRIBUTE_COPY_PHASE_STRIP[variant=D
|
||||
set_target_properties(code PROPERTIES XCODE_ATTRIBUTE_STRIP_INSTALLED_PRODUCT[variant=Debug] "NO")
|
||||
set_target_properties(code PROPERTIES XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN[variant=Debug] "NO")
|
||||
|
||||
# Prevent warnings on files with no symbols on Mac
|
||||
suppress_no_symbol_warnings(code)
|
||||
|
||||
# Prevent GCC warnings in third-party BitOp... see GitHub #4366
|
||||
suppress_file_warnings(scripting/lua/bitop/bit.c)
|
||||
+2
-6
@@ -295,7 +295,6 @@ typedef struct ai_info {
|
||||
vec3d path_create_pos; // Object's position at time of global path creation.
|
||||
matrix path_create_orient; // Object's orientation at time of global path creation.
|
||||
int mp_index; // Model path index. Index in polymodel:model_paths
|
||||
int mp_randomized_vert; // Vertex of the model path that was given a random offset, or -1
|
||||
fix path_next_check_time; // Last time checked to see if would collide with model.
|
||||
int path_goal_dist; // minimum distance to first path point to consider path reached
|
||||
int path_subsystem_next_check; // timestamp to next check if subsystem is still visible
|
||||
@@ -535,7 +534,6 @@ extern void ai_ignore_wing(object *ignorer, int wingnum);
|
||||
extern void ai_dock_with_object(object *docker, int docker_index, object *dockee, int dockee_index, int dock_type);
|
||||
extern void ai_stay_still(object *still_objp, vec3d *view_pos);
|
||||
extern void ai_do_default_behavior(object *obj);
|
||||
extern void ai_reset_order_state(ai_info *aip);
|
||||
extern void ai_start_waypoints(object *objp, int wl_index, int wp_flags, int start_index, bool force = false);
|
||||
extern void ai_ship_hit(object *objp_ship, object *hit_objp, const vec3d *hit_normal);
|
||||
extern void ai_ship_destroy(int shipnum);
|
||||
@@ -598,9 +596,7 @@ extern int ai_maybe_fire_afterburner(object *objp, ai_info *aip);
|
||||
extern void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, vec3d *enemy_pos, vec3d *enemy_vel, ai_info *aip);
|
||||
|
||||
extern int is_instructor(object *objp);
|
||||
extern int find_enemy(int objnum, float range, int max_attackers, bool for_pursuit, int ship_info_index = -1, int class_type = -1);
|
||||
extern bool ai_targets_for_pursuit(const ai_info *aip);
|
||||
extern bool ai_declines_pursuit(const object *attacker_objp, const object *target_objp);
|
||||
extern int find_enemy(int objnum, float range, int max_attackers, int ship_info_index = -1, int class_type = -1);
|
||||
|
||||
float ai_get_weapon_speed(const ship_weapon *swp);
|
||||
void set_predicted_enemy_pos_turret(vec3d *predicted_enemy_pos, const vec3d *gun_pos, const object *pobjp, const vec3d *enemy_pos, const vec3d *enemy_vel, float weapon_speed, float time_enemy_in_range);
|
||||
@@ -621,7 +617,7 @@ extern float dock_orient_and_approach(object *docker_objp, int docker_index, obj
|
||||
void ai_set_mode_warp_out(object *objp, ai_info *aip);
|
||||
|
||||
// prototyped by Goober5000
|
||||
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers, bool for_pursuit, int ship_info_index, int class_type = -1);
|
||||
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers, int ship_info_index, int class_type = -1);
|
||||
|
||||
// moved to header file by Goober5000
|
||||
void ai_announce_ship_dying(object *dying_objp);
|
||||
|
||||
+2
-10
@@ -178,10 +178,8 @@ namespace AI {
|
||||
Fix_standard_strafe,
|
||||
Fix_ai_target_recovery, // a) strafing ships that lose their target re-process their orders, like chasing ships already do
|
||||
// b) ships parked in AIM_NONE while holding a standing chase order (attack-any etc.) re-process their orders;
|
||||
// c) target selection for pursuit (chasing, guard reactions, retaliation) skips ships outside the attacker's
|
||||
// actively-pursues list; targets held while not chasing are unaffected, and explicitly ordered targets are
|
||||
// still assigned but not chased or strafed;
|
||||
// d) enemy_wing is reset when a new order takes over (shared with Fix_stale_ai_order_state)
|
||||
// c) target selection skips ships outside the attacker's actively-pursues list, and self-chosen targets
|
||||
// outside that list are dropped rather than held forever
|
||||
Standard_strafe_used_more,
|
||||
Unify_usage_ai_shield_manage_delay,
|
||||
Fix_AI_shield_management_bug,
|
||||
@@ -202,12 +200,6 @@ namespace AI {
|
||||
// b) completion no longer requires moving 0.1m in a single frame (framerate-dependent)
|
||||
Fix_shockwave_expire_before_do_damage, // shockwaves whose lifetime is shorter than one frame apply their area damage at least once before expiring
|
||||
Fix_small_ai_recover_after_engines_repaired, // ensure small ship AI can switch back to useful AI modes if engines get repaired
|
||||
Fix_model_path_refresh_randomization, // a subsystem path keeps its randomized point when the path is refreshed because the target moved
|
||||
Fix_bay_speed_ramp, // the fighterbay speed ramp covers only the bay path itself, not points that route a departing ship around the carrier, and never exceeds max speed
|
||||
Fix_stale_ai_order_state, // a) enemy_wing, guard_*, previous_mode, resume_goal_time, and the targeted subsystem (with its path) are reset when a new order takes over (enemy_wing is also reset under Fix_ai_target_recovery);
|
||||
// b) a dynamic chase saves previous_mode/previous_submode; it and strafe entry leave them alone during an ongoing dynamic goal (evading a weapon still overwrites them, which is harmless since the evade resume re-processes orders);
|
||||
// c) resuming guard duty discards any subsystem target and path left over from the interruption;
|
||||
// d) a ship ordered to guard itself, or to guard a wing it leads (including one that becomes leader mid-mission), treats that goal as unachievable instead of holding it forever
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
|
||||
+7
-16
@@ -140,7 +140,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
// don't create multiple profiles with the same name
|
||||
if (previous_profile != NULL)
|
||||
{
|
||||
Warning(LOCATION, "An AI profile named '%s' already exists! The new one will not be created.\n", profile_name);
|
||||
Warning(LOCATION, "An ai profile named '%s' already exists! The new one will not be created.\n", profile_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -412,7 +412,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
set_flag(profile, "$disable player secondary doublefire:", AI::Profile_Flags::Disable_player_secondary_doublefire);
|
||||
|
||||
set_flag(profile, "$disable AI secondary doublefire:", AI::Profile_Flags::Disable_ai_secondary_doublefire);
|
||||
set_flag(profile, "$disable ai secondary doublefire:", AI::Profile_Flags::Disable_ai_secondary_doublefire);
|
||||
|
||||
set_flag(profile, "$disable weapon damage scaling:", AI::Profile_Flags::Disable_weapon_damage_scaling);
|
||||
|
||||
@@ -450,7 +450,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
set_flag(profile, "$force beam turrets to use normal fov:", AI::Profile_Flags::Force_beam_turret_fov);
|
||||
|
||||
set_flag(profile, "$fix AI class bug:", AI::Profile_Flags::Fix_ai_class_bug);
|
||||
set_flag(profile, "$fix ai class bug:", AI::Profile_Flags::Fix_ai_class_bug);
|
||||
|
||||
set_flag(profile, "$turrets ignore targets radius in range checks:", AI::Profile_Flags::Turrets_ignore_target_radius);
|
||||
|
||||
@@ -505,13 +505,13 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
profile->ai_path_mode = j;
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "Invalid AI path mode '%s' specified", buf);
|
||||
Warning(LOCATION, "Invalid ai path mode '%s' specified", buf);
|
||||
}
|
||||
}
|
||||
|
||||
set_flag(profile, "$no warp camera:", AI::Profile_Flags::No_warp_camera);
|
||||
|
||||
set_flag(profile, "$fix AI path order bug:", AI::Profile_Flags::Fix_ai_path_order_bug);
|
||||
set_flag(profile, "$fix ai path order bug:", AI::Profile_Flags::Fix_ai_path_order_bug);
|
||||
|
||||
set_flag(profile, "$strict turret-tagged-only targeting:", AI::Profile_Flags::Strict_turret_tagged_only_targeting);
|
||||
|
||||
@@ -622,7 +622,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
profile->ai_range_aware_secondary_select_mode = j;
|
||||
}
|
||||
else {
|
||||
Warning(LOCATION, "Invalid AI secondary range awareness mode '%s' specified", buf);
|
||||
Warning(LOCATION, "Invalid ai secondary range awareness mode '%s' specified", buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,7 +677,7 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
set_flag(profile, "$fix standard strafe:", AI::Profile_Flags::Fix_standard_strafe);
|
||||
|
||||
set_flag(profile, "$fix AI target recovery:", AI::Profile_Flags::Fix_ai_target_recovery);
|
||||
set_flag(profile, "$fix ai target recovery:", AI::Profile_Flags::Fix_ai_target_recovery);
|
||||
|
||||
set_flag(profile, "$standard strafe used more:", AI::Profile_Flags::Standard_strafe_used_more);
|
||||
|
||||
@@ -767,12 +767,6 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
set_flag(profile, "$fix fighter/bomber AI recovers after engines repaired:", AI::Profile_Flags::Fix_small_ai_recover_after_engines_repaired);
|
||||
|
||||
set_flag(profile, "$fix subsystem path randomization on refresh:", AI::Profile_Flags::Fix_model_path_refresh_randomization);
|
||||
|
||||
set_flag(profile, "$fix fighterbay speed ramp:", AI::Profile_Flags::Fix_bay_speed_ramp);
|
||||
|
||||
set_flag(profile, "$fix stale AI order state:", AI::Profile_Flags::Fix_stale_ai_order_state);
|
||||
|
||||
// end of options ----------------------------------------
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
@@ -1007,8 +1001,5 @@ void ai_profile_t::reset()
|
||||
flags.set(AI::Profile_Flags::Fix_small_ai_recover_after_engines_repaired);
|
||||
flags.set(AI::Profile_Flags::Fix_standard_strafe);
|
||||
flags.set(AI::Profile_Flags::Fix_ai_target_recovery);
|
||||
flags.set(AI::Profile_Flags::Fix_model_path_refresh_randomization);
|
||||
flags.set(AI::Profile_Flags::Fix_bay_speed_ramp);
|
||||
flags.set(AI::Profile_Flags::Fix_stale_ai_order_state);
|
||||
}
|
||||
}
|
||||
+12
-22
@@ -66,16 +66,6 @@ static bool ai_big_strafe_maybe_retreat(const vec3d *target_pos);
|
||||
extern void compute_desired_rvec(vec3d *rvec, const vec3d *goal_pos, const vec3d *cur_pos);
|
||||
extern void big_ship_collide_recover_start(const object *objp, const object *big_objp, const vec3d *collision_normal);
|
||||
|
||||
// Record the mode being left as the one to return to, unless a dynamic goal is already in progress
|
||||
// (in which case previous_mode still refers to the mode that goal interrupted).
|
||||
static void ai_big_save_previous_mode(ai_info *aip)
|
||||
{
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_stale_ai_order_state] && aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC)
|
||||
return;
|
||||
|
||||
aip->previous_mode = aip->mode;
|
||||
}
|
||||
|
||||
|
||||
// Called by ai_big_pick_attack_point.
|
||||
// Generates a random attack point.
|
||||
@@ -509,7 +499,7 @@ bool ai_big_maybe_follow_subsys_path(bool do_dot_check)
|
||||
// for now, only follow the path to the first point
|
||||
if ( aip->path_cur < (aip->path_start+aip->path_length-1) ) {
|
||||
if ( aip->goal_objnum != aip->target_objnum ) {
|
||||
ai_big_save_previous_mode(aip);
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->mode = AIM_NONE;
|
||||
aip->submode = -1;
|
||||
aip->submode_start_time = Missiontime;
|
||||
@@ -716,8 +706,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
if (vm_vec_dot(&in_vec, &objp->orient.vec.fvec) > 0.0f) {
|
||||
dist = vm_vec_normalize(&in_vec);
|
||||
if ((dist < 200.0f) && (vm_vec_dot(&in_vec, &objp->orient.vec.fvec) > 0.95f)) {
|
||||
if ((Objects[objp->parent].signature == objp->parent_sig) && (vm_vec_dist_quick(&objp->pos, &Objects[objp->parent].pos) < 300.0f)
|
||||
&& !ai_declines_pursuit(Pl_objp, &Objects[objp->parent])) {
|
||||
if ((Objects[objp->parent].signature == objp->parent_sig) && (vm_vec_dist_quick(&objp->pos, &Objects[objp->parent].pos) < 300.0f)) {
|
||||
set_target_objnum(aip, objp->parent);
|
||||
aip->submode = SM_ATTACK;
|
||||
aip->submode_start_time = Missiontime;
|
||||
@@ -738,7 +727,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
// including ai_profile flag and if enemy fighters are near
|
||||
if (Pl_objp->phys_info.speed < The_mission.ai_profile->standard_strafe_when_below_speed &&
|
||||
(The_mission.ai_profile->flags[AI::Profile_Flags::Standard_strafe_used_more] || ai_big_maybe_start_strafe(aip, sip))) {
|
||||
ai_big_save_previous_mode(aip);
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->mode = AIM_STRAFE;
|
||||
aip->submode_parm0 = Missiontime; // use parm0 as time strafe mode entered (i.e. MODE start time)
|
||||
ai_big_strafe_position();
|
||||
@@ -747,7 +736,7 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
|
||||
|
||||
//Maybe enter glide strafe (check every 8 seconds, on a different schedule for each ship)
|
||||
if ((sip->can_glide == true) && !(aip->ai_flags[AI::AI_Flags::Kamikaze]) && static_randf((Missiontime + static_rand(aip->shipnum)) >> 19) < aip->ai_glide_strafe_percent) {
|
||||
ai_big_save_previous_mode(aip);
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->mode = AIM_STRAFE;
|
||||
aip->submode_parm0 = Missiontime; // use parm0 as time strafe mode entered (i.e. MODE start time)
|
||||
aip->submode = AIS_STRAFE_GLIDE_ATTACK;
|
||||
@@ -1019,7 +1008,7 @@ static void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy)
|
||||
// switch ai ship into chase mode
|
||||
void ai_big_switch_to_chase_mode(ai_info *aip)
|
||||
{
|
||||
ai_big_save_previous_mode(aip);
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->mode = AIM_CHASE;
|
||||
aip->submode = SM_ATTACK;
|
||||
aip->submode_start_time = Missiontime;
|
||||
@@ -1119,7 +1108,7 @@ void ai_big_chase()
|
||||
} else if (En_objp->flags[Object::Object_Flags::Protected]) { // If protected and we're not attacking a subsystem, stop attacking!
|
||||
update_aspect_lock_information(aip, &vec_to_enemy, dist_to_enemy - En_objp->radius, En_objp->radius);
|
||||
aip->target_objnum = -1;
|
||||
if (find_enemy(OBJ_INDEX(Pl_objp), MAX_ENEMY_DISTANCE, The_mission.ai_profile->max_attackers[Game_skill_level], ai_targets_for_pursuit(aip)) == -1) {
|
||||
if (find_enemy(OBJ_INDEX(Pl_objp), MAX_ENEMY_DISTANCE, The_mission.ai_profile->max_attackers[Game_skill_level]) == -1) {
|
||||
ai_do_default_behavior(Pl_objp);
|
||||
return;
|
||||
}
|
||||
@@ -1979,25 +1968,26 @@ int ai_big_maybe_enter_strafe_mode(const object *pl_objp, int weapon_objnum)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ai_declines_pursuit(pl_objp, parent_objp)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Maybe the ship which fired the weapon isn't the current target
|
||||
if ( OBJ_INDEX(parent_objp) != aip->target_objnum ) {
|
||||
|
||||
//JAS IMPOSSIBLE if (1) { // consider_target_only ) {
|
||||
//JAS IMPOSSIBLE return 0;
|
||||
//JAS IMPOSSIBLE } else {
|
||||
// switch targets
|
||||
sip = &Ship_info[Ships[parent_objp->instance].ship_info_index];
|
||||
if ( !(sip->is_big_or_huge()) || (sip->flags[Ship::Info_Flags::Transport]) ) {
|
||||
return 0;
|
||||
}
|
||||
set_target_objnum(aip, OBJ_INDEX(parent_objp));
|
||||
//JAS IMPOSSIBLE }
|
||||
}
|
||||
|
||||
ai_big_strafe_maybe_attack_turret(pl_objp, weapon_objp);
|
||||
|
||||
// if we've got this far, the weapon must have come from the player's target, and it is a
|
||||
// big/capital ship... so enter strafe mode
|
||||
ai_big_save_previous_mode(aip);
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->mode = AIM_STRAFE;
|
||||
aip->submode_parm0 = Missiontime; // use parm0 as time strafe mode entered (i.e. MODE start time)
|
||||
aip->submode = AIS_STRAFE_AVOID;
|
||||
|
||||
+42
-136
@@ -2215,35 +2215,16 @@ static bool ai_class_type_actively_pursues(int attacker_class_type, int target_c
|
||||
return std::any_of(pursues.begin(), pursues.end(), [target_class_type](int pursued_type) { return pursued_type == target_class_type; });
|
||||
}
|
||||
|
||||
// Returns true if a target this ship picks for itself will be used for pursuit, and therefore applicable to the "actively_pursues" check.
|
||||
// In other modes a ship's target is held for its turrets, and is also read by other ships (guard reactions, attacker counts).
|
||||
bool ai_targets_for_pursuit(const ai_info *aip)
|
||||
{
|
||||
return aip->mode == AIM_CHASE || aip->mode == AIM_STRAFE;
|
||||
}
|
||||
|
||||
// Returns true if attacker_objp should not pick target_objp as a target to pursue.
|
||||
bool ai_declines_pursuit(const object *attacker_objp, const object *target_objp)
|
||||
{
|
||||
Assertion(attacker_objp->type == OBJ_SHIP, "ai_declines_pursuit() was called with an attacker of object type %d; it must be a ship!", attacker_objp->type);
|
||||
|
||||
if (!The_mission.ai_profile->flags[AI::Profile_Flags::Fix_ai_target_recovery] || target_objp->type != OBJ_SHIP)
|
||||
return false;
|
||||
|
||||
return !ai_class_type_actively_pursues(Ship_info[Ships[attacker_objp->instance].ship_info_index].class_type,
|
||||
Ship_info[Ships[target_objp->instance].ship_info_index].class_type);
|
||||
}
|
||||
|
||||
typedef struct eval_nearest_objnum {
|
||||
int objnum;
|
||||
object *trial_objp;
|
||||
int enemy_team_mask;
|
||||
int enemy_ship_info_index;
|
||||
int enemy_class_type;
|
||||
int attacker_class_type;
|
||||
int enemy_wing;
|
||||
float range;
|
||||
int max_attackers;
|
||||
bool for_pursuit;
|
||||
int nearest_objnum;
|
||||
float nearest_dist;
|
||||
int check_danger_weapon_objnum;
|
||||
@@ -2299,10 +2280,11 @@ void evaluate_object_as_nearest_objnum(eval_nearest_objnum *eno)
|
||||
float dist;
|
||||
int num_attacking;
|
||||
|
||||
// If pursuing, don't pick a target that this ship's type refuses to pursue, or it will park in AIM_NONE holding a target it never attacks.
|
||||
// Don't pick a target that this ship's type refuses to chase, or it will park in AIM_NONE holding a target it never attacks.
|
||||
// Only for unconstrained searches: an explicit chase-ship-class/type order should still produce a target even if ai_chase() doesn't chase it.
|
||||
if (eno->for_pursuit && eno->enemy_ship_info_index < 0 && eno->enemy_class_type < 0
|
||||
&& ai_declines_pursuit(&Objects[eno->objnum], eno->trial_objp))
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_ai_target_recovery]
|
||||
&& eno->enemy_ship_info_index < 0 && eno->enemy_class_type < 0
|
||||
&& !ai_class_type_actively_pursues(eno->attacker_class_type, Ship_info[shipp->ship_info_index].class_type))
|
||||
return;
|
||||
|
||||
// Allow targeting of stealth in nebula by his firing at me
|
||||
@@ -2370,11 +2352,10 @@ void evaluate_object_as_nearest_objnum(eval_nearest_objnum *eno)
|
||||
* @param enemy_wing Enemy wing chosen
|
||||
* @param range Ship must be within range "range".
|
||||
* @param max_attackers Don't attack a ship that already has at least max_attackers attacking it.
|
||||
* @param for_pursuit True if the ship will chase the enemy found; false if the target is only held (e.g. for turrets)
|
||||
* @param ship_info_index If >=0, the enemy object must be of the specified ship class
|
||||
* @param class_type If >=0, the enemy object must be of the specified ship type
|
||||
*/
|
||||
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers, bool for_pursuit, int ship_info_index, int class_type)
|
||||
int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float range, int max_attackers, int ship_info_index, int class_type)
|
||||
{
|
||||
object *danger_weapon_objp;
|
||||
ai_info *aip;
|
||||
@@ -2385,9 +2366,9 @@ int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float ra
|
||||
eno.enemy_team_mask = enemy_team_mask;
|
||||
eno.enemy_ship_info_index = ship_info_index;
|
||||
eno.enemy_class_type = class_type;
|
||||
eno.attacker_class_type = Ship_info[Ships[Objects[objnum].instance].ship_info_index].class_type;
|
||||
eno.enemy_wing = enemy_wing;
|
||||
eno.max_attackers = max_attackers;
|
||||
eno.for_pursuit = for_pursuit;
|
||||
eno.objnum = objnum;
|
||||
eno.range = range;
|
||||
eno.nearest_dist = range;
|
||||
@@ -2428,17 +2409,10 @@ int get_nearest_objnum(int objnum, int enemy_team_mask, int enemy_wing, float ra
|
||||
}
|
||||
}
|
||||
|
||||
// If no wing member can be pursued, hold one anyway rather than leave the wing, as an explicit order to attack an unpursued ship does
|
||||
if ((eno.nearest_objnum == -1) && (enemy_wing != -1) && for_pursuit && The_mission.ai_profile->flags[AI::Profile_Flags::Fix_ai_target_recovery]) {
|
||||
int held_objnum = get_nearest_objnum(objnum, enemy_team_mask, enemy_wing, range, max_attackers, false, ship_info_index, class_type);
|
||||
if (held_objnum >= 0 && Objects[held_objnum].type == OBJ_SHIP && Ships[Objects[held_objnum].instance].wingnum == enemy_wing)
|
||||
return held_objnum;
|
||||
}
|
||||
|
||||
// If only looking for target in certain wing and couldn't find anything in
|
||||
// that wing, look for any object.
|
||||
if ((eno.nearest_objnum == -1) && (enemy_wing != -1)) {
|
||||
return get_nearest_objnum(objnum, enemy_team_mask, -1, range, max_attackers, for_pursuit, ship_info_index, class_type);
|
||||
return get_nearest_objnum(objnum, enemy_team_mask, -1, range, max_attackers, ship_info_index, class_type);
|
||||
}
|
||||
|
||||
return eno.nearest_objnum;
|
||||
@@ -2545,11 +2519,10 @@ int get_enemy_timestamp()
|
||||
* @param objnum Object number
|
||||
* @param range Range within which to look
|
||||
* @param max_attackers Don't attack a ship that already has at least max_attackers attacking it.
|
||||
* @param for_pursuit True if the ship will chase the enemy found; false if the target is only held (e.g. for turrets)
|
||||
* @param ship_info_index If specified, restrict the search to enemies with this ship class
|
||||
* @param class_type If specified, restrict the search to enemies with this ship type
|
||||
*/
|
||||
int find_enemy(int objnum, float range, int max_attackers, bool for_pursuit, int ship_info_index, int class_type)
|
||||
int find_enemy(int objnum, float range, int max_attackers, int ship_info_index, int class_type)
|
||||
{
|
||||
int enemy_team_mask;
|
||||
|
||||
@@ -2579,7 +2552,10 @@ int find_enemy(int objnum, float range, int max_attackers, bool for_pursuit, int
|
||||
if (class_type < 0 || class_type == Ship_info[target_shipp->ship_info_index].class_type) {
|
||||
if (!(target_objp->flags[Object::Object_Flags::Protected])) {
|
||||
// same as get_nearest_objnum: only skip an unpursued target for unconstrained searches
|
||||
if (!for_pursuit || ship_info_index >= 0 || class_type >= 0 || !ai_declines_pursuit(objp, target_objp)) {
|
||||
if (!The_mission.ai_profile->flags[AI::Profile_Flags::Fix_ai_target_recovery]
|
||||
|| ship_info_index >= 0 || class_type >= 0
|
||||
|| ai_class_type_actively_pursues(Ship_info[shipp->ship_info_index].class_type,
|
||||
Ship_info[target_shipp->ship_info_index].class_type)) {
|
||||
return target_objnum;
|
||||
}
|
||||
}
|
||||
@@ -2592,7 +2568,7 @@ int find_enemy(int objnum, float range, int max_attackers, bool for_pursuit, int
|
||||
}
|
||||
}
|
||||
|
||||
return get_nearest_objnum(objnum, enemy_team_mask, aip->enemy_wing, range, max_attackers, for_pursuit, ship_info_index, class_type);
|
||||
return get_nearest_objnum(objnum, enemy_team_mask, aip->enemy_wing, range, max_attackers, ship_info_index, class_type);
|
||||
} else {
|
||||
aip->target_objnum = -1;
|
||||
aip->target_signature = -1;
|
||||
@@ -2666,7 +2642,7 @@ void ai_attack_object(object* attacker, object* attacked, int ship_info_index, i
|
||||
if (attacked == nullptr) {
|
||||
aip->choose_enemy_timestamp = timestamp(0);
|
||||
// nebula safe
|
||||
set_target_objnum(aip, find_enemy(OBJ_INDEX(attacker), 99999.9f, 4, true, ship_info_index, class_type));
|
||||
set_target_objnum(aip, find_enemy(OBJ_INDEX(attacker), 99999.9f, 4, ship_info_index, class_type));
|
||||
} else {
|
||||
// check if we can see attacked in nebula
|
||||
if (aip->target_objnum != OBJ_INDEX(attacked)) {
|
||||
@@ -2727,24 +2703,10 @@ void ai_attack_wing(object *attacker, int wingnum)
|
||||
if (count > 0) {
|
||||
int index;
|
||||
|
||||
// prefer wing members we will pursue; if there are none, hold any member, as an explicit order to attack an unpursued ship does
|
||||
SCP_vector<int> pursued_indexes;
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_ai_target_recovery]) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto member_shipp = &Ships[Wings[wingnum].ship_index[i]];
|
||||
if (!member_shipp->flags[Ship::Ship_Flags::Dying] && !ai_declines_pursuit(attacker, &Objects[member_shipp->objnum]))
|
||||
pursued_indexes.push_back(i);
|
||||
}
|
||||
}
|
||||
index = (int) (frand() * count);
|
||||
|
||||
if (!pursued_indexes.empty()) {
|
||||
index = pursued_indexes[Random::next(sz2i(pursued_indexes.size()))];
|
||||
} else {
|
||||
index = (int) (frand() * count);
|
||||
|
||||
if (index >= count)
|
||||
index = 0;
|
||||
}
|
||||
if (index >= count)
|
||||
index = 0;
|
||||
|
||||
set_target_objnum(aip, Ships[Wings[wingnum].ship_index[index]].objnum);
|
||||
|
||||
@@ -3164,7 +3126,6 @@ void create_model_path(object *pl_objp, object *mobjp, int path_num, int subsys_
|
||||
aip->path_dir = PD_FORWARD;
|
||||
aip->path_objnum = OBJ_INDEX(mobjp);
|
||||
aip->mp_index = path_num;
|
||||
aip->mp_randomized_vert = subsys_path ? mp->nverts-2 : -1;
|
||||
aip->path_length = (int)(Ppfp - ppfp_start);
|
||||
aip->path_next_check_time = timestamp(1);
|
||||
|
||||
@@ -3224,7 +3185,6 @@ void create_model_exit_path(object *pl_objp, object *mobjp, int path_num, int co
|
||||
aip->path_dir = PD_FORWARD;
|
||||
aip->path_objnum = OBJ_INDEX(mobjp);
|
||||
aip->mp_index = path_num;
|
||||
aip->mp_randomized_vert = -1;
|
||||
aip->path_length = (int)(Ppfp - ppfp_start);
|
||||
aip->path_next_check_time = timestamp(1);
|
||||
|
||||
@@ -3920,14 +3880,14 @@ void ai_afterburn_hard(object* objp, ai_info* aip) {
|
||||
accelerate_ship(aip, 1.0f);
|
||||
};
|
||||
|
||||
// Given an ai_info struct, by reading global path information,
|
||||
// extract model path information and return in pmp and pmpv.
|
||||
// Given an ai_info struct, by reading current goal and path information,
|
||||
// extract base path information and return in pmp and pmpv.
|
||||
// Return true if found, else return false.
|
||||
// false means the current point is not on the original path.
|
||||
int get_base_path_info(int path_cur, int path_objnum, model_path **pmp, mp_vert **pmpv)
|
||||
int get_base_path_info(int path_cur, int goal_objnum, model_path **pmp, mp_vert **pmpv)
|
||||
{
|
||||
pnode *pn = &Path_points[path_cur];
|
||||
ship *shipp = &Ships[Objects[path_objnum].instance];
|
||||
ship *shipp = &Ships[Objects[goal_objnum].instance];
|
||||
polymodel *pm = model_get(Ship_info[shipp->ship_info_index].model_num);
|
||||
|
||||
*pmpv = NULL;
|
||||
@@ -3972,14 +3932,7 @@ void modify_model_path_points(object *objp)
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
// an exit path may have been created with fewer than nverts points, so don't write past its end
|
||||
int count = aip->path_length - static_cast<int>(pnp - &Path_points[aip->path_start]);
|
||||
|
||||
int randomize_pnt = -1;
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_model_path_refresh_randomization])
|
||||
randomize_pnt = aip->mp_randomized_vert;
|
||||
|
||||
copy_xlate_model_path_points(mobjp, &pm->paths[path_num], dir, count, path_num, pnp, randomize_pnt);
|
||||
copy_xlate_model_path_points(mobjp, &pm->paths[path_num], dir, pm->paths[path_num].nverts, path_num, pnp);
|
||||
}
|
||||
|
||||
// Return an indication of the distance between two matrices.
|
||||
@@ -4082,18 +4035,12 @@ void set_accel_for_docking(object *objp, ai_info *aip, float dot, float dot_to_n
|
||||
ai_afterburn_hard(Pl_objp, aip);
|
||||
} else {
|
||||
float max_bay_speed = sip->max_speed;
|
||||
bool fix_bay_speed_ramp = The_mission.ai_profile->flags[AI::Profile_Flags::Fix_bay_speed_ramp];
|
||||
ship_info *gsip = &Ship_info[Ships[gobjp->instance].ship_info_index];
|
||||
polymodel *pm = model_get(gsip->model_num);
|
||||
|
||||
// a departure path can begin with points that route the ship around the carrier, ahead of the bay path itself
|
||||
int ramp_start = aip->path_start;
|
||||
if (aip->mode == AIM_BAY_DEPART && fix_bay_speed_ramp)
|
||||
ramp_start = MAX(aip->path_start, aip->path_start + aip->path_length - pm->paths[aip->mp_index].nverts);
|
||||
|
||||
// Maybe gradually ramp up/down the speed of a ship flying a fighterbay path
|
||||
if (aip->mode == AIM_BAY_EMERGE || (aip->mode == AIM_BAY_DEPART && aip->path_cur > ramp_start)) {
|
||||
SCP_string pathName(pm->paths[aip->mp_index].name);
|
||||
if (aip->mode == AIM_BAY_EMERGE || (aip->mode == AIM_BAY_DEPART && aip->path_cur != aip->path_start)) {
|
||||
ship_info *gsip = &Ship_info[Ships[gobjp->instance].ship_info_index];
|
||||
polymodel *pm = model_get(gsip->model_num);
|
||||
SCP_string pathName(pm->paths[Path_points[aip->path_start].path_num].name);
|
||||
float speed_mult = FLT_MIN;
|
||||
|
||||
if (aip->mode == AIM_BAY_EMERGE) { // Arriving
|
||||
@@ -4117,7 +4064,7 @@ void set_accel_for_docking(object *objp, ai_info *aip, float dot, float dot_to_n
|
||||
if (speed_mult != FLT_MIN && speed_mult != 1.0f) {
|
||||
// We use the distance between the first and last point on the path here; it's not accurate
|
||||
// if the path is not straight, but should be good enough usually; can be changed if necessary.
|
||||
float total_path_length = vm_vec_dist_quick(&Path_points[ramp_start].pos, &Path_points[aip->path_start + aip->path_length - 1].pos);
|
||||
float total_path_length = vm_vec_dist_quick(&Path_points[aip->path_start].pos, &Path_points[aip->path_start + aip->path_length - 1].pos);
|
||||
float dist_to_end;
|
||||
|
||||
if (aip->mode == AIM_BAY_EMERGE) { // Arriving
|
||||
@@ -4126,12 +4073,8 @@ void set_accel_for_docking(object *objp, ai_info *aip, float dot, float dot_to_n
|
||||
dist_to_end = vm_vec_dist_quick(&Pl_objp->pos, &Path_points[aip->path_start + aip->path_length - 1].pos);
|
||||
}
|
||||
|
||||
float ramp_fraction = dist_to_end / total_path_length;
|
||||
if (fix_bay_speed_ramp)
|
||||
CLAMP(ramp_fraction, 0.0f, 1.0f);
|
||||
|
||||
// Calculate max speed, but respect the waypoint speed cap if it's lower
|
||||
max_bay_speed = sip->max_speed * (speed_mult + (1.0f - speed_mult) * ramp_fraction);
|
||||
max_bay_speed = sip->max_speed * (speed_mult + (1.0f - speed_mult) * (dist_to_end / total_path_length));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5223,8 +5166,6 @@ int maybe_resume_previous_mode(object *objp, ai_info *aip)
|
||||
aip->submode = AIS_GUARD_PATROL;
|
||||
aip->submode_start_time = Missiontime;
|
||||
aip->active_goal = AI_ACTIVE_GOAL_NONE;
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_stale_ai_order_state])
|
||||
set_targeted_subsys(aip, nullptr, -1); // also discards any subsystem path from attacking a big ship
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -8390,7 +8331,6 @@ void ai_set_guard_wing(object *objp, int wingnum)
|
||||
// prevents a ship from trying to guard a non-existent wing.
|
||||
if (Wings[wingnum].current_count < 1) {
|
||||
aip->guard_objnum = -1;
|
||||
aip->guard_signature = -1;
|
||||
aip->guard_wingnum = -1;
|
||||
aip->mode = AIM_NONE;
|
||||
} else {
|
||||
@@ -9089,6 +9029,15 @@ void ai_chase()
|
||||
|
||||
//WMC - Guess we do need this
|
||||
if (!go_after_it) {
|
||||
// If we picked this target ourselves -- through auto-attack, dynamic chase, or a standing chase order --
|
||||
// drop it, so that the retargeting logic in ai_frame() can find something we are willing to chase.
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_ai_target_recovery]) {
|
||||
if (aip->active_goal < 0 || aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC
|
||||
|| (aip->active_goal < MAX_AI_GOALS && ai_goal_is_standing_chase(aip->goals[aip->active_goal].ai_mode))) {
|
||||
aip->target_objnum = -1;
|
||||
aip->target_signature = -1;
|
||||
}
|
||||
}
|
||||
aip->mode = AIM_NONE;
|
||||
return;
|
||||
}
|
||||
@@ -10487,10 +10436,6 @@ void guard_object_was_hit(object *guard_objp, object *hitter_objp)
|
||||
if (Ships[guard_objp->instance].team == Ships[hitter_objp->instance].team)
|
||||
return;
|
||||
|
||||
// Keep guarding rather than chase a ship we won't pursue
|
||||
if (ai_declines_pursuit(guard_objp, hitter_objp))
|
||||
return;
|
||||
|
||||
// limit the number of ships attacking hitter_objnum (for now, only if hitter_objnum is player)
|
||||
if ( ai_maybe_limit_attackers(hitter_objnum) == 1 ) {
|
||||
return;
|
||||
@@ -15532,7 +15477,7 @@ void ai_frame(int objnum)
|
||||
} else if (aip->resume_goal_time == -1) {
|
||||
// AL 12-9-97: Don't allow cargo and navbuoys to set their aip->target_objnum
|
||||
if ( Ship_info[shipp->ship_info_index].class_type > -1 && (Ship_types[Ship_info[shipp->ship_info_index].class_type].flags[Ship::Type_Info_Flags::AI_auto_attacks]) ) {
|
||||
target_objnum = find_enemy(objnum, MAX_ENEMY_DISTANCE, The_mission.ai_profile->max_attackers[Game_skill_level], ai_targets_for_pursuit(aip)); // Attack up to 2.5K units away.
|
||||
target_objnum = find_enemy(objnum, MAX_ENEMY_DISTANCE, The_mission.ai_profile->max_attackers[Game_skill_level]); // Attack up to 2.5K units away.
|
||||
if (target_objnum != -1) {
|
||||
if (aip->target_objnum != target_objnum)
|
||||
aip->aspect_locked_time = 0.0f;
|
||||
@@ -15616,7 +15561,7 @@ void ai_frame(int objnum)
|
||||
if ((aip->resume_goal_time > 0) && (aip->resume_goal_time < Missiontime)) {
|
||||
aip->active_goal = AI_ACTIVE_GOAL_NONE;
|
||||
aip->resume_goal_time = -1;
|
||||
target_objnum = find_enemy(objnum, 2000.0f, The_mission.ai_profile->max_attackers[Game_skill_level], ai_targets_for_pursuit(aip));
|
||||
target_objnum = find_enemy(objnum, 2000.0f, The_mission.ai_profile->max_attackers[Game_skill_level]);
|
||||
if (target_objnum != -1) {
|
||||
if (aip->target_objnum != target_objnum) {
|
||||
aip->aspect_locked_time = 0.0f;
|
||||
@@ -15936,7 +15881,6 @@ void init_ai_object(int objnum)
|
||||
aip->path_start = -1;
|
||||
aip->path_goal_dist = -1;
|
||||
aip->path_length = 0;
|
||||
aip->mp_randomized_vert = -1;
|
||||
aip->path_subsystem_next_check = 1;
|
||||
|
||||
aip->support_ship_objnum = -1;
|
||||
@@ -16095,29 +16039,6 @@ void init_aip_from_class_and_profile(ai_info *aip, ai_class *aicp, ai_profile_t
|
||||
aip->ai_profile_flags = profile->flags | (aicp->ai_profile_flags & aicp->ai_profile_flags_set);
|
||||
}
|
||||
|
||||
// Clear the fields that remember which order set them up or which order a dynamic goal interrupted.
|
||||
// Call when a new order takes over; the order's own setup repopulates whatever it needs.
|
||||
void ai_reset_order_state(ai_info *aip)
|
||||
{
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_stale_ai_order_state]
|
||||
|| The_mission.ai_profile->flags[AI::Profile_Flags::Fix_ai_target_recovery])
|
||||
aip->enemy_wing = -1;
|
||||
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_stale_ai_order_state])
|
||||
{
|
||||
aip->guard_objnum = -1;
|
||||
aip->guard_signature = -1;
|
||||
aip->guard_wingnum = -1;
|
||||
aip->previous_mode = AIM_NONE;
|
||||
aip->previous_submode = 0;
|
||||
aip->resume_goal_time = -1;
|
||||
|
||||
// the player's targeted subsystem is HUD state, not order state
|
||||
if (aip != Player_ai || Player_use_ai)
|
||||
set_targeted_subsys(aip, nullptr, -1); // also discards any subsystem path
|
||||
}
|
||||
}
|
||||
|
||||
void ai_do_default_behavior(object *obj)
|
||||
{
|
||||
Assertion(obj != nullptr, "Ai_do_default_behavior() was given a bad information. Specifically obj is a nullptr. This is a coder error, please report!");
|
||||
@@ -16131,7 +16052,6 @@ void ai_do_default_behavior(object *obj)
|
||||
aip->mode = AIM_NONE;
|
||||
aip->submode_start_time = Missiontime;
|
||||
aip->active_goal = AI_ACTIVE_GOAL_NONE;
|
||||
ai_reset_order_state(aip);
|
||||
|
||||
// if we're not docked, we may modify the behavior a bit
|
||||
if (!object_is_docked(obj))
|
||||
@@ -16139,7 +16059,7 @@ void ai_do_default_behavior(object *obj)
|
||||
// fighters automatically chase things
|
||||
if (!is_instructor(obj) && (sip->is_fighter_bomber()))
|
||||
{
|
||||
int enemy_objnum = find_enemy(OBJ_INDEX(obj), 1000.0f, The_mission.ai_profile->max_attackers[Game_skill_level], true);
|
||||
int enemy_objnum = find_enemy(OBJ_INDEX(obj), 1000.0f, The_mission.ai_profile->max_attackers[Game_skill_level]);
|
||||
set_target_objnum(aip, enemy_objnum);
|
||||
aip->mode = AIM_CHASE;
|
||||
aip->submode = SM_ATTACK;
|
||||
@@ -16361,29 +16281,15 @@ void maybe_set_dynamic_chase(ai_info *aip, int hitter_objnum)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ai_declines_pursuit(&Objects[Ships[aip->shipnum].objnum], &Objects[hitter_objnum])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aip->target_objnum != hitter_objnum)
|
||||
aip->aspect_locked_time = 0.0f;
|
||||
set_target_objnum(aip, hitter_objnum);
|
||||
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_stale_ai_order_state]) {
|
||||
// don't bash the mode we're returning to if this is a dynamic goal interrupting another one
|
||||
if (aip->active_goal != AI_ACTIVE_GOAL_DYNAMIC) {
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->previous_submode = aip->submode;
|
||||
}
|
||||
} else {
|
||||
aip->previous_submode = aip->mode; // retail typo, almost certainly meant to be previous_mode
|
||||
}
|
||||
|
||||
aip->resume_goal_time = Missiontime + i2f(20); // Only chase up to 20 seconds.
|
||||
aip->active_goal = AI_ACTIVE_GOAL_DYNAMIC;
|
||||
|
||||
set_targeted_subsys(aip, NULL, -1); // Say not attacking any particular subsystem.
|
||||
|
||||
aip->previous_submode = aip->mode;
|
||||
aip->mode = AIM_CHASE;
|
||||
aip->submode = SM_ATTACK;
|
||||
aip->submode_start_time = Missiontime;
|
||||
|
||||
+1
-16
@@ -1803,20 +1803,6 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
auto target_ship_entry = aigp->target_name == nullptr ? nullptr : ship_registry_get(aigp->target_name);
|
||||
|
||||
// a ship can't guard itself, and the leader of a wing is the ship the rest of the wing guards
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_stale_ai_order_state])
|
||||
{
|
||||
if (aigp->ai_mode == AI_GOAL_GUARD && target_ship_entry && target_ship_entry->has_shipp() && target_ship_entry->shipp() == shipp)
|
||||
return ai_achievability::NOT_ACHIEVABLE;
|
||||
|
||||
if (aigp->ai_mode == AI_GOAL_GUARD_WING)
|
||||
{
|
||||
int wingnum = wing_name_lookup(aigp->target_name);
|
||||
if (wingnum >= 0 && Wings[wingnum].ship_index[0] == objp->instance)
|
||||
return ai_achievability::NOT_ACHIEVABLE;
|
||||
}
|
||||
}
|
||||
|
||||
// warp (depart) only achievable if there's somewhere to depart to
|
||||
if (aigp->ai_mode == AI_GOAL_WARP)
|
||||
{
|
||||
@@ -2549,9 +2535,8 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
if ( !(Player_use_ai) && (objp->flags[Object::Object_Flags::Player_ship]) && (current_goal->ai_mode != AI_GOAL_FORM_ON_WING) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ai_reset_order_state(aip);
|
||||
|
||||
std::unique_ptr<ai_goal> current_goal_backup;
|
||||
auto current_goal_target_ship = current_goal->target_name ? ship_registry_get(current_goal->target_name) : nullptr;
|
||||
|
||||
@@ -1693,7 +1693,7 @@ static void asteroid_do_area_effect(object *asteroid_objp)
|
||||
if ( weapon_area_calc_damage(ship_objp, &asteroid_objp->pos, asip->inner_rad, asip->outer_rad, asip->blast, asip->damage, &blast, &damage, asip->outer_rad) == -1 )
|
||||
continue;
|
||||
|
||||
ship_apply_global_damage(ship_objp, asteroid_objp, &asteroid_objp->pos, damage, asip->damage_type_idx, DamageSource::Explosion);
|
||||
ship_apply_global_damage(ship_objp, asteroid_objp, &asteroid_objp->pos, damage, asip->damage_type_idx);
|
||||
weapon_area_apply_blast(nullptr, ship_objp, &asteroid_objp->pos, blast, false);
|
||||
} // end for
|
||||
}
|
||||
|
||||
@@ -1036,13 +1036,6 @@ void bm_init() {
|
||||
bm_inited = true;
|
||||
}
|
||||
|
||||
bool bm_is_cubemap(int handle)
|
||||
{
|
||||
const BM_TYPE type = bm_get_entry(handle)->comp_type;
|
||||
return type == BM_TYPE_CUBEMAP_DDS || type == BM_TYPE_CUBEMAP_DXT1 || type == BM_TYPE_CUBEMAP_DXT3 ||
|
||||
type == BM_TYPE_CUBEMAP_DXT5;
|
||||
}
|
||||
|
||||
int bm_is_compressed(int num) {
|
||||
auto entry = bm_get_entry(num);
|
||||
BM_TYPE type = BM_TYPE_NONE;
|
||||
|
||||
@@ -594,14 +594,6 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
|
||||
*/
|
||||
int bm_is_compressed(int handle);
|
||||
|
||||
/**
|
||||
* @brief Returns true if the bitmap indexed by handle was loaded from a cubemap image file
|
||||
*
|
||||
* @note Render targets return false, even cubemap ones, and so do BC7 (DX10) DDS cubemaps, whose cube flag the DDS
|
||||
* loader does not keep
|
||||
*/
|
||||
bool bm_is_cubemap(int handle);
|
||||
|
||||
/**
|
||||
* @brief Gets the correct TCACHE_TYPE for compressed graphics (uncompressed are assumed TCACHE_TYPE_NORMAL)
|
||||
*/
|
||||
|
||||
+15
-90
@@ -33,7 +33,7 @@
|
||||
#include "parse/encrypt.h"
|
||||
#include "cfilesystem.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <limits>
|
||||
|
||||
char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN] = "";
|
||||
@@ -185,12 +185,7 @@ int cfile_init(const char *exe_dir, const char *cdrom_dir)
|
||||
|
||||
char buf[CFILE_ROOT_DIRECTORY_LEN];
|
||||
|
||||
#ifndef __ANDROID__
|
||||
strncpy(buf, exe_dir, CFILE_ROOT_DIRECTORY_LEN - 1);
|
||||
#else
|
||||
(void)exe_dir;
|
||||
strncpy(buf, os_android_get_working_folder_path().c_str(), CFILE_ROOT_DIRECTORY_LEN - 1);
|
||||
#endif
|
||||
strncpy(buf, exe_dir, CFILE_ROOT_DIRECTORY_LEN - 1);
|
||||
|
||||
buf[CFILE_ROOT_DIRECTORY_LEN - 1] = '\0';
|
||||
|
||||
@@ -1110,98 +1105,28 @@ void cfread_string(char *buf, int n, CFILE *file)
|
||||
} while (c != 0 );
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct string_len_header {
|
||||
int len = 0;
|
||||
int stored = 0;
|
||||
int start = 0;
|
||||
bool length_cut = false;
|
||||
};
|
||||
|
||||
// a past-the-end length is clamped like any cfread, but a negative one has nothing to clamp to, so inside a
|
||||
// limited section it throws and the loader skips the rest of the section
|
||||
string_len_header read_string_len_header(CFILE* file)
|
||||
void cfread_string_len(char *buf, int buffer_size, CFILE *file)
|
||||
{
|
||||
string_len_header h;
|
||||
if (!cf_is_valid(file)) {
|
||||
return h;
|
||||
int len;
|
||||
len = cfread_int(file);
|
||||
Assertion( (len <= buffer_size), "String cannot fit in buffer, len: %i, buffer: %i", len, buffer_size);
|
||||
if (len) {
|
||||
cfread(buf, len, 1, file);
|
||||
Assertion(len != buffer_size || buf[len - 1] == 0, "Unterminated string does not fit in buffer");
|
||||
}
|
||||
int before = cftell(file);
|
||||
h.length_cut = cfread(&h.len, sizeof(h.len), 1, file) != 1;
|
||||
h.start = cftell(file);
|
||||
if (h.length_cut) {
|
||||
// a clean end of file reads as an empty string without a warning, as cfread_int does
|
||||
h.length_cut = (h.start != before) || (cfeof(file) == 0);
|
||||
return h;
|
||||
}
|
||||
h.len = INTEL_INT(h.len);
|
||||
if ((h.len < 0) && (file->max_read_len != 0)) {
|
||||
throw cfile::max_read_length("Attempted to read a string of negative length " + std::to_string(h.len));
|
||||
}
|
||||
h.stored = static_cast<int>(cf_check_read_size(file, static_cast<size_t>(std::max(h.len, 0))));
|
||||
return h;
|
||||
}
|
||||
|
||||
// reads count of the stored characters and leaves the file just past the whole string; false if the read failed
|
||||
bool read_string_len_body(const string_len_header& h, char* dest, int count, CFILE* file)
|
||||
{
|
||||
bool ok = (count <= 0) || (cfread(dest, count, 1, file) == 1);
|
||||
if (!ok || (h.stored > count)) {
|
||||
cfseek(file, h.start + h.stored, CF_SEEK_SET);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// warned last, so the file position is right even if a debug build stops here
|
||||
void warn_string_len(const string_len_header& h, bool read_ok, bool cut, int buffer_size, CFILE* file)
|
||||
{
|
||||
if (h.length_cut) {
|
||||
Warning(LOCATION, "cfread_string_len: cut-off string length field in %s", cf_get_filename(file));
|
||||
} else if (!read_ok) {
|
||||
Warning(LOCATION,
|
||||
"cfread_string_len: could not read a string of %d characters in %s",
|
||||
h.stored,
|
||||
cf_get_filename(file));
|
||||
} else if (h.len != h.stored) {
|
||||
Warning(LOCATION, "cfread_string_len: corrupt string length %d in %s", h.len, cf_get_filename(file));
|
||||
} else if (cut) {
|
||||
Warning(LOCATION,
|
||||
"cfread_string_len: a string of %d bytes was cut to fit a buffer of %d in %s",
|
||||
h.len,
|
||||
buffer_size,
|
||||
cf_get_filename(file));
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void cfread_string_len(char* buf, int buffer_size, CFILE* file)
|
||||
{
|
||||
Assertion(buffer_size > 0, "cfread_string_len needs room for at least the terminator, buffer: %i", buffer_size);
|
||||
string_len_header h = read_string_len_header(file);
|
||||
if (buffer_size <= 0) {
|
||||
bool read_ok = read_string_len_body(h, buf, 0, file);
|
||||
warn_string_len(h, read_ok, h.stored > 0, buffer_size, file);
|
||||
return;
|
||||
}
|
||||
int count = std::min(h.stored, buffer_size);
|
||||
bool read_ok = read_string_len_body(h, buf, count, file);
|
||||
int kept = read_ok ? count : 0;
|
||||
bool cut = (kept == buffer_size) && (memchr(buf, 0, buffer_size) == nullptr);
|
||||
buf[std::min(kept, buffer_size - 1)] = 0;
|
||||
warn_string_len(h, read_ok, cut, buffer_size, file);
|
||||
buf[MIN(len, buffer_size - 1)] = 0;
|
||||
}
|
||||
|
||||
SCP_string cfread_string_len(CFILE *file)
|
||||
{
|
||||
string_len_header h = read_string_len_header(file);
|
||||
int len = cfread_int(file);
|
||||
|
||||
SCP_string str;
|
||||
str.resize(h.stored);
|
||||
bool read_ok = read_string_len_body(h, str.data(), h.stored, file);
|
||||
if (!read_ok) {
|
||||
str.clear();
|
||||
}
|
||||
warn_string_len(h, read_ok, false, 0, file);
|
||||
str.resize(len);
|
||||
|
||||
if (len)
|
||||
cfread(&str[0], len, 1, file);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
+2
-8
@@ -320,26 +320,20 @@ void cfread_string(char *buf,int n, CFILE *file);
|
||||
/**
|
||||
* @brief Read a fixed length string that is not null-terminated, with the length stored in file.
|
||||
*
|
||||
* Keeps at most buffer_size - 1 characters and leaves the file just past the whole string, unless it throws.
|
||||
*
|
||||
* If it is not null-terminated, the length of the string *must* be less than the size of the buffer (to make room for one)
|
||||
*
|
||||
* @param buf Pre-allocated array to store string
|
||||
* @param buffer_size Size of pre-allocated array
|
||||
* @param file File to read from
|
||||
*
|
||||
* @note Appends NULL character to string (buf)
|
||||
* @note Bad data gets a warning; at a clean end of file, or with an invalid file, the string is empty and nothing is
|
||||
* warned. Inside a limited section (cf_set_max_read_len), a negative length, or a read that still passes the limit
|
||||
* once clamped to the end of the file, throws cfile::max_read_length.
|
||||
*/
|
||||
void cfread_string_len(char *buf,int buffer_size, CFILE *file);
|
||||
|
||||
/**
|
||||
* @brief Read a string from the file where the length is stored in the file
|
||||
*
|
||||
* @param file The file to read the string from
|
||||
* @return The string that was read
|
||||
*
|
||||
* @note Warns and throws like the char* overload, except that nothing is cut.
|
||||
*/
|
||||
SCP_string cfread_string_len(CFILE *file);
|
||||
|
||||
|
||||
+14
-24
@@ -193,8 +193,21 @@ int cfseek( CFILE *cfile, int offset, int where )
|
||||
}
|
||||
|
||||
|
||||
size_t cf_check_read_size(CFILE* cfile, size_t size)
|
||||
// cfread() reads from a file
|
||||
//
|
||||
// returns: returns the number of full elements read
|
||||
//
|
||||
//
|
||||
int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
{
|
||||
if(!cf_is_valid(cfile))
|
||||
return 0;
|
||||
|
||||
size_t size = elsize*nelem;
|
||||
|
||||
if(buf == NULL || size <= 0)
|
||||
return 0;
|
||||
|
||||
if ( (cfile->raw_position+size) > cfile->size ) {
|
||||
Assertion(cfile->raw_position <= cfile->size, "Invalid raw_position value detected!");
|
||||
size = cfile->size - cfile->raw_position;
|
||||
@@ -213,29 +226,6 @@ size_t cf_check_read_size(CFILE* cfile, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
// cfread() reads from a file
|
||||
//
|
||||
// returns: returns the number of full elements read
|
||||
//
|
||||
//
|
||||
int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
|
||||
{
|
||||
if(!cf_is_valid(cfile))
|
||||
return 0;
|
||||
|
||||
size_t size = elsize*nelem;
|
||||
|
||||
if(buf == nullptr || size <= 0)
|
||||
return 0;
|
||||
|
||||
size = cf_check_read_size(cfile, size);
|
||||
if (size < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t bytes_read;
|
||||
if (cfile->data != nullptr) {
|
||||
// This is a file from memory
|
||||
|
||||
@@ -62,9 +62,4 @@ void cf_check_compression(CFILE* cfile);
|
||||
// Used to clear compression info data and free dynamic memory used by compression
|
||||
void cf_clear_compression_info(CFILE* cfile);
|
||||
|
||||
// Clamps a read of size bytes to the end of the file and returns the clamped size, or 0 at the end of the file
|
||||
// without checking the limit; throws cfile::max_read_length if the clamped read would pass the file's read limit
|
||||
// (cf_set_max_read_len).
|
||||
size_t cf_check_read_size(CFILE* cfile, size_t size);
|
||||
|
||||
#endif
|
||||
+50
-85
@@ -75,7 +75,6 @@ const char *cmdline_arg_types[] =
|
||||
enum class flag_output_type {
|
||||
Binary,
|
||||
Json_V1,
|
||||
Json_V2,
|
||||
};
|
||||
|
||||
// variables
|
||||
@@ -556,12 +555,7 @@ int Cmdline_show_pos = 0;
|
||||
int Cmdline_show_stats = 0;
|
||||
int Cmdline_save_render_targets = 0;
|
||||
bool Cmdline_window = false;
|
||||
#ifdef __ANDROID__
|
||||
// Default to borderless in the legacy window-mode path as well.
|
||||
bool Cmdline_fullscreen_window = true;
|
||||
#else
|
||||
bool Cmdline_fullscreen_window = false;
|
||||
#endif
|
||||
std::optional<std::pair<uint16_t, uint16_t>>Cmdline_window_res = std::nullopt;
|
||||
char *Cmdline_res = 0;
|
||||
char *Cmdline_center_res = 0;
|
||||
@@ -1364,58 +1358,51 @@ static void handle_unix_modlist(char **modlist, size_t *len)
|
||||
|
||||
// external entry point into this modules
|
||||
|
||||
static void json_add_version(json_t* root) {
|
||||
auto version_obj = json_object();
|
||||
|
||||
json_object_set_new(version_obj, "full", json_string(FS_VERSION_FULL));
|
||||
json_object_set_new(version_obj, "major", json_integer(FS_VERSION_MAJOR));
|
||||
json_object_set_new(version_obj, "minor", json_integer(FS_VERSION_MINOR));
|
||||
json_object_set_new(version_obj, "build", json_integer(FS_VERSION_BUILD));
|
||||
|
||||
json_object_set_new(version_obj, "has_revision", json_boolean(FS_VERSION_HAS_REVIS));
|
||||
json_object_set_new(version_obj, "revision", json_integer(FS_VERSION_REVIS));
|
||||
json_object_set_new(version_obj, "revision_str", json_string(FS_VERSION_REVIS_STR));
|
||||
|
||||
json_object_set_new(root, "version", version_obj);
|
||||
}
|
||||
|
||||
static void json_add_easy_flags(json_t* root) {
|
||||
auto easy_array = json_array();
|
||||
|
||||
for (auto& easy_flag : easy_flags) {
|
||||
json_array_append_new(easy_array, json_string(easy_flag.name));
|
||||
}
|
||||
|
||||
json_object_set_new(root, "easy_flags", easy_array);
|
||||
}
|
||||
|
||||
static void json_add_flags(json_t* root) {
|
||||
auto flags_array = json_array();
|
||||
|
||||
for (auto& flag : exe_params) {
|
||||
auto flag_obj = json_object();
|
||||
|
||||
json_object_set_new(flag_obj, "name", json_string(flag.name));
|
||||
json_object_set_new(flag_obj, "description", json_string(flag.desc));
|
||||
json_object_set_new(flag_obj, "fso_only", json_boolean(flag.fso_only));
|
||||
json_object_set_new(flag_obj, "on_flags", json_integer(flag.on_flags));
|
||||
json_object_set_new(flag_obj, "off_flags", json_integer(flag.off_flags));
|
||||
json_object_set_new(flag_obj, "type", json_string(flag.type));
|
||||
json_object_set_new(flag_obj, "web_url", json_string(flag.web_url));
|
||||
|
||||
json_array_append_new(flags_array, flag_obj);
|
||||
}
|
||||
|
||||
json_object_set_new(root, "flags", flags_array);
|
||||
}
|
||||
|
||||
static json_t* json_get_v1() {
|
||||
auto root = json_object();
|
||||
|
||||
json_add_version(root);
|
||||
json_add_easy_flags(root);
|
||||
json_add_flags(root);
|
||||
{
|
||||
auto version_obj = json_object();
|
||||
|
||||
json_object_set_new(version_obj, "full", json_string(FS_VERSION_FULL));
|
||||
json_object_set_new(version_obj, "major", json_integer(FS_VERSION_MAJOR));
|
||||
json_object_set_new(version_obj, "minor", json_integer(FS_VERSION_MINOR));
|
||||
json_object_set_new(version_obj, "build", json_integer(FS_VERSION_BUILD));
|
||||
|
||||
json_object_set_new(version_obj, "has_revision", json_boolean(FS_VERSION_HAS_REVIS));
|
||||
json_object_set_new(version_obj, "revision", json_integer(FS_VERSION_REVIS));
|
||||
json_object_set_new(version_obj, "revision_str", json_string(FS_VERSION_REVIS_STR));
|
||||
|
||||
json_object_set_new(root, "version", version_obj);
|
||||
}
|
||||
{
|
||||
auto easy_array = json_array();
|
||||
|
||||
for (auto& easy_flag : easy_flags) {
|
||||
json_array_append_new(easy_array, json_string(easy_flag.name));
|
||||
}
|
||||
|
||||
json_object_set_new(root, "easy_flags", easy_array);
|
||||
}
|
||||
{
|
||||
auto flags_array = json_array();
|
||||
|
||||
for (auto& flag : exe_params) {
|
||||
auto flag_obj = json_object();
|
||||
|
||||
json_object_set_new(flag_obj, "name", json_string(flag.name));
|
||||
json_object_set_new(flag_obj, "description", json_string(flag.desc));
|
||||
json_object_set_new(flag_obj, "fso_only", json_boolean(flag.fso_only));
|
||||
json_object_set_new(flag_obj, "on_flags", json_integer(flag.on_flags));
|
||||
json_object_set_new(flag_obj, "off_flags", json_integer(flag.off_flags));
|
||||
json_object_set_new(flag_obj, "type", json_string(flag.type));
|
||||
json_object_set_new(flag_obj, "web_url", json_string(flag.web_url));
|
||||
|
||||
json_array_append_new(flags_array, flag_obj);
|
||||
}
|
||||
|
||||
json_object_set_new(root, "flags", flags_array);
|
||||
}
|
||||
{
|
||||
auto caps_array = json_array();
|
||||
|
||||
@@ -1526,19 +1513,6 @@ static json_t* json_get_v1() {
|
||||
return root;
|
||||
}
|
||||
|
||||
// json_v2 reports version, supported flags, and the preferences path for launchers,
|
||||
// without querying graphics, audio, or joystick devices.
|
||||
static json_t* json_get_v2() {
|
||||
auto root = json_object();
|
||||
|
||||
json_add_version(root);
|
||||
json_add_easy_flags(root);
|
||||
json_add_flags(root);
|
||||
json_object_set_new(root, "pref_path", json_string(os_get_config_path().c_str()));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static void write_flags_file() {
|
||||
FILE *fp = fopen("flags.lch","w");
|
||||
|
||||
@@ -1596,8 +1570,6 @@ static flag_output_type get_flags_output_type() {
|
||||
return flag_output_type::Binary;
|
||||
} else if (type == "json_v1") {
|
||||
return flag_output_type::Json_V1;
|
||||
} else if (type == "json_v2") {
|
||||
return flag_output_type::Json_V2;
|
||||
} else {
|
||||
// This is supposed to make it easy for the launcher to recognize an unsupported type
|
||||
printf("OUTPUT TYPE NOT SUPPORTED!\n");
|
||||
@@ -1608,23 +1580,17 @@ static flag_output_type get_flags_output_type() {
|
||||
|
||||
static void write_flags() {
|
||||
auto type = get_flags_output_type();
|
||||
|
||||
if (type == flag_output_type::Binary) {
|
||||
switch(type) {
|
||||
case flag_output_type::Binary:
|
||||
write_flags_file();
|
||||
return;
|
||||
break;
|
||||
case flag_output_type::Json_V1:
|
||||
json_t* root = json_get_v1();
|
||||
|
||||
json_dumpf(root, stdout, JSON_INDENT(4));
|
||||
json_decref(root);
|
||||
break;
|
||||
}
|
||||
|
||||
json_t* root = (type == flag_output_type::Json_V1) ? json_get_v1() : json_get_v2();
|
||||
|
||||
#ifdef __ANDROID__
|
||||
char* dumped = json_dumps(root, JSON_INDENT(4));
|
||||
os_android_set_flags_string(dumped ? dumped : "");
|
||||
free(dumped);
|
||||
#else
|
||||
json_dumpf(root, stdout, JSON_INDENT(4));
|
||||
#endif
|
||||
|
||||
json_decref(root);
|
||||
}
|
||||
|
||||
bool SetCmdlineParams()
|
||||
@@ -1821,7 +1787,6 @@ bool SetCmdlineParams()
|
||||
options::OptionsManager::instance()->setOverride("Graphics.WindowMode",
|
||||
std::unique_ptr<json_t>(json_integer(static_cast<int>(os::ViewportState::Windowed))), "-window");
|
||||
Cmdline_window = true;
|
||||
Cmdline_fullscreen_window = false;
|
||||
}
|
||||
|
||||
if ( fullscreen_window_arg.found( ) )
|
||||
|
||||
@@ -1322,7 +1322,7 @@ bool control_config_accept(bool API_Access)
|
||||
|
||||
// Check if a hardcoded preset with name already exists. If so, complain to user and force retry
|
||||
auto it = std::find_if(Control_config_presets.begin(), Control_config_presets.end(), [str](CC_preset& p) {
|
||||
return ((p.name == str) && ((p.get_type() == Preset_t::tbl) || (p.get_type() == Preset_t::hardcode)));
|
||||
return ((p.name == str) && ((p.type == Preset_t::tbl) || (p.type == Preset_t::hardcode)));
|
||||
});
|
||||
|
||||
if (it != Control_config_presets.end()) {
|
||||
@@ -1353,14 +1353,15 @@ bool control_config_accept(bool API_Access)
|
||||
}
|
||||
|
||||
// Pack the current bindings into a preset, then save the file
|
||||
CC_preset preset(std::move(str), Preset_t::pst);
|
||||
CC_preset preset;
|
||||
preset.name = std::move(str);
|
||||
std::copy(Control_config.begin(), Control_config.end(), std::back_inserter(preset.bindings));
|
||||
Control_config_presets.push_back(preset);
|
||||
save_preset_file(preset, true);
|
||||
|
||||
// Reload the presets from file. Do this instead of just pushing the preset to the vector direct to get
|
||||
// consistant ordering
|
||||
Control_config_presets.erase(Control_config_presets.begin() + 1, Control_config_presets.end());
|
||||
Control_config_presets.resize(1);
|
||||
load_preset_files();
|
||||
|
||||
// finally, save the new preset so that changes will get saved to this preset
|
||||
@@ -1777,7 +1778,7 @@ bool control_config_create_new_preset(const SCP_string& newName, bool overwrite)
|
||||
|
||||
// Check if a hardcoded preset with name already exists. If so, complain to user and force retry
|
||||
auto it = std::find_if(Control_config_presets.begin(), Control_config_presets.end(), [newName](CC_preset& p) {
|
||||
return (p.name == newName) && ((p.get_type() == Preset_t::tbl) || (p.get_type() == Preset_t::hardcode));
|
||||
return (p.name == newName) && ((p.type == Preset_t::tbl) || (p.type == Preset_t::hardcode));
|
||||
});
|
||||
|
||||
if (it != Control_config_presets.end()) {
|
||||
@@ -1790,7 +1791,9 @@ bool control_config_create_new_preset(const SCP_string& newName, bool overwrite)
|
||||
}
|
||||
|
||||
// Pack the current bindings into a preset, then save the file
|
||||
CC_preset preset(newName, Preset_t::pst);
|
||||
CC_preset preset;
|
||||
preset.name = newName;
|
||||
preset.type = Preset_t::pst;
|
||||
std::copy(Control_config.begin(), Control_config.end(), std::back_inserter(preset.bindings));
|
||||
|
||||
// Done with the file
|
||||
@@ -1802,7 +1805,7 @@ bool control_config_create_new_preset(const SCP_string& newName, bool overwrite)
|
||||
save_preset_file(preset, true);
|
||||
|
||||
// Reload the presets from file.
|
||||
Control_config_presets.erase(Control_config_presets.begin() + 1, Control_config_presets.end());
|
||||
Control_config_presets.resize(1);
|
||||
load_preset_files(newName);
|
||||
|
||||
// use the newly created preset
|
||||
@@ -1810,9 +1813,10 @@ bool control_config_create_new_preset(const SCP_string& newName, bool overwrite)
|
||||
|
||||
return true;
|
||||
|
||||
} else if ((clone->name != preset.name) || (clone->get_type() != Preset_t::pst)) {
|
||||
} else if ((clone->name != preset.name) || (clone->type != Preset_t::pst)) {
|
||||
// Complain and ignore if the preset names or the type differs
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return false; //should be unreachable, but just in case
|
||||
@@ -1822,7 +1826,7 @@ bool control_config_clone_preset(const CC_preset& preset, const SCP_string& newN
|
||||
|
||||
// Check if a hardcoded preset with name already exists. If so, complain to user and force retry
|
||||
auto it = std::find_if(Control_config_presets.begin(), Control_config_presets.end(), [newName](CC_preset& p) {
|
||||
return (p.name == newName) && ((p.get_type() == Preset_t::tbl) || (p.get_type() == Preset_t::hardcode));
|
||||
return (p.name == newName) && ((p.type == Preset_t::tbl) || (p.type == Preset_t::hardcode));
|
||||
});
|
||||
|
||||
if (it != Control_config_presets.end()) {
|
||||
@@ -1834,13 +1838,13 @@ bool control_config_clone_preset(const CC_preset& preset, const SCP_string& newN
|
||||
return false;
|
||||
}
|
||||
|
||||
CC_preset newPreset(newName, Preset_t::pst);
|
||||
newPreset.bindings = preset.bindings;
|
||||
CC_preset newPreset = preset;
|
||||
newPreset.name = newName;
|
||||
|
||||
bool success = save_preset_file(newPreset, false);
|
||||
|
||||
// Reload the presets from file.
|
||||
Control_config_presets.erase(Control_config_presets.begin() + 1, Control_config_presets.end());
|
||||
Control_config_presets.resize(1);
|
||||
load_preset_files(newName);
|
||||
|
||||
// use the newly cloned preset
|
||||
|
||||
@@ -572,28 +572,20 @@ public:
|
||||
* A preset, a collection of bindings for use in Control_config with an associated name
|
||||
*/
|
||||
class CC_preset {
|
||||
public:
|
||||
public:
|
||||
SCP_vector<CCB> bindings;
|
||||
SCP_string name;
|
||||
Preset_t type = Preset_t::hardcode;
|
||||
|
||||
private:
|
||||
// No default value: the type is always set explicitly by the constructor
|
||||
Preset_t type;
|
||||
public:
|
||||
CC_preset() = default;
|
||||
CC_preset(const CC_preset& A) = default;
|
||||
|
||||
public:
|
||||
// No default constructor: every preset must be created with an explicit type
|
||||
CC_preset(SCP_string preset_name, Preset_t preset_type) : name(std::move(preset_name)), type(preset_type) {}
|
||||
CC_preset(const CC_preset&) = default;
|
||||
|
||||
// Preserve target's preset type during copy assignment
|
||||
CC_preset& operator=(const CC_preset& other);
|
||||
|
||||
Preset_t get_type() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
bool is_duplicate_of(const CC_preset& other) const;
|
||||
CC_preset& operator=(const CC_preset&);
|
||||
/*!
|
||||
* Checks if the given preset is a duplicate of this one
|
||||
*/
|
||||
bool is_duplicate_of(CC_preset&);
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
@@ -292,8 +292,10 @@ void control_config_common_init_bindings() {
|
||||
// init default preset
|
||||
Control_config_presets.clear();
|
||||
|
||||
CC_preset preset("default", Preset_t::hardcode);
|
||||
CC_preset preset;
|
||||
preset.bindings.reserve(Control_config.size());
|
||||
preset.name = "default";
|
||||
preset.type = Preset_t::hardcode;
|
||||
|
||||
for (auto &item : Control_config) {
|
||||
preset.bindings.push_back(CCB(item));
|
||||
@@ -1731,13 +1733,14 @@ size_t read_bind_1(CC_preset &preset) {
|
||||
*/
|
||||
void control_config_common_read_section(int s, bool first_override) {
|
||||
Assertion((s == 0) || (s == 1), "Expected value of s to be either 0 or 1, found %i instead.", s);
|
||||
CC_preset new_preset("", Preset_t::tbl);
|
||||
CC_preset new_preset;
|
||||
|
||||
// Set references to the default preset and bindings
|
||||
auto& default_preset = Control_config_presets[0];
|
||||
auto& default_bindings = default_preset.bindings;
|
||||
|
||||
new_preset.bindings.clear();
|
||||
new_preset.type = Preset_t::tbl;
|
||||
|
||||
if (s == 0) {
|
||||
// #ControlConfigOverride
|
||||
@@ -2999,22 +3002,23 @@ CCI_builder& CCI_builder::operator()(IoActionId action_id, short primary, short
|
||||
return *this;
|
||||
}
|
||||
|
||||
CC_preset& CC_preset::operator=(const CC_preset& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
bindings = other.bindings;
|
||||
name = other.name;
|
||||
// 'type' is intentionally preserved to maintain instance identity
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
CC_preset& CC_preset::operator=(const CC_preset& A) {
|
||||
name = A.name;
|
||||
type = A.type;
|
||||
|
||||
bool CC_preset::is_duplicate_of(const CC_preset& other) const
|
||||
{
|
||||
for (size_t i = 0; i < other.bindings.size(); ++i) {
|
||||
if (bindings[i] != other.bindings[i]) {
|
||||
std::copy(A.bindings.begin(), A.bindings.end(), bindings.begin());
|
||||
|
||||
return *this;
|
||||
};
|
||||
|
||||
bool CC_preset::is_duplicate_of(CC_preset& A) {
|
||||
for (size_t i = 0; i < A.bindings.size(); ++i) {
|
||||
if (bindings[i] != A.bindings[i]) {
|
||||
// Found a binding that's different. Thus, this preset is not a duplicate
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Else, did not find any differences in the bindings. Thus, this preset is a duplicate
|
||||
return true;
|
||||
}
|
||||
@@ -74,7 +74,9 @@ void load_preset_files(SCP_string clone) {
|
||||
|
||||
|
||||
// Start reading in data
|
||||
CC_preset preset(file, Preset_t::pst);
|
||||
CC_preset preset;
|
||||
preset.name = file;
|
||||
preset.type = Preset_t::pst;
|
||||
preset.bindings.resize(Control_config.size());
|
||||
|
||||
size_t size;
|
||||
@@ -132,7 +134,7 @@ void load_preset_files(SCP_string clone) {
|
||||
if ((clone == preset.name) || (it == Control_config_presets.end())) {
|
||||
Control_config_presets.push_back(preset);
|
||||
|
||||
} else if ((it->name != preset.name) || ((it->get_type() != Preset_t::pst))) {
|
||||
} else if ((it->name != preset.name) || (it->type != Preset_t::pst)) {
|
||||
if (gameseq_get_state() == GS_STATE_CONTROL_CONFIG) {
|
||||
popup(PF_TITLE_WHITE | PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Preset '%s' is a duplicate of an existing preset, ignoring", preset.name.c_str());
|
||||
} else {
|
||||
@@ -171,7 +173,7 @@ bool delete_preset_file(CC_preset preset) {
|
||||
cf_delete(filename.c_str(), CF_TYPE_PLAYER_BINDS, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
|
||||
|
||||
// Reload the presets from file.
|
||||
Control_config_presets.erase(Control_config_presets.begin() + 1, Control_config_presets.end());
|
||||
Control_config_presets.resize(1);
|
||||
load_preset_files();
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2DArray;
|
||||
#endif
|
||||
|
||||
#include "gamma.sdr"
|
||||
|
||||
layout(location=0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout (location = 0) in vec4 fragTexCoord;
|
||||
layout (location = 1) in vec4 fragColor;
|
||||
|
||||
layout (location = 0) out vec4 fragOut0;
|
||||
|
||||
layout (set = 1, binding = 1) uniform sampler2DArray baseMap;
|
||||
|
||||
layout (set = 2, binding = 0, std140) uniform genericData {
|
||||
@@ -21,6 +17,8 @@ layout (set = 2, binding = 0, std140) uniform genericData {
|
||||
in vec4 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2DArray baseMap;
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout (location = 0) in vec4 vertPosition;
|
||||
layout (location = 1) in vec4 vertColor;
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
layout(location=0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(set = 1, binding = 1) uniform sampler2D bloomed;
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
|
||||
out vec4 fragOut0;
|
||||
uniform sampler2D bloomed;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(set = 1, binding = 1) uniform sampler2D tex;
|
||||
#else
|
||||
out vec4 fragOut0;
|
||||
in vec4 fragTexCoord;
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(set = 1, binding = 1) uniform sampler2D tex;
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
const float Luminance = 0.08;
|
||||
const float fMiddleGray = 0.2;
|
||||
const float fWhiteCutoff = 0.4;
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
precision highp sampler2DArray;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(set = 1, binding = 1) uniform sampler2D tex;
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
#ifdef COPY_ARRAY
|
||||
uniform sampler2DArray tex;
|
||||
#else
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
precision highp sampler2DArray;
|
||||
#endif
|
||||
|
||||
// NOTE: The technique and some of this code is based on this tutorial:
|
||||
// http://martindevans.me/game-development/2015/02/27/Drawing-Stuff-On-Other-Stuff-With-Deferred-Screenspace-Decals/
|
||||
@@ -35,14 +29,9 @@ layout (set = 1, binding = 1) uniform sampler2DArray decalTextures;
|
||||
layout (set = 1, binding = 4) uniform sampler2D gDepthBuffer;
|
||||
layout (set = 1, binding = 6) uniform sampler2D gNormalBuffer;
|
||||
#else
|
||||
layout (location=0) out vec4 fragOut0; // Diffuse buffer
|
||||
#ifndef GL_ES
|
||||
layout (location=1) out vec4 fragOut1; // Normal buffer
|
||||
layout (location=2) out vec4 fragOut2; // Emissive buffer
|
||||
#else
|
||||
layout (location=2) out vec4 fragOut1; // Normal buffer -> COLOR_ATTACHMENT2
|
||||
layout (location=4) out vec4 fragOut2; // Emissive buffer -> COLOR_ATTACHMENT4
|
||||
#endif
|
||||
out vec4 fragOut0; // Diffuse buffer
|
||||
out vec4 fragOut1; // Normal buffer
|
||||
out vec4 fragOut2; // Emissive buffer
|
||||
|
||||
flat in mat4 invModelMatrix;
|
||||
flat in vec3 decalDirection;
|
||||
@@ -135,7 +124,7 @@ vec3 getPixelNormal(vec3 frag_position, vec2 tex_coord, inout float alpha, out v
|
||||
}
|
||||
|
||||
// Make a smooth alpha transition leading up to an edge
|
||||
alpha = alpha * (1.0 - smoothstep(angle_fade_start, normal_angle_cutoff, angle));
|
||||
alpha = alpha * (1 - smoothstep(angle_fade_start, normal_angle_cutoff, angle));
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
// Binding 0: box vertex positions
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
#extension GL_EXT_clip_cull_distance : enable
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2DArray;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(set = 2, binding = 0, std140)
|
||||
#else
|
||||
@@ -27,28 +20,22 @@ uniform genericData {
|
||||
uint clipEnabled;
|
||||
};
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler2DArray baseMap;
|
||||
|
||||
layout(location = 0) in vec4 fragTexCoord;
|
||||
layout(location = 1) in vec4 fragColor;
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
layout(location = 2) in float vClipDist;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#else
|
||||
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
in float vClipDist;
|
||||
#endif
|
||||
|
||||
uniform sampler2DArray baseMap;
|
||||
|
||||
in vec4 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
out vec4 fragOut0;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,11 +43,6 @@ in vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
if (clipEnabled != 0u && vClipDist < 0.0) {
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
vec4 baseColor = texture(baseMap, vec3(fragTexCoord.xy, float(baseMapIndex)));
|
||||
if(alphaThreshold > baseColor.a) discard;
|
||||
baseColor.rgb = (srgb == 1) ? srgb_to_linear(baseColor.rgb) : baseColor.rgb;
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
#extension GL_EXT_clip_cull_distance : enable
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(set = 2, binding = 0, std140)
|
||||
#else
|
||||
@@ -44,15 +38,10 @@ layout(location = 2) in vec4 vertTexCoord;
|
||||
|
||||
layout(location = 0) out vec4 fragTexCoord;
|
||||
layout(location = 1) out vec4 fragColor;
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
layout(location = 2) out float vClipDist;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
out float vClipDist;
|
||||
#endif
|
||||
out float gl_ClipDistance[1];
|
||||
|
||||
out vec4 fragTexCoord;
|
||||
in vec4 vertTexCoord;
|
||||
@@ -69,16 +58,13 @@ void main()
|
||||
gl_Position = projMatrix * modelViewMatrix * vertPosition;
|
||||
|
||||
if (clipEnabled != 0u) {
|
||||
#ifndef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
gl_ClipDistance[0] = dot(clipEquation, modelMatrix * vertPosition);
|
||||
#else
|
||||
vClipDist = dot(clipEquation, modelMatrix * vertPosition);
|
||||
#endif
|
||||
} else {
|
||||
#ifndef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
#ifdef VULKAN
|
||||
// Vulkan has no glEnable(GL_CLIP_DISTANCE0) equivalent — clip distances are
|
||||
// always evaluated when declared in the shader. Must write a positive value
|
||||
// when clipping is disabled to prevent undefined-value vertex culling.
|
||||
gl_ClipDistance[0] = 1.0;
|
||||
#else
|
||||
vClipDist = 1.0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,9 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
layout (location=0) out vec4 fragOut0;
|
||||
layout (location=1) out vec4 fragOut1;
|
||||
layout (location=2) out vec4 fragOut2;
|
||||
layout (location=3) out vec4 fragOut3;
|
||||
layout (location=4) out vec4 fragOut4;
|
||||
layout (location=5) out vec4 fragOut5;
|
||||
|
||||
out vec4 fragOut0;
|
||||
out vec4 fragOut1;
|
||||
out vec4 fragOut2;
|
||||
out vec4 fragOut3;
|
||||
out vec4 fragOut4;
|
||||
out vec4 fragOut5;
|
||||
void main()
|
||||
{
|
||||
fragOut0 = vec4(0.0, 0.0, 0.0, 1.0); // color
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
//? #version 150
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
precision highp samplerCube;
|
||||
precision highp sampler2DArrayShadow;
|
||||
#endif
|
||||
|
||||
#include "lighting.sdr" //! #include "lighting.sdr"
|
||||
#include "gamma.sdr" //! #include "gamma.sdr"
|
||||
#include "shadows.sdr" //! #include "shadows.sdr"
|
||||
#include "z-compress.sdr" //! #include "z-compress.sdr"
|
||||
|
||||
#ifndef GL_ES
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
#else
|
||||
layout(location = 5) out vec4 fragOut0; //COLOR_ATTACHMENTn is on location n in ES, here it uses COLOR_ATTACHMENT5
|
||||
out vec4 fragOut0;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
@@ -153,7 +145,7 @@ void GetLightInfo(vec3 position, in float alpha, in vec3 reflectDir, out vec3 li
|
||||
dist = length(lightDirOut);
|
||||
lightDist = dist;
|
||||
// Energy conservation term
|
||||
float alpha_adjust = clamp(alpha + (sourceRadius/(2.0*dist)), 0.0, 1.0);
|
||||
float alpha_adjust = clamp(alpha + (sourceRadius/(2*dist)), 0.0, 1.0);
|
||||
area_normalisation = alpha/alpha_adjust;
|
||||
area_normalisation *= area_normalisation;
|
||||
//end chunk
|
||||
@@ -196,7 +188,7 @@ void GetLightInfo(vec3 position, in float alpha, in vec3 reflectDir, out vec3 li
|
||||
float dist = length(lightDirOut);
|
||||
lightDist = dist;
|
||||
// Energy conservation term
|
||||
float alpha_adjust = min(alpha + (sourceRadius/(2.0*dist)), 1.0);
|
||||
float alpha_adjust = min(alpha + (sourceRadius/(2*dist)), 1.0);
|
||||
area_normalisation = alpha/alpha_adjust;
|
||||
// don't need to square as it's a line rather than a sphere.
|
||||
//end chunk
|
||||
@@ -243,11 +235,11 @@ void ComputeEnvLight(float alpha, float ao, vec3 light_dir, vec3 eyeDir, vec3 no
|
||||
// so let s = (2/alpha^2 - 2)
|
||||
// 1/2 log(s + 1) = 1/2 log(2/alpha^2 -1)
|
||||
|
||||
const float ENV_REZ = 512.0; // Ideally this would be #define'd and shader recompiled with envmap rez changes
|
||||
const float REZ_BIAS = log2(ENV_REZ * sqrt(3.0));
|
||||
const float ENV_REZ = 512; // Ideally this would be #define'd and shader recompiled with envmap rez changes
|
||||
const float REZ_BIAS = log2(ENV_REZ * sqrt(3));
|
||||
|
||||
float alphaSqr = alpha * alpha;
|
||||
float rough_bias = 0.5 * log2(2.0/alphaSqr - 1.0);
|
||||
float rough_bias = 0.5 * log2(2/alphaSqr - 1);
|
||||
float mip_bias = REZ_BIAS - rough_bias;
|
||||
|
||||
// Sample light, using mip bias to blur it.
|
||||
@@ -265,7 +257,7 @@ void ComputeEnvLight(float alpha, float ao, vec3 light_dir, vec3 eyeDir, vec3 no
|
||||
// Pseudo-IBL, so use k_IBL
|
||||
float k = alpha * alpha/ 2.0f;
|
||||
|
||||
float NdotL = max(dot(light_dir, normal),0.0);
|
||||
float NdotL = max(dot(light_dir, normal),0);
|
||||
|
||||
float g1vNL = GeometrySchlickGGX(NdotL, k);
|
||||
vec3 specEnvLighting = specEnvColour.rgb * fresnel * g1vNL;
|
||||
@@ -346,6 +338,6 @@ void main()
|
||||
float NdotL = clamp(dot(normal, lightDir), 0.0, 1.0);
|
||||
fragmentColor.rgb = computeLighting(specColor.rgb, diffColor, lightDir, normal.xyz, halfVec, eyeDir, roughness, fresnel, NdotL).rgb * diffuseLightColor * attenuation * area_normalisation;
|
||||
}
|
||||
|
||||
|
||||
fragOut0 = max(fragmentColor, vec4(0.0));
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
#endif
|
||||
|
||||
#include "lighting.sdr"
|
||||
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
precision highp sampler2DArray;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec4 fragTexCoord;
|
||||
layout(location = 1) in vec4 fragColor;
|
||||
layout(location = 2) in float fragOffset;
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler2DArray baseMap;
|
||||
layout(set = 1, binding = 4) uniform sampler2D depthMap;
|
||||
layout(set = 1, binding = 5) uniform sampler2D frameBuffer;
|
||||
@@ -20,6 +14,8 @@ in vec4 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
in float fragOffset;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2DArray baseMap;
|
||||
uniform sampler2D depthMap;
|
||||
uniform sampler2D distMap;
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec4 vertPosition;
|
||||
layout(location = 1) in vec4 vertColor;
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
precision highp sampler2DArray;
|
||||
#endif
|
||||
|
||||
#include "gamma.sdr"
|
||||
#include "z-compress.sdr"
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec4 fragTexCoord;
|
||||
layout(location = 1) in vec4 fragColor;
|
||||
layout(location = 2) in float fragRadius;
|
||||
layout(location = 3) in vec4 fragPosition;
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler2DArray baseMap;
|
||||
layout(set = 1, binding = 4) uniform sampler2D depthMap;
|
||||
#else
|
||||
@@ -24,6 +18,8 @@ in vec4 fragPosition;
|
||||
in vec4 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2DArray baseMap;
|
||||
uniform sampler2D depthMap;
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
layout (points) in;
|
||||
layout (triangle_strip, max_vertices = 4) out;
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec4 vertPosition;
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp samplerCube;
|
||||
#endif
|
||||
|
||||
uniform samplerCube envmap;
|
||||
|
||||
in vec4 fragTexCoord;
|
||||
|
||||
layout(location=0) out vec4 fragOut0;
|
||||
out vec4 fragOut0;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
const float theta = -fragTexCoord.x * (2.0 * M_PI);
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
#include "gamma.sdr"
|
||||
|
||||
layout(location=0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler2D tex;
|
||||
layout(set = 1, binding = 4) uniform sampler2D depth_tex;
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D depth_tex;
|
||||
#endif
|
||||
@@ -43,7 +40,7 @@ void main()
|
||||
// If the scene is in fog then we change the color we operate on based on the depth of the pixel
|
||||
float depth_val = texture(depth_tex, fragTexCoord.xy).x;
|
||||
// Transform depth value from [0, 1] to [-1, 1]
|
||||
float depth_normalized = 2.0 * depth_val - 1.0;
|
||||
float depth_normalized = 2 * depth_val - 1;
|
||||
// Now we compute the depth value in projection space using the clipping plane information
|
||||
float view_depth = 2.0 * zNear * zFar / (zFar + zNear - depth_normalized * (zFar - zNear));
|
||||
|
||||
@@ -53,7 +50,7 @@ void main()
|
||||
if (isinf(view_depth)) {
|
||||
fragOut0.rgb = color_in.rgb;
|
||||
} else {
|
||||
float fog_dist = clamp(1.0 - pow(fog_density, view_depth - fog_start) , 0.0, 1.0);
|
||||
float fog_dist = clamp(1 - pow(fog_density, view_depth - fog_start) , 0.0, 1.0);
|
||||
vec3 finalFogColor = srgb_to_linear(fog_color);
|
||||
|
||||
fragOut0.rgb = mix(color_in.rgb, finalFogColor, fog_dist);
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_EXT_gpu_shader5
|
||||
#extension GL_EXT_gpu_shader5 : enable
|
||||
#define FXAA_GATHER4_ALPHA 1
|
||||
#endif
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
#define FXAA_EARLY_EXIT 1
|
||||
#define FXAA_DISCARD 1
|
||||
#define FXAA_FAST_PIXEL_OFFSET 1 // With OpenGL 3.2 we can always do this
|
||||
@@ -509,12 +500,8 @@ layout(std140, set = 2, binding = 0) uniform genericData {
|
||||
#else
|
||||
uniform sampler2D tex0;
|
||||
in vec2 v_rcpFrame;
|
||||
#ifdef GL_ES
|
||||
in vec2 v_pos;
|
||||
#else
|
||||
noperspective in vec2 v_pos;
|
||||
#endif
|
||||
layout(location=0)out vec4 fragOut0;
|
||||
out vec4 fragOut0;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) out vec2 fragTexCoord;
|
||||
@@ -13,11 +10,7 @@ void main() {
|
||||
in vec4 vertPosition;
|
||||
|
||||
out vec2 v_rcpFrame;
|
||||
#ifdef GL_ES
|
||||
out vec2 v_pos;
|
||||
#else
|
||||
noperspective out vec2 v_pos;
|
||||
#endif
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
float rt_w;
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
layout(location=0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
// [0]=real color (passed through as-is), [1]=luma detection proxy (see
|
||||
// getAADetectionView; may be the same view as [0] when not HDR)
|
||||
layout(set = 1, binding = 1) uniform sampler2D fxaaTex[2];
|
||||
@@ -14,9 +8,9 @@ layout(set = 1, binding = 1) uniform sampler2D fxaaTex[2];
|
||||
#define lumaTex fxaaTex[1]
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec4 color = texture(tex, fragTexCoord.xy);
|
||||
#ifdef VULKAN
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
#include "gamma.sdr"
|
||||
|
||||
layout(location=0)out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(set = 1, binding = 1) uniform sampler2D tex;
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
const float SRGB_GAMMA = 2.2;
|
||||
const float SRGB_GAMMA_INVERSE = 1.0 / SRGB_GAMMA;
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
//!#version 150
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp samplerCube;
|
||||
#endif
|
||||
|
||||
#include "gamma.sdr"
|
||||
#include "gamma.sdr" //! #include "gamma.sdr"
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(set = 1, binding = 1) uniform samplerCube envmap;
|
||||
#else
|
||||
uniform samplerCube envmap;
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
@@ -160,8 +154,8 @@ vec3( 0.7305, 0.6698, 0.1333)
|
||||
);
|
||||
|
||||
void main() {
|
||||
float xpos = 2.0 * gl_FragCoord.x/16.0 - 1.0; // remap to (-1, 1)
|
||||
float ypos = 2.0 * gl_FragCoord.y/16.0 - 1.0;
|
||||
float xpos = 2 * gl_FragCoord.x/16 - 1; // remap to (-1, 1)
|
||||
float ypos = 2 * gl_FragCoord.y/16 - 1;
|
||||
vec3 fragDir;
|
||||
vec4 fragCol = vec4(0.0);
|
||||
|
||||
@@ -197,5 +191,5 @@ void main() {
|
||||
vec3 sampDir = points[i] + (aPdotD - PdotD) * fragDir;
|
||||
fragCol += aPdotD * vec4(srgb_to_linear(texture(envmap, sampDir)).rgb, 1.0);
|
||||
}
|
||||
fragOut0 = linear_to_srgb(PI * fragCol * (1.0/128.0));
|
||||
fragOut0 = linear_to_srgb(PI * fragCol * (1.0/128));
|
||||
}
|
||||
@@ -57,7 +57,7 @@ vec3 ComputeGGX(vec3 specColor, vec3 diffColor, vec3 light, vec3 normal, vec3 ha
|
||||
|
||||
|
||||
|
||||
vec3 specular = distribution * fresnel * geometry / (4.0*dotNV*dotNL + 0.0001);
|
||||
vec3 specular = distribution * fresnel * geometry / (4*dotNV*dotNL + 0.0001);
|
||||
|
||||
// Diffuse term - Lambertian, kD represents energy lost to specular reflection.
|
||||
vec3 kD = vec3(1.0)-fresnel;
|
||||
@@ -70,7 +70,7 @@ vec3 ComputeGGX(vec3 specColor, vec3 diffColor, vec3 light, vec3 normal, vec3 ha
|
||||
vec3 computeLighting(vec3 specColor, vec3 diffColor, vec3 light, vec3 normal, vec3 halfVec, vec3 view, float roughness, float fresnelFactor, float dotNL)
|
||||
{
|
||||
#ifdef FLAG_LIGHT_MODEL_BLINN_PHONG
|
||||
return SpecularBlinnPhong(specColor, light, normal, halfVec, 32.0, fresnelFactor, dotNL);
|
||||
return SpecularBlinnPhong(specColor, light, normal, halfVec, 32, fresnelFactor, dotNL);
|
||||
#else
|
||||
return ComputeGGX(specColor, diffColor, light, normal, halfVec, view, roughness, fresnelFactor, dotNL);
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler2D textures[16];
|
||||
#define scene textures[0]
|
||||
@@ -16,6 +9,8 @@ layout(set = 1, binding = 1) uniform sampler2D textures[16];
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D scene;
|
||||
uniform sampler2D cockpit;
|
||||
#endif
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
//? #version 150
|
||||
#ifdef GL_ES
|
||||
#extension GL_EXT_clip_cull_distance: enable
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
precision highp sampler2DArray;
|
||||
precision highp sampler2DArrayShadow;
|
||||
#endif
|
||||
|
||||
#include "shadows.sdr" //! #include "shadows.sdr"
|
||||
#include "lighting.sdr" //! #include "lighting.sdr"
|
||||
#include "gamma.sdr" //! #include "gamma.sdr"
|
||||
@@ -121,13 +112,6 @@ uniform shadowCascadeParams {
|
||||
vec4 smoothness_factors[(NUM_SHADOW_CASCADES + 4 - 1) / 4];
|
||||
};
|
||||
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(location = 1) out vec4 fragOut1;
|
||||
layout(location = 2) out vec4 fragOut2;
|
||||
layout(location = 3) out vec4 fragOut3;
|
||||
layout(location = 4) out vec4 fragOut4;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(set = 1, binding = 1) uniform sampler2DArray materialTextures[16];
|
||||
#define sBasemap materialTextures[0]
|
||||
@@ -155,12 +139,13 @@ layout(location = 0) in VertexOutput {
|
||||
vec4 shadowUV[NUM_SHADOW_CASCADES];
|
||||
vec4 shadowPos;
|
||||
#prereplace ENDIF_FLAG_COMPILED MODEL_SDR_FLAG_SHADOWS
|
||||
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
float vClipDist;
|
||||
#endif
|
||||
} vertIn;
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(location = 1) out vec4 fragOut1;
|
||||
layout(location = 2) out vec4 fragOut2;
|
||||
layout(location = 3) out vec4 fragOut3;
|
||||
layout(location = 4) out vec4 fragOut4;
|
||||
#else
|
||||
#prereplace IF_FLAG_COMPILED MODEL_SDR_FLAG_DIFFUSE
|
||||
uniform sampler2DArray sBasemap;
|
||||
@@ -200,10 +185,13 @@ in VertexOutput {
|
||||
vec4 shadowUV[NUM_SHADOW_CASCADES];
|
||||
vec4 shadowPos;
|
||||
#prereplace ENDIF_FLAG_COMPILED MODEL_SDR_FLAG_SHADOWS
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
float vClipDist;
|
||||
#endif
|
||||
} vertIn;
|
||||
|
||||
out vec4 fragOut0;
|
||||
out vec4 fragOut1;
|
||||
out vec4 fragOut2;
|
||||
out vec4 fragOut3;
|
||||
out vec4 fragOut4;
|
||||
#endif
|
||||
|
||||
vec3 FresnelLazarovEnv(vec3 specColor, vec3 view, vec3 normal, float gloss)
|
||||
@@ -295,10 +283,6 @@ vec3 CalculateLighting(vec3 normal, vec3 diffuseMaterial, vec3 specularMaterial,
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
if (vertIn.vClipDist < 0.0) discard;
|
||||
#endif
|
||||
|
||||
vec3 eyeDir = vec3(normalize(-vertIn.position).xyz);
|
||||
vec2 texCoord = vertIn.texCoord.xy;
|
||||
|
||||
@@ -480,7 +464,7 @@ void main()
|
||||
#prereplace ENDIF_FLAG //MODEL_SDR_FLAG_DIFFUSE
|
||||
// This code will only be used by the forward renderer so we apply the fog effect to both the emissive and the base
|
||||
// color.
|
||||
float fogDensityFinal = clamp(1.0 - pow(fogDensity, vertIn.fogDist) , 0.0, 1.0);
|
||||
float fogDensityFinal = clamp(1 - pow(fogDensity, vertIn.fogDist) , 0.0, 1.0);
|
||||
baseColor.rgb = mix(emissiveColor.rgb + baseColor.rgb, finalFogColor, fogDensityFinal);
|
||||
emissiveColor.rgb = vec3(0.0); // Zero the emissive color since it has already been added by the previous line
|
||||
specColor.rgb *= fogDensityFinal;
|
||||
@@ -525,12 +509,11 @@ void main()
|
||||
#prereplace IF_NOT_FLAG MODEL_SDR_FLAG_LIGHT
|
||||
#prereplace IF_FLAG MODEL_SDR_FLAG_SPEC
|
||||
baseColor.rgb += pow(1.0 - clamp(dot(eyeDir, normal), 0.0, 1.0), 5.0 * clamp(glossData, 0.01, 1.0)) * specColor.rgb;
|
||||
glossData = 0.0f;
|
||||
glossData = 0;
|
||||
#prereplace ENDIF_FLAG //MODEL_SDR_FLAG_SPEC
|
||||
// If there is no lighting then we copy the color data so far into the emissive.
|
||||
emissiveColor.rgb += baseColor.rgb;
|
||||
|
||||
aoFactors.x = 0.0f;
|
||||
aoFactors.x = 0;
|
||||
// and leave nothing for the light pass to add on top of it
|
||||
baseColor.rgb = vec3(0.0);
|
||||
specColor = vec4(0.0);
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
#ifdef GL_ES
|
||||
#extension GL_EXT_gpu_shader5: enable
|
||||
#extension GL_EXT_clip_cull_distance: enable
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
#else
|
||||
#extension GL_ARB_gpu_shader5: enable
|
||||
#endif
|
||||
|
||||
#conditional_include +"LARGE_SHADER" "main_large.sdr"
|
||||
#conditional_include -"LARGE_SHADER" "main_small.sdr"
|
||||
@@ -107,9 +100,6 @@ in VertexOutput {
|
||||
vec4 shadowUV[NUM_SHADOW_CASCADES];
|
||||
vec4 shadowPos;
|
||||
#prereplace ENDIF_FLAG_COMPILED MODEL_SDR_FLAG_SHADOWS
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
float vClipDist;
|
||||
#endif
|
||||
} vertIn[];
|
||||
|
||||
out VertexOutput {
|
||||
@@ -127,10 +117,6 @@ out VertexOutput {
|
||||
vec4 shadowUV[NUM_SHADOW_CASCADES];
|
||||
vec4 shadowPos;
|
||||
#prereplace ENDIF_FLAG_COMPILED MODEL_SDR_FLAG_SHADOWS
|
||||
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
float vClipDist;
|
||||
#endif
|
||||
} vertOut;
|
||||
|
||||
#ifdef MODEL_SDR_FLAG_THICK_OUTLINES
|
||||
@@ -180,19 +166,8 @@ out VertexOutput {
|
||||
#prereplace ENDIF_FLAG //MODEL_SDR_FLAG_SHADOWS
|
||||
|
||||
if (use_clip_plane != 0) {
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
vertOut.vClipDist = vertIn[vert].vClipDist;
|
||||
#else
|
||||
gl_ClipDistance[0] = gl_in[vert].gl_ClipDistance[0];
|
||||
#endif
|
||||
} else {
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
vertOut.vClipDist = 1.0;
|
||||
#else
|
||||
gl_ClipDistance[0] = 1.0;
|
||||
#endif
|
||||
gl_ClipDistance[0] = gl_in[vert].gl_ClipDistance[0];
|
||||
}
|
||||
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
|
||||
#ifndef VULKAN
|
||||
//? #version 150
|
||||
#ifdef GL_ES
|
||||
#extension GL_EXT_gpu_shader5: enable
|
||||
#extension GL_EXT_clip_cull_distance: enable
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp samplerBuffer;
|
||||
precision highp sampler2DArrayShadow;
|
||||
#else
|
||||
#extension GL_ARB_gpu_shader5: enable
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "shadows.sdr"
|
||||
|
||||
#conditional_include +"LARGE_SHADER" "main_large.sdr"
|
||||
@@ -155,10 +145,6 @@ layout(location = 0) out VertexOutput {
|
||||
vec4 shadowUV[NUM_SHADOW_CASCADES];
|
||||
vec4 shadowPos;
|
||||
#prereplace ENDIF_FLAG_COMPILED MODEL_SDR_FLAG_SHADOWS
|
||||
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
float vClipDist;
|
||||
#endif
|
||||
} vertOut;
|
||||
#else
|
||||
#prereplace IF_FLAG_COMPILED MODEL_SDR_FLAG_TRANSFORM
|
||||
@@ -180,10 +166,6 @@ out VertexOutput {
|
||||
vec4 shadowUV[NUM_SHADOW_CASCADES];
|
||||
vec4 shadowPos;
|
||||
#prereplace ENDIF_FLAG_COMPILED MODEL_SDR_FLAG_SHADOWS
|
||||
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
float vClipDist;
|
||||
#endif
|
||||
} vertOut;
|
||||
|
||||
#define TEXELS_PER_MATRIX 4
|
||||
@@ -265,20 +247,12 @@ void main()
|
||||
}
|
||||
#prereplace ENDIF_FLAG //MODEL_SDR_FLAG_TRANSFORM
|
||||
|
||||
#ifndef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
if (use_clip_plane != 0) {
|
||||
gl_ClipDistance[0] = dot(clip_equation, modelMatrix * orient * vertex);
|
||||
} else {
|
||||
gl_ClipDistance[0] = 1.0;
|
||||
}
|
||||
#else
|
||||
if (use_clip_plane != 0) {
|
||||
vertOut.vClipDist = dot(clip_equation, modelMatrix * orient * vertex);
|
||||
} else {
|
||||
vertOut.vClipDist = 1.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Clip plane
|
||||
if(use_clip_plane != 0) {
|
||||
gl_ClipDistance[0] = dot(clip_equation, modelMatrix * orient * vertex);
|
||||
} else {
|
||||
gl_ClipDistance[0] = 1.0;
|
||||
}
|
||||
|
||||
vertOut.position = position;
|
||||
vertOut.normal = normal;
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2DMS;
|
||||
#endif
|
||||
|
||||
#include "z-compress.sdr"
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(location = 1) out vec4 fragOut1;
|
||||
layout(location = 2) out vec4 fragOut2;
|
||||
layout(location = 3) out vec4 fragOut3;
|
||||
layout(location = 4) out vec4 fragOut4;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler2DMS msaaTex[6];
|
||||
#define texColor msaaTex[0]
|
||||
#define texPos msaaTex[1]
|
||||
@@ -29,7 +23,12 @@ layout(std140, set = 2, binding = 0) uniform genericData {
|
||||
};
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
layout(location=5)out vec4 fragOut5;
|
||||
out vec4 fragOut0;
|
||||
out vec4 fragOut1;
|
||||
out vec4 fragOut2;
|
||||
out vec4 fragOut3;
|
||||
out vec4 fragOut4;
|
||||
out vec4 fragOut5;
|
||||
|
||||
uniform sampler2DMS texColor;
|
||||
uniform sampler2DMS texPos;
|
||||
@@ -177,7 +176,7 @@ float getMedianDist(ivec2 texel) {
|
||||
|
||||
//Fallback, do front first
|
||||
float getMedianDist(ivec2 texel) {
|
||||
float minDist = -1000000.0;
|
||||
float minDist = -1000000;
|
||||
for(int i = 0; i < samples; i++) {
|
||||
minDist = max(minDist, uncompress_depth_value(texelFetch(texPos, texel, i).z));
|
||||
}
|
||||
@@ -191,7 +190,7 @@ float getMedianDist(ivec2 texel) {
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texSize = vec2(textureSize(texColor));
|
||||
vec2 texSize = textureSize(texColor);
|
||||
#ifdef VULKAN
|
||||
ivec2 texel = ivec2(texSize * fragTexCoord);
|
||||
#else
|
||||
@@ -207,7 +206,7 @@ void main()
|
||||
vec4 normal = vec4(0);
|
||||
vec4 specular = vec4(0);
|
||||
vec4 emissive = vec4(0);
|
||||
float depth = 0.0;
|
||||
float depth = 0;
|
||||
|
||||
for(int i = 0; i < SAMPLE_CNT; i++) {
|
||||
vec4 localPos = texelFetch(texPos, texel, i);
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2DArray;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout (location = 0) in vec2 ftcoord;
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout (location = 0) in vec4 vertPosition;
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
vec3 unpackNormal(vec2 normal_sample) {
|
||||
vec3 normal;
|
||||
normal.xy = normal_sample * 2.0 - 1.0;
|
||||
normal.z = sqrt(1.0 - normal_sample.x * normal_sample.x - normal_sample.y * normal_sample.y);
|
||||
normal.z = sqrt(1 - normal_sample.x * normal_sample.x - normal_sample.y * normal_sample.y);
|
||||
return normal;
|
||||
}
|
||||
@@ -1,14 +1,9 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
#include "gamma.sdr"
|
||||
|
||||
in vec4 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
layout(location=0) out vec4 fragOut0;
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D baseMap;
|
||||
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(set = 1, binding = 1) uniform sampler2D tex;
|
||||
layout(set = 1, binding = 4) uniform sampler2D depth_tex;
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D depth_tex;
|
||||
#endif
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2DArray;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 1) in vec4 fragColor;
|
||||
layout(location = 2) in vec2 fragScreenPosition;
|
||||
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler2DArray baseMap;
|
||||
#else
|
||||
@@ -19,6 +12,8 @@ in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
in vec2 fragScreenPosition;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2DArray baseMap;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 vertPosition;
|
||||
|
||||
@@ -1,24 +1,5 @@
|
||||
//? #version 150
|
||||
#ifdef GL_ES
|
||||
#extension GL_EXT_clip_cull_distance: enable
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in VertexOutput {
|
||||
float vClipDist;
|
||||
} vertIn;
|
||||
#else
|
||||
in VertexOutput {
|
||||
float vClipDist;
|
||||
} vertIn;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
if (vertIn.vClipDist < 0.0) discard;
|
||||
#endif
|
||||
}
|
||||
@@ -1,16 +1,9 @@
|
||||
//? #version 150
|
||||
#ifdef GL_ES
|
||||
#extension GL_EXT_gpu_shader5: enable
|
||||
#extension GL_EXT_clip_cull_distance: enable
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
#else
|
||||
#extension GL_ARB_gpu_shader5: enable
|
||||
#endif
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
#if defined(GL_ARB_gpu_shader5) || defined(GL_EXT_gpu_shader5)
|
||||
#ifdef GL_ARB_gpu_shader5
|
||||
layout(invocations = NUM_SHADOW_CASCADES) in;
|
||||
#endif
|
||||
|
||||
@@ -31,25 +24,16 @@ layout (std140) uniform shadowCascadeParams {
|
||||
};
|
||||
|
||||
in VertexOutput {
|
||||
#if !defined(GL_ARB_gpu_shader5) && !defined(GL_EXT_gpu_shader5)
|
||||
#if !defined(GL_ARB_gpu_shader5)
|
||||
float instance;
|
||||
#endif
|
||||
float clipModel;
|
||||
vec3 normal;
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
float vClipDist;
|
||||
#endif
|
||||
} vertIn[];
|
||||
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
out VertexOutput {
|
||||
float vClipDist;
|
||||
} vertOut;
|
||||
#endif
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#if defined(GL_ARB_gpu_shader5) || defined(GL_EXT_gpu_shader5)
|
||||
#ifdef GL_ARB_gpu_shader5
|
||||
if (gl_InvocationID >= cascade_count) return;
|
||||
int cascade_id = cascade_offset + gl_InvocationID;
|
||||
#else
|
||||
@@ -65,12 +49,7 @@ void main(void)
|
||||
}
|
||||
|
||||
gl_Layer = cascade_id;
|
||||
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
vertOut.vClipDist = vertIn[vert].vClipDist;
|
||||
#else
|
||||
gl_ClipDistance[0] = gl_in[vert].gl_ClipDistance[0];
|
||||
#endif
|
||||
gl_ClipDistance[0] = gl_in[vert].gl_ClipDistance[0];
|
||||
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
//? #version 150
|
||||
#ifdef GL_ES
|
||||
#extension GL_EXT_gpu_shader5: enable
|
||||
#extension GL_EXT_clip_cull_distance: enable
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp samplerBuffer;
|
||||
#else
|
||||
#extension GL_ARB_gpu_shader5: enable
|
||||
|
||||
#ifndef GEOMETRY_FALLBACK
|
||||
#extension GL_ARB_shader_viewport_layer_array : enable
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec4 vertPosition;
|
||||
@@ -73,25 +66,12 @@ uniform samplerBuffer transform_tex;
|
||||
// supports writing gl_Layer from the vertex shader, see CAPABILITY_FAST_SHADOWS).
|
||||
#ifdef GEOMETRY_FALLBACK
|
||||
out VertexOutput {
|
||||
#if !defined(GL_ARB_gpu_shader5) && !defined(GL_EXT_gpu_shader5)
|
||||
#if !defined(GL_ARB_gpu_shader5)
|
||||
float instance;
|
||||
#endif
|
||||
float clipModel;
|
||||
vec3 normal;
|
||||
#ifdef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
float vClipDist;
|
||||
#endif
|
||||
} vertOut;
|
||||
#elif defined(SDR_FLAG_SW_CLIP_FALLBACK)
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) out VertexOutput {
|
||||
float vClipDist;
|
||||
} vertOut;
|
||||
#else
|
||||
out VertexOutput {
|
||||
float vClipDist;
|
||||
} vertOut;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define TEXELS_PER_MATRIX 4
|
||||
@@ -132,7 +112,7 @@ void main()
|
||||
#ifdef VULKAN
|
||||
int instanceIndex = gl_InstanceIndex;
|
||||
#else
|
||||
#if !defined(GL_ARB_gpu_shader5) && !defined(GL_EXT_gpu_shader5)
|
||||
#if !defined(GL_ARB_gpu_shader5)
|
||||
#ifdef APPLE
|
||||
vertOut.instance = float(gl_InstanceIDARB);
|
||||
#else
|
||||
@@ -153,19 +133,11 @@ void main()
|
||||
gl_Position = position;
|
||||
}
|
||||
|
||||
#ifndef SDR_FLAG_SW_CLIP_FALLBACK
|
||||
if (use_clip_plane != 0) {
|
||||
gl_ClipDistance[0] = dot(clip_equation, modelMatrix * orient * vertex);
|
||||
} else {
|
||||
gl_ClipDistance[0] = 1.0;
|
||||
}
|
||||
#else
|
||||
if (use_clip_plane != 0) {
|
||||
vertOut.vClipDist = dot(clip_equation, modelMatrix * orient * vertex);
|
||||
} else {
|
||||
vertOut.vClipDist = 1.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GEOMETRY_FALLBACK
|
||||
vertOut.normal = normal;
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2DArray;
|
||||
#endif
|
||||
|
||||
#include "gamma.sdr"
|
||||
|
||||
const float EMISSIVE_GAIN = 2.0;
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec4 fragImpactUV;
|
||||
layout(location = 1) in float fragNormOffset;
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler2DArray shieldMap;
|
||||
#else
|
||||
in vec4 fragImpactUV;
|
||||
in float fragNormOffset;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2DArray shieldMap;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec4 vertPosition;
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(std140, set = 2, binding = 0) uniform genericData {
|
||||
@@ -20,13 +16,13 @@ layout (std140) uniform genericData {
|
||||
|
||||
#include "SMAA.sdr"
|
||||
|
||||
layout(location=0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 1) in vec2 fragPixcoord;
|
||||
layout(location = 2) in vec4 fragOffset[3];
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
// [0]=edgesTex, [1]=areaTex, [2]=searchTex
|
||||
layout(set = 1, binding = 1) uniform sampler2D smaaTex[3];
|
||||
#define edgesTex smaaTex[0]
|
||||
@@ -37,6 +33,8 @@ in vec2 fragTexCoord;
|
||||
in vec2 fragPixcoord;
|
||||
in vec4 fragOffset[3];
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D edgesTex;
|
||||
uniform sampler2D areaTex;
|
||||
uniform sampler2D searchTex;
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(std140, set = 2, binding = 0) uniform genericData {
|
||||
@@ -20,17 +16,19 @@ layout (std140) uniform genericData {
|
||||
|
||||
#include "SMAA.sdr"
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 1) in vec4 fragOffset[3];
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler2D colorTex;
|
||||
#else
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragOffset[3];
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D colorTex;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(std140, set = 2, binding = 0) uniform genericData {
|
||||
@@ -20,12 +16,11 @@ layout (std140) uniform genericData {
|
||||
|
||||
#include "SMAA.sdr"
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 1) in vec4 fragOffset;
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
// [0]=colorTex, [1]=blendTex
|
||||
layout(set = 1, binding = 1) uniform sampler2D smaaTex[2];
|
||||
@@ -35,6 +30,8 @@ layout(set = 1, binding = 1) uniform sampler2D smaaTex[2];
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragOffset;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D colorTex;
|
||||
uniform sampler2D blendTex;
|
||||
#endif
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(set = 1, binding = 1) uniform sampler2D tex;
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
#endif
|
||||
|
||||
#include "gamma.sdr"
|
||||
|
||||
layout(location=0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(set = 1, binding = 1) uniform sampler2D tex;
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
uniform sampler2D tex;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp sampler2DArray;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec4 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler2DArray textures[16];
|
||||
#define ytex textures[0]
|
||||
@@ -14,6 +8,7 @@ layout(set = 1, binding = 1) uniform sampler2DArray textures[16];
|
||||
#define vtex textures[2]
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
uniform sampler2DArray ytex;
|
||||
uniform sampler2DArray utex;
|
||||
uniform sampler2DArray vtex;
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
precision highp sampler3D;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(location = 0) in vec2 fragTexCoord;
|
||||
layout(location = 0) out vec4 fragOut0;
|
||||
layout(set = 1, binding = 1) uniform sampler2D tex2D[16];
|
||||
#define composite tex2D[0]
|
||||
#define emissive tex2D[1]
|
||||
@@ -17,7 +10,7 @@ layout(set = 1, binding = 5) uniform sampler3D volume_tex;
|
||||
layout(set = 1, binding = 6) uniform sampler3D noise_volume_tex;
|
||||
#else
|
||||
in vec4 fragTexCoord;
|
||||
|
||||
out vec4 fragOut0;
|
||||
layout (binding = 0) uniform sampler2D composite;
|
||||
layout (binding = 1) uniform sampler2D emissive;
|
||||
layout (binding = 2) uniform sampler2D depth_tex;
|
||||
@@ -84,7 +77,7 @@ void main()
|
||||
#else
|
||||
vec4 eyeDirection = p_inv * vec4(fragTexCoord.xy * 2.0 - 1.0, -1, 1);
|
||||
#endif
|
||||
eyeDirection.w = 0.0;
|
||||
eyeDirection.w = 0;
|
||||
vec3 rayDirection = normalize((v_inv * eyeDirection).xyz);
|
||||
|
||||
vec4 color_in = texture(composite, fragTexCoord.xy);
|
||||
@@ -110,14 +103,14 @@ void main()
|
||||
#endif
|
||||
|
||||
//The t at which the ray enters the nebula cube
|
||||
float maxtMin = max(0.0, max(tMin.x, max(tMin.y, tMin.z)));
|
||||
float maxtMin = max(0,max(tMin.x, max(tMin.y, tMin.z)));
|
||||
//The t at which the ray leaves the nebula cube
|
||||
float mintMax = min(fragDepth, min(tMax.x, min(tMax.y, tMax.z)));
|
||||
|
||||
//The cumulative one minus alpha value of the nebula. Corresponds to the multiplier of the current step when additively drawing to a fragment for which the steps closer to the camera are already drawn.
|
||||
float cumOMAlpha = 1.0;
|
||||
float cumOMAlpha = 1;
|
||||
//The cumulative distance already travelled through the nebula.
|
||||
float cumnebdist = 0.0;
|
||||
float cumnebdist = 0;
|
||||
//The color of the current fragment
|
||||
vec3 cumcolor = vec3(0, 0, 0);
|
||||
|
||||
@@ -128,14 +121,6 @@ void main()
|
||||
|
||||
vec3 sidestep = 1.0 / vec3(textureSize(volume_tex, 0));
|
||||
|
||||
#ifdef GL_ES
|
||||
// The emissive texture has a complete mip chain generated by the engine.
|
||||
ivec2 emissiveSize = textureSize(emissive, 0);
|
||||
float maxEmissiveLod = float(findMSB(max(emissiveSize.x, emissiveSize.y)));
|
||||
#else
|
||||
float maxEmissiveLod = float(textureQueryLevels(emissive) - 1);
|
||||
#endif
|
||||
|
||||
for(float stept = maxtMin; stept < mintMax;) {
|
||||
//Step setup
|
||||
vec3 position = camera + rayDirection * stept - nebPos;
|
||||
@@ -174,7 +159,7 @@ void main()
|
||||
#ifdef NOISE
|
||||
//Mix the actual nebula color with the noise color depending on the product of the noise channels multiplied with intensity, smooth-clamped from 0 to 1
|
||||
vec3 stepcolor_neb = mix(nebulaColor, noiseColor,
|
||||
smoothstep(0.0, 1.0, (textureGrad(noise_volume_tex, position / noiseColorScale1, gradX, gradY).r + textureGrad(noise_volume_tex, position / noiseColorScale2, gradX, gradY).g) / 2.0 * noiseIntensity));
|
||||
smoothstep(0, 1, (textureGrad(noise_volume_tex, position / noiseColorScale1, gradX, gradY).r + textureGrad(noise_volume_tex, position / noiseColorScale2, gradX, gradY).g) / 2.0 * noiseIntensity));
|
||||
#else
|
||||
vec3 stepcolor_neb = nebulaColor;
|
||||
#endif
|
||||
@@ -184,19 +169,19 @@ void main()
|
||||
//From the current position in the volumetric cloud, sample towards the sun to test whether or not the current part of the nebula is bright or not
|
||||
for(int dlstep = 1; dlstep <= directionalLightSampleSteps; dlstep++){
|
||||
//TODO Sample these in a cone towards the sun, not just a line. Also add the high-distance sample for concave nebulae
|
||||
vec3 dlsteppos = (position - globalLightDirection * (float(dlstep) * directionalLightStepSize)) / nebSize + 0.5;
|
||||
float dlstepalpha = textureGrad(volume_tex, dlsteppos, gradX, gradY).a * step(0.0, dlsteppos.x) * step(dlsteppos.x, 1.0) * step(0.0, dlsteppos.y) * step(dlsteppos.y, 1.0) * step(0.0, dlsteppos.z) * step(dlsteppos.z, 1.0);
|
||||
vec3 dlsteppos = (position - globalLightDirection * (dlstep * directionalLightStepSize)) / nebSize + 0.5;
|
||||
float dlstepalpha = textureGrad(volume_tex, dlsteppos, gradX, gradY).a * step(0, dlsteppos.x) * step(dlsteppos.x, 1) * step(0, dlsteppos.y) * step(dlsteppos.y, 1) * step(0, dlsteppos.z) * step(dlsteppos.z, 1);
|
||||
directionalLightDepth += dlstepalpha * directionalLightStep;
|
||||
}
|
||||
stepcolor_diffuse *= beer_powder_norm * (1.0 - exp(-directionalLightDepth * 2.0)) * exp(-directionalLightDepth);
|
||||
stepcolor_diffuse *= beer_powder_norm * (1 - exp(-directionalLightDepth * 2.0)) * exp(-directionalLightDepth);
|
||||
|
||||
//Emissive
|
||||
cumnebdist += stepcolor_alpha * stepsize_current;
|
||||
vec3 emissive_lod = textureLod(emissive, fragTexCoord.xy, clamp(cumnebdist * emissiveSpreadFactor, 0.0, maxEmissiveLod)).rgb;
|
||||
vec3 stepcolor_emissive = clamp(emissive_lod.rgb * pow(alphalim, 1.0 / (opacitydistance / ((fragDepth - stept) * emissiveFalloff + 0.01))) * emissiveIntensity, 0.0, 1.0);
|
||||
vec3 emissive_lod = textureLod(emissive, fragTexCoord.xy, clamp(cumnebdist * emissiveSpreadFactor, 0, float(textureQueryLevels(emissive) - 1))).rgb;
|
||||
vec3 stepcolor_emissive = clamp(emissive_lod.rgb * pow(alphalim, 1.0 / (opacitydistance / ((fragDepth - stept) * emissiveFalloff + 0.01))) * emissiveIntensity, 0, 1);
|
||||
|
||||
//Step finish
|
||||
vec3 stepcolor = clamp(stepcolor_diffuse + stepcolor_emissive, 0.0, 1.0);
|
||||
vec3 stepcolor = clamp(stepcolor_diffuse + stepcolor_emissive, 0, 1);
|
||||
cumcolor += stepalpha * cumOMAlpha * stepcolor;
|
||||
}
|
||||
|
||||
|
||||
@@ -381,7 +381,7 @@ int __cdecl RecordExceptionInfo(PEXCEPTION_POINTERS data, const char *Message)
|
||||
|
||||
wsprintf(DebugMessage, "%s location %08x caused an access violation.\r\n", readwrite, Exception->ExceptionInformation[1]);
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef _DEBUG
|
||||
// The VisualC++ debugger doesn't actually tell you whether a read
|
||||
// or a write caused the access violation, nor does it tell what
|
||||
// address was being read or written. So I fixed that.
|
||||
|
||||
@@ -28,23 +28,6 @@ protected:
|
||||
return FALSE;
|
||||
|
||||
m_library = SDL_LoadObject(externlib);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
if (m_library == NULL) {
|
||||
auto android_path = SDL_GetAndroidInternalStoragePath();
|
||||
if (android_path != nullptr) {
|
||||
SCP_string android_full_path = android_path;
|
||||
if (android_full_path.back() != DIR_SEPARATOR_CHAR) {
|
||||
android_full_path += DIR_SEPARATOR_CHAR;
|
||||
}
|
||||
android_full_path += SCP_string("natives") + DIR_SEPARATOR_CHAR + externlib;
|
||||
#ifndef NDEBUG
|
||||
mprintf(("Calling SDL_LoadObject with the following path: '%s'\n", android_full_path.c_str()));
|
||||
#endif
|
||||
m_library = SDL_LoadObject(android_full_path.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// check full path as a fallback for our own libraries
|
||||
// NOTE: basePath is assumed to have a trailing slash!
|
||||
|
||||
+2
-29
@@ -289,11 +289,7 @@ GraphicsAPI gr_get_configured_render_api()
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ANDROID__
|
||||
os::ViewportState Gr_configured_window_state = os::ViewportState::Fullscreen;
|
||||
#else
|
||||
os::ViewportState Gr_configured_window_state = os::ViewportState::Borderless;
|
||||
#endif
|
||||
|
||||
static bool mode_change_func(os::ViewportState state, bool initial)
|
||||
{
|
||||
@@ -2188,30 +2184,7 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, GraphicsAPI
|
||||
//
|
||||
// As such, window_res is effectively no longer optional, part of the core render path and must always be enabled.
|
||||
// The only reason it is not yet refactored into an always-on thing is due to issues with FRED integration.
|
||||
int window_width = width;
|
||||
int window_height = height;
|
||||
|
||||
// In exclusive fullscreen, the window must match the monitor. Using the render resolution instead would require a
|
||||
// video mode switch to that resolution, which may not exist as a display mode (leaving the window at a different
|
||||
// size than window_res) and is repeated on every alt-tab.
|
||||
if (!gr_is_viewport_window()) {
|
||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO)) {
|
||||
auto displayMode = SDL_GetDesktopDisplayMode(gr_get_preferred_display());
|
||||
if (displayMode) {
|
||||
window_width = displayMode->w;
|
||||
window_height = displayMode->h;
|
||||
} else {
|
||||
mprintf(("Could not query desktop display mode for fullscreen window size: %s\n", SDL_GetError()));
|
||||
}
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
} else {
|
||||
mprintf(("Could not initialize SDL video for fullscreen window size: %s\n", SDL_GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
mprintf(("Forcing window_res to %dx%d (render resolution %dx%d)\n", window_width, window_height, width, height));
|
||||
Cmdline_window_res.emplace(static_cast<uint16_t>(window_width), static_cast<uint16_t>(window_height));
|
||||
Cmdline_window_res.emplace(static_cast<uint16_t>(width), static_cast<uint16_t>(height));
|
||||
}
|
||||
|
||||
if (d_mode == GraphicsAPI::Default) {
|
||||
@@ -2282,7 +2255,7 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, GraphicsAPI
|
||||
// built in debug mode. This helps if you run with the debugger active as the
|
||||
// game won't be switching from fullscreen to minimized every time you hit a breakpoint or
|
||||
// warning message.
|
||||
#ifndef NDEBUG
|
||||
#ifdef _DEBUG
|
||||
#ifdef _FORCE_DEBUG_WIDESCREEN
|
||||
width = 1280;
|
||||
height = 800;
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#define GL_CLAMP_VERTEX_COLOR 0x891A
|
||||
#define GL_CLAMP_FRAGMENT_COLOR 0x891B
|
||||
#define GL_FIXED_ONLY 0x891D
|
||||
#define GLAD_GL_ARB_shader_viewport_layer_array 0 // Disabled, no gl_layer in vertex shader //0x8DAE
|
||||
|
||||
//Enums Redefinitions
|
||||
#define GL_CLIP_DISTANCE0 GL_CLIP_DISTANCE0_EXT // GL_EXT_clip_cull_distance
|
||||
@@ -49,7 +48,6 @@
|
||||
#define GLAD_GL_ARB_texture_storage GL_TRUE // ES 3.2
|
||||
#define GLAD_GL_ARB_draw_buffers_blend GL_TRUE // ES 3.2 (glBlendFunci and glBlendEquationi)
|
||||
#define GLAD_GL_ARB_vertex_attrib_binding GL_TRUE // ES 3.1
|
||||
#define GL_DEPTH_CLAMP GL_DEPTH_CLAMP_EXT
|
||||
|
||||
//Functions Redefinitions
|
||||
#define glBlendFunciARB glBlendFunci // ES 3.2
|
||||
@@ -236,7 +234,9 @@ inline void glDrawBuffer(GLenum buf)
|
||||
}
|
||||
}
|
||||
|
||||
// ES uses layout(location = ) directly on shader
|
||||
// does not exist on ES, ES uses layout(location=) directly on shader
|
||||
// Notes:
|
||||
// -This function is not required to run.
|
||||
#define glBindFragDataLocation(program, colorNumber, name) ((void)0)
|
||||
|
||||
// glPolygonMode() is not supported on ES, no wireframe, GL_FILL is default, GL_POINTS, and GL_LINES needs an alternative path
|
||||
@@ -254,7 +254,6 @@ static inline void glQueryCounter(GLuint id, GLenum target)
|
||||
#else
|
||||
(void)id;
|
||||
#endif
|
||||
(void)target;
|
||||
}
|
||||
|
||||
// glGetCompressedTexImage not present on GLES and no equivalent
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
#if !defined __APPLE_CC__ && !defined __ANDROID__ && defined SCP_UNIX
|
||||
#if !defined __APPLE_CC__ && defined SCP_UNIX
|
||||
#include<glad/glad_glx.h>
|
||||
//Required because X defines none and always, which is used later
|
||||
#undef None
|
||||
@@ -956,7 +956,7 @@ void gr_opengl_use_viewport(os::Viewport* view) {
|
||||
|
||||
int opengl_init_display_device()
|
||||
{
|
||||
os::ViewPortProperties attrs = {};
|
||||
os::ViewPortProperties attrs;
|
||||
attrs.enable_opengl = true;
|
||||
|
||||
attrs.gl_attributes.major_version = MIN_REQUIRED_GL_VERSION / 10;
|
||||
@@ -1394,7 +1394,7 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
|
||||
Error(LOCATION, "Failed to load OpenGL!");
|
||||
}
|
||||
|
||||
#if !defined __APPLE_CC__ && !defined __ANDROID__ && defined SCP_UNIX
|
||||
#if !defined __APPLE_CC__ && defined SCP_UNIX
|
||||
if (!gladLoadGLXLoader(GL_context->getLoaderFunction(), nullptr, 0)) {
|
||||
Error(LOCATION, "Failed to load GLX!");
|
||||
}
|
||||
@@ -1453,9 +1453,7 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
|
||||
"Deferred lightning is enabled in settings but the gpu does not support the minimum of 6 draw buffers. "
|
||||
"This will result in rendering errors.");
|
||||
}
|
||||
|
||||
mprintf((" Depth Clamp support : %s\n", GLAD_GL_EXT_depth_clamp ? NOX("YES") : NOX("NO")));
|
||||
mprintf((" HW Cull distance support : %s\n", GLAD_GL_EXT_clip_cull_distance ? NOX("YES") : NOX("NO")));
|
||||
|
||||
mprintf((" Precompiled shaders support : %s\n", GLAD_GL_OES_get_program_binary ? NOX("YES") : NOX("NO")));
|
||||
mprintf((" Immutable buffer storage support : %s\n", GLAD_GL_EXT_buffer_storage ? NOX("YES") : NOX("NO")));
|
||||
mprintf((" BGRA8888 format support: %s\n", GLAD_GL_EXT_texture_format_BGRA8888 ? NOX("YES") : NOX("NO")));
|
||||
|
||||
@@ -72,7 +72,7 @@ bool gr_opengl_openxr_test_capabilities() {
|
||||
#ifdef WIN32
|
||||
bool gr_opengl_openxr_create_session() {
|
||||
auto hdc = static_cast<HDC>(SDL_GetPointerProperty(SDL_GetWindowProperties(os::getSDLMainWindow()),
|
||||
SDL_PROP_WINDOW_WIN32_HDC_POINTER,
|
||||
SDL_PROP_WINDOW_WIN32_HWND_POINTER,
|
||||
nullptr));
|
||||
|
||||
XrGraphicsBindingOpenGLWin32KHR graphicsBinding{
|
||||
|
||||
@@ -178,20 +178,10 @@ static SCP_string opengl_shader_get_header(shader_type type_id, int flags, bool
|
||||
|
||||
#ifndef USE_OPENGL_ES
|
||||
sflags << "#version " << GLSL_version << " core\n";
|
||||
if (GLSL_version < 330) {
|
||||
sflags << "#extension GL_ARB_explicit_attrib_location : enable\n";
|
||||
}
|
||||
#else
|
||||
sflags << "#version " << GLSL_version << " es\n";
|
||||
#endif
|
||||
sflags << "#define OPENGL\n";
|
||||
|
||||
#ifdef USE_OPENGL_ES
|
||||
if (!GLAD_GL_EXT_clip_cull_distance) {
|
||||
sflags << "#define SDR_FLAG_SW_CLIP_FALLBACK\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
sflags << shader_get_shadow_cascade_defines();
|
||||
sflags << shader_get_rt_shadow_light_limit_define();
|
||||
|
||||
|
||||
@@ -360,13 +360,6 @@ GLboolean opengl_state::ClipDistance(GLint num, bool state)
|
||||
|
||||
GLboolean save_state = clipdistance_Status[num];
|
||||
|
||||
#ifdef USE_OPENGL_ES
|
||||
if (!GLAD_GL_EXT_clip_cull_distance) {
|
||||
clipdistance_Status[num] = state;
|
||||
return save_state;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (state != clipdistance_Status[num]) {
|
||||
if (state) {
|
||||
glEnable(GL_CLIP_DISTANCE0+num);
|
||||
|
||||
@@ -732,13 +732,7 @@ void gr_opengl_shadow_map_start(matrix4 *shadow_view_matrix, const matrix *light
|
||||
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
#ifdef USE_OPENGL_ES
|
||||
if (GLAD_GL_EXT_depth_clamp) {
|
||||
glEnable(GL_DEPTH_CLAMP);
|
||||
}
|
||||
#else
|
||||
glEnable(GL_DEPTH_CLAMP);
|
||||
#endif
|
||||
|
||||
Glowpoint_override_save = Glowpoint_override;
|
||||
Glowpoint_override = true;
|
||||
@@ -759,13 +753,7 @@ void gr_opengl_shadow_map_end()
|
||||
{
|
||||
gr_end_view_matrix();
|
||||
|
||||
#ifdef USE_OPENGL_ES
|
||||
if (GLAD_GL_EXT_depth_clamp) {
|
||||
glDisable(GL_DEPTH_CLAMP);
|
||||
}
|
||||
#else
|
||||
glDisable(GL_DEPTH_CLAMP);
|
||||
#endif
|
||||
|
||||
gr_zbuffer_set(ZBUFFER_TYPE_FULL);
|
||||
GL_state.PopFramebufferState();
|
||||
@@ -1148,12 +1136,6 @@ void opengl_tnl_set_material_nanovg(nanovg_material* material_info) {
|
||||
void opengl_tnl_set_material_decal(decal_material* material_info) {
|
||||
opengl_tnl_set_material(material_info, false);
|
||||
|
||||
#ifdef USE_OPENGL_ES
|
||||
// ES decal outputs use G-buffer locations instead of packed draw-buffer indices.
|
||||
GL_state.SetAlphaBlendModei(2, material_info->get_blend_mode(1));
|
||||
GL_state.SetAlphaBlendModei(4, material_info->get_blend_mode(2));
|
||||
#endif
|
||||
|
||||
float u_scale, v_scale;
|
||||
uint32_t array_index;
|
||||
|
||||
|
||||
@@ -75,27 +75,7 @@ void openxr_prepare(float hudscale) {
|
||||
openxr_req = true;
|
||||
}
|
||||
|
||||
static void openxr_check_api_layers() {
|
||||
uint32_t layerCount = 0;
|
||||
if (xrEnumerateApiLayerProperties(0, &layerCount, nullptr) != XR_SUCCESS || layerCount == 0)
|
||||
return;
|
||||
|
||||
SCP_vector<XrApiLayerProperties> layers(layerCount, XrApiLayerProperties { XR_TYPE_API_LAYER_PROPERTIES, nullptr, "", 0, 0, "" });
|
||||
if (xrEnumerateApiLayerProperties(layerCount, &layerCount, layers.data()) != XR_SUCCESS)
|
||||
return;
|
||||
|
||||
for (const auto& layer : layers) {
|
||||
mprintf(("OpenXR API layer: %s (version %u)\n", layer.layerName, layer.layerVersion));
|
||||
|
||||
if (!strcmp(layer.layerName, "XR_APILAYER_NOVENDOR_toolkit")) {
|
||||
ReleaseWarning(LOCATION, "OpenXR Toolkit is installed and active. There are known compatibility issues with FSO that will likely crash the game.\nPlease disable or uninstall OpenXR Toolkit to use VR with FSO.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool openxr_init_instance() {
|
||||
openxr_check_api_layers();
|
||||
|
||||
auto extensions = gr_openxr_get_extensions();
|
||||
|
||||
const gameversion::version& fso_version = gameversion::get_executable_version();
|
||||
|
||||
@@ -162,19 +162,6 @@ static ShaderVariantInfo SHADER_VARIANTS[] = {
|
||||
{SDR_TYPE_SHADOW_MAP_GEN, true, SDR_FLAG_SHADOW_FALLBACK, "GEOMETRY_FALLBACK", {}, "Use a geometry shader to select the cascade layer instead of writing gl_Layer from the vertex shader"}
|
||||
};
|
||||
|
||||
static_assert(VATTRIB_MODEL_MATRIX + 4 <= 32, "vertex input mask is 32 bits wide");
|
||||
|
||||
uint32_t shader_vertex_input_mask(const ShaderTypeInfo& info)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
for (auto attr : info.attributes) {
|
||||
// The Vulkan pipeline drops every location the mask omits, so a mat4 needs all four of its bits.
|
||||
const uint32_t locations = (attr == VATTRIB_MODEL_MATRIX) ? 4u : 1u;
|
||||
mask |= ((1u << locations) - 1u) << attr;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
const ShaderTypeInfo* shader_get_type_info(shader_type type)
|
||||
{
|
||||
for (auto & i : SHADER_TYPES) {
|
||||
|
||||
@@ -55,14 +55,6 @@ const ShaderTypeInfo* shader_get_type_info(shader_type type);
|
||||
// Lookup helper: find variant info by (type, flag). Returns nullptr if not found.
|
||||
const ShaderVariantInfo* shader_get_variant_info(shader_type type, int flag);
|
||||
|
||||
/**
|
||||
* @brief Bitmask of the vertex attribute locations a shader type reads.
|
||||
*
|
||||
* One bit per location; VATTRIB_MODEL_MATRIX contributes bits 8-11 because a
|
||||
* mat4 input occupies four consecutive locations.
|
||||
*/
|
||||
uint32_t shader_vertex_input_mask(const ShaderTypeInfo& info);
|
||||
|
||||
// Iterate all variants matching type whose flag bit is set in flags.
|
||||
void shader_for_each_active_variant(shader_type type, unsigned int flags, const std::function<void(const ShaderVariantInfo&)>& fn);
|
||||
|
||||
|
||||
@@ -271,9 +271,6 @@ void vulkan_deferred_lighting_begin(bool clearNonColorBufs)
|
||||
|
||||
void vulkan_deferred_lighting_msaa()
|
||||
{
|
||||
if (!Deferred_lighting) {
|
||||
return;
|
||||
}
|
||||
if (Cmdline_msaa_enabled <= 0) {
|
||||
return;
|
||||
}
|
||||
@@ -959,7 +956,6 @@ void vulkan_render_decals(decal_material* material_info,
|
||||
// Build pipeline config for decal rendering
|
||||
PipelineConfig config;
|
||||
config.shaderType = SDR_TYPE_DECAL;
|
||||
config.shaderFlags = material_info->get_shader_flags();
|
||||
config.primitiveType = prim_type;
|
||||
config.depthMode = material_info->get_depth_mode();
|
||||
config.depthWriteEnabled = false;
|
||||
|
||||
@@ -748,7 +748,7 @@ void VulkanDrawManager::renderShadowDraw(gr_buffer_handle ubo_handle, size_t ubo
|
||||
}
|
||||
|
||||
stateTracker->bindPipeline(pipeline, pipelineManager->getPipelineLayout());
|
||||
stateTracker->setDepthBias(1024.0f, 1.0f); // GL shadow pass: gr_zbias(-1024) = polygon offset factor 1, units 1024
|
||||
stateTracker->setDepthBias(-1024.0f, 0.0f);
|
||||
|
||||
// Bind descriptor sets: shadowMapData (per-draw) and shadowCascadeParams
|
||||
// (bound separately, per-frame, via shadow_cascade_params_bind) both live in
|
||||
@@ -1281,10 +1281,6 @@ bool VulkanDrawManager::applyMaterial(material* mat, primitive_type prim_type, v
|
||||
|
||||
m_frameStats.applyMaterialCalls++;
|
||||
|
||||
// Like opengl_tnl_set_material(), every material draw sets the texture addressing (e.g. MR_FORCE_CLAMP skyboxes)
|
||||
setTextureAddressing(mat->get_texture_addressing());
|
||||
vulkan_zbias(mat->get_depth_bias());
|
||||
|
||||
// Build pipeline configuration from material
|
||||
PipelineConfig config = buildPipelineConfig(mat, prim_type);
|
||||
|
||||
@@ -1484,6 +1480,9 @@ bool VulkanDrawManager::applyMaterial(material* mat, primitive_type prim_type, v
|
||||
stateTracker->setStencilMode(GR_STENCIL_NONE);
|
||||
}
|
||||
|
||||
// Set depth bias if needed
|
||||
stateTracker->setDepthBias(static_cast<float>(mat->get_depth_bias()), 0.0f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1541,7 +1540,7 @@ void VulkanDrawManager::draw(primitive_type prim_type, int first_vertex, int ver
|
||||
m_frameStats.totalVertices += vertex_count;
|
||||
|
||||
// Flush any dirty dynamic state (viewport, scissor, depth bias, stencil ref)
|
||||
// before issuing the draw command. applyMaterial sets some of these AFTER bindPipeline,
|
||||
// before issuing the draw command. applyMaterial sets these AFTER bindPipeline,
|
||||
// so they may be dirty even when the pipeline didn't change.
|
||||
stateTracker->applyDynamicState();
|
||||
|
||||
|
||||
@@ -98,7 +98,8 @@ void vulkan_set_default_material_uniforms(material* material_info)
|
||||
(clip_plane.normal.xyz.y * clip_plane.position.xyz.y) +
|
||||
(clip_plane.normal.xyz.z * clip_plane.position.xyz.z));
|
||||
|
||||
data->modelMatrix = gr_model_matrix_stack.get_transform();
|
||||
// Model matrix (identity for now, material doesn't provide one)
|
||||
vm_matrix4_set_identity(&data->modelMatrix);
|
||||
} else {
|
||||
data->clipEnabled = 0;
|
||||
vm_matrix4_set_identity(&data->modelMatrix);
|
||||
@@ -612,9 +613,6 @@ void vulkan_calculate_irrmap()
|
||||
}
|
||||
|
||||
// Get envmap cubemap view
|
||||
if (!texManager->ensureCubemapUploaded(ENVMAP)) {
|
||||
return;
|
||||
}
|
||||
auto* envSlot = bm_get_slot(ENVMAP, true);
|
||||
if (!envSlot || !envSlot->gr_info) {
|
||||
return;
|
||||
@@ -640,6 +638,9 @@ void vulkan_calculate_irrmap()
|
||||
|
||||
vk::CommandBuffer cmd = stateTracker->getCommandBuffer();
|
||||
|
||||
// End the current swap chain render pass
|
||||
cmd.endRenderPass();
|
||||
|
||||
// Create pipeline for irradiance map generation
|
||||
PipelineConfig config;
|
||||
config.shaderType = SDR_TYPE_IRRADIANCE_MAP_GEN;
|
||||
@@ -710,9 +711,6 @@ void vulkan_calculate_irrmap()
|
||||
|
||||
vk::Extent2D irrExtent(irrTs->width, irrTs->height);
|
||||
|
||||
// End the swap chain pass only after the early returns above, which never resume it
|
||||
cmd.endRenderPass();
|
||||
|
||||
for (size_t face = 0; face < irrTs->cubeFaceFramebuffers.size(); face++) {
|
||||
vk::Framebuffer fb = irrTs->cubeFaceFramebuffers[face];
|
||||
if (!fb) {
|
||||
@@ -763,8 +761,7 @@ void vulkan_calculate_irrmap()
|
||||
writer.writeSet(materialSet, VulkanDescriptorManager::getSetTemplate(DescriptorSetIndex::Material));
|
||||
{
|
||||
std::array<vk::DescriptorImageInfo, VulkanDescriptorManager::MAX_TEXTURE_BINDINGS> texImages;
|
||||
// irrmap-f.sdr declares this binding as samplerCube, so every element needs a cube view
|
||||
texImages.fill(descManager->getFallbacks().textureCube);
|
||||
texImages.fill(descManager->getFallbacks().texture2D);
|
||||
texImages[0].imageView = envmapView;
|
||||
writer.setImageArray(MaterialBinding::TextureArray, texImages);
|
||||
}
|
||||
|
||||
@@ -121,12 +121,6 @@ public:
|
||||
*/
|
||||
vk::Pipeline getPipeline(const PipelineConfig& config, const vertex_layout& vertexLayout);
|
||||
|
||||
/**
|
||||
* @brief Destroy all cached pipelines; later getPipeline calls build them again
|
||||
* @note No submitted or recording command buffer may still use them
|
||||
*/
|
||||
void forgetAllPipelines() { m_pipelines.clear(); }
|
||||
|
||||
/**
|
||||
* @brief Get the common pipeline layout
|
||||
*
|
||||
|
||||
@@ -272,7 +272,8 @@ vk::DescriptorImageInfo VulkanDistortion::getTextureInfo() const
|
||||
// Distortion_texture[!Distortion_switch] binding for thrusters).
|
||||
// After update() toggles the switch, m_switch points to the old read
|
||||
// source, which is the texture that was just written.
|
||||
return {m_sampler, m_tex[m_switch].view, vk::ImageLayout::eShaderReadOnlyOptimal};
|
||||
return {m_ctx->linearSampler, m_tex[m_switch].view,
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal};
|
||||
}
|
||||
|
||||
} // namespace graphics::vulkan
|
||||
@@ -531,9 +531,6 @@ void VulkanLDR::executeLightshafts(vk::CommandBuffer cmd)
|
||||
if (dot > 0.7f) {
|
||||
sun_x = asinf_safe(vm_vec_dot(&light_dir, &Eye_matrix.vec.rvec)) / PI * 1.5f + 0.5f;
|
||||
sun_y = asinf_safe(vm_vec_dot(&light_dir, &Eye_matrix.vec.uvec)) / PI * 1.5f * gr_screen.clip_aspect + 0.5f;
|
||||
// The formula above is OpenGL's, whose texture V grows upward. The Vulkan fullscreen triangle in
|
||||
// post-v.sdr has V = 0 at the top of the screen, so flip to the space ls-f.sdr's fragTexCoord is in.
|
||||
sun_y = 1.0f - sun_y;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Loaded 100 of 241 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user