Compare commits

..
Author SHA1 Message Date
SirKnightly 284927c4f0 Automated build commit 2020-01-25 10:45:09 -06:00
305 changed files with 4659 additions and 88092 deletions

No files matched your search

+16 -19
View File
@@ -1,27 +1,25 @@
---
Language: Cpp
Standard: Cpp11
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowAllArgumentsOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
@@ -52,17 +50,15 @@ ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^(<.*\.(h|hh|hpp)>)$' # Includes of external libraries
Priority: 5
- Regex: '^(<.*>)$' # standard library includes (won't match deprecated C headers)
Priority: 6
- Regex: '^"globalincs\/.*\.h"$' # globalincs always come first
Priority: 1
- Regex: '^"[^/]*\.(h)"$' # Local includes
Priority: 2
- Regex: '^".*\.(h)"$' # standard engine includes
Priority: 3
- Regex: '.*' # Catch all in case something is unhandled above
Priority: 4
- Regex: '^(<.*>)$' # standard library includes (won't match deprecated C headers)
Priority: 5
- Regex: '^"[^/]*\.(h)"$' # Local includes
Priority: 1
- Regex: '^".*\.(h)"$' # standard engine includes
Priority: 2
- Regex: '.*' # Catch all in case something is unhandled above
Priority: 3
IncludeIsMainRegex: '$'
IndentCaseLabels: false
IndentWidth: 4
@@ -97,7 +93,8 @@ SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: ForContinuationAndIndentation
UseTab: ForIndentation
...
-2
View File
@@ -1,2 +0,0 @@
/build
/.git
-4
View File
@@ -5,7 +5,3 @@ indent_style = tab
[*.sdr]
indent_style = tab
[*.{yml,yaml}]
indent_style = space
indent_size = 2
+8 -1
View File
@@ -76,8 +76,15 @@ jobs:
strategy:
matrix:
configuration: [Debug, Release]
compiler: [MSVC]
compiler: [MSVC, MinGW]
arch: [Win32, x64]
exclude:
- configuration: Debug
compiler: MinGW
arch: x64
- configuration: Release
compiler: MinGW
arch: x64
name: Windows
runs-on: windows-2019
steps:
@@ -1,48 +0,0 @@
name: Publish Standalone docker image
on:
push:
tags:
- '*'
jobs:
build_images:
strategy:
matrix:
configuration: [FastDebug, Release]
include:
- configuration: FastDebug
latest_tag: latest_debug
nightly_tag: nightly_debug
release_tag: release_debug
- configuration: Release
latest_tag: latest
nightly_tag: nightly
release_tag: release
fail-fast: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
name: Checkout
with:
submodules: true
- name: Docker login
run: echo ${{ secrets.DOCKER_ACCESSTOKEN }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
- name: Docker build
run: docker build --build-arg build_type=${{ matrix.configuration }} -f docker/standalone/Dockerfile -t ${{ secrets.DOCKER_REPOSITORY }}:${{ matrix.latest_tag }} .
- name: Push latest tag
run: |
docker push ${{ secrets.DOCKER_REPOSITORY }}:${{ matrix.latest_tag }}
- name: Push nightly tag
if: contains(github.ref, 'refs/tags/nightly_')
run: |
docker tag ${{ secrets.DOCKER_REPOSITORY }}:${{ matrix.latest_tag }} ${{ secrets.DOCKER_REPOSITORY }}:${{ matrix.nightly_tag }}
docker push ${{ secrets.DOCKER_REPOSITORY }}:${{ matrix.nightly_tag }}
- name: Push release tag
if: contains(github.ref, 'refs/tags/release_')
run: |
docker tag ${{ secrets.DOCKER_REPOSITORY }}:${{ matrix.latest_tag }} ${{ secrets.DOCKER_REPOSITORY }}:${{ matrix.release_tag }}
docker push ${{ secrets.DOCKER_REPOSITORY }}:${{ matrix.release_tag }}
-1
View File
@@ -257,4 +257,3 @@ CMakeSettings.json
# This gets ignored by one of the rules above for some reason...
!/code/scripting/lua/LuaConvert.h
!/code/debugconsole/
!/docker/build
+3 -3
View File
@@ -36,9 +36,9 @@ env:
# These declarations set INDIEGAMES_USER and INDIEGAMES_PASSWORD for uploading nightly builds to the indiegames server
- secure: "lUuRu8XIi8MKNf1ebOfyC4iVEpPyASojJIDWXRo2bNqEF4ILAljXdkVeXeN6H5yKCHD52cxCNTtyePIG/o3p3QEuGSVud9bDS3D7LaQicLETGGrsw3l07U49gF2OKHXGopg0MzBbZUU9QmhoFTAe8t6PV9NDuEayYCheqvTqjZg="
- secure: "E/DHLYcPK/hBUqxBYYlUqp5sjgvIqY5A0qRHyQ4bmjsB+WB/Xx71bGCSiF7hk6lTxar1ZI1i5RAXXh9AIvNVaYAIdEOlCP+q3gvwCYuc5naZEKmkxlUCf0oEL4O9Fye93A/3VkFHuBdC1TGPYYf69m4W5r4367wWO9dPRIdWpJA="
# These declarations set DATACORDER_USER and DATACORDER_PASSWORD
- secure: "dpBH/dDN3bmU/NFlh+2v9isNx9wX0ocoRy+W+kBXRH32sosUGp26REhMqgVRpBNP5oxPBU8ic5bEogxAYWCB+0xUygBbkxAwyMPgoA34s0OXdTCY/ofw14ni8qqV2Ffy7fQJbP/jkMURyiMHx3kBTxNv3YjxKJqLnOuOMlQLpT8="
- secure: "tLMRBD1Ufp5iKNwlqPDVbbuczgusaXNoBJyAnPATpJq2YwlkW4j3PqP9rW5vd85+52xam2EOP20w9PoBR5J6FLdiXRu4Lf7yCEhSHFAgowVqQj8QcJpPlyXr90bM4emFGrGqpdxVwxyQ5AFhKwLuEZKsI14GYLN+UMEwpNCMing="
# These declarations set FS2DOWNLOADS_USER and FS2DOWNLOADS_PASSWORD
- secure: "h6GbMX2jLsW1bS9fCM9fthOSJ1nfQQIRWi6EUH2p8u4NFLD5Bfi/C8JhQPKHUzyo3wvKkSHl+PsW7bgr1oXLusRwAur/dtv2N3imqvtbfIz305b00hZlsvbcYmQmUzQFSAdOGShK57JJ5aKQKccaUBP25KqB7Q+JaqBRdaMBS54="
- secure: "fUDAPAUUaaYZy8I4zU3SJ0JcK7aw4eb6eTdaEr7LyNyTMSfPgwY6P1MrbSQC0lJNQIUQ5ffjdxE5g7D7OYpoJF9L14ni4UY8t2QASt7kmpgcYihmjeuYy8FQXgmFG8CTxiWBPKTybZJ7voQcvIvRaNG7b2wM9PMfc5lRIondB6c="
deploy:
- provider: releases
api_key:
-8
View File
@@ -117,10 +117,6 @@ option(FSO_INSTALL_DEBUG_FILES "Install some debug files (currently only PDB fil
option(ENABLE_COTIRE "Enable cotire for faster compilation. Enabled by default." ON)
option(FSO_RELEASE_LOGGING "Enable logging output for release builds" OFF)
OPTION(FSO_BUILD_WITH_FFMPEG "Enable the usage of FFmpeg for sound and custscenes" ON)
MARK_AS_ADVANCED(FORCE FSO_CMAKE_DEBUG)
MARK_AS_ADVANCED(FORCE FSO_BUILD_INCLUDED_LIBS)
MARK_AS_ADVANCED(FORCE FSO_USE_OPENALSOFT)
@@ -129,8 +125,6 @@ MARK_AS_ADVANCED(FORCE FSO_DEVELOPMENT_MODE)
MARK_AS_ADVANCED(FORCE FSO_FATAL_WARNINGS)
mark_as_advanced(FORCE FSO_INSTALL_DEBUG_FILES)
mark_as_advanced(FORCE ENABLE_COTIRE)
mark_as_advanced(FORCE FSO_RELEASE_LOGGING)
mark_as_advanced(FORCE FSO_BUILD_WITH_FFMPEG)
# Include cotire file from https://github.com/sakra/cotire/
include(cotire)
@@ -203,5 +197,3 @@ ENDIF()
message(STATUS "Building FSO tools: ${FSO_BUILD_TOOLS}")
message(STATUS "Building qtFRED: ${FSO_BUILD_QTFRED}")
message(STATUS "Fatal warnings: ${FSO_FATAL_WARNINGS}")
message(STATUS "Release logging: ${FSO_RELEASE_LOGGING}")
message(STATUS "With FFmpeg: ${FSO_BUILD_WITH_FFMPEG}")
+2 -3
View File
@@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [19.0.0] - 2020-01-25 ([Thread](https://www.hard-light.net/forums/index.php?topic=96226.0))
## [19.0.0-RC1] - 2019-08-29 ([Thread](https://www.hard-light.net/forums/index.php?topic=95868.0))
### Meta
- With this release we decided to drop the "`3.Major_revision.Minor_revision`" versioning scheme in favor of a year based scheme since the Major and Minor versions did not have much meaning anymore. Instead the scheme will now be "`<year>.<number that is incremented every release>.0`". The last 0 is still there because some of our systems expect that. It will be gone at some point.
### Added
@@ -21,7 +21,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Model uniforms get sent to the GPU using uniform buffers for less overhead
- Various other minor changes
- Converted pilot files from custom binary format to JSON
- Replaced Blinn-Phong BRDF with GGX BRDF
### Fixed
- Refactored bitmap slot handling and removed the fixed upper limit on the number of bitmaps. No more bmpman corruption!
@@ -1994,4 +1993,4 @@ NOTE:
# generated by cvs2cl.pl
# cvs2cl.pl -r -S --utc -f ChangeLog2
```
```
+14 -12
View File
@@ -40,23 +40,25 @@ deploy:
NightlyBuild: true # deploy on nightly push only
- provider: FTP
protocol: sftp
host: porphyrion.feralhosting.com
username:
secure: 36+bVD8eJgI0BVbi7TZ4zQ==
protocol: ftp
host: swc.fs2downloads.com
username:
secure: EXg2ADoKzMduZF90ip2Q0g==
password:
secure: CrzmDVca8AGG08iWPA1gOD4Ge06+wJ3rcBagBGclwYQ=
folder: www/datacorder.porphyrion.feralhosting.com/public_html/builds/nightly/$(VersionName)
secure: x0LL0uY9yBAQ7JTARhQ6AA==
folder: swc.fs2downloads.com/builds/nightly/$(VersionName)
beta: true
on:
NightlyBuild: true # deploy on nightly push only
- provider: FTP
protocol: sftp
host: porphyrion.feralhosting.com
username:
secure: 36+bVD8eJgI0BVbi7TZ4zQ==
protocol: ftp
host: swc.fs2downloads.com
username:
secure: EXg2ADoKzMduZF90ip2Q0g==
password:
secure: CrzmDVca8AGG08iWPA1gOD4Ge06+wJ3rcBagBGclwYQ=
folder: www/datacorder.porphyrion.feralhosting.com/public_html/builds/test/$(VersionName)
secure: x0LL0uY9yBAQ7JTARhQ6AA==
folder: swc.fs2downloads.com/builds/test/$(VersionName)
beta: true
on:
TestBuild: true # deploy on test build push only
+4 -4
View File
@@ -77,13 +77,13 @@ cd /tmp/builds
for file in *; do
if [ "$TEST_BUILD" = true ]; then
# Upload to datacorder
curl -k "sftp://porphyrion.feralhosting.com/www/datacorder.porphyrion.feralhosting.com/public_html/builds/test/$VERSION_NAME/" --user "$DATACORDER_USER:$DATACORDER_PASSWORD" -T "$file" --ftp-create-dirs
# Upload to fs2downloads
curl -k "ftp://swc.fs2downloads.com/swc.fs2downloads.com/builds/test/$VERSION_NAME/" --user "$FS2DOWNLOADS_USER:$FS2DOWNLOADS_PASSWORD" -T "$file" --ftp-create-dirs
else
# Upload to indiegames
curl -k "sftp://scp.indiegames.us/~/public_html/builds/nightly/$VERSION_NAME/" --user "$INDIEGAMES_USER:$INDIEGAMES_PASSWORD" -T "$file" --ftp-create-dirs
# Upload to datacorder
curl -k "sftp://porphyrion.feralhosting.com/~/www/datacorder.porphyrion.feralhosting.com/public_html/builds/nightly/$VERSION_NAME/" --user "$DATACORDER_USER:$DATACORDER_PASSWORD" -T "$file" --ftp-create-dirs
# Upload to fs2downloads
curl -k "ftp://swc.fs2downloads.com/swc.fs2downloads.com/builds/nightly/$VERSION_NAME/" --user "$FS2DOWNLOADS_USER:$FS2DOWNLOADS_PASSWORD" -T "$file" --ftp-create-dirs
fi
done
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/sh
HERE=$(dirname $(readlink -f "${0}"))
export LD_LIBRARY_PATH="${HERE}"/lib:"$LD_LIBRARY_PATH"
exec "${HERE}"/bin/$<TARGET_FILE_NAME:Freespace2> $@
"${HERE}"/bin/$<TARGET_FILE_NAME:Freespace2> $@
+2 -1
View File
@@ -8,7 +8,8 @@
#cmakedefine SCP_HAVE_MAX_ALIGN_T
#cmakedefine SCP_HAVE_STD_MAX_ALIGN_T
#cmakedefine01 HAVE_STD_IS_TRIVIALLY_COPYABLE
#cmakedefine SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE
#cmakedefine SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE_ARRAY
#cmakedefine01 IS_64BIT
+4 -4
View File
@@ -6,9 +6,9 @@ if (EXISTS "${PROJECT_SOURCE_DIR}/version_override.cmake")
include("${PROJECT_SOURCE_DIR}/version_override.cmake")
endif()
set_if_not_defined(FSO_VERSION_MAJOR 20)
set_if_not_defined(FSO_VERSION_MINOR 1)
set_if_not_defined(FSO_VERSION_BUILD 0)
set_if_not_defined(FSO_VERSION_MAJOR 3)
set_if_not_defined(FSO_VERSION_MINOR 8)
set_if_not_defined(FSO_VERSION_BUILD 1)
# A numeric revision e.g. the CI build number
set_if_not_defined(FSO_VERSION_REVISION 0)
@@ -49,4 +49,4 @@ IF (NOT "${FSO_BUILD_POSTFIX}" STREQUAL "")
ENDIF()
set(CONFIG_POSTFIX "$<$<CONFIG:Release>:>$<$<CONFIG:Debug>:-DEBUG>$<$<CONFIG:FastDebug>:-FASTDBG>")
set(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}${CONFIG_POSTFIX}")
set(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}${CONFIG_POSTFIX}")
+1 -13
View File
@@ -28,9 +28,7 @@ TARGET_LINK_LIBRARIES(code PUBLIC ${JPEG_LIBS})
TARGET_LINK_LIBRARIES(code PUBLIC sdl2)
if (FSO_BUILD_WITH_FFMPEG)
TARGET_LINK_LIBRARIES(code PUBLIC ffmpeg)
endif()
TARGET_LINK_LIBRARIES(code PUBLIC ffmpeg)
TARGET_LINK_LIBRARIES(code PUBLIC utfcpp)
@@ -45,8 +43,6 @@ target_link_libraries(code PUBLIC libRocket)
target_link_libraries(code PUBLIC pcp)
target_link_libraries(code PUBLIC vulkan-hpp)
enable_clang_tidy(code)
IF (FSO_USE_SPEECH)
@@ -83,14 +79,6 @@ else()
ENDIF()
endif()
if (FSO_RELEASE_LOGGING)
target_compile_definitions(code PUBLIC SCP_RELEASE_LOGGING)
endif()
if (FSO_BUILD_WITH_FFMPEG)
target_compile_definitions(code PUBLIC WITH_FFMPEG)
endif()
include(util)
configure_cotire(code)
+16 -18
View File
@@ -4652,7 +4652,7 @@ void ai_fly_to_ship()
{
if (aip->mode == AIM_FLY_TO_SHIP || aip->goals[i].ai_mode == AI_GOAL_FLY_TO_SHIP)
{
mprintf(("Ship '%s' told to fly to target ship '%s'\n",
mprintf(("Ship '%s' told to fly to target ship '%s'",
Ships[Pl_objp->instance].ship_name,
aip->goals[i].target_name));
}
@@ -5226,7 +5226,7 @@ static int ai_select_primary_weapon_OLD(const object *objp, Weapon::Info_Flags f
ship *shipp = &Ships[objp->instance];
ship_weapon *swp = &shipp->weapons;
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < ship_info_size());
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()));
if (flags == Weapon::Info_Flags::Puncture) {
if (swp->current_primary_bank >= 0) {
@@ -5315,7 +5315,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
return ai_select_primary_weapon_OLD(objp, flags);
}
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < ship_info_size());
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()));
//made it so it only selects puncture weapons if the active goal is to disable something -Bobboau
if ((flags == Weapon::Info_Flags::Puncture) && (Ai_info[shipp->ai_index].goals[0].ai_mode & (AI_GOAL_DISARM_SHIP | AI_GOAL_DISABLE_SHIP)))
@@ -5506,35 +5506,33 @@ void set_primary_weapon_linkage(object *objp)
weapon_info *wip;
shipp = &Ships[objp->instance];
if (Num_weapons > (int) (MAX_WEAPONS * 0.75f)) {
if (shipp->flags[Ship::Ship_Flags::Primary_linked]) {
nprintf(("AI", "Frame %i, ship %s: Unlinking primaries.\n", Framecount, shipp->ship_name));
shipp->flags.remove(Ship::Ship_Flags::Primary_linked);
}
return; // If low on slots, don't link.
}
sip = &Ship_info[shipp->ship_info_index];
aip = &Ai_info[shipp->ai_index];
swp = &shipp->weapons;
shipp->flags.remove(Ship::Ship_Flags::Primary_linked);
shipp->flags.remove(Ship::Ship_Flags::Primary_linked);
// AL: ensure target is a ship!
if ( (aip->target_objnum != -1) && (Objects[aip->target_objnum].type == OBJ_SHIP) ) {
// If trying to destroy a big ship (i.e., not disable/disarm), always unleash all weapons
if ( Ship_info[Ships[Objects[aip->target_objnum].instance].ship_info_index].is_big_ship() ) {
if ( aip->targeted_subsys == nullptr ) {
if ( aip->targeted_subsys == NULL ) {
if (!sip->flags[Ship::Info_Flags::No_primary_linking] ) {
shipp->flags.set(Ship::Ship_Flags::Primary_linked);
}
shipp->flags.set(Ship::Ship_Flags::Secondary_dual_fire);
shipp->flags.set(Ship::Ship_Flags::Secondary_dual_fire);
return;
}
}
}
if (Num_weapons > (int) (MAX_WEAPONS * 0.75f) || sip->flags[Ship::Info_Flags::No_primary_linking]) {
if (shipp->flags[Ship::Ship_Flags::Primary_linked])
nprintf(("AI", "Frame %i, ship %s: Unlinking primaries.\n", Framecount, shipp->ship_name));
shipp->flags.remove(Ship::Ship_Flags::Primary_linked);
return; // If low on slots or primary linking disallowed, don't link.
}
// AL 2-11-98: If ship has a disarm or disable goal, don't link unless both weapons are
// puncture weapons
if ( (aip->active_goal != AI_GOAL_NONE) && (aip->active_goal != AI_ACTIVE_GOAL_DYNAMIC) )
@@ -5636,7 +5634,7 @@ int ai_fire_primary_weapon(object *objp)
ai_info *aip;
object *enemy_objp;
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < ship_info_size());
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()));
aip = &Ai_info[shipp->ai_index];
@@ -6062,7 +6060,7 @@ int ai_fire_secondary_weapon(object *objp)
shipp = &Ships[objp->instance];
swp = &shipp->weapons;
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < ship_info_size());
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()));
// Select secondary weapon.
current_bank = swp->current_secondary_bank;
@@ -10685,7 +10683,7 @@ void ai_dock()
char *goal_dock_path_name = model_get(goal_sip->model_num)->paths[aip->mp_index].name;
mprintf(("Ship class %s has only %i points on dock path \"%s\". Recommended minimum number of points is 4. "\
"Docking along that path will look strange. You may wish to edit the model.\n", goal_ship_class_name, aip->path_length, goal_dock_path_name));
"Docking along that path will look strange. You may wish to edit the model.", goal_ship_class_name, aip->path_length, goal_dock_path_name));
}
aip->submode = AIS_DOCK_1;
+1 -1
View File
@@ -1376,7 +1376,7 @@ void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
}
if (j >= MAX_AI_GOALS) {
mprintf(("Unable to assign wing goal to ship %s; the ship goals are already filled to capacity\n", Ships[aip->shipnum].ship_name));
mprintf(("Unable to assign wing goal to ship %s; the ship goals are already filled to capacity", Ships[aip->shipnum].ship_name));
}
}
+1 -1
View File
@@ -1812,7 +1812,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
parent_aip = &Ai_info[Ships[Objects[parent_objnum].instance].ai_index];
parent_ship = &Ships[Objects[parent_objnum].instance];
wip = get_turret_weapon_wip(&turret->weapons, weapon_num);
int turret_weapon_class = weapon_info_get_index(wip);
int turret_weapon_class = WEAPON_INFO_INDEX(wip);
#ifndef NDEBUG
// moved here from check_ok_to_fire
+3 -3
View File
@@ -478,7 +478,7 @@ static void asteroid_load(int asteroid_info_index, int asteroid_subtype)
}
else
{
nprintf(("Warning", "For asteroid '%s', detail level mismatch (POF needs %d)\n", asip->name, pm->n_detail_levels));
nprintf(("Warning", "For asteroid '%s', detail level mismatch (POF needs %d)", asip->name, pm->n_detail_levels));
}
}
// Stuff detail level distances.
@@ -1937,11 +1937,11 @@ static void asteroid_parse_tbl()
if (tally != max_asteroids)
{
#ifndef NDEBUG
mprintf(("Asteroid.tbl as parsed:\n"));
for (SCP_vector<SCP_string>::iterator iter = parsed_asteroids.begin();
iter != parsed_asteroids.end(); ++iter)
{
mprintf(("%s\n", iter->c_str()));
mprintf(("Asteroid.tbl as parsed:\n"));
mprintf(("%s", iter->c_str()));
}
#endif
Error(LOCATION,
+2 -2
View File
@@ -218,9 +218,9 @@ bool StartAutopilot()
if (shipp->team != Player_ship->team)
continue;
Assertion((shipp->ship_info_index >= 0) && (shipp->ship_info_index < ship_info_size()),
Assertion((shipp->ship_info_index >= 0) && (shipp->ship_info_index < static_cast<int>(Ship_info.size())),
"Ship '%s' does not have a valid pointer to a ship class. Pointer is %d, which is smaller than 0 or bigger than %d",
shipp->ship_name, shipp->ship_info_index, ship_info_size());
shipp->ship_name, shipp->ship_info_index, static_cast<int>(Ship_info.size()));
ship_info *sip = &Ship_info[shipp->ship_info_index];
if ( !(sip->flags[Ship::Info_Flags::Support]) )
+15 -30
View File
@@ -153,22 +153,22 @@ typedef struct
// Please group them by type, ie graphics, gameplay etc, maximum 20 different types
Flag exe_params[] =
{
{ "-nospec", "Disable specular", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nospec", },
{ "-noglow", "Disable glow maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noglow", },
{ "-noenv", "Disable environment maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noenv", },
{ "-nonormal", "Disable normal maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nonormal" },
{ "-nospec", "Disable specular", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
{ "-noglow", "Disable glow maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
{ "-noenv", "Disable environment maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-env", },
{ "-nonormal", "Disable normal maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-normal" },
{ "-emissive_light", "Enable emissive light from ships", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-emissive_light" },
{ "-noheight", "Disable height/parallax maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noheight" },
{ "-noheight", "Disable height/parallax maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-height" },
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
{ "-no_post_process", "Disable post-processing", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_post_process" },
{ "-soft_particles", "Enable soft particles", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
{ "-fxaa", "Enable FXAA anti-aliasing", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
{ "-smaa", "Enable SMAA anti-aliasing", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-smaa" },
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nolightshafts"},
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_explosions", },
{ "-fb_thrusters", "Enable Framebuffer Thrusters", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_thrusters", },
{ "-no_deferred", "Disable Deferred Lighting", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_deferred"},
{ "-enable_shadows", "Enable Shadows", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-enable_shadows"},
{ "-enable_shadows", "Enable Shadows", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_shadows"},
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
@@ -216,12 +216,12 @@ Flag exe_params[] =
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT | EASY_HI_MEM_OFF, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-use_gldrawelements", },
{ "-gl_finish", "Fix input lag on some ATI+Linux systems", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gl_finish", },
{ "-no_geo_effects", "Disable geometry shader for effects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_geo_effects", },
{ "-set_cpu_affinity", "Sets processor affinity to config value", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-set_cpu_affinity", },
{ "-no_geo_effects", "Disable geometry shader for effects", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-set_cpu_affinity", "Sets processor affinity to config value", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-nograb", "Disables mouse grabbing", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nograb", },
{ "-noshadercache", "Disables the shader cache", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noshadercache", },
#ifdef WIN32
{ "-fix_registry", "Use a different registry path", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fix_registry", },
{ "-fix_registry", "Use a different registry path", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
#endif
{ "-ingame_join", "Allow in-game joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
@@ -242,14 +242,13 @@ Flag exe_params[] =
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-save_render_target", },
{ "-verify_vps", "Spew VP CRCs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-verify_vps", },
{ "-reparse_mainhall", "Reparse mainhall.tbl when loading halls", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-reparse_mainhall", },
{ "-noninteractive", "Disables interactive dialogs", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noninteractive", },
{ "-profile_write_file", "Write profiling information to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_write_file", },
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
{ "-benchmark_mode", "Puts the game into benchmark mode", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-benchmark_mode", },
{ "-profile_frame_time","Profile frame time", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_time", },
{ "-profile_write_file", "Write profiling information to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_write_file", },
{ "-noninteractive", "Disables interactive dialogs", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noninteractive", },
{ "-json_profiling", "Generate JSON profiling output", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-json_profiling", },
{ "-profile_frame_time","Profile engine subsystems", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_timings", },
{ "-debug_window", "Enable the debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", },
{ "-gr_debug", "Output graphics debug information", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gr_debug", },
};
// clang-format on
@@ -479,8 +478,6 @@ cmdline_parm json_profiling("-json_profiling", NULL, AT_NONE); //Cmdline_json_pr
cmdline_parm show_video_info("-show_video_info", NULL, AT_NONE); //Cmdline_show_video_info
cmdline_parm frame_profile_arg("-profile_frame_time", NULL, AT_NONE); //Cmdline_frame_profile
cmdline_parm debug_window_arg("-debug_window", NULL, AT_NONE); // Cmdline_debug_window
cmdline_parm graphics_debug_output_arg("-gr_debug", nullptr, AT_NONE); // Cmdline_graphics_debug_output
cmdline_parm log_to_stdout_arg("-stdout_log", nullptr, AT_NONE); // Cmdline_log_to_stdout
char *Cmdline_start_mission = NULL;
@@ -510,8 +507,6 @@ bool Cmdline_json_profiling = false;
bool Cmdline_frame_profile = false;
bool Cmdline_show_video_info = false;
bool Cmdline_debug_window = false;
bool Cmdline_graphics_debug_output = false;
bool Cmdline_log_to_stdout = false;
// Other
cmdline_parm get_flags_arg(GET_FLAGS_STRING, "Output the launcher flags file", AT_STRING);
@@ -1877,6 +1872,8 @@ bool SetCmdlineParams()
Gr_aa_mode = AntiAliasMode::FXAA_Low;
}
}
Gr_aa_mode_last_frame = Gr_aa_mode;
}
if (smaa_arg.found()) {
@@ -1903,10 +1900,6 @@ bool SetCmdlineParams()
}
}
// If any of the AA presets were chosen, update the _last_frame AA mode to avoid an unnecessary
// shader recompile.
Gr_aa_mode_last_frame = Gr_aa_mode;
if ( glow_arg.found() )
Cmdline_glow = 0;
@@ -2140,14 +2133,6 @@ bool SetCmdlineParams()
Cmdline_debug_window = true;
}
if (graphics_debug_output_arg.found()) {
Cmdline_graphics_debug_output = true;
}
if (log_to_stdout_arg.found()) {
Cmdline_log_to_stdout = true;
}
if (show_video_info.found())
{
Cmdline_show_video_info = true;
-2
View File
@@ -147,7 +147,5 @@ extern bool Cmdline_json_profiling;
extern bool Cmdline_frame_profile;
extern bool Cmdline_show_video_info;
extern bool Cmdline_debug_window;
extern bool Cmdline_graphics_debug_output;
extern bool Cmdline_log_to_stdout;
#endif
+1 -1
View File
@@ -2304,7 +2304,7 @@ int check_control_used(int id, int key)
if ((Control_config[id].key_id == key) || joy_down_count(Control_config[id].joy_id, 1) ||
((Control_config[id].joy_id >= 0) && (Control_config[id].joy_id < MOUSE_NUM_BUTTONS) && mouse_down_count(1 << Control_config[id].joy_id))) {
//mprintf(("Key used %d\n", key));
//mprintf(("Key used %d", key));
control_used(id);
return 1;
}
@@ -17,7 +17,6 @@
#include "io/joy.h"
#include "io/key.h"
#include "localization/localize.h"
#include "options/Option.h"
#include "parse/parselo.h"
// z64: These enumerations MUST equal to those in controlsconfig.cpp...
@@ -33,29 +32,8 @@ int Failed_key_index;
// Joystick configuration
int Joy_dead_zone_size = 10;
auto DeadZoneOption =
options::OptionBuilder<int>("Input.JoystickDeadZone", "Deadzone", "The deadzone of the selected joystick.")
.category("Input")
.range(0, 45)
.level(options::ExpertLevel::Beginner)
.default_val(10)
.bind_to(&Joy_dead_zone_size)
.importance(1)
.finish();
int Joy_sensitivity = 9;
auto SensitivityOption =
options::OptionBuilder<int>("Input.JoystickSensitivity", "Sensitivity", "The sentitivity of the selected joystick.")
.category("Input")
.range(0, 9)
.level(options::ExpertLevel::Beginner)
.default_val(9)
.bind_to(&Joy_sensitivity)
.importance(2)
.finish();
int Invert_axis[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
int Invert_axis_defaults[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
+1 -1
View File
@@ -126,7 +126,7 @@ void AudioDecoder::handleDecodedFrame(AVFrame* frame) {
auto ret = av_samples_alloc(m_outData, &m_outLinesize, OUT_NUM_CHANNELS, m_outNumSamples,
OUT_SAMPLE_FORMAT, 1);
if (ret < 0) {
mprintf(("FFMPEG: Failed to allocate samples!!!\n"));
mprintf(("FFMPEG: Failed to allocate samples!!!"));
return;
}
+1 -3
View File
@@ -27,15 +27,13 @@ using namespace cutscene;
const int MAX_AUDIO_BUFFERS = 15;
std::unique_ptr<Decoder> findDecoder(__UNUSED const SCP_string& name, __UNUSED const PlaybackProperties& properties) {
#ifdef WITH_FFMPEG
std::unique_ptr<Decoder> findDecoder(const SCP_string& name, const PlaybackProperties& properties) {
{
std::unique_ptr<Decoder> ffmpeg(new ::cutscene::ffmpeg::FFMPEGDecoder());
if (ffmpeg->initialize(name, properties)) {
return ffmpeg;
}
}
#endif
return nullptr;
}
+2 -1
View File
@@ -468,9 +468,10 @@ void renderAll() {
return;
}
graphics::decal_draw_list draw_list;
auto mission_time = f2fl(Missiontime);
graphics::decal_draw_list draw_list(active_decals.size());
for (auto& decal : active_decals) {
int diffuse_bm = -1;
int glow_bm = -1;
+1 -7
View File
@@ -3,15 +3,9 @@
in vec4 fragTexCoord;
in vec4 fragColor;
out vec4 fragOut0;
uniform sampler2DArray baseMap;
layout (std140) uniform genericData {
vec4 color;
float intensity;
};
uniform float intensity;
void main()
{
+3 -12
View File
@@ -1,20 +1,11 @@
in vec4 vertPosition;
in vec4 vertTexCoord;
in vec4 vertColor;
out vec4 fragTexCoord;
out vec4 fragColor;
layout (std140) uniform matrixData {
mat4 modelViewMatrix;
mat4 projMatrix;
};
layout (std140) uniform genericData {
vec4 color;
float intensity;
};
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
uniform vec4 color;
void main()
{
fragTexCoord = vec4(vertTexCoord.xyz, 0.0);
+3 -10
View File
@@ -1,15 +1,8 @@
in vec4 fragTexCoord;
out vec4 fragOut0;
uniform sampler2D bloomed;
layout (std140) uniform genericData {
float bloom_intensity;
int levels;
};
uniform float bloom_intensity;
uniform int levels;
void main() {
vec4 color_out = vec4(0.0, 0.0, 0.0, 1.0);
float factor = 0.0;
@@ -21,4 +14,4 @@ void main() {
color_out.rgb /= factor;
color_out.rgb *= bloom_intensity;
fragOut0 = color_out;
}
}
+8 -15
View File
@@ -1,16 +1,9 @@
out vec4 fragOut0;
uniform float texSize;
uniform float tapSize;
uniform int level;
in vec4 fragTexCoord;
uniform sampler2D tex;
const float TapSize = 1.0;
layout (std140) uniform genericData {
float texSize;
int level;
};
// Gaussian Blur
// 2 passes required
void main()
@@ -27,15 +20,15 @@ void main()
vec4 sum = textureLod(tex, fragTexCoord.xy, float(level)) * BlurWeights[0];
#ifdef PASS_0
for (int i = 1; i < 6; i++) {
sum += textureLod(tex, vec2(clamp(fragTexCoord.x - float(i) * (texSize) * TapSize, 0.0, 1.0), fragTexCoord.y), float(level)) * BlurWeights[i];
sum += textureLod(tex, vec2(clamp(fragTexCoord.x + float(i) * (texSize) * TapSize, 0.0, 1.0), fragTexCoord.y), float(level)) * BlurWeights[i];
sum += textureLod(tex, vec2(clamp(fragTexCoord.x - float(i) * (texSize) * tapSize, 0.0, 1.0), fragTexCoord.y), float(level)) * BlurWeights[i];
sum += textureLod(tex, vec2(clamp(fragTexCoord.x + float(i) * (texSize) * tapSize, 0.0, 1.0), fragTexCoord.y), float(level)) * BlurWeights[i];
}
#endif
#ifdef PASS_1
for (int i = 1; i < 6; i++) {
sum += textureLod(tex, vec2(fragTexCoord.x, clamp(fragTexCoord.y - float(i) * (texSize) * TapSize, 0.0, 1.0)), float(level)) * BlurWeights[i];
sum += textureLod(tex, vec2(fragTexCoord.x, clamp(fragTexCoord.y + float(i) * (texSize) * TapSize, 0.0, 1.0)), float(level)) * BlurWeights[i];
sum += textureLod(tex, vec2(fragTexCoord.x, clamp(fragTexCoord.y - float(i) * (texSize) * tapSize, 0.0, 1.0)), float(level)) * BlurWeights[i];
sum += textureLod(tex, vec2(fragTexCoord.x, clamp(fragTexCoord.y + float(i) * (texSize) * tapSize, 0.0, 1.0)), float(level)) * BlurWeights[i];
}
#endif
fragOut0 = sum;
}
}
@@ -6,23 +6,12 @@ in vec4 fragColor;
out vec4 fragOut0;
uniform sampler2DArray baseMap;
layout (std140) uniform genericData {
mat4 modelMatrix;
vec4 color;
vec4 clipEquation;
int baseMapIndex;
int alphaTexture;
int noTexturing;
int srgb;
float intensity;
float alphaThreshold;
bool clipEnabled;
};
uniform int baseMapIndex;
uniform int alphaTexture;
uniform int noTexturing;
uniform int srgb;
uniform float intensity;
uniform float alphaThreshold;
void main()
{
@@ -1,38 +0,0 @@
in vec4 vertPosition;
in vec4 vertTexCoord;
in vec4 vertColor;
out vec4 fragTexCoord;
out vec4 fragColor;
layout (std140) uniform matrixData {
mat4 modelViewMatrix;
mat4 projMatrix;
};
layout (std140) uniform genericData {
mat4 modelMatrix;
vec4 color;
vec4 clipEquation;
int baseMapIndex;
int alphaTexture;
int noTexturing;
int srgb;
float intensity;
float alphaThreshold;
bool clipEnabled;
};
void main()
{
fragTexCoord = vertTexCoord;
fragColor = vertColor * color;
gl_Position = projMatrix * modelViewMatrix * vertPosition;
if (clipEnabled) {
gl_ClipDistance[0] = dot(clipEquation, modelMatrix * vertPosition);
}
}
+2 -5
View File
@@ -2,11 +2,8 @@
#include "lighting.sdr"
in vec4 vertPosition;
layout (std140) uniform matrixData {
mat4 modelViewMatrix;
mat4 projMatrix;
};
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
layout (std140) uniform lightData {
vec3 diffuseLightColor;
@@ -1,20 +1,13 @@
in vec4 fragTexCoord;
in vec4 fragColor;
in float fragOffset;
out vec4 fragOut0;
uniform sampler2DArray baseMap;
uniform sampler2D depthMap;
uniform float window_width;
uniform float window_height;
uniform sampler2D distMap;
uniform sampler2D frameBuffer;
layout (std140) uniform genericData {
float window_width;
float window_height;
float use_offset;
};
void main()
{
vec2 depthCoord = vec2(gl_FragCoord.x / window_width, gl_FragCoord.y / window_height);
@@ -5,18 +5,9 @@ in float vertRadius;
out vec4 fragTexCoord;
out vec4 fragColor;
out float fragOffset;
layout (std140) uniform matrixData {
mat4 modelViewMatrix;
mat4 projMatrix;
};
layout (std140) uniform genericData {
float window_width;
float window_height;
float use_offset;
};
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
uniform float use_offset;
void main()
{
gl_Position = projMatrix * modelViewMatrix * vertPosition;
@@ -1,27 +1,21 @@
#include "gamma.sdr"
uniform sampler2DArray baseMap;
uniform sampler2D depthMap;
uniform float window_width;
uniform float window_height;
uniform float nearZ;
uniform float farZ;
uniform int linear_depth;
uniform int srgb;
uniform int blend_alpha;
in float fragRadius;
in vec4 fragPosition;
in vec4 fragTexCoord;
in vec4 fragColor;
out vec4 fragOut0;
uniform sampler2DArray baseMap;
uniform sampler2D depthMap;
layout (std140) uniform genericData {
float window_width;
float window_height;
float nearZ;
float farZ;
int linear_depth;
int srgb;
int blend_alpha;
};
void main()
{
vec4 fragmentColor = texture(baseMap, fragTexCoord.xyz);
@@ -1,21 +1,14 @@
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
in vec3 geoUvec[];
in float geoRadius[];
in vec4 geoColor[];
in float geoArrayIndex[];
out float fragRadius;
out vec4 fragPosition;
out vec4 fragTexCoord;
out vec4 fragColor;
layout (std140) uniform matrixData {
mat4 modelViewMatrix;
mat4 projMatrix;
};
uniform mat4 projMatrix;
void main(void)
{
vec3 forward_vec = vec3(0.0, 0.0, 1.0);
+22 -21
View File
@@ -1,9 +1,7 @@
in vec4 vertPosition;
in vec4 vertTexCoord;
in vec4 vertColor;
in float vertRadius;
#ifdef FLAG_EFFECT_GEOMETRY
in vec3 vertUvec;
out vec3 geoUvec;
@@ -16,25 +14,28 @@ in float vertRadius;
out vec4 fragTexCoord;
out vec4 fragColor;
#endif
layout (std140) uniform matrixData {
mat4 modelViewMatrix;
mat4 projMatrix;
};
#ifdef FLAG_EFFECT_DISTORTION
out float fragOffset;
uniform float use_offset;
#endif
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
void main()
{
#ifdef FLAG_EFFECT_GEOMETRY
geoRadius = vertRadius;
geoUvec = vertUvec;
gl_Position = modelViewMatrix * vertPosition;
geoColor = vertColor;
geoArrayIndex = vertTexCoord.z;
#else
fragRadius = vertRadius;
gl_Position = projMatrix * modelViewMatrix * vertPosition;
fragPosition = modelViewMatrix * vertPosition;
fragTexCoord = vec4(vertTexCoord.xyz, 0.0);
fragColor = vertColor;
#endif
#ifdef FLAG_EFFECT_GEOMETRY
geoRadius = vertRadius;
geoUvec = vertUvec;
gl_Position = modelViewMatrix * vertPosition;
geoColor = vertColor;
geoArrayIndex = vertTexCoord.z;
#else
fragRadius = vertRadius;
gl_Position = projMatrix * modelViewMatrix * vertPosition;
fragPosition = modelViewMatrix * vertPosition;
fragTexCoord = vec4(vertTexCoord.xyz, 0.0);
fragColor = vertColor;
#endif
#ifdef FLAG_EFFECT_DISTORTION
fragOffset = vertRadius * use_offset;
#endif
}
+5 -9
View File
@@ -2,20 +2,16 @@
#include "gamma.sdr"
in vec4 fragTexCoord;
out vec4 fragOut0;
uniform sampler2D tex;
uniform sampler2D depth_tex;
layout (std140) uniform genericData {
vec3 fog_color;
float fog_start;
float fog_scale;
float zNear;
float zFar;
};
uniform float fog_start;
uniform float fog_scale;
uniform vec3 fog_color;
uniform float zNear;
uniform float zFar;
void main()
{
+2 -7
View File
@@ -1,14 +1,9 @@
in vec4 vertPosition;
uniform float rt_w;
uniform float rt_h;
out vec2 v_rcpFrame;
noperspective out vec2 v_pos;
layout (std140) uniform genericData {
float rt_w;
float rt_h;
};
void main() {
gl_Position = vertPosition;
v_rcpFrame = vec2(1.0/rt_w, 1.0/rt_h);
+7 -14
View File
@@ -1,20 +1,13 @@
in vec4 fragTexCoord;
out vec4 fragOut0;
uniform sampler2D scene;
uniform sampler2D cockpit;
layout (std140) uniform genericData {
vec2 sun_pos;
float density;
float weight;
float falloff;
float intensity;
float cp_intensity;
};
uniform vec2 sun_pos;
uniform float density;
uniform float weight;
uniform float falloff;
uniform float intensity;
uniform float cp_intensity;
void main()
{
vec2 step = vec2( fragTexCoord.st - sun_pos.xy );
@@ -36,4 +29,4 @@ void main()
}
fragOut0 = sum * intensity;
fragOut0.a = 1.0;
}
}
@@ -4,13 +4,9 @@
in vec4 fragTexCoord;
in vec4 fragColor;
out vec4 fragOut0;
uniform sampler2D baseMap;
layout (std140) uniform genericData {
int noTexturing;
int srgb;
};
uniform int noTexturing;
uniform int srgb;
void main()
{
+11 -5
View File
@@ -3,15 +3,21 @@ in vec4 vertTexCoord;
in vec4 vertColor;
out vec4 fragTexCoord;
out vec4 fragColor;
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
uniform vec4 color;
layout (std140) uniform matrixData {
mat4 modelViewMatrix;
mat4 projMatrix;
};
uniform mat4 modelMatrix;
uniform bool clipEnabled;
uniform vec4 clipEquation;
void main()
{
fragTexCoord = vertTexCoord;
fragColor = vertColor;
fragColor = vertColor * color;
gl_Position = projMatrix * modelViewMatrix * vertPosition;
if (clipEnabled) {
gl_ClipDistance[0] = dot(clipEquation, modelMatrix * vertPosition);
}
}
+29 -18
View File
@@ -1,25 +1,36 @@
in vec4 fragTexCoord;
out vec4 fragOut0;
uniform sampler2D tex;
uniform float timer;
#ifdef FLAG_DISTORT_NOISE
uniform float noise_amount;
#endif
#ifdef FLAG_SATURATION
uniform float saturation;
#endif
#ifdef FLAG_BRIGHTNESS
uniform float brightness;
#endif
#ifdef FLAG_CONTRAST
uniform float contrast;
#endif
#ifdef FLAG_GRAIN
uniform float film_grain;
#endif
#ifdef FLAG_STRIPES
uniform float tv_stripes;
#endif
#ifdef FLAG_CUTOFF
uniform float cutoff;
#endif
#ifdef FLAG_DITH
uniform float dither;
#endif
#ifdef FLAG_TINT
uniform vec3 tint;
#endif
uniform sampler2D blurred_tex;
uniform sampler2D depth_tex;
layout (std140) uniform genericData {
float timer;
float noise_amount;
float saturation;
float brightness;
float contrast;
float film_grain;
float tv_stripes;
float cutoff;
vec3 tint;
float dither;
};
void main()
{
#ifdef FLAG_DISTORT_NOISE
+3 -1
View File
@@ -1,8 +1,10 @@
in vec4 vertPosition;
in vec4 vertTexCoord;
out vec4 fragTexCoord;
out float blurSize;
uniform float bsize;
void main()
{
fragTexCoord = vertTexCoord;
gl_Position = vertPosition;
}
}
+2 -8
View File
@@ -4,15 +4,9 @@ in vec4 fragColor;
out vec4 fragOut0;
uniform bool textured;
uniform sampler2DArray baseMap;
layout (std140) uniform genericData {
mat4 modelViewMatrix;
mat4 projMatrix;
bool textured;
int baseMapIndex;
};
uniform int baseMapIndex;
void main() {
if (textured) {
+2 -7
View File
@@ -6,13 +6,8 @@ in vec2 vertTexCoord;
out vec2 fragTexCoord;
out vec4 fragColor;
layout (std140) uniform genericData {
mat4 modelViewMatrix;
mat4 projMatrix;
bool textured;
int baseMapIndex;
};
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
void main()
{
@@ -0,0 +1,10 @@
in vec4 fragTexCoord;
out vec4 fragOut0;
uniform sampler2DArray shadow_map;
//uniform sampler2D shadow_map;
uniform int index;
void main()
{
vec3 texcoord = vec3(fragTexCoord.xy, float(index));
fragOut0 = vec4(texture(shadow_map, texcoord).rgb,1.0);
}
@@ -0,0 +1,8 @@
in vec4 vertPosition;
in vec4 vertTexCoord;
out vec4 fragTexCoord;
void main()
{
fragTexCoord = vertTexCoord;
gl_Position = vertPosition;
}
@@ -1,27 +1,14 @@
#include "gamma.sdr"
const float EMISSIVE_GAIN = 2.0;
in vec4 fragImpactUV;
in float fragNormOffset;
out vec4 fragOut0;
uniform vec4 color;
uniform sampler2DArray shieldMap;
layout (std140) uniform genericData {
mat4 shieldModelViewMatrix;
mat4 shieldProjMatrix;
vec3 hitNormal;
int srgb;
vec4 color;
int shieldMapIndex;
};
uniform int shieldMapIndex;
uniform int srgb;
out vec4 fragOut0;
#define EMISSIVE_GAIN 2.0
void main()
{
if(fragNormOffset < 0.0) discard;
@@ -1,28 +1,12 @@
in vec4 vertPosition;
in vec3 vertNormal;
out vec4 fragImpactUV;
out float fragNormOffset;
layout (std140) uniform matrixData {
mat4 modelViewMatrix;
mat4 projMatrix;
};
layout (std140) uniform genericData {
mat4 shieldModelViewMatrix;
mat4 shieldProjMatrix;
vec3 hitNormal;
int srgb;
vec4 color;
int shieldMapIndex;
};
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
uniform vec3 hitNormal;
uniform mat4 shieldModelViewMatrix;
uniform mat4 shieldProjMatrix;
void main()
{
gl_Position = projMatrix * modelViewMatrix * vertPosition;
@@ -31,4 +15,4 @@ void main()
fragImpactUV = shieldProjMatrix * shieldModelViewMatrix * vertPosition;
fragImpactUV += 1.0f;
fragImpactUV *= 0.5f;
}
}
+1 -3
View File
@@ -1,7 +1,5 @@
layout (std140) uniform genericData {
vec2 smaa_rt_metrics;
};
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
+1 -3
View File
@@ -1,7 +1,5 @@
layout (std140) uniform genericData {
vec2 smaa_rt_metrics;
};
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
+1 -3
View File
@@ -1,7 +1,5 @@
layout (std140) uniform genericData {
vec2 smaa_rt_metrics;
};
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
+1 -3
View File
@@ -1,7 +1,5 @@
layout (std140) uniform genericData {
vec2 smaa_rt_metrics;
};
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
@@ -1,7 +1,5 @@
layout (std140) uniform genericData {
vec2 smaa_rt_metrics;
};
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
@@ -1,7 +1,5 @@
layout (std140) uniform genericData {
vec2 smaa_rt_metrics;
};
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
@@ -4,11 +4,7 @@
in vec4 fragTexCoord;
out vec4 fragOut0;
uniform sampler2D tex;
layout (std140) uniform genericData {
float exposure;
};
uniform float exposure;
vec3 Uncharted2Tonemapping(vec3 hdr_color)
{
float A = 0.15;
+3 -7
View File
@@ -1,14 +1,10 @@
in vec4 vertPosition;
in vec4 vertTexCoord;
out vec4 fragTexCoord;
layout (std140) uniform matrixData {
mat4 modelViewMatrix;
mat4 projMatrix;
};
uniform mat4 modelViewMatrix;
uniform mat4 projMatrix;
void main()
{
fragTexCoord = vertTexCoord;
gl_Position = projMatrix * modelViewMatrix * vertPosition;
}
}
+1 -2
View File
@@ -54,7 +54,6 @@ static auto WarpOption = options::OptionBuilder<bool>("Graphics.3dWarp", "3D War
.bind_to(&Fireball_use_3d_warp)
.importance(65)
.finish();
/**
* Play warp in sound for warp effect
*/
@@ -74,7 +73,7 @@ void fireball_play_warphole_open_sound(int ship_class, fireball *fb)
if(fb->warp_open_sound_index.isValid()) {
sound_index = fb->warp_open_sound_index;
} else if ((ship_class >= 0) && (ship_class < ship_info_size())) {
} else if ((ship_class >= 0) && (ship_class < static_cast<int>(Ship_info.size()))) {
if ( Ship_info[ship_class].is_huge_ship() ) {
sound_index = gamesnd_id(GameSounds::CAPITAL_WARP_IN);
fb->flags |= FBF_WARP_CAPITAL_SIZE;
+15 -44
View File
@@ -1,15 +1,17 @@
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
#include "gamesnd/eventmusic.h"
#include "cmdline/cmdline.h"
#include "gamesnd/eventmusic.h"
#include "globalincs/linklist.h"
#include "iff_defs/iff_defs.h"
#include "io/timer.h"
@@ -17,12 +19,12 @@
#include "mission/missiongoals.h"
#include "mission/missionparse.h"
#include "object/object.h"
#include "options/Option.h"
#include "parse/parselo.h"
#include "ship/ship.h"
#include "sound/audiostr.h"
#include "sound/sound.h"
#ifdef _MSC_VER
#pragma optimize("", off)
#endif
@@ -36,23 +38,6 @@ int Event_Music_battle_started = 0;
float Default_music_volume = 0.5f; // range is 0->1
float Master_event_music_volume = Default_music_volume;
static bool music_volume_change_listener(float new_val, bool /*initial*/)
{
Assertion(new_val >= 0.0f && new_val <= 1.0f, "Invalid value %f supplied by options system!", new_val);
event_music_set_volume(new_val);
return true;
}
static auto MusicVolumeOption = options::OptionBuilder<float>("Audio.Music", "Music", "Volume used for playing music")
.category("Audio")
.default_val(Default_music_volume)
.range(0.0f, 1.0f)
.change_listener(music_volume_change_listener)
.importance(1)
.finish();
typedef struct tagSNDPATTERN {
int default_next_pattern; // Needed so the next_pattern member can be reset
int next_pattern; // Next pattern to play at loop time (can be same pattern)
@@ -532,7 +517,7 @@ void event_music_do_frame()
}
// -------------------------------------------------------------------------------------------------
// event_music_level_start()
// event_music_level_init()
//
// Called at the start of a mission (level). Sets up the pattern data, and kicks off the
// first track to play().
@@ -540,7 +525,7 @@ void event_music_do_frame()
// input: force_soundtrack => OPTIONAL parameter (default value -1)
// forces the soundtrack to ignore the music.tbl assignment
//
void event_music_level_start(int force_soundtrack)
void event_music_level_init(int force_soundtrack)
{
int i;
SOUNDTRACK_INFO *strack;
@@ -558,7 +543,8 @@ void event_music_level_start(int force_soundtrack)
if (Event_music_inited == FALSE)
return;
if (force_soundtrack != -1)
Current_soundtrack_num = force_soundtrack;
@@ -643,7 +629,7 @@ void event_music_first_pattern()
}
if ( Event_music_level_inited == FALSE ) {
event_music_level_start();
event_music_level_init();
}
if ( Event_music_level_inited == FALSE ) { //-V581
@@ -704,7 +690,6 @@ void event_music_level_close()
audiostream_close_all(0);
}
Current_soundtrack_num = -1;
Current_pattern = -1;
Event_music_level_inited = FALSE;
Event_Music_battle_started = FALSE;
@@ -1470,7 +1455,7 @@ void event_music_enable()
Event_music_enabled = TRUE;
if ( Event_music_level_inited == FALSE ) {
event_music_level_start();
event_music_level_init();
// start the first pattern to play (delayed)
if ( Game_mode & GM_IN_MISSION ) {
event_music_first_pattern();
@@ -1609,7 +1594,7 @@ int event_music_next_soundtrack(int delta)
new_soundtrack = 0;
event_music_level_close();
event_music_level_start(new_soundtrack);
event_music_level_init(new_soundtrack);
return Current_soundtrack_num;
}
@@ -1634,7 +1619,7 @@ void event_sexp_change_soundtrack(char *name)
event_music_level_close();
Current_soundtrack_num = -1;
event_music_level_start(new_soundtrack);
event_music_level_init(new_soundtrack);
}
// ----------------------------------------------------------------
@@ -1721,20 +1706,6 @@ void event_music_hostile_ship_destroyed()
Battle_over_timestamp = timestamp(BATTLE_CHECK_INTERVAL);
}
void event_music_set_volume(float volume)
{
Assertion(volume >= 0.0f && volume <= 1.0f, "Invalid event music volume %f!", volume);
Master_event_music_volume = volume;
event_music_set_volume_all(Master_event_music_volume);
if (Master_event_music_volume > 0.0f) {
event_music_enable();
} else {
event_music_disable();
}
}
#ifdef _MSC_VER
#pragma optimize("", on)
#endif
+1 -7
View File
@@ -97,7 +97,7 @@ extern int Num_soundtracks;
void event_music_init();
void event_music_close();
void event_music_level_start(int force_soundtrack = -1);
void event_music_level_init(int force_soundtrack = -1);
void event_music_level_close();
void event_music_do_frame();
void event_music_disable();
@@ -129,10 +129,4 @@ int event_music_player_respawn();
int event_music_player_respawn_as_observer();
void event_music_hostile_ship_destroyed();
/**
* @brief Sets the master music volume to the specified value
* @param volume The new music volume value. Must be in the range [0, 1].
*/
void event_music_set_volume(float volume);
#endif /* __EVENT_MUSIC_H__ */
+20 -28
View File
@@ -1207,37 +1207,29 @@ void parse_sound_table(const char* filename)
// parse flyby sound section
if (optional_string("#Flyby Sounds Start"))
{
// try parsing sounds for each species
// Note 1: instead of going through Species_info and requiring a sound for each species,
// we now parse the token and extract the species name from it
// Note 2: if a species doesn't have a flyby sound, the flyby code will just not play anything
while (!check_for_string("#Flyby Sounds End"))
char species_name_tag[NAME_LENGTH + 2];
int sanity_check = 0;
size_t i;
while (!check_for_string("#Flyby Sounds End") && (sanity_check <= (int)Species_info.size()))
{
char species_name_tag[NAME_LENGTH + 2];
stuff_string_until(species_name_tag, ":", NAME_LENGTH + 2);
if (species_name_tag[0] != '$')
for (i = 0; i < Species_info.size(); i++)
{
error_display(0, "Unexpected token tag %s", species_name_tag);
advance_to_eoln(nullptr);
continue;
species_info *species = &Species_info[i];
sprintf(species_name_tag, "$%s:", species->species_name);
if (check_for_string(species_name_tag))
{
gamesnd_parse_line(&species->snd_flyby_fighter, species_name_tag);
gamesnd_parse_line(&species->snd_flyby_bomber, species_name_tag);
sanity_check--;
}
else
{
sanity_check++;
}
}
int idx = species_info_lookup(&species_name_tag[1]);
if (idx < 0)
{
mprintf(("Skipping flyby sound for unknown species %s\n", &species_name_tag[1]));
advance_to_eoln(nullptr);
continue;
}
// now we have a known species
species_info *species = &Species_info[idx];
strcat_s(species_name_tag, ":"); // put back the terminator to restore the entire tag
// parse the two sounds for it
gamesnd_parse_line(&species->snd_flyby_fighter, ":"); // since we stuffed most of the tag, the : is all that remains on this line
gamesnd_parse_line(&species->snd_flyby_bomber, species_name_tag); // for the subsequent line we use required_string on the whole tag
}
required_string("#Flyby Sounds End");
+6 -23
View File
@@ -45,12 +45,6 @@
#define DIR_SEPARATOR_STR "/"
#endif
#ifndef NDEBUG
constexpr bool FSO_DEBUG = true;
#else
constexpr bool FSO_DEBUG = false;
#endif
typedef std::int32_t _fs_time_t; // time_t here is 64-bit and we need 32-bit
typedef std::int32_t fix;
@@ -232,17 +226,12 @@ extern int Global_error_count;
// To debug printf do this:
// mprintf(( "Error opening %s\n", filename ));
#ifndef NDEBUG
constexpr bool LoggingEnabled = true;
#define mprintf(args) outwnd_printf2 args
#define nprintf(args) outwnd_printf args
#else
#ifdef SCP_RELEASE_LOGGING
constexpr bool LoggingEnabled = true;
#else
constexpr bool LoggingEnabled = false;
#define mprintf(args)
#define nprintf(args)
#endif
#endif
#define mprintf(args) do { if (LoggingEnabled) { outwnd_printf2 args; } } while (false)
#define nprintf(args) do { if (LoggingEnabled) { outwnd_printf args; } } while (false)
#define LOCATION __FILE__,__LINE__
@@ -457,7 +446,7 @@ SCP_string dump_stacktrace();
// DEBUG compile time catch for dangerous uses of memset/memcpy/memmove
// This is disabled for VS2013 and lower since that doesn't support the necessary features
#if !defined(NDEBUG) && !defined(USING_THIRD_PARTY_LIBS) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
#if SCP_COMPILER_CXX_AUTO_TYPE && SCP_COMPILER_CXX_STATIC_ASSERT && HAVE_STD_IS_TRIVIALLY_COPYABLE
#if SCP_COMPILER_CXX_AUTO_TYPE && SCP_COMPILER_CXX_STATIC_ASSERT && defined(SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE)
// feature support seems to be: gcc clang msvc
// auto 4.4 2.9 2010
// std::is_trivial 4.5 ? 2012 (2010 only duplicates std::is_pod)
@@ -539,18 +528,12 @@ namespace std
#define memmove memmove_if_trivial_else_error
template<typename T, typename U>
inline void *memmove_if_trivial_else_error(T *memmove_dest, U *memmove_src, size_t count)
void *memmove_if_trivial_else_error(T *memmove_dest, U *memmove_src, size_t count)
{
static_assert(trivial_check<T>::value, "memmove on non-trivial object T");
static_assert(trivial_check<U>::value, "memmove on non-trivial object U");
return ptr_memmove(memmove_dest, memmove_src, count);
}
// Not really needed but else clang thinks ptr_memmove isn't used
inline void *memmove_if_trivial_else_error(void *memmove_dest, void *memmove_src, size_t count)
{
return ptr_memmove(memmove_dest, memmove_src, count);
}
}
// Put into global namespace
using std::memcpy_if_trivial_else_error;
+7 -58
View File
@@ -1,20 +1,20 @@
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
#include "globalincs/systemvars.h"
#include "debugconsole/console.h"
#include "globalincs/pstypes.h"
#include "globalincs/systemvars.h"
#include "graphics/2d.h"
#include "io/timer.h"
#include "nebula/neb.h"
#include "options/Option.h"
fix Missiontime;
fix Skybox_timestamp;
@@ -287,60 +287,9 @@ detail_levels Detail_defaults[NUM_DEFAULT_DETAIL_LEVELS] = {
},
};
// Global used to access detail levels in game and libs
detail_levels Detail = Detail_defaults[NUM_DEFAULT_DETAIL_LEVELS - 1];
const SCP_vector<std::pair<int, SCP_string>> DetailLevelValues = {{ 0, "Minimum" },
{ 1, "Low" },
{ 2, "Medium" },
{ 3, "High" },
{ 4, "Ultra" }, };
const auto ModelDetailOption =
options::OptionBuilder<int>("Graphics.Detail", "Model Detail", "Detail level of models").importance(8).category(
"Graphics").values(DetailLevelValues).default_val(MAX_DETAIL_LEVEL).change_listener([](int val, bool) {
Detail.detail_distance = val;
return true;
}).finish();
const auto TexturesOption = options::OptionBuilder<int>("Graphics.Texture",
"3D Hardware Textures",
"Level of detail of textures").importance(6).category("Graphics").values(
DetailLevelValues).default_val(MAX_DETAIL_LEVEL).change_listener([](int val, bool) {
Detail.hardware_textures = val;
return true;
}).finish();
const auto ParticlesOption = options::OptionBuilder<int>("Graphics.Particles",
"Particles",
"Level of detail for particles").importance(5).category(
"Graphics").values(DetailLevelValues).default_val(MAX_DETAIL_LEVEL).change_listener([](int val, bool) {
Detail.num_particles = val;
return true;
}).finish();
const auto SmallDebrisOption =
options::OptionBuilder<int>("Graphics.SmallDebris", "Impact Effects", "Level of detail of impact effects").category(
"Graphics").values(DetailLevelValues).default_val(MAX_DETAIL_LEVEL).importance(4).change_listener([](int val,
bool) {
Detail.num_small_debris = val;
return true;
}).finish();
const auto ShieldEffectsOption = options::OptionBuilder<int>("Graphics.ShieldEffects",
"Shield Hit Effects",
"Level of detail of shield impacts").importance(3).category(
"Graphics").values(DetailLevelValues).default_val(MAX_DETAIL_LEVEL).change_listener([](int val, bool) {
Detail.shield_effects = val;
return true;
}).finish();
const auto StarsOption =
options::OptionBuilder<int>("Graphics.Stars", "Stars", "Number of stars in the mission").importance(2).category(
"Graphics").values(DetailLevelValues).default_val(MAX_DETAIL_LEVEL).change_listener([](int val, bool) {
Detail.num_stars = val;
return true;
}).finish();
detail_levels Detail = Detail_defaults[NUM_DEFAULT_DETAIL_LEVELS-1];
// Call this with:
// 0 - lowest
-3
View File
@@ -147,9 +147,6 @@ SCP_string get_version_string()
case GR_OPENGL:
str += " OpenGL";
break;
case GR_VULKAN:
str += " Vulkan";
break;
}
return str;
+1 -1
View File
@@ -53,7 +53,7 @@ struct version {
int build = 0;
int revision = 0;
version() = default;
version() {}
version(int major, int minor, int build, int revision);
+116 -444
View File
@@ -1,59 +1,58 @@
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
#include "2d.h"
#include "globalincs/alphacolors.h"
#include "globalincs/systemvars.h"
#include "debug.h"
#include "grinternal.h"
#include "grstub.h"
#include "light.h"
#include "material.h"
#include "matrix.h"
#include "cmdline/cmdline.h"
#include "debugconsole/console.h"
#include "graphics/opengl/gropengl.h"
#include "graphics/paths/PathRenderer.h"
#include "graphics/util/GPUMemoryHeap.h"
#include "graphics/util/UniformBuffer.h"
#include "graphics/util/UniformBufferManager.h"
#include "graphics/vulkan/gr_vulkan.h"
#include "io/mouse.h"
#include "libs/jansson.h"
#include "options/Option.h"
#include "osapi/osapi.h"
#include "parse/parselo.h"
#include "popup/popup.h"
#include "render/3d.h"
#include "scripting/hook_api.h"
#include "scripting/scripting.h"
#include "tracing/tracing.h"
#include "utils/boost/hash_combine.h"
#include <SDL_surface.h>
#include <algorithm>
#include <climits>
#ifdef _WIN32
#include <windows.h>
#include <windowsx.h>
#endif
#if (SDL_VERSION_ATLEAST(1, 2, 7))
#include <climits>
#include <algorithm>
#include "cmdline/cmdline.h"
#include "debugconsole/console.h"
#include "gamesequence/gamesequence.h" //WMC - for scripting hooks in gr_flip()
#include "globalincs/systemvars.h"
#include "graphics/2d.h"
#include "graphics/font.h"
#include "graphics/grbatch.h"
#include "graphics/grinternal.h"
#include "graphics/grstub.h"
#include "graphics/light.h"
#include "graphics/matrix.h"
#include "graphics/opengl/gropengl.h"
#include "graphics/paths/PathRenderer.h"
#include "graphics/util/GPUMemoryHeap.h"
#include "graphics/util/UniformBuffer.h"
#include "graphics/util/UniformBufferManager.h"
#include "io/keycontrol.h" // m!m
#include "io/timer.h"
#include "libs/jansson.h"
#include "options/Option.h"
#include "osapi/osapi.h"
#include "parse/parselo.h"
#include "popup/popup.h"
#include "render/3d.h"
#include "scripting/scripting.h"
#include "tracing/tracing.h"
#include "utils/boost/hash_combine.h"
#if ( SDL_VERSION_ATLEAST(1, 2, 7) )
#include "SDL_cpuinfo.h"
#endif
const char* Resolution_prefixes[GR_NUM_RESOLUTIONS] = {"", "2_"};
#include "SDL_surface.h"
#include "material.h"
const char *Resolution_prefixes[GR_NUM_RESOLUTIONS] = { "", "2_" };
screen gr_screen;
@@ -74,107 +73,12 @@ int Gr_inited = 0;
uint Gr_signature = 0;
float Gr_gamma = 1.0f;
static SCP_vector<float> gamma_value_enumerator()
{
SCP_vector<float> vals;
// We want to divide the possible values into increments of 0.05
constexpr auto UPPER_LIMIT = (int)(5.0 / 0.05);
for (int i = 2; i <= UPPER_LIMIT; ++i) {
vals.push_back(0.05f * i);
}
return vals;
}
static SCP_string gamma_display(float value)
{
SCP_string out;
sprintf(out, "%.2f", value);
return out;
}
static bool gamma_change_listener(float new_val, bool initial)
{
if (!initial) {
// This is not valid for the initial config load since that happens before the graphics system is initialized
gr_set_gamma(new_val);
} else {
Gr_gamma = new_val;
}
return true;
}
static auto GammaOption =
options::OptionBuilder<float>("Graphics.Gamma", "Brightness", "The brighness value used for the game window")
.category("Graphics")
.default_val(1.0f)
.enumerator(gamma_value_enumerator)
.display(gamma_display)
.change_listener(gamma_change_listener)
.finish();
const SCP_vector<std::pair<int, SCP_string>> DetailLevelValues = {{ 0, "Minimum" },
{ 1, "Low" },
{ 2, "Medium" },
{ 3, "High" },
{ 4, "Ultra" }, };
const auto LightingOption = options::OptionBuilder<int>("Graphics.Lighting", "Lighting", "Level of detail of the lighting")
.importance(1)
.category("Graphics")
.values(DetailLevelValues)
.default_val(MAX_DETAIL_LEVEL)
.change_listener([](int val, bool initial) {
Detail.lighting = val;
if (!initial) {
gr_recompile_all_shaders(nullptr);
}
return true;
})
.finish();
os::ViewportState Gr_configured_window_state = os::ViewportState::Windowed;
static bool mode_change_func(os::ViewportState state, bool initial)
{
Gr_configured_window_state = state;
if (initial) {
return false;
}
auto window = os::getMainViewport();
if (window == nullptr) {
return false;
}
window->setState(state);
return true;
}
static auto WindowModeOption = options::OptionBuilder<os::ViewportState>("Graphics.WindowMode", "Window Mode",
"Controls how the game window is created.")
.category("Graphics")
.level(options::ExpertLevel::Beginner)
.values({{os::ViewportState::Fullscreen, "Fullscreen"},
{os::ViewportState::Borderless, "Borderless"},
{os::ViewportState::Windowed, "Windowed"}})
.importance(98)
.default_val(os::ViewportState::Fullscreen)
.change_listener(mode_change_func)
.finish();
const std::shared_ptr<scripting::OverridableHook> OnFrameHook = scripting::OverridableHook::Factory(
"On Frame", "Called every frame as the last action before showing the frame result to the user.", {}, CHA_ONFRAME);
float Gr_gamma = 1.8f;
int Gr_gamma_int = 180;
// z-buffer stuff
int gr_zbuffering = 0;
int gr_zbuffering_mode = 0;
int gr_zbuffering = 0;
int gr_zbuffering_mode = 0;
int gr_global_zbuffering = 0;
// stencil buffer stuff
@@ -204,8 +108,6 @@ bool Save_custom_screen_size;
bool Deferred_lighting = false;
bool High_dynamic_range = false;
static ushort* Gr_original_gamma_ramp = nullptr;
static int videodisplay_deserializer(const json_t* value)
{
int id;
@@ -317,7 +219,7 @@ static ResolutionInfo resolution_default()
if (SDL_GetDesktopDisplayMode(VideoDisplayOption->getValue(), &mode) != 0) {
return {};
}
return {(uint32_t)mode.w, (uint32_t)mode.h};
return ResolutionInfo(mode.w, mode.h);
}
static bool resolution_change(const ResolutionInfo& /*info*/, bool initial)
{
@@ -446,8 +348,6 @@ static auto VSyncOption = options::OptionBuilder<bool>("Graphis.VSync", "Vertica
.importance(70)
.finish();
static std::unique_ptr<graphics::util::UniformBufferManager> UniformBufferManager;
// Forward definitions
static void uniform_buffer_managers_init();
static void uniform_buffer_managers_deinit();
@@ -456,8 +356,7 @@ static void uniform_buffer_managers_retire_buffers();
static void gpu_heap_init();
static void gpu_heap_deinit();
void gr_set_screen_scale(int w, int h, int zoom_w, int zoom_h, int max_w, int max_h, int center_w, int center_h,
bool force_stretch)
void gr_set_screen_scale(int w, int h, int zoom_w, int zoom_h, int max_w, int max_h, int center_w, int center_h, bool force_stretch)
{
bool do_zoom = zoom_w > 0 && zoom_h > 0 && (zoom_w != w || zoom_h != h);
@@ -992,23 +891,10 @@ bool gr_unsize_screen_posf(float *x, float *y, float *w, float *h, int resize_mo
void gr_close()
{
if (!Gr_inited) {
if ( !Gr_inited ) {
return;
}
graphics::debug::cleanup();
if (Gr_original_gamma_ramp != nullptr && os::getSDLMainWindow() != nullptr) {
SDL_SetWindowGammaRamp(os::getSDLMainWindow(),
Gr_original_gamma_ramp,
(Gr_original_gamma_ramp + 256),
(Gr_original_gamma_ramp + 512));
}
// This is valid even if Gr_original_gamma_ramp is nullptr
vm_free(Gr_original_gamma_ramp);
Gr_original_gamma_ramp = nullptr;
gpu_heap_deinit();
// Cleanup uniform buffer managers
@@ -1128,108 +1014,12 @@ int gr_get_resolution_class(int width, int height)
}
}
static void init_colors()
{
int bpp = gr_screen.bits_per_pixel;
Assertion((bpp == 16) || (bpp == 32), "Invalid bits-per-pixel value %d!", bpp);
// screen format
switch (bpp) {
case 16: {
Gr_red.bits = 5;
Gr_red.shift = 11;
Gr_red.scale = 8;
Gr_red.mask = 0xF800;
Gr_green.bits = 6;
Gr_green.shift = 5;
Gr_green.scale = 4;
Gr_green.mask = 0x7E0;
Gr_blue.bits = 5;
Gr_blue.shift = 0;
Gr_blue.scale = 8;
Gr_blue.mask = 0x1F;
break;
}
case 32: {
Gr_red.bits = 8;
Gr_red.shift = 16;
Gr_red.scale = 1;
Gr_red.mask = 0xff0000;
Gr_green.bits = 8;
Gr_green.shift = 8;
Gr_green.scale = 1;
Gr_green.mask = 0x00ff00;
Gr_blue.bits = 8;
Gr_blue.shift = 0;
Gr_blue.scale = 1;
Gr_blue.mask = 0x0000ff;
Gr_alpha.bits = 8;
Gr_alpha.shift = 24;
Gr_alpha.mask = 0xff000000;
Gr_alpha.scale = 1;
break;
}
}
// texture format
Gr_t_red.bits = 5;
Gr_t_red.mask = 0x7c00;
Gr_t_red.shift = 10;
Gr_t_red.scale = 8;
Gr_t_green.bits = 5;
Gr_t_green.mask = 0x03e0;
Gr_t_green.shift = 5;
Gr_t_green.scale = 8;
Gr_t_blue.bits = 5;
Gr_t_blue.mask = 0x001f;
Gr_t_blue.shift = 0;
Gr_t_blue.scale = 8;
Gr_t_alpha.bits = 1;
Gr_t_alpha.mask = 0x8000;
Gr_t_alpha.scale = 255;
Gr_t_alpha.shift = 15;
// alpha-texture format
Gr_ta_red.bits = 4;
Gr_ta_red.mask = 0x0f00;
Gr_ta_red.shift = 8;
Gr_ta_red.scale = 17;
Gr_ta_green.bits = 4;
Gr_ta_green.mask = 0x00f0;
Gr_ta_green.shift = 4;
Gr_ta_green.scale = 17;
Gr_ta_blue.bits = 4;
Gr_ta_blue.mask = 0x000f;
Gr_ta_blue.shift = 0;
Gr_ta_blue.scale = 17;
Gr_ta_alpha.bits = 4;
Gr_ta_alpha.mask = 0xf000;
Gr_ta_alpha.shift = 12;
Gr_ta_alpha.scale = 17;
}
static bool gr_init_sub(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int mode, int width, int height,
int depth, float center_aspect_ratio)
static bool gr_init_sub(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int mode, int width, int height, int depth, float center_aspect_ratio)
{
int res = GR_1024;
bool rc = false;
memset(&gr_screen, 0, sizeof(screen));
memset( &gr_screen, 0, sizeof(screen) );
float aspect_ratio = (float)width / (float)height;
@@ -1314,31 +1104,26 @@ static bool gr_init_sub(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, i
gr_screen.clip_center_y = (gr_screen.clip_top + gr_screen.clip_bottom) * 0.5f;
if (gr_screen.custom_size) {
gr_unsize_screen_pos(&gr_screen.max_w_unscaled, &gr_screen.max_h_unscaled);
gr_unsize_screen_pos(&gr_screen.max_w_unscaled_zoomed, &gr_screen.max_h_unscaled_zoomed);
gr_unsize_screen_pos(&gr_screen.clip_right_unscaled, &gr_screen.clip_bottom_unscaled);
gr_unsize_screen_pos(&gr_screen.clip_width_unscaled, &gr_screen.clip_height_unscaled);
gr_unsize_screen_pos( &gr_screen.max_w_unscaled, &gr_screen.max_h_unscaled );
gr_unsize_screen_pos( &gr_screen.max_w_unscaled_zoomed, &gr_screen.max_h_unscaled_zoomed );
gr_unsize_screen_pos( &gr_screen.clip_right_unscaled, &gr_screen.clip_bottom_unscaled );
gr_unsize_screen_pos( &gr_screen.clip_width_unscaled, &gr_screen.clip_height_unscaled );
}
gr_screen.save_max_w_unscaled = gr_screen.max_w_unscaled;
gr_screen.save_max_h_unscaled = gr_screen.max_h_unscaled;
gr_screen.save_max_w_unscaled = gr_screen.max_w_unscaled;
gr_screen.save_max_h_unscaled = gr_screen.max_h_unscaled;
gr_screen.save_max_w_unscaled_zoomed = gr_screen.max_w_unscaled_zoomed;
gr_screen.save_max_h_unscaled_zoomed = gr_screen.max_h_unscaled_zoomed;
init_colors();
switch (mode) {
case GR_OPENGL:
rc = gr_opengl_init(std::move(graphicsOps));
break;
case GR_VULKAN:
rc = graphics::vulkan::initialize(std::move(graphicsOps));
break;
case GR_STUB:
rc = gr_stub_init();
break;
default:
Int3(); // Invalid graphics mode
case GR_OPENGL:
rc = gr_opengl_init(std::move(graphicsOps));
break;
case GR_STUB:
rc = gr_stub_init();
break;
default:
Int3(); // Invalid graphics mode
}
if ( !rc ) {
@@ -1460,17 +1245,6 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
if (sscanf(ptr + 5, "(%dx%d)x%d ", &width, &height, &depth) != 3) {
Error(LOCATION, "Can't understand 'VideocardFs2open' config entry!");
}
// Get the first 4 characters of the video string which is the chosen API
SCP_string videoApi(ptr, ptr + 4);
if (videoApi == "OGL ") {
d_mode = GR_OPENGL; // GR_OPENGL;
} else if (videoApi == "VK ") {
d_mode = GR_VULKAN;
} else {
ReleaseWarning(LOCATION, "Unknown video API '%s'", videoApi.c_str());
}
}
if (Cmdline_res != nullptr) {
@@ -1594,10 +1368,6 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
gpu_heap_init();
mprintf(("Checking graphics capabilities:\n"));
mprintf((" Persistent buffer mapping: %s\n",
gr_is_capable(CAPABILITY_PERSISTENT_BUFFER_MAPPING) ? "Enabled" : "Disabled"));
bool missing_installation = false;
if (!running_unittests && Web_cursor == nullptr) {
if (Is_standalone) {
@@ -1628,17 +1398,6 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
gr_set_shader(NULL);
if (!Is_standalone) {
if (Using_in_game_options) {
// The value should have been loaded into the variable already so we can use that here
gr_set_gamma(Gr_gamma);
} else {
// D3D's gamma system now works differently. 1.0 is the default value
ptr = os_config_read_string(nullptr, NOX("GammaD3D"), NOX("1.0"));
gr_set_gamma((float)atof(ptr));
}
}
Gr_inited = 1;
return true;
@@ -1650,6 +1409,15 @@ void gr_force_windowed()
return;
}
switch( gr_screen.mode ) {
case GR_OPENGL:
break;
case GR_STUB:
break;
default:
Int3(); // Invalid graphics mode
}
if ( Os_debugger_running ) {
os_sleep(1000);
}
@@ -1669,7 +1437,7 @@ void gr_activate(int active)
}
if (active) {
if (Cmdline_fullscreen_window || Cmdline_window) {
if (Cmdline_fullscreen_window||Cmdline_window) {
os::getMainViewport()->restore();
} else {
os::getMainViewport()->setState(os::ViewportState::Fullscreen);
@@ -1678,11 +1446,17 @@ void gr_activate(int active)
os::getMainViewport()->minimize();
}
if (active) {
if (!Cmdline_fullscreen_window && !Cmdline_window) {
gr_set_gamma(Gr_gamma);
}
switch( gr_screen.mode ) {
case GR_OPENGL:
extern void gr_opengl_activate(int active);
gr_opengl_activate(active);
break;
case GR_STUB:
break;
default:
Int3(); // Invalid graphics mode
}
}
// color stuff
@@ -2220,7 +1994,7 @@ int poly_list::find_first_vertex_fast(int idx)
if ( first_idx == sorted_indices + n_verts ) {
// if this happens then idx was never in the index list to begin with which is not good
mprintf(("Sorted index list missing index %d!\n", idx));
mprintf(("Sorted index list missing index %d!", idx));
Int3();
return idx;
}
@@ -2603,53 +2377,26 @@ bool poly_list::finder::operator()(const uint a, const uint b)
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
{
gr_screen.current_alpha = alpha;
gr_screen.current_alpha = alpha;
gr_screen.current_alphablend_mode = alphablend_mode;
gr_screen.current_bitblt_mode = bitblt_mode;
gr_screen.current_bitmap = bitmap_num;
}
static void output_uniform_debug_data()
{
int line_height = gr_get_font_height() + 1;
gr_set_color_fast(&Color_bright_white);
gr_printf_no_resize(gr_screen.center_offset_x + 20, gr_screen.center_offset_y + 160,
"Uniform buffer size: " SIZE_T_ARG, UniformBufferManager->getBufferSize());
gr_printf_no_resize(gr_screen.center_offset_x + 20, gr_screen.center_offset_y + 160 + line_height,
"Currently used data: " SIZE_T_ARG, UniformBufferManager->getCurrentlyUsedSize());
gr_screen.current_bitblt_mode = bitblt_mode;
gr_screen.current_bitmap = bitmap_num;
}
void gr_flip(bool execute_scripting)
{
TRACE_SCOPE(tracing::PageFlip);
// m!m avoid running CHA_ONFRAME when the "Quit mission" popup is shown. See mantis 2446 for reference
if (execute_scripting && !popup_active()) {
TRACE_SCOPE(tracing::LuaOnFrame);
// WMC - Do conditional hooks. Yippee!
OnFrameHook->run();
// WMC - Do scripting reset stuff
//WMC - Do conditional hooks. Yippee!
Script_system.RunCondition(CHA_ONFRAME);
//WMC - Do scripting reset stuff
Script_system.EndFrame();
}
graphics::debug::render_elements();
gr_reset_immediate_buffer();
// Do per frame operations on the matrix state
gr_matrix_on_frame();
gr_reset_clip();
mouse_reset_deltas();
if (Cmdline_graphics_debug_output) {
output_uniform_debug_data();
}
// Use this opportunity for retiring the uniform buffers
uniform_buffer_managers_retire_buffers();
@@ -2666,13 +2413,32 @@ void gr_print_timestamp(int x, int y, fix timestamp, int resize_mode)
gr_string(x, y, time.c_str(), resize_mode);
}
static void uniform_buffer_managers_init() { UniformBufferManager.reset(new graphics::util::UniformBufferManager()); }
static void uniform_buffer_managers_deinit() { UniformBufferManager.reset(); }
static void uniform_buffer_managers_retire_buffers() { UniformBufferManager->onFrameEnd(); }
graphics::util::UniformBuffer gr_get_uniform_buffer(uniform_block_type type, size_t num_elements, size_t element_size_override)
{
return UniformBufferManager->getUniformBuffer(type, num_elements, element_size_override);
static std::unique_ptr<graphics::util::UniformBufferManager>
uniform_buffer_managers[static_cast<size_t>(uniform_block_type::NUM_BLOCK_TYPES)];
static void uniform_buffer_managers_init() {
for (size_t i = 0; i < static_cast<size_t>(uniform_block_type::NUM_BLOCK_TYPES); ++i) {
auto enumVal = static_cast<uniform_block_type>(i);
uniform_buffer_managers[i].reset(new graphics::util::UniformBufferManager(enumVal));
}
}
static void uniform_buffer_managers_deinit() {
for (auto& manager: uniform_buffer_managers) {
manager.reset();
}
}
static void uniform_buffer_managers_retire_buffers() {
GR_DEBUG_SCOPE("Retiring unused uniform buffers");
for (auto& manager: uniform_buffer_managers) {
manager->retireBuffers();
}
}
graphics::util::UniformBuffer* gr_get_uniform_buffer(uniform_block_type type) {
return uniform_buffer_managers[static_cast<size_t>(type)]->getBuffer();
}
SCP_vector<DisplayData> gr_enumerate_displays()
@@ -2831,104 +2597,10 @@ void gr_heap_allocate(GpuHeap heap_type, size_t size, void* data, size_t& offset
handle_out = gpuHeap->bufferHandle();
}
void gr_heap_deallocate(GpuHeap heap_type, size_t data_offset)
{
void gr_heap_deallocate(GpuHeap heap_type, size_t data_offset) {
TRACE_SCOPE(tracing::GpuHeapDeallocate);
auto gpuHeap = get_gpu_heap(heap_type);
gpuHeap->freeGpuData(data_offset);
}
// I feel dirty...
static void make_gamma_ramp(float gamma, ushort* ramp)
{
ushort x, y;
ushort base_ramp[256];
Assert(ramp != nullptr);
// generate the base ramp values first off
// if no gamma set then just do this quickly
if (gamma <= 0.0f) {
memset(ramp, 0, 3 * 256 * sizeof(ushort));
return;
}
// identity gamma, avoid all of the math
else if (gamma == 1.0f || Gr_original_gamma_ramp == nullptr) {
if (Gr_original_gamma_ramp != nullptr) {
memcpy(ramp, Gr_original_gamma_ramp, 3 * 256 * sizeof(ushort));
}
// set identity if no original ramp
else {
for (x = 0; x < 256; x++) {
ramp[x] = (x << 8) | x;
ramp[x + 256] = (x << 8) | x;
ramp[x + 512] = (x << 8) | x;
}
}
return;
}
// for everything else we need to actually figure it up
else {
double g = 1.0 / (double)gamma;
double val;
Assert(Gr_original_gamma_ramp != nullptr);
for (x = 0; x < 256; x++) {
val = (pow(x / 255.0, g) * 65535.0 + 0.5);
CLAMP(val, 0, 65535);
base_ramp[x] = (ushort)val;
}
for (y = 0; y < 3; y++) {
for (x = 0; x < 256; x++) {
val = (base_ramp[x] * 2) - Gr_original_gamma_ramp[x + y * 256];
CLAMP(val, 0, 65535);
ramp[x + y * 256] = (ushort)val;
}
}
}
}
void gr_set_gamma(float gamma)
{
Gr_gamma = gamma;
// new way - but not while running FRED
if (!Fred_running && !Cmdline_no_set_gamma && os::getSDLMainWindow() != nullptr) {
if (Gr_original_gamma_ramp == nullptr) {
// First time we are here so get the current (original) gamma ramp here so we can reset it later
Gr_original_gamma_ramp = (ushort*)vm_malloc(3 * 256 * sizeof(ushort), memory::quiet_alloc);
if (Gr_original_gamma_ramp == nullptr) {
mprintf((" Unable to allocate memory for gamma ramp! Disabling...\n"));
Cmdline_no_set_gamma = 1;
} else {
SDL_GetWindowGammaRamp(os::getSDLMainWindow(), Gr_original_gamma_ramp, (Gr_original_gamma_ramp + 256),
(Gr_original_gamma_ramp + 512));
}
}
auto gamma_ramp = (ushort*)vm_malloc(3 * 256 * sizeof(ushort), memory::quiet_alloc);
if (gamma_ramp == nullptr) {
Int3();
return;
}
memset(gamma_ramp, 0, 3 * 256 * sizeof(ushort));
// Create the Gamma lookup table
make_gamma_ramp(gamma, gamma_ramp);
SDL_SetWindowGammaRamp(os::getSDLMainWindow(), gamma_ramp, (gamma_ramp + 256), (gamma_ramp + 512));
vm_free(gamma_ramp);
}
}
+30 -50
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
#ifndef _GRAPHICS_H
#define _GRAPHICS_H
#include "globalincs/flagset.h"
#include "globalincs/pstypes.h"
#include "bmpman/bmpman.h"
#include "cfile/cfile.h"
#include "globalincs/flagset.h"
#include "globalincs/pstypes.h"
#include "graphics/grinternal.h"
#include "graphics/tmapper.h"
#include "io/cursor.h"
@@ -26,10 +27,7 @@ namespace graphics {
namespace util {
class UniformBuffer;
class GPUMemoryHeap;
} // namespace util
} // namespace graphics
namespace scripting {
class OverridableHook;
}
}
extern const float Default_min_draw_distance;
@@ -48,16 +46,16 @@ FLAG_LIST(FramebufferEffects){Thrusters = 0, Shockwaves, NUM_VALUES};
extern flagset<FramebufferEffects> Gr_framebuffer_effects;
enum class AntiAliasMode {
None = 0,
None,
FXAA_Low = 1,
FXAA_Medium = 2,
FXAA_High = 3,
FXAA_Low,
FXAA_Medium,
FXAA_High,
SMAA_Low = 4,
SMAA_Medium = 5,
SMAA_High = 6,
SMAA_Ultra = 7,
SMAA_Low,
SMAA_Medium,
SMAA_High,
SMAA_Ultra,
};
extern AntiAliasMode Gr_aa_mode;
extern AntiAliasMode Gr_aa_mode_last_frame;
@@ -72,10 +70,6 @@ extern bool Gr_enable_vsync;
extern bool Deferred_lighting;
extern bool High_dynamic_range;
extern os::ViewportState Gr_configured_window_state;
extern const std::shared_ptr<scripting::OverridableHook> OnFrameHook;
class material;
class model_material;
class particle_material;
@@ -246,8 +240,6 @@ enum class uniform_block_type {
DecalInfo = 3,
DecalGlobals = 4,
DeferredGlobals = 5,
Matrices = 6,
GenericData = 7,
NUM_BLOCK_TYPES
};
@@ -329,7 +321,6 @@ typedef enum gr_capability {
CAPABILITY_POINT_PARTICLES,
CAPABILITY_TIMESTAMP_QUERY,
CAPABILITY_SEPARATE_BLEND_FUNCTIONS,
CAPABILITY_PERSISTENT_BUFFER_MAPPING,
} gr_capability;
enum class gr_property {
@@ -632,7 +623,11 @@ enum class BufferType {
Uniform
};
enum class BufferUsageHint { Static, Dynamic, Streaming, PersistentMapping };
enum class BufferUsageHint {
Static,
Dynamic,
Streaming
};
/**
* @brief Type of a graphics sync object
@@ -731,6 +726,9 @@ typedef struct screen {
// Frees up a saved screen.
void (*gf_free_screen)(int id);
// Sets the gamma
void (*gf_set_gamma)(float gamma);
// grab a region of the screen. assumes data is large enough
void (*gf_get_region)(int front, int w, int h, ubyte *data);
@@ -761,10 +759,8 @@ typedef struct screen {
int (*gf_create_buffer)(BufferType type, BufferUsageHint usage);
void (*gf_delete_buffer)(int handle);
void (*gf_update_buffer_data)(int handle, size_t size, const void* data);
void (*gf_update_buffer_data_offset)(int handle, size_t offset, size_t size, const void* data);
void* (*gf_map_buffer)(int handle);
void (*gf_flush_mapped_buffer)(int handle, size_t offset, size_t size);
void (*gf_update_buffer_data)(int handle, size_t size, void* data);
void (*gf_update_buffer_data_offset)(int handle, size_t offset, size_t size, void* data);
void (*gf_update_transform_buffer)(void* data, size_t size);
// postprocessing effects
@@ -853,8 +849,7 @@ typedef struct screen {
// # Software Re-added by Kazan --- THIS HAS TO STAY -- It is used by standalone!
#define GR_DEFAULT (-1) // set to use default settings
#define GR_STUB (100)
#define GR_OPENGL (104) // Use OpenGl hardware renderer
#define GR_VULKAN (105) // Use Vulkan hardware renderer
#define GR_OPENGL (104) // Use OpenGl hardware renderer
// resolution constants - always keep resolutions in ascending order and starting from 0
#define GR_NUM_RESOLUTIONS 2
@@ -959,6 +954,8 @@ void gr_set_bitmap(int bitmap_num, int alphablend = GR_ALPHABLEND_NONE, int bitb
#define gr_restore_screen GR_CALL(gr_screen.gf_restore_screen)
#define gr_free_screen GR_CALL(gr_screen.gf_free_screen)
#define gr_set_gamma GR_CALL(gr_screen.gf_set_gamma)
#define gr_get_region GR_CALL(gr_screen.gf_get_region)
#define gr_set_cull GR_CALL(gr_screen.gf_set_cull)
@@ -993,11 +990,6 @@ inline int gr_create_buffer(BufferType type, BufferUsageHint usage)
#define gr_delete_buffer GR_CALL(gr_screen.gf_delete_buffer)
#define gr_update_buffer_data GR_CALL(gr_screen.gf_update_buffer_data)
#define gr_update_buffer_data_offset GR_CALL(gr_screen.gf_update_buffer_data_offset)
inline void* gr_map_buffer(int handle) { return gr_screen.gf_map_buffer(handle); }
inline void gr_flush_mapped_buffer(int handle, size_t offset, size_t size)
{
gr_screen.gf_flush_mapped_buffer(handle, offset, size);
}
#define gr_update_transform_buffer GR_CALL(gr_screen.gf_update_transform_buffer)
#define gr_scene_texture_begin GR_CALL(gr_screen.gf_scene_texture_begin)
@@ -1216,16 +1208,7 @@ enum AnimatedShader {
ANIMATED_SHADER_CLOAK = 2,
};
/**
* @brief Retreives a uniform buffer for storing uniform block data
* @param type The type of uniform data that will be stored in the buffer
* @param num_elements The number of elements that will be used in the buffer
* @param element_size_override Override what the size of the element should be instead of relying on the preconfigured
* size for that block type
* @return A structure which gives access to a memory buffer where the uniform data can be stored
*/
graphics::util::UniformBuffer gr_get_uniform_buffer(uniform_block_type type, size_t num_elements,
size_t element_size_override = 0);
graphics::util::UniformBuffer* gr_get_uniform_buffer(uniform_block_type type);
struct VideoModeData {
uint32_t width = 0;
@@ -1271,9 +1254,6 @@ void gr_heap_allocate(GpuHeap heap_type, size_t size, void* data, size_t& offset
*/
void gr_heap_deallocate(GpuHeap heap_type, size_t data_offset);
void gr_set_gamma(float gamma);
// Include this last to make the 2D rendering function available everywhere
#include "graphics/render.h"
-146
View File
@@ -1,146 +0,0 @@
#include "debug.h"
#include "render/3dinternal.h"
namespace graphics {
namespace debug {
namespace {
enum DebugElementType {
Line,
Text,
};
struct LineParams {
vertex projected_from;
vertex projected_to;
color line_color;
};
struct TextParams {
vertex projected_pos;
color text_color;
SCP_string text;
};
struct DebugElement {
DebugElementType type;
// A variant/union would be good here but our C++ version does not support that yet
LineParams lineParams;
TextParams textParams;
};
bool vertex_offscreen(const vertex& v) { return v.flags & PF_OVERFLOW; }
SCP_vector<DebugElement> debugElements;
void render_line(LineParams& lineParams)
{
if (vertex_offscreen(lineParams.projected_from) && vertex_offscreen(lineParams.projected_to)) {
return;
}
gr_set_color_fast(&lineParams.line_color);
gr_line(lineParams.projected_from.screen.xyw.x,
lineParams.projected_from.screen.xyw.y,
lineParams.projected_to.screen.xyw.x,
lineParams.projected_to.screen.xyw.y,
GR_RESIZE_NONE);
}
void render_text(TextParams& params)
{
if (vertex_offscreen(params.projected_pos)) {
return;
}
font::set_font(font::FONT1);
gr_set_color_fast(&params.text_color);
gr_string(params.projected_pos.screen.xyw.x,
params.projected_pos.screen.xyw.y,
params.text.c_str(),
GR_RESIZE_NONE);
}
void render_element(DebugElement& el)
{
switch (el.type) {
case Line:
render_line(el.lineParams);
break;
case Text:
render_text(el.textParams);
break;
default:
UNREACHABLE("Unknown debug element type!");
}
}
} // namespace
void line_3d(const vec3d* from, const vec3d* to, const color* color)
{
DebugElement el;
el.type = DebugElementType::Line;
bool do_g3 = G3_count < 1;
if (do_g3)
g3_start_frame(0);
g3_rotate_vertex(&el.lineParams.projected_from, from);
g3_project_vertex(&el.lineParams.projected_from);
g3_rotate_vertex(&el.lineParams.projected_to, to);
g3_project_vertex(&el.lineParams.projected_to);
if (do_g3)
g3_end_frame();
el.lineParams.line_color = *color;
debugElements.push_back(el);
}
void text_3d(const vec3d* world_pos, const color* color, SCP_string text)
{
DebugElement el;
el.type = DebugElementType::Text;
bool do_g3 = G3_count < 1;
if (do_g3)
g3_start_frame(0);
g3_rotate_vertex(&el.textParams.projected_pos, world_pos);
g3_project_vertex(&el.textParams.projected_pos);
if (do_g3)
g3_end_frame();
el.textParams.text_color = *color;
el.textParams.text = std::move(text);
debugElements.push_back(el);
}
void render_elements()
{
if (debugElements.empty()) {
return;
}
for (auto& dbgEl : debugElements) {
render_element(dbgEl);
}
debugElements.clear();
}
void cleanup() { debugElements.clear(); }
} // namespace debug
} // namespace graphics
-18
View File
@@ -1,18 +0,0 @@
#pragma once
#include "graphics/2d.h"
#include "math/vecmat.h"
namespace graphics {
namespace debug {
void line_3d(const vec3d* from, const vec3d* to, const color* color);
void text_3d(const vec3d* world_pos, const color* color, SCP_string text);
void render_elements();
void cleanup();
} // namespace debug
} // namespace graphics
+15 -11
View File
@@ -96,10 +96,9 @@ void decal_draw_list::globalShutdown() {
gr_delete_buffer(box_index_buffer);
}
decal_draw_list::decal_draw_list(size_t num_decals)
{
_buffer = gr_get_uniform_buffer(uniform_block_type::DecalInfo, num_decals);
auto& aligner = _buffer.aligner();
decal_draw_list::decal_draw_list() {
_buffer = gr_get_uniform_buffer(uniform_block_type::DecalInfo);
auto& aligner = _buffer->aligner();
// Initialize header data
auto header = aligner.getHeader<graphics::decal_globals>();
@@ -132,12 +131,13 @@ decal_draw_list::decal_draw_list(size_t num_decals)
header->ambientLight.xyz.z += gr_light_emission[2];
}
decal_draw_list::~decal_draw_list() {
_buffer->finished();
}
void decal_draw_list::render() {
GR_DEBUG_SCOPE("Render decals");
TRACE_SCOPE(tracing::RenderDecals);
_buffer.submitData();
_buffer->submitData();
std::sort(_draws.begin(), _draws.end(), decal_draw_list::sort_draws);
@@ -149,16 +149,20 @@ void decal_draw_list::render() {
source.Ibuffer_handle = box_index_buffer;
// Bind the global data only once
gr_bind_uniform_buffer(uniform_block_type::DecalGlobals, 0, sizeof(graphics::decal_globals),
_buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::DecalGlobals,
0,
sizeof(graphics::decal_globals),
_buffer->bufferHandle());
gr_screen.gf_start_decal_pass();
for (auto& draw : _draws) {
GR_DEBUG_SCOPE("Draw single decal");
TRACE_SCOPE(tracing::RenderSingleDecal);
gr_bind_uniform_buffer(uniform_block_type::DecalInfo, draw.uniform_offset, sizeof(graphics::decal_info),
_buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::DecalInfo,
draw.uniform_offset,
sizeof(graphics::decal_info),
_buffer->bufferHandle());
gr_screen.gf_render_decals(&draw.draw_mat, PRIM_TYPE_TRIS, &layout, BOX_NUM_FACES, source);
}
@@ -176,7 +180,7 @@ void decal_draw_list::add_decal(int diffuse_bitmap,
return;
}
auto& aligner = _buffer.aligner();
auto& aligner = _buffer->aligner();
auto info = aligner.addTypedElement<graphics::decal_info>();
info->model_matrix = transform;
@@ -198,7 +202,7 @@ void decal_draw_list::add_decal(int diffuse_bitmap,
info->normal_index = normal_bitmap < 0 ? -1 : bm_get_array_index(normal_bitmap);
decal_draw_info current_draw;
current_draw.uniform_offset = _buffer.getBufferOffset(aligner.getCurrentOffset());
current_draw.uniform_offset = aligner.getCurrentOffset();
material_set_decal(&current_draw.draw_mat,
bm_get_base_frame(diffuse_bitmap),
+10 -5
View File
@@ -15,19 +15,23 @@ class decal_draw_list {
};
SCP_vector<decal_draw_info> _draws;
util::UniformBuffer _buffer;
util::UniformBuffer* _buffer = nullptr;
static bool sort_draws(const decal_draw_info& left, const decal_draw_info& right);
public:
explicit decal_draw_list(size_t num_decals);
public:
decal_draw_list();
~decal_draw_list();
decal_draw_list(const decal_draw_list&) = delete;
decal_draw_list& operator=(const decal_draw_list&) = delete;
void add_decal(int diffuse_bitmap, int glow_bitmap, int normal_bitmap, float decal_timer, const matrix4& transform,
float base_alpha);
void add_decal(int diffuse_bitmap,
int glow_bitmap,
int normal_bitmap,
float decal_timer,
const matrix4& transform,
float base_alpha);
void render();
@@ -35,4 +39,5 @@ class decal_draw_list {
static void globalShutdown();
};
}
+1 -1
View File
@@ -254,7 +254,7 @@ int generic_anim_stream(generic_anim *ga, const bool cache)
}
ga->bitmap_id = bm_load(frame_name);
if(ga->bitmap_id < 0) {
mprintf(("Cannot find first frame for eff streaming. eff Filename: %s\n", ga->filename));
mprintf(("Cannot find first frame for eff streaming. eff Filename: %s", ga->filename));
return -1;
}
if (snprintf(frame_name, MAX_FILENAME_LEN, "%s_0001", ga->filename) >= MAX_FILENAME_LEN) {
+1
View File
@@ -41,6 +41,7 @@ extern color_gun Gr_ta_red, Gr_ta_green, Gr_ta_blue, Gr_ta_alpha;
extern color_gun *Gr_current_red, *Gr_current_green, *Gr_current_blue, *Gr_current_alpha;
extern float Gr_gamma;
extern int Gr_gamma_int;
#define TCACHE_TYPE_AABITMAP 0 // HUD bitmap. All Alpha.
#define TCACHE_TYPE_NORMAL 1 // Normal bitmap. Alpha = 0.
+13 -14
View File
@@ -110,9 +110,13 @@ void gr_stub_save_mouse_area(int /*x*/, int /*y*/, int /*w*/, int /*h*/)
{
}
void gr_stub_update_buffer_data(int /*handle*/, size_t /*size*/, const void* /*data*/) {}
void gr_stub_update_buffer_data(int /*handle*/, size_t /*size*/, void* /*data*/)
{
}
void gr_stub_update_buffer_data_offset(int /*handle*/, size_t /*offset*/, size_t /*size*/, const void* /*data*/) {}
void gr_stub_update_buffer_data_offset(int /*handle*/, size_t /*offset*/, size_t /*size*/, void* /*data*/)
{
}
void gr_stub_update_transform_buffer(void* /*data*/, size_t /*size*/)
{
@@ -137,6 +141,10 @@ int gr_stub_set_color_buffer(int /*mode*/)
return 0;
}
void gr_stub_set_gamma(float /*gamma*/)
{
}
void gr_stub_set_tex_env_scale(float /*scale*/)
{
}
@@ -341,15 +349,6 @@ bool gr_stub_is_capable(gr_capability /*capability*/)
{
return false;
}
bool gr_stub_get_property(gr_property p, void* dest)
{
if (p == gr_property::UNIFORM_BUFFER_OFFSET_ALIGNMENT) {
// This is required by the startup code of the uniform buffer manager
*reinterpret_cast<int*>(dest) = 4;
return true;
}
return false;
};
void gr_stub_push_debug_group(const char*){
}
@@ -430,6 +429,8 @@ bool gr_stub_init()
gr_screen.gf_save_screen = gr_stub_save_screen;
gr_screen.gf_restore_screen = gr_stub_restore_screen;
gr_screen.gf_free_screen = gr_stub_free_screen;
gr_screen.gf_set_gamma = gr_stub_set_gamma;
// UnknownPlayer : Don't recognize this - MAY NEED DEBUGGING
gr_screen.gf_get_region = gr_stub_get_region;
@@ -460,8 +461,6 @@ bool gr_stub_init()
gr_screen.gf_update_transform_buffer = gr_stub_update_transform_buffer;
gr_screen.gf_update_buffer_data = gr_stub_update_buffer_data;
gr_screen.gf_update_buffer_data_offset = gr_stub_update_buffer_data_offset;
gr_screen.gf_map_buffer = [](int) -> void* { return nullptr; };
gr_screen.gf_flush_mapped_buffer = [](int, size_t, size_t) {};
gr_screen.gf_post_process_set_effect = gr_stub_post_process_set_effect;
gr_screen.gf_post_process_set_defaults = gr_stub_post_process_set_defaults;
@@ -505,7 +504,7 @@ bool gr_stub_init()
gr_screen.gf_render_rocket_primitives = gr_stub_render_rocket_primitives;
gr_screen.gf_is_capable = gr_stub_is_capable;
gr_screen.gf_get_property = gr_stub_get_property;
gr_screen.gf_get_property = [](gr_property,void*) { return false; };
gr_screen.gf_push_debug_group = gr_stub_push_debug_group;
gr_screen.gf_pop_debug_group = gr_stub_pop_debug_group;
-2
View File
@@ -134,8 +134,6 @@ void material_set_rocket_interface(interface_material* mat_info, int texture, co
mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
mat_info->set_blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
mat_info->set_texture_type(material::TEX_TYPE_INTERFACE);
}
void material_set_movie(movie_material* mat_info, int y_bm, int u_bm, int v_bm) {
+9 -64
View File
@@ -1,10 +1,6 @@
#include "matrix.h"
#include "graphics/util/UniformBuffer.h"
#include <graphics/util/uniform_structs.h>
transform_stack gr_model_matrix_stack;
matrix4 gr_view_matrix;
matrix4 gr_model_view_matrix;
@@ -15,17 +11,16 @@ matrix4 gr_last_view_matrix;
matrix4 gr_texture_matrix;
matrix4 gr_env_texture_matrix;
static bool gr_env_texture_matrix_set = false;
bool gr_htl_projection_matrix_set = false;
static int modelview_matrix_depth = 1;
static bool htl_view_matrix_set = false;
static int htl_2d_matrix_depth = 0;
static bool htl_2d_matrix_set = false;
static bool htl_view_matrix_set = false;
static int htl_2d_matrix_depth = 0;
static bool htl_2d_matrix_set = false;
static bool matrix_uniform_up_to_date = false;
static matrix4 create_view_matrix(const vec3d* pos, const matrix* orient)
static matrix4 create_view_matrix(const vec3d *pos, const matrix *orient)
{
vec3d scaled_pos;
vec3d inv_pos;
@@ -87,8 +82,6 @@ void gr_start_instance_matrix(const vec3d *offset, const matrix *rotation)
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
modelview_matrix_depth++;
matrix_uniform_up_to_date = false;
}
void gr_start_angles_instance_matrix(const vec3d *pos, const angles *rotation)
@@ -111,8 +104,6 @@ void gr_end_instance_matrix()
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
modelview_matrix_depth--;
matrix_uniform_up_to_date = false;
}
// the projection matrix; fov, aspect ratio, near, far
@@ -136,8 +127,6 @@ void gr_set_proj_matrix(float fov, float aspect, float z_near, float z_far) {
}
gr_htl_projection_matrix_set = true;
matrix_uniform_up_to_date = false;
}
void gr_end_proj_matrix() {
@@ -153,8 +142,6 @@ void gr_end_proj_matrix() {
}
gr_htl_projection_matrix_set = false;
matrix_uniform_up_to_date = false;
}
void gr_set_view_matrix(const vec3d *pos, const matrix *orient)
@@ -167,6 +154,8 @@ void gr_set_view_matrix(const vec3d *pos, const matrix *orient)
gr_model_view_matrix = gr_view_matrix;
if (Cmdline_env) {
gr_env_texture_matrix_set = true;
// setup the texture matrix which will make the the envmap keep lined
// up properly with the environment
@@ -188,8 +177,6 @@ void gr_set_view_matrix(const vec3d *pos, const matrix *orient)
modelview_matrix_depth = 2;
htl_view_matrix_set = true;
matrix_uniform_up_to_date = false;
}
void gr_end_view_matrix()
@@ -202,8 +189,7 @@ void gr_end_view_matrix()
modelview_matrix_depth = 1;
htl_view_matrix_set = false;
matrix_uniform_up_to_date = false;
gr_env_texture_matrix_set = false;
}
// set a view and projection matrix for a 2D element
@@ -242,8 +228,6 @@ void gr_set_2d_matrix(/*int x, int y, int w, int h*/)
htl_2d_matrix_set = true;
htl_2d_matrix_depth++;
matrix_uniform_up_to_date = false;
}
// ends a previously set 2d view and projection matrix
@@ -268,8 +252,6 @@ void gr_end_2d_matrix()
htl_2d_matrix_set = false;
htl_2d_matrix_depth = 0;
matrix_uniform_up_to_date = false;
}
static bool scale_matrix_set = false;
@@ -287,8 +269,6 @@ void gr_push_scale_matrix(const vec3d *scale_factor)
auto model_matrix = gr_model_matrix_stack.get_transform();
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
matrix_uniform_up_to_date = false;
}
void gr_pop_scale_matrix()
@@ -303,8 +283,6 @@ void gr_pop_scale_matrix()
modelview_matrix_depth--;
scale_matrix_set = false;
matrix_uniform_up_to_date = false;
}
void gr_setup_viewport() {
if (Gr_inited) {
@@ -322,8 +300,6 @@ void gr_setup_viewport() {
} else {
create_orthographic_projection_matrix(&gr_projection_matrix, 0, i2fl(gr_screen.max_w), i2fl(gr_screen.max_h), 0, -1, 1);
}
matrix_uniform_up_to_date = false;
}
void gr_reset_matrices() {
vm_matrix4_set_identity(&gr_projection_matrix);
@@ -336,43 +312,12 @@ void gr_reset_matrices() {
gr_model_matrix_stack.clear();
vm_matrix4_set_identity(&gr_texture_matrix);
matrix_uniform_up_to_date = false;
}
void gr_set_texture_panning(float u, float v, bool enable)
{
void gr_set_texture_panning(float u, float v, bool enable) {
vm_matrix4_set_identity(&gr_texture_matrix);
if (enable) {
gr_texture_matrix.a2d[3][0] = u;
gr_texture_matrix.a2d[3][1] = v;
}
}
void gr_matrix_on_frame()
{
// The old uniform state is now out of date and should not be used anymore
matrix_uniform_up_to_date = false;
}
void gr_matrix_set_uniforms()
{
if (matrix_uniform_up_to_date) {
// No changes since last time, no need to update
return;
}
GR_DEBUG_SCOPE("Updating matrix uniforms");
auto uniform_buffer = gr_get_uniform_buffer(uniform_block_type::Matrices, 1);
auto& aligner = uniform_buffer.aligner();
auto matrix_data = aligner.addTypedElement<graphics::matrix_uniforms>();
matrix_data->modelViewMatrix = gr_model_view_matrix;
matrix_data->projMatrix = gr_projection_matrix;
uniform_buffer.submitData();
gr_bind_uniform_buffer(uniform_block_type::Matrices, uniform_buffer.getBufferOffset(0),
sizeof(graphics::matrix_uniforms), uniform_buffer.bufferHandle());
matrix_uniform_up_to_date = true;
}
+3 -13
View File
@@ -9,16 +9,14 @@ extern matrix4 gr_projection_matrix;
extern matrix4 gr_last_projection_matrix;
extern matrix4 gr_env_texture_matrix;
void gr_matrix_on_frame();
void gr_start_instance_matrix(const vec3d* offset, const matrix* rotation);
void gr_start_angles_instance_matrix(const vec3d* pos, const angles* rotation);
void gr_start_instance_matrix(const vec3d *offset, const matrix *rotation);
void gr_start_angles_instance_matrix(const vec3d *pos, const angles *rotation);
void gr_end_instance_matrix();
void gr_set_proj_matrix(float fov, float aspect, float z_near, float z_far);
void gr_end_proj_matrix();
void gr_set_view_matrix(const vec3d* pos, const matrix* orient);
void gr_set_view_matrix(const vec3d *pos, const matrix *orient);
void gr_end_view_matrix();
void gr_set_2d_matrix(/*int x, int y, int w, int h*/);
@@ -34,11 +32,3 @@ void gr_reset_matrices();
extern matrix4 gr_texture_matrix;
void gr_set_texture_panning(float u, float v, bool enable);
/**
* @brief Set current matrix uniforms
*
* Use this before rendering with a shader requiring the matrix uniforms so that the matrix uniform block point has the
* up-to-date data.
*/
void gr_matrix_set_uniforms();
+537 -15
View File
@@ -234,46 +234,568 @@ size_t opengl::ShaderUniforms::findUniform(const SCP_string& name)
if (iter == _uniform_lookup.end()) {
return INVALID_SIZE;
} else {
}
else {
return iter->second;
}
}
void opengl::ShaderUniforms::setTextureUniform(const SCP_string& name, const int texture_unit)
void opengl::ShaderUniforms::setUniformi(const SCP_string &name, const int val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()),
"The program must be current before setting uniforms!");
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
size_t uniform_index = findUniform(name);
bool resident = false;
bool resident = false;
if (uniform_index != INVALID_SIZE) {
if (uniform_index != (size_t)-1) {
Assert(uniform_index < _uniforms.size());
uniform_bind* bind_info = &_uniforms[uniform_index];
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->value == texture_unit) {
return;
if (bind_info->type == uniform_bind::INT) {
if (_uniform_data_ints[bind_info->index] == val) {
return;
}
_uniform_data_ints[bind_info->index] = val;
resident = true;
}
bind_info->value = texture_unit;
resident = true;
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
_uniform_data_ints.push_back(val);
uniform_bind new_bind;
new_bind.name = name;
new_bind.value = texture_unit;
new_bind.count = 1;
new_bind.index = _uniform_data_ints.size() - 1;
new_bind.type = uniform_bind::INT;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniform1i(findUniformLocation(name.c_str()), texture_unit);
glUniform1i(findUniformLocation(name.c_str()), val);
}
void opengl::ShaderUniforms::setUniform1iv(const SCP_string &name, const int count, const int *val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
auto uniform_index = findUniform(name);
bool resident = false;
if (uniform_index != INVALID_SIZE) {
Assert((size_t)uniform_index < _uniforms.size());
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->type == uniform_bind::INT && bind_info->count == count) {
bool equal = true;
// if the values are close enough, pass.
for (int i = 0; i < count; ++i) {
if (val[i] != _uniform_data_ints[bind_info->index + i]) {
equal = false;
break;
}
}
if (equal) {
return;
}
resident = true;
for (int i = 0; i < count; ++i) {
_uniform_data_ints[bind_info->index + i] = val[i];
}
}
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
for (int i = 0; i < count; ++i) {
_uniform_data_ints.push_back(val[i]);
}
uniform_bind new_bind;
new_bind.count = count;
new_bind.index = _uniform_data_ints.size() - count;
// new_bind.index = num_matrix_uniforms - count;
new_bind.type = uniform_bind::INT;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniform1iv(findUniformLocation(name.c_str()), count, (const GLint*)val);
}
void opengl::ShaderUniforms::setUniformf(const SCP_string &name, const float val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
size_t uniform_index = findUniform(name);
bool resident = false;
if (uniform_index != (size_t)-1) {
Assert((size_t)uniform_index < _uniforms.size());
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->type == uniform_bind::FLOAT) {
if (fl_equal(_uniform_data_floats[bind_info->index], val)) {
return;
}
_uniform_data_floats[bind_info->index] = val;
resident = true;
}
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
_uniform_data_floats.push_back(val);
uniform_bind new_bind;
new_bind.count = 1;
new_bind.index = _uniform_data_floats.size() - 1;
new_bind.type = uniform_bind::FLOAT;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniform1f(findUniformLocation(name.c_str()), val);
}
void opengl::ShaderUniforms::setUniform2f(const SCP_string &name, const float x, const float y)
{
vec2d temp;
temp.x = x;
temp.y = y;
setUniform2f(name, temp);
}
void opengl::ShaderUniforms::setUniform2f(const SCP_string &name, const vec2d &val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
size_t uniform_index = findUniform(name);
bool resident = false;
if (uniform_index != (size_t)-1) {
Assert((size_t)uniform_index < _uniforms.size());
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->type == uniform_bind::VEC2) {
if (vm_vec_equal(_uniform_data_vec2d[bind_info->index], val)) {
return;
}
_uniform_data_vec2d[bind_info->index] = val;
resident = true;
}
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
_uniform_data_vec2d.push_back(val);
uniform_bind new_bind;
new_bind.count = 1;
new_bind.index = _uniform_data_vec2d.size() - 1;
new_bind.type = uniform_bind::VEC2;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniform2f(findUniformLocation(name.c_str()), val.x, val.y);
}
void opengl::ShaderUniforms::setUniform3f(const SCP_string &name, const float x, const float y, const float z)
{
vec3d temp;
temp.xyz.x = x;
temp.xyz.y = y;
temp.xyz.z = z;
setUniform3f(name, temp);
}
void opengl::ShaderUniforms::setUniform3f(const SCP_string &name, const vec3d &val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
size_t uniform_index = findUniform(name);
bool resident = false;
if (uniform_index != (size_t)-1) {
Assert((size_t)uniform_index < _uniforms.size());
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->type == uniform_bind::VEC3) {
if (vm_vec_equal(_uniform_data_vec3d[bind_info->index], val)) {
return;
}
_uniform_data_vec3d[bind_info->index] = val;
resident = true;
}
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
_uniform_data_vec3d.push_back(val);
uniform_bind new_bind;
new_bind.count = 1;
new_bind.index = _uniform_data_vec3d.size() - 1;
new_bind.type = uniform_bind::VEC3;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniform3f(findUniformLocation(name.c_str()), val.a1d[0], val.a1d[1], val.a1d[2]);
}
void opengl::ShaderUniforms::setUniform4f(const SCP_string &name, const float x, const float y, const float z, const float w)
{
vec4 temp;
temp.xyzw.x = x;
temp.xyzw.y = y;
temp.xyzw.z = z;
temp.xyzw.w = w;
setUniform4f(name, temp);
}
void opengl::ShaderUniforms::setUniform4f(const SCP_string &name, const vec4 &val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
size_t uniform_index = findUniform(name);
bool resident = false;
if (uniform_index != (size_t)-1) {
Assert((size_t)uniform_index < _uniforms.size());
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->type == uniform_bind::VEC4) {
if (vm_vec_equal(_uniform_data_vec4[bind_info->index], val)) {
// if the values are close enough, pass.
return;
}
_uniform_data_vec4[bind_info->index] = val;
resident = true;
}
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
_uniform_data_vec4.push_back(val);
uniform_bind new_bind;
new_bind.count = 1;
new_bind.index = _uniform_data_vec4.size() - 1;
new_bind.type = uniform_bind::VEC4;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniform4f(findUniformLocation(name.c_str()), val.a1d[0], val.a1d[1], val.a1d[2], val.a1d[3]);
}
void opengl::ShaderUniforms::setUniform1fv(const SCP_string &name, const int count, const float *val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
auto uniform_index = findUniform(name);
bool resident = false;
if (uniform_index != INVALID_SIZE) {
Assert((size_t)uniform_index < _uniforms.size());
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->type == uniform_bind::FLOAT && bind_info->count == count) {
bool equal = true;
// if the values are close enough, pass.
for (int i = 0; i < count; ++i) {
if (!fl_equal(val[i], _uniform_data_floats[bind_info->index + i])) {
equal = false;
break;
}
}
if (equal) {
return;
}
resident = true;
for (int i = 0; i < count; ++i) {
_uniform_data_floats[bind_info->index + i] = val[i];
}
}
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
for (int i = 0; i < count; ++i) {
_uniform_data_floats.push_back(val[i]);
}
uniform_bind new_bind;
new_bind.count = count;
new_bind.index = _uniform_data_floats.size() - count;
// new_bind.index = num_matrix_uniforms - count;
new_bind.type = uniform_bind::FLOAT;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniform1fv(findUniformLocation(name.c_str()), count, (const GLfloat*)val);
}
void opengl::ShaderUniforms::setUniform3fv(const SCP_string &name, const int count, const vec3d *val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
auto uniform_index = findUniform(name);
bool resident = false;
if (uniform_index != INVALID_SIZE) {
Assert((size_t)uniform_index < _uniforms.size());
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->type == uniform_bind::VEC3 && bind_info->count == count) {
bool equal = true;
// if the values are close enough, pass.
for (int i = 0; i < count; ++i) {
if (!vm_vec_equal(val[i], _uniform_data_vec3d[bind_info->index + i])) {
equal = false;
break;
}
}
if (equal) {
return;
}
resident = true;
for (int i = 0; i < count; ++i) {
_uniform_data_vec3d[bind_info->index + i] = val[i];
}
}
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
for (int i = 0; i < count; ++i) {
_uniform_data_vec3d.push_back(val[i]);
}
uniform_bind new_bind;
new_bind.count = count;
new_bind.index = _uniform_data_vec3d.size() - count;
// new_bind.index = num_matrix_uniforms - count;
new_bind.type = uniform_bind::VEC3;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniform3fv(findUniformLocation(name.c_str()), count, (const GLfloat*)val);
}
void opengl::ShaderUniforms::setUniform4fv(const SCP_string &name, const int count, const vec4 *val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
auto uniform_index = findUniform(name);
bool resident = false;
if (uniform_index != INVALID_SIZE) {
Assert((size_t)uniform_index < _uniforms.size());
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->type == uniform_bind::VEC4 && bind_info->count == count) {
bool equal = true;
// if the values are close enough, pass.
for (int i = 0; i < count; ++i) {
if (!vm_vec_equal(val[i], _uniform_data_vec4[bind_info->index + i])) {
equal = false;
break;
}
}
if (equal) {
return;
}
resident = true;
for (int i = 0; i < count; ++i) {
_uniform_data_vec4[bind_info->index + i] = val[i];
}
}
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
for (int i = 0; i < count; ++i) {
_uniform_data_vec4.push_back(val[i]);
}
uniform_bind new_bind;
new_bind.count = count;
new_bind.index = _uniform_data_vec4.size() - count;
// new_bind.index = num_matrix_uniforms - count;
new_bind.type = uniform_bind::VEC4;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniform4fv(findUniformLocation(name.c_str()), count, (const GLfloat*)val);
}
void opengl::ShaderUniforms::setUniformMatrix4f(const SCP_string &name, const matrix4 &val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
size_t uniform_index = findUniform(name);
bool resident = false;
if (uniform_index != (size_t)-1) {
Assert((size_t)uniform_index < _uniforms.size());
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->type == uniform_bind::MATRIX4 && bind_info->count == 1) {
if (vm_matrix_equal(_uniform_data_matrix4[bind_info->index], val)) {
return;
}
_uniform_data_matrix4[bind_info->index] = val;
resident = true;
}
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
//matrix_uniform_data[num_matrix_uniforms] = val;
//memcpy(&(matrix_uniform_data[num_matrix_uniforms]), &val, sizeof(matrix4));
_uniform_data_matrix4.push_back(val);
// num_matrix_uniforms += 1;
uniform_bind new_bind;
new_bind.count = 1;
new_bind.index = _uniform_data_matrix4.size() - 1;
// new_bind.index = num_matrix_uniforms - 1;
new_bind.type = uniform_bind::MATRIX4;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniformMatrix4fv(findUniformLocation(name.c_str()), 1, GL_FALSE, (const GLfloat*)&val);
}
void opengl::ShaderUniforms::setUniformMatrix4fv(const SCP_string &name, const int count, const matrix4 *val)
{
Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");
size_t uniform_index = findUniform(name);
bool resident = false;
if (uniform_index != (size_t)-1) {
Assert((size_t)uniform_index < _uniforms.size());
uniform_bind *bind_info = &_uniforms[uniform_index];
if (bind_info->type == uniform_bind::MATRIX4 && bind_info->count == count) {
bool equal = true;
// if the values are close enough, pass.
for (int i = 0; i < count; ++i) {
if (!vm_matrix_equal(val[i], _uniform_data_matrix4[bind_info->index + i])) {
equal = false;
break;
}
}
if (equal) {
return;
}
resident = true;
for (int i = 0; i < count; ++i) {
_uniform_data_matrix4[bind_info->index + i] = val[i];
}
}
}
if (!resident) {
// uniform doesn't exist in our previous uniform block so queue this new value
for (int i = 0; i < count; ++i) {
_uniform_data_matrix4.push_back(val[i]);
}
uniform_bind new_bind;
new_bind.count = count;
new_bind.index = _uniform_data_matrix4.size() - count;
// new_bind.index = num_matrix_uniforms - count;
new_bind.type = uniform_bind::MATRIX4;
new_bind.name = name;
_uniforms.push_back(new_bind);
_uniform_lookup[name] = _uniforms.size() - 1;
}
glUniformMatrix4fv(findUniformLocation(name.c_str()), count, GL_FALSE, (const GLfloat*)val);
}
GLint opengl::ShaderUniforms::findUniformLocation(const SCP_string& name) {
auto iter = _uniform_locations.find(name);
+35 -2
View File
@@ -16,13 +16,33 @@ class ShaderUniforms {
{
SCP_string name;
int value;
enum data_type {
INT,
FLOAT,
VEC2,
VEC3,
VEC4,
MATRIX4
};
uniform_bind::data_type type;
size_t index;
int count;
int tranpose;
};
ShaderProgram* _program;
SCP_vector<uniform_bind> _uniforms;
SCP_vector<int> _uniform_data_ints;
SCP_vector<float> _uniform_data_floats;
SCP_vector<vec2d> _uniform_data_vec2d;
SCP_vector<vec3d> _uniform_data_vec3d;
SCP_vector<vec4> _uniform_data_vec4;
SCP_vector<matrix4> _uniform_data_matrix4;
SCP_unordered_map<SCP_string, size_t> _uniform_lookup;
SCP_unordered_map<SCP_string, GLint> _uniform_locations;
@@ -32,7 +52,20 @@ class ShaderUniforms {
public:
explicit ShaderUniforms(ShaderProgram* shaderProgram);
void setTextureUniform(const SCP_string &name, const int texture_unit);
void setUniformi(const SCP_string &name, const int value);
void setUniform1iv(const SCP_string &name, const int count, const int *val);
void setUniformf(const SCP_string &name, const float value);
void setUniform2f(const SCP_string &name, const float x, const float y);
void setUniform2f(const SCP_string &name, const vec2d &val);
void setUniform3f(const SCP_string &name, const float x, const float y, const float z);
void setUniform3f(const SCP_string &name, const vec3d &value);
void setUniform4f(const SCP_string &name, const float x, const float y, const float z, const float w);
void setUniform4f(const SCP_string &name, const vec4 &val);
void setUniform1fv(const SCP_string &name, const int count, const float *val);
void setUniform3fv(const SCP_string &name, const int count, const vec3d *val);
void setUniform4fv(const SCP_string &name, const int count, const vec4 *val);
void setUniformMatrix4fv(const SCP_string &name, const int count, const matrix4 *value);
void setUniformMatrix4f(const SCP_string &name, const matrix4 &val);
};
enum ShaderStage {
+329 -8
View File
@@ -1,7 +1,6 @@
#include "gropengl.h"
#include "gropenglbmpman.h"
#include "gropengldeferred.h"
#include "gropengldraw.h"
@@ -12,21 +11,29 @@
#include "gropenglsync.h"
#include "gropengltexture.h"
#include "gropengltnl.h"
#include "bmpman/bmpman.h"
#include "cfile/cfile.h"
#include "cmdline/cmdline.h"
#include "ddsutils/ddsutils.h"
#include "debugconsole/console.h"
#include "globalincs/systemvars.h"
#include "graphics/2d.h"
#include "graphics/line.h"
#include "graphics/matrix.h"
#include "graphics/paths/PathRenderer.h"
#include "io/mouse.h"
#include "io/timer.h"
#include "libs/renderdoc/renderdoc.h"
#include "math/floating.h"
#include "model/model.h"
#include "nebula/neb.h"
#include "options/Option.h"
#include "osapi/osapi.h"
#include "osapi/osregistry.h"
#include "pngutils/pngutils.h"
#include "popup/popup.h"
#include "render/3d.h"
#include "tracing/tracing.h"
#if defined(_WIN32)
#include <windows.h>
@@ -53,6 +60,8 @@ bool GL_initted = 0;
//3==NV Radial
int OGL_fogmode = 0;
static ushort *GL_original_gamma_ramp = NULL;
int Use_PBOs = 0;
static ubyte *GL_saved_screen = NULL;
@@ -66,6 +75,16 @@ extern SCP_string Window_title;
extern GLfloat GL_anisotropy;
extern float FreeSpace_gamma;
void gr_opengl_set_gamma(float gamma);
extern float FreeSpace_gamma;
void gr_opengl_set_gamma(float gamma);
static int GL_fullscreen = 0;
static int GL_windowed = 0;
static int GL_minimized = 0;
static GLenum GL_read_format = GL_BGRA;
GLuint GL_vao = 0;
@@ -78,6 +97,74 @@ static std::unique_ptr<os::OpenGLContext> GL_context = nullptr;
static std::unique_ptr<os::GraphicsOperations> graphic_operations = nullptr;
static os::Viewport* current_viewport = nullptr;
static bool mode_change_func(os::ViewportState state, bool initial)
{
if (initial) {
return false;
}
auto window = os::getMainViewport();
if (window == nullptr) {
return false;
}
window->setState(state);
return true;
}
static auto WindowModeOption = options::OptionBuilder<os::ViewportState>("Graphics.WindowMode", "Window Mode",
"Controls how the game window is created.")
.category("Graphics")
.level(options::ExpertLevel::Beginner)
.values({{os::ViewportState::Fullscreen, "Fullscreen"},
{os::ViewportState::Borderless, "Borderless"},
{os::ViewportState::Windowed, "Windowed"}})
.importance(98)
.default_val(os::ViewportState::Fullscreen)
.change_listener(mode_change_func)
.finish();
void opengl_go_fullscreen()
{
if (Cmdline_fullscreen_window || Cmdline_window || GL_fullscreen || Fred_running)
return;
gr_opengl_set_gamma(FreeSpace_gamma);
GL_fullscreen = 1;
GL_minimized = 0;
GL_windowed = 0;
}
void opengl_go_windowed()
{
if ( ( !Cmdline_fullscreen_window && !Cmdline_window ) /*|| GL_windowed*/ || Fred_running )
return;
GL_windowed = 1;
GL_minimized = 0;
GL_fullscreen = 0;
}
void opengl_minimize()
{
GL_minimized = 1;
GL_windowed = 0;
GL_fullscreen = 0;
}
void gr_opengl_activate(int active)
{
if (active) {
if (Cmdline_fullscreen_window||Cmdline_window)
opengl_go_windowed();
else
opengl_go_fullscreen();
} else {
opengl_minimize();
}
}
void gr_opengl_clear()
{
float red = gr_screen.current_clear_color.red / 255.0f;
@@ -103,9 +190,15 @@ void gr_opengl_clear()
void gr_opengl_flip()
{
if (!GL_initted)
if ( !GL_initted )
return;
TRACE_SCOPE(tracing::PageFlip);
gr_reset_clip();
mouse_reset_deltas();
if (Cmdline_gl_finish)
glFinish();
@@ -303,6 +396,15 @@ void gr_opengl_shutdown()
glDeleteVertexArrays(1, &GL_vao);
GL_vao = 0;
if (GL_original_gamma_ramp != NULL && os::getSDLMainWindow() != nullptr) {
SDL_SetWindowGammaRamp( os::getSDLMainWindow(), GL_original_gamma_ramp, (GL_original_gamma_ramp+256), (GL_original_gamma_ramp+512) );
}
if (GL_original_gamma_ramp != NULL) {
vm_free(GL_original_gamma_ramp);
GL_original_gamma_ramp = NULL;
}
graphic_operations->makeOpenGLContextCurrent(nullptr, nullptr);
GL_context = nullptr;
}
@@ -461,6 +563,89 @@ int gr_opengl_alpha_mask_set(int mode, float alpha)
return mode;
}
// I feel dirty...
static void opengl_make_gamma_ramp(float gamma, ushort *ramp)
{
ushort x, y;
ushort base_ramp[256];
Assert( ramp != NULL );
// generate the base ramp values first off
// if no gamma set then just do this quickly
if (gamma <= 0.0f) {
memset( ramp, 0, 3 * 256 * sizeof(ushort) );
return;
}
// identity gamma, avoid all of the math
else if ( (gamma == 1.0f) || (GL_original_gamma_ramp == NULL) ) {
if (GL_original_gamma_ramp != NULL) {
memcpy( ramp, GL_original_gamma_ramp, 3 * 256 * sizeof(ushort) );
}
// set identity if no original ramp
else {
for (x = 0; x < 256; x++) {
ramp[x] = (x << 8) | x;
ramp[x + 256] = (x << 8) | x;
ramp[x + 512] = (x << 8) | x;
}
}
return;
}
// for everything else we need to actually figure it up
else {
double g = 1.0 / (double)gamma;
double val;
Assert( GL_original_gamma_ramp != NULL );
for (x = 0; x < 256; x++) {
val = (pow(x/255.0, g) * 65535.0 + 0.5);
CLAMP( val, 0, 65535 );
base_ramp[x] = (ushort)val;
}
for (y = 0; y < 3; y++) {
for (x = 0; x < 256; x++) {
val = (base_ramp[x] * 2) - GL_original_gamma_ramp[x + y * 256];
CLAMP( val, 0, 65535 );
ramp[x + y * 256] = (ushort)val;
}
}
}
}
void gr_opengl_set_gamma(float gamma)
{
ushort *gamma_ramp = NULL;
Gr_gamma = gamma;
Gr_gamma_int = int (Gr_gamma*10);
// new way - but not while running FRED
if (!Fred_running && !Cmdline_no_set_gamma && os::getSDLMainWindow() != nullptr) {
gamma_ramp = (ushort*) vm_malloc( 3 * 256 * sizeof(ushort), memory::quiet_alloc);
if (gamma_ramp == NULL) {
Int3();
return;
}
memset( gamma_ramp, 0, 3 * 256 * sizeof(ushort) );
// Create the Gamma lookup table
opengl_make_gamma_ramp(gamma, gamma_ramp);
SDL_SetWindowGammaRamp( os::getSDLMainWindow(), gamma_ramp, (gamma_ramp+256), (gamma_ramp+512) );
vm_free(gamma_ramp);
}
}
void gr_opengl_get_region(int /*front*/, int w, int h, ubyte *data)
{
@@ -718,6 +903,113 @@ void gr_opengl_use_viewport(os::Viewport* view) {
int opengl_init_display_device()
{
int bpp = gr_screen.bits_per_pixel;
Assertion((bpp == 16) || (bpp == 32), "Invalid bits-per-pixel value %d!", bpp);
// screen format
switch (bpp) {
case 16: {
Gr_red.bits = 5;
Gr_red.shift = 11;
Gr_red.scale = 8;
Gr_red.mask = 0xF800;
Gr_green.bits = 6;
Gr_green.shift = 5;
Gr_green.scale = 4;
Gr_green.mask = 0x7E0;
Gr_blue.bits = 5;
Gr_blue.shift = 0;
Gr_blue.scale = 8;
Gr_blue.mask = 0x1F;
break;
}
case 32: {
Gr_red.bits = 8;
Gr_red.shift = 16;
Gr_red.scale = 1;
Gr_red.mask = 0xff0000;
Gr_green.bits = 8;
Gr_green.shift = 8;
Gr_green.scale = 1;
Gr_green.mask = 0x00ff00;
Gr_blue.bits = 8;
Gr_blue.shift = 0;
Gr_blue.scale = 1;
Gr_blue.mask = 0x0000ff;
Gr_alpha.bits = 8;
Gr_alpha.shift = 24;
Gr_alpha.mask = 0xff000000;
Gr_alpha.scale = 1;
break;
}
}
// texture format
Gr_t_red.bits = 5;
Gr_t_red.mask = 0x7c00;
Gr_t_red.shift = 10;
Gr_t_red.scale = 8;
Gr_t_green.bits = 5;
Gr_t_green.mask = 0x03e0;
Gr_t_green.shift = 5;
Gr_t_green.scale = 8;
Gr_t_blue.bits = 5;
Gr_t_blue.mask = 0x001f;
Gr_t_blue.shift = 0;
Gr_t_blue.scale = 8;
Gr_t_alpha.bits = 1;
Gr_t_alpha.mask = 0x8000;
Gr_t_alpha.scale = 255;
Gr_t_alpha.shift = 15;
// alpha-texture format
Gr_ta_red.bits = 4;
Gr_ta_red.mask = 0x0f00;
Gr_ta_red.shift = 8;
Gr_ta_red.scale = 17;
Gr_ta_green.bits = 4;
Gr_ta_green.mask = 0x00f0;
Gr_ta_green.shift = 4;
Gr_ta_green.scale = 17;
Gr_ta_blue.bits = 4;
Gr_ta_blue.mask = 0x000f;
Gr_ta_blue.shift = 0;
Gr_ta_blue.scale = 17;
Gr_ta_alpha.bits = 4;
Gr_ta_alpha.mask = 0xf000;
Gr_ta_alpha.shift = 12;
Gr_ta_alpha.scale = 17;
// allocate storage for original gamma settings
if ( !Cmdline_no_set_gamma && (GL_original_gamma_ramp == NULL) ) {
GL_original_gamma_ramp = (ushort*) vm_malloc( 3 * 256 * sizeof(ushort), memory::quiet_alloc);
if (GL_original_gamma_ramp == NULL) {
mprintf((" Unable to allocate memory for gamma ramp! Disabling...\n"));
Cmdline_no_set_gamma = 1;
} else {
// assume identity ramp by default, to be overwritten by true ramp later
for (ushort x = 0; x < 256; x++) {
GL_original_gamma_ramp[x] = GL_original_gamma_ramp[x + 256] = GL_original_gamma_ramp[x + 512] = (x << 8) | x;
}
}
}
os::ViewPortProperties attrs;
attrs.enable_opengl = true;
@@ -740,7 +1032,7 @@ int opengl_init_display_device()
}
if (Using_in_game_options) {
switch (Gr_configured_window_state) {
switch (WindowModeOption->getValue()) {
case os::ViewportState::Windowed:
// That's the default
break;
@@ -792,6 +1084,11 @@ int opengl_init_display_device()
graphic_operations->makeOpenGLContextCurrent(port, GL_context.get());
current_viewport = port;
if (GL_original_gamma_ramp != NULL && os::getSDLMainWindow() != nullptr) {
SDL_GetWindowGammaRamp( os::getSDLMainWindow(), GL_original_gamma_ramp, (GL_original_gamma_ramp+256),
(GL_original_gamma_ramp+512) );
}
return 0;
}
@@ -821,6 +1118,8 @@ void opengl_setup_function_pointers()
gr_screen.gf_restore_screen = gr_opengl_restore_screen;
gr_screen.gf_free_screen = gr_opengl_free_screen;
gr_screen.gf_set_gamma = gr_opengl_set_gamma;
// UnknownPlayer : Don't recognize this - MAY NEED DEBUGGING
gr_screen.gf_get_region = gr_opengl_get_region;
@@ -848,8 +1147,6 @@ void opengl_setup_function_pointers()
gr_screen.gf_delete_buffer = gr_opengl_delete_buffer;
gr_screen.gf_update_buffer_data = gr_opengl_update_buffer_data;
gr_screen.gf_update_buffer_data_offset = gr_opengl_update_buffer_data_offset;
gr_screen.gf_map_buffer = gr_opengl_map_buffer;
gr_screen.gf_flush_mapped_buffer = gr_opengl_flush_mapped_buffer;
gr_screen.gf_bind_uniform_buffer = gr_opengl_bind_uniform_buffer;
gr_screen.gf_update_transform_buffer = gr_opengl_update_transform_buffer;
@@ -1177,6 +1474,12 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
GL_binary_formats.resize(formats);
glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, GL_binary_formats.data());
if (Cmdline_fullscreen_window || Cmdline_window) {
opengl_go_windowed();
} else {
opengl_go_fullscreen();
}
init_extensions();
// init state system (must come AFTER light is set up)
@@ -1304,8 +1607,6 @@ bool gr_opengl_is_capable(gr_capability capability)
return GLAD_GL_ARB_timer_query != 0; // Timestamp queries are available from 3.3 onwards
case CAPABILITY_SEPARATE_BLEND_FUNCTIONS:
return GLAD_GL_ARB_draw_buffers_blend != 0; // We need an OpenGL extension for this
case CAPABILITY_PERSISTENT_BUFFER_MAPPING:
return GLAD_GL_ARB_buffer_storage != 0;
}
return false;
@@ -1370,6 +1671,26 @@ uint opengl_data_type_size(GLenum data_type)
return 0;
}
DCF(ogl_minimize, "Minimizes opengl")
{
bool minimize_ogl = false;
if ( gr_screen.mode != GR_OPENGL ) {
dc_printf("Command only available in OpenGL mode.\n");
return;
}
if (dc_optional_string_either("help", "--help")) {
dc_printf("[bool] If true is passed, then the OpenGL window will minimize.\n");
return;
}
dc_stuff_boolean(&minimize_ogl);
if (minimize_ogl) {
opengl_minimize();
}
}
DCF(ogl_anisotropy, "toggles anisotropic filtering")
{
bool process = true;
+56 -58
View File
@@ -1,32 +1,28 @@
#include "gropengldeferred.h"
#include "ShaderProgram.h"
#include "gropengldraw.h"
#include "gropenglstate.h"
#include "gropengltnl.h"
#include "graphics/2d.h"
#include "gropenglstate.h"
#include "gropengldraw.h"
#include "gropengldeferred.h"
#include "gropengltnl.h"
#include "graphics/matrix.h"
#include "graphics/util/UniformAligner.h"
#include "graphics/util/UniformBuffer.h"
#include "graphics/util/uniform_structs.h"
#include "lighting/lighting.h"
#include "mission/mission_flags.h"
#include "mission/missionparse.h"
#include "nebula/neb.h"
#include "render/3d.h"
#include "graphics/util/UniformBuffer.h"
#include "tracing/tracing.h"
#include "lighting/lighting.h"
#include "render/3d.h"
#include "ShaderProgram.h"
#include "nebula/neb.h"
#include "mission/missionparse.h"
#include "mission/mission_flags.h"
#include <math/bitarray.h>
void gr_opengl_deferred_init()
{
void gr_opengl_deferred_init() {
gr_opengl_deferred_light_cylinder_init(16);
gr_opengl_deferred_light_sphere_init(16, 16);
}
void gr_opengl_deferred_shutdown() {}
void gr_opengl_deferred_shutdown() {
}
void opengl_clear_deferred_buffers()
{
@@ -129,18 +125,9 @@ void gr_opengl_deferred_lighting_finish()
std::stable_sort(Lights.begin(), Lights.end(), light_compare_by_type);
using namespace graphics;
// We need to precompute how many elements we are going to need
size_t num_data_elements = 0;
for (auto& l : Lights) {
++num_data_elements;
if (l.type == Light_Type::Tube) {
++num_data_elements;
}
}
// Get a uniform buffer for our data
auto buffer = gr_get_uniform_buffer(uniform_block_type::Lights, num_data_elements);
auto& uniformAligner = buffer.aligner();
// Get a uniform buffer for out data
auto buffer = gr_get_uniform_buffer(uniform_block_type::Lights);
auto& uniformAligner = buffer->aligner();
{
GR_DEBUG_SCOPE("Build buffer data");
@@ -183,9 +170,6 @@ void gr_opengl_deferred_lighting_finish()
light_data->diffuseLightColor = diffuse;
light_data->specLightColor = spec;
// Set a default value for all lights. Only the first directional light will change this.
light_data->enable_shadows = false;
switch (l.type) {
case Light_Type::Directional:
if (Shadow_quality != ShadowQuality::Disabled) {
@@ -215,6 +199,9 @@ void gr_opengl_deferred_lighting_finish()
light_data->coneDir = l.vec2;
FALLTHROUGH;
case Light_Type::Point:
light_data->diffuseLightColor = diffuse;
light_data->specLightColor = spec;
vm_vec_scale(&light_data->specLightColor, static_point_factor);
light_data->lightRadius = MAX(l.rada, l.radb) * 1.25f;
@@ -223,6 +210,7 @@ void gr_opengl_deferred_lighting_finish()
light_data->scale.xyz.z = MAX(l.rada, l.radb) * 1.28f;
break;
case Light_Type::Tube: {
light_data->diffuseLightColor = diffuse;
light_data->lightRadius = l.radb * 1.5f;
light_data->lightType = LT_TUBE;
@@ -255,12 +243,14 @@ void gr_opengl_deferred_lighting_finish()
}
// Uniform data has been assembled, upload it to the GPU and issue the draw calls
buffer.submitData();
buffer->submitData();
}
{
GR_DEBUG_SCOPE("Render light geometry");
gr_bind_uniform_buffer(uniform_block_type::DeferredGlobals, buffer.getBufferOffset(0),
sizeof(graphics::deferred_global_data), buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::DeferredGlobals,
0,
sizeof(graphics::deferred_global_data),
buffer->bufferHandle());
size_t element_index = 0;
for (auto& l : Lights) {
@@ -268,21 +258,27 @@ void gr_opengl_deferred_lighting_finish()
switch (l.type) {
case Light_Type::Directional:
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(element_index),
sizeof(graphics::deferred_light_data), buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::Lights,
uniformAligner.getOffset(element_index),
sizeof(graphics::deferred_light_data),
buffer->bufferHandle());
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
++element_index;
break;
case Light_Type::Cone:
case Light_Type::Point:
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(element_index),
sizeof(graphics::deferred_light_data), buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::Lights,
uniformAligner.getOffset(element_index),
sizeof(graphics::deferred_light_data),
buffer->bufferHandle());
gr_opengl_draw_deferred_light_sphere(&l.vec);
++element_index;
break;
case Light_Type::Tube:
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(element_index),
sizeof(graphics::deferred_light_data), buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::Lights,
uniformAligner.getOffset(element_index),
sizeof(graphics::deferred_light_data),
buffer->bufferHandle());
vec3d a;
matrix orient;
@@ -293,8 +289,10 @@ void gr_opengl_deferred_lighting_finish()
++element_index;
// The next two draws use the same uniform block element
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(element_index),
sizeof(graphics::deferred_light_data), buffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::Lights,
uniformAligner.getOffset(element_index),
sizeof(graphics::deferred_light_data),
buffer->bufferHandle());
gr_opengl_draw_deferred_light_sphere(&l.vec);
gr_opengl_draw_deferred_light_sphere(&l.vec2);
@@ -304,6 +302,9 @@ void gr_opengl_deferred_lighting_finish()
continue;
}
}
// We don't need the buffer anymore
buffer->finished();
}
gr_end_view_matrix();
@@ -325,18 +326,13 @@ void gr_opengl_deferred_lighting_finish()
unsigned char r, g, b;
neb2_get_fog_color(&r, &g, &b);
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
Current_shader->program->Uniforms.setTextureUniform("depth_tex", 1);
opengl_set_generic_uniform_data<graphics::generic_data::fog_data>([&](graphics::generic_data::fog_data* data) {
data->fog_start = fog_near;
data->fog_scale = 1.0f / (fog_far - fog_near);
data->fog_color.xyz.x = r / 255.f;
data->fog_color.xyz.y = g / 255.f;
data->fog_color.xyz.z = b / 255.f;
data->zNear = Min_draw_distance;
data->zFar = Max_draw_distance;
});
Current_shader->program->Uniforms.setUniformi("tex", 0);
Current_shader->program->Uniforms.setUniformi("depth_tex", 1);
Current_shader->program->Uniforms.setUniformf("fog_start", fog_near);
Current_shader->program->Uniforms.setUniformf("fog_scale", 1.0f / (fog_far - fog_near));
Current_shader->program->Uniforms.setUniform3f("fog_color", r / 255.f, g / 255.f, b / 255.f);
Current_shader->program->Uniforms.setUniformf("zNear", Min_draw_distance);
Current_shader->program->Uniforms.setUniformf("zFar", Max_draw_distance);
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
} else {
@@ -368,7 +364,8 @@ void gr_opengl_draw_deferred_light_sphere(const vec3d *position)
{
g3_start_instance_matrix(position, &vmd_identity_matrix, true);
gr_matrix_set_uniforms();
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
opengl_draw_sphere();
@@ -595,7 +592,8 @@ void gr_opengl_draw_deferred_light_cylinder(const vec3d *position, const matrix
{
g3_start_instance_matrix(position, orient, true);
gr_matrix_set_uniforms();
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
vertex_layout vertex_declare;
+12 -15
View File
@@ -611,27 +611,24 @@ void gr_opengl_render_shield_impact(shield_material *material_info, primitive_ty
vm_matrix4_set_inverse_transform(&impact_transform, &impact_orient, &impact_pos);
uint32_t array_index = 0;
if (material_info->get_texture_map(TM_BASE_TYPE) >= 0) {
if ( material_info->get_texture_map(TM_BASE_TYPE) >= 0 ) {
float u_scale, v_scale;
if (!gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), material_info->get_texture_type(),
&u_scale, &v_scale, &array_index)) {
if ( !gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), material_info->get_texture_type(), &u_scale, &v_scale, &array_index) ) {
mprintf(("WARNING: Error setting bitmap texture (%i)!\n", material_info->get_texture_map(TM_BASE_TYPE)));
}
}
opengl_set_generic_uniform_data<graphics::generic_data::shield_impact_data>(
[&](graphics::generic_data::shield_impact_data* data) {
data->hitNormal = impact_orient.vec.fvec;
data->shieldProjMatrix = impact_projection;
data->shieldModelViewMatrix = impact_transform;
data->shieldMapIndex = array_index;
data->srgb = High_dynamic_range ? 1 : 0;
data->color = material_info->get_color();
});
gr_matrix_set_uniforms();
Current_shader->program->Uniforms.setUniform3f("hitNormal", impact_orient.vec.fvec);
Current_shader->program->Uniforms.setUniformMatrix4f("shieldProjMatrix", impact_projection);
Current_shader->program->Uniforms.setUniformMatrix4f("shieldModelViewMatrix", impact_transform);
Current_shader->program->Uniforms.setUniformi("shieldMap", 0);
Current_shader->program->Uniforms.setUniformi("shieldMapIndex", array_index);
Current_shader->program->Uniforms.setUniformi("srgb", High_dynamic_range ? 1 : 0);
Current_shader->program->Uniforms.setUniform4f("color", material_info->get_color());
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
opengl_render_primitives(prim_type, layout, n_verts, buffer_handle, 0, 0);
}
+102 -211
View File
@@ -12,7 +12,6 @@
#include "cmdline/cmdline.h"
#include "def_files/def_files.h"
#include "graphics/util/uniform_structs.h"
#include "io/timer.h"
#include "lighting/lighting.h"
#include "mod_table/mod_table.h"
@@ -24,50 +23,44 @@
extern bool PostProcessing_override;
extern int opengl_check_framebuffer();
// Needed to track where the FXAA shaders are
// In case we don't find the shaders at all, this override is needed
//Needed to track where the FXAA shaders are
//In case we don't find the shaders at all, this override is needed
bool fxaa_unavailable = false;
bool zbuffer_saved = false;
bool zbuffer_saved = false;
// lightshaft parameters
bool ls_on = false;
bool ls_force_off = false;
float ls_density = 0.5f;
float ls_weight = 0.02f;
float ls_falloff = 1.0f;
float ls_intensity = 0.5f;
bool ls_on = false;
bool ls_force_off = false;
float ls_density = 0.5f;
float ls_weight = 0.02f;
float ls_falloff = 1.0f;
float ls_intensity = 0.5f;
float ls_cpintensity = 0.5f * 50 * 0.02f;
int ls_samplenum = 50;
int ls_samplenum = 50;
const int MAX_MIP_BLUR_LEVELS = 4;
enum class PostEffectUniformType {
Invalid,
NoiseAmount,
Saturation,
Brightness,
Contrast,
FilmGrain,
TvStripes,
Cutoff,
Tint,
Dither,
};
struct post_effect_t {
typedef struct post_effect_t {
SCP_string name;
PostEffectUniformType uniform_type = PostEffectUniformType::Invalid;
SCP_string uniform_name;
SCP_string define_name;
float intensity{0.0f};
float default_intensity{0.0f};
float div{1.0f};
float add{0.0f};
float intensity;
float default_intensity;
float div;
float add;
vec3d rgb = vmd_zero_vector;
vec3d rgb;
bool always_on{false};
};
bool always_on;
post_effect_t() :
intensity(0.0f), default_intensity(0.0f), div(1.0f), add(0.0f),
rgb(),
always_on(false)
{
}
} post_effect_t;
SCP_vector<post_effect_t> Post_effects;
@@ -102,12 +95,10 @@ void opengl_post_pass_tonemap()
GR_DEBUG_SCOPE("Tonemapping");
TRACE_SCOPE(tracing::Tonemapping);
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_TONEMAPPING, 0));
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_TONEMAPPING, 0) );
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
opengl_set_generic_uniform_data<graphics::generic_data::tonemapping_data>(
[](graphics::generic_data::tonemapping_data* data) { data->exposure = 4.0f; });
Current_shader->program->Uniforms.setUniformi("tex", 0);
Current_shader->program->Uniforms.setUniformf("exposure", 4.0f);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Scene_ldr_texture, 0);
@@ -144,7 +135,7 @@ void opengl_post_pass_bloom()
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BRIGHTPASS, 0));
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
Current_shader->program->Uniforms.setUniformi("tex", 0);
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_color_texture);
@@ -172,19 +163,17 @@ void opengl_post_pass_bloom()
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLUR, SDR_FLAG_BLUR_VERTICAL));
}
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
Current_shader->program->Uniforms.setUniformi("tex", 0);
GL_state.Texture.Enable(0, GL_TEXTURE_2D, source_tex);
for (int mipmap = 0; mipmap < MAX_MIP_BLUR_LEVELS; ++mipmap) {
int bloom_width = width >> mipmap;
int bloom_width = width >> mipmap;
int bloom_height = height >> mipmap;
opengl_set_generic_uniform_data<graphics::generic_data::blur_data>(
[&](graphics::generic_data::blur_data* data) {
data->texSize = (pass) ? 1.0f / i2fl(bloom_width) : 1.0f / i2fl(bloom_height);
data->level = mipmap;
});
Current_shader->program->Uniforms.setUniformf("texSize", (pass) ? 1.0f / i2fl(bloom_width) : 1.0f / i2fl(bloom_height));
Current_shader->program->Uniforms.setUniformi("level", mipmap);
Current_shader->program->Uniforms.setUniformf("tapSize", 1.0f);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dest_tex, mipmap);
@@ -204,13 +193,9 @@ void opengl_post_pass_bloom()
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLOOM_COMP, 0));
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
opengl_set_generic_uniform_data<graphics::generic_data::bloom_composition_data>(
[](graphics::generic_data::bloom_composition_data* data) {
data->levels = MAX_MIP_BLUR_LEVELS;
data->bloom_intensity = Cmdline_bloom_intensity / 100.0f;
});
Current_shader->program->Uniforms.setUniformi("tex", 0);
Current_shader->program->Uniforms.setUniformi("levels", MAX_MIP_BLUR_LEVELS);
Current_shader->program->Uniforms.setUniformf("bloom_intensity", Cmdline_bloom_intensity / 100.0f);
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Bloom_textures[0]);
@@ -254,39 +239,29 @@ void gr_opengl_post_process_begin()
Post_in_frame = true;
}
void recompile_aa_shader() {
auto stype = SCP_vector<shader_type>();
if (gr_is_fxaa_mode(Gr_aa_mode)) {
stype.push_back(shader_type::SDR_TYPE_POST_PROCESS_FXAA);
}
else if (gr_is_smaa_mode(Gr_aa_mode)) {
stype.push_back(shader_type::SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT);
stype.push_back(shader_type::SDR_TYPE_POST_PROCESS_SMAA_EDGE);
stype.push_back(shader_type::SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING);
void recompile_fxaa_shader() {
if (!gr_is_fxaa_mode(Gr_aa_mode)) {
return;
}
mprintf(("Recompiling AA shader(s)...\n"));
mprintf(("Recompiling FXAA shader...\n"));
for (auto sdr : stype) {
// start recompile by grabbing deleting the current shader we have, assuming it's already created
opengl_delete_shader( gr_opengl_maybe_create_shader(sdr, 0) );
// start recompile by grabbing deleting the current shader we have, assuming it's already created
opengl_delete_shader( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) );
// then recreate it again. shader loading code will be updated with the new AA presets
gr_opengl_maybe_create_shader(sdr, 0);
}
// then recreate it again. shader loading code will be updated with the new FXAA presets
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0);
Gr_aa_mode_last_frame = Gr_aa_mode;
}
void opengl_post_pass_fxaa()
{
void opengl_post_pass_fxaa() {
GR_DEBUG_SCOPE("FXAA");
TRACE_SCOPE(tracing::FXAA);
// If the preset changed, recompile the shader
//If the preset changed, recompile the shader
if (Gr_aa_mode_last_frame != Gr_aa_mode) {
recompile_aa_shader();
recompile_fxaa_shader();
}
// We only want to draw to ATTACHMENT0
@@ -294,10 +269,10 @@ void opengl_post_pass_fxaa()
GL_state.ColorMask(true, true, true, true);
// Do a prepass to convert the main shaders' RGBA output into RGBL
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0));
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0) );
// basic/default uniforms
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
Current_shader->program->Uniforms.setUniformi( "tex", 0 );
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Scene_luminance_texture, 0);
@@ -306,17 +281,14 @@ void opengl_post_pass_fxaa()
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
// set and configure post shader ..
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0));
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) );
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Scene_ldr_texture, 0);
// basic/default uniforms
Current_shader->program->Uniforms.setTextureUniform("tex0", 0);
opengl_set_generic_uniform_data<graphics::generic_data::fxaa_data>([](graphics::generic_data::fxaa_data* data) {
data->rt_w = i2fl(Post_texture_width);
data->rt_h = i2fl(Post_texture_height);
});
Current_shader->program->Uniforms.setUniformi( "tex0", 0 );
Current_shader->program->Uniforms.setUniformf( "rt_w", static_cast<float>(Post_texture_width));
Current_shader->program->Uniforms.setUniformf( "rt_h", static_cast<float>(Post_texture_height));
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_luminance_texture);
@@ -339,7 +311,9 @@ static void smaa_detect_edges()
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_EDGE, 0));
// basic/default uniforms
Current_shader->program->Uniforms.setTextureUniform("colorTex", 0);
Current_shader->program->Uniforms.setUniformi("colorTex", 0);
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
i2fl(Post_texture_height));
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
@@ -360,9 +334,11 @@ static void smaa_calculate_blending_weights()
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT, 0));
// basic/default uniforms
Current_shader->program->Uniforms.setTextureUniform("edgesTex", 0);
Current_shader->program->Uniforms.setTextureUniform("areaTex", 1);
Current_shader->program->Uniforms.setTextureUniform("searchTex", 2);
Current_shader->program->Uniforms.setUniformi("edgesTex", 0);
Current_shader->program->Uniforms.setUniformi("areaTex", 1);
Current_shader->program->Uniforms.setUniformi("searchTex", 2);
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
i2fl(Post_texture_height));
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Smaa_edges_tex);
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Smaa_area_tex);
@@ -385,8 +361,10 @@ static void smaa_neighborhood_blending()
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING, 0));
// basic/default uniforms
Current_shader->program->Uniforms.setTextureUniform("colorTex", 0);
Current_shader->program->Uniforms.setTextureUniform("blendTex", 1);
Current_shader->program->Uniforms.setUniformi("colorTex", 0);
Current_shader->program->Uniforms.setUniformi("blendTex", 1);
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
i2fl(Post_texture_height));
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Smaa_blend_tex);
@@ -417,21 +395,10 @@ void opengl_post_pass_smaa()
GR_DEBUG_SCOPE("SMAA");
TRACE_SCOPE(tracing::SMAA);
// If the preset changed, recompile the shader
if (Gr_aa_mode_last_frame != Gr_aa_mode) {
recompile_aa_shader();
}
GL_state.PushFramebufferState();
GL_state.ColorMask(true, true, true, true);
// All SMAA stages share the same shader data so we only need this once
opengl_set_generic_uniform_data<graphics::generic_data::smaa_data>([](graphics::generic_data::smaa_data* data) {
data->smaa_rt_metrics.x = i2fl(Post_texture_width);
data->smaa_rt_metrics.y = i2fl(Post_texture_height);
});
smaa_detect_edges();
smaa_calculate_blending_weights();
@@ -477,24 +444,16 @@ void opengl_post_lightshafts()
float dot;
if ( (dot = vm_vec_dot(&light_dir, &Eye_matrix.vec.fvec)) > 0.7f ) {
x = asinf(vm_vec_dot(&light_dir, &Eye_matrix.vec.rvec)) / PI * 1.5f +
0.5f; // cant get the coordinates right but this works for the limited glare fov
y = asinf(vm_vec_dot(&light_dir, &Eye_matrix.vec.uvec)) / PI * 1.5f * gr_screen.clip_aspect + 0.5f;
opengl_set_generic_uniform_data<graphics::generic_data::lightshaft_data>(
[&](graphics::generic_data::lightshaft_data* data) {
data->sun_pos.x = x;
data->sun_pos.y = y;
data->density = ls_density;
data->falloff = ls_falloff;
data->weight = ls_weight;
data->intensity = Sun_spot * ls_intensity;
data->cp_intensity = Sun_spot * ls_cpintensity;
});
Current_shader->program->Uniforms.setTextureUniform("scene", 0);
Current_shader->program->Uniforms.setTextureUniform("cockpit", 1);
x = asinf(vm_vec_dot(&light_dir, &Eye_matrix.vec.rvec)) / PI*1.5f + 0.5f; //cant get the coordinates right but this works for the limited glare fov
y = asinf(vm_vec_dot(&light_dir, &Eye_matrix.vec.uvec)) / PI*1.5f*gr_screen.clip_aspect + 0.5f;
Current_shader->program->Uniforms.setUniform2f("sun_pos", x, y);
Current_shader->program->Uniforms.setUniformi("scene", 0);
Current_shader->program->Uniforms.setUniformi("cockpit", 1);
Current_shader->program->Uniforms.setUniformf("density", ls_density);
Current_shader->program->Uniforms.setUniformf("falloff", ls_falloff);
Current_shader->program->Uniforms.setUniformf("weight", ls_weight);
Current_shader->program->Uniforms.setUniformf("intensity", Sun_spot * ls_intensity);
Current_shader->program->Uniforms.setUniformf("cp_intensity", Sun_spot * ls_cpintensity);
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_depth_texture);
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Cockpit_depth_texture);
@@ -562,7 +521,7 @@ void gr_opengl_post_process_end()
int post_sdr_handle = Post_active_shader_index;
if (post_sdr_handle < 0) {
if ( post_sdr_handle < 0 ) {
// no active shader index? use the always on shader.
post_sdr_handle = gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_MAIN, flags);
}
@@ -570,57 +529,30 @@ void gr_opengl_post_process_end()
opengl_shader_set_current(post_sdr_handle);
// basic/default uniforms
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
Current_shader->program->Uniforms.setUniformi( "tex", 0 );
Current_shader->program->Uniforms.setUniformi( "depth_tex", 1);
Current_shader->program->Uniforms.setUniformf( "timer", static_cast<float>(timer_get_milliseconds() % 100 + 1) );
Current_shader->program->Uniforms.setTextureUniform("depth_tex", 1);
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_depth_texture);
for (size_t idx = 0; idx < Post_effects.size(); idx++) {
if ( GL_shader[post_sdr_handle].flags & (1<<idx) ) {
const char *name = Post_effects[idx].uniform_name.c_str();
float value = Post_effects[idx].intensity;
opengl_set_generic_uniform_data<graphics::generic_data::post_data>([&](graphics::generic_data::post_data* data) {
data->timer = i2fl(timer_get_milliseconds() % 100 + 1);
for (size_t idx = 0; idx < Post_effects.size(); idx++) {
if (GL_shader[post_sdr_handle].flags & (1 << idx)) {
float value = Post_effects[idx].intensity;
switch (Post_effects[idx].uniform_type) {
case PostEffectUniformType::Invalid:
// Invalid name specified, do nothing
break;
case PostEffectUniformType::NoiseAmount:
data->noise_amount = value;
break;
case PostEffectUniformType::Saturation:
data->saturation = value;
break;
case PostEffectUniformType::Brightness:
data->brightness = value;
break;
case PostEffectUniformType::Contrast:
data->contrast = value;
break;
case PostEffectUniformType::FilmGrain:
data->film_grain = value;
break;
case PostEffectUniformType::TvStripes:
data->tv_stripes = value;
break;
case PostEffectUniformType::Cutoff:
data->cutoff = value;
break;
case PostEffectUniformType::Dither:
data->dither = value;
break;
case PostEffectUniformType::Tint:
data->tint = Post_effects[idx].rgb;
break;
}
if (!(vmd_zero_vector == Post_effects[idx].rgb)) {
Current_shader->program->Uniforms.setUniform3f( name, Post_effects[idx].rgb );
}
else {
Current_shader->program->Uniforms.setUniformf( name, value );
}
}
});
}
// now render it to the screen ...
GL_state.PopFramebufferState();
//GL_state.Texture.Enable(Scene_color_texture);
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_depth_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
@@ -784,31 +716,6 @@ void gr_opengl_post_process_restore_zbuffer()
}
}
static PostEffectUniformType mapUniformNameToType(const SCP_string& uniform_name)
{
if (!stricmp(uniform_name.c_str(), "noise_amount")) {
return PostEffectUniformType::NoiseAmount;
} else if (!stricmp(uniform_name.c_str(), "saturation")) {
return PostEffectUniformType::Saturation;
} else if (!stricmp(uniform_name.c_str(), "brightness")) {
return PostEffectUniformType::Brightness;
} else if (!stricmp(uniform_name.c_str(), "contrast")) {
return PostEffectUniformType::Contrast;
} else if (!stricmp(uniform_name.c_str(), "film_grain")) {
return PostEffectUniformType::FilmGrain;
} else if (!stricmp(uniform_name.c_str(), "tv_stripes")) {
return PostEffectUniformType::TvStripes;
} else if (!stricmp(uniform_name.c_str(), "cutoff")) {
return PostEffectUniformType::Cutoff;
} else if (!stricmp(uniform_name.c_str(), "dither")) {
return PostEffectUniformType::Dither;
} else if (!stricmp(uniform_name.c_str(), "tint")) {
return PostEffectUniformType::Tint;
} else {
error_display(0, "Unknown uniform name '%s'!", uniform_name.c_str());
return PostEffectUniformType::Invalid;
}
}
static bool opengl_post_init_table()
{
@@ -826,19 +733,20 @@ static bool opengl_post_init_table()
if (optional_string("#Effects")) {
while (!required_string_one_of(3, "$Name:", "#Ship Effects", "#End")) {
char tbuf[NAME_LENGTH + 1] = { 0 };
post_effect_t eff;
required_string("$Name:");
stuff_string(eff.name, F_NAME);
stuff_string(tbuf, F_NAME, NAME_LENGTH);
eff.name = tbuf;
required_string("$Uniform:");
SCP_string tbuf;
stuff_string(tbuf, F_NAME);
eff.uniform_type = mapUniformNameToType(tbuf);
stuff_string(tbuf, F_NAME, NAME_LENGTH);
eff.uniform_name = tbuf;
required_string("$Define:");
stuff_string(eff.define_name, F_NAME);
stuff_string(tbuf, F_NAME, NAME_LENGTH);
eff.define_name = tbuf;
required_string("$AlwaysOn:");
stuff_boolean(&eff.always_on);
@@ -977,23 +885,6 @@ void set_smaa_defines(SCP_stringstream& sflags)
} else {
sflags << "#define SMAA_GLSL_3\n";
}
switch (Gr_aa_mode) {
case AntiAliasMode::SMAA_Low:
sflags << "#define SMAA_PRESET_LOW\n";
break;
case AntiAliasMode::SMAA_Medium:
sflags << "#define SMAA_PRESET_MEDIUM\n";
break;
case AntiAliasMode::SMAA_High:
sflags << "#define SMAA_PRESET_HIGH\n";
break;
case AntiAliasMode::SMAA_Ultra:
sflags << "#define SMAA_PRESET_ULTRA\n";
break;
default:
UNREACHABLE("Unhandled SMAA mode!");
}
}
void opengl_post_shader_header(SCP_stringstream& sflags, shader_type shader_t, int flags)
{
+179 -132
View File
@@ -1,35 +1,33 @@
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
#include "graphics/opengl/gropenglshader.h"
#include "ShaderProgram.h"
#include "cfile/cfile.h"
#include "cmdline/cmdline.h"
#include "def_files/def_files.h"
#include "graphics/2d.h"
#include "graphics/grinternal.h"
#include "graphics/matrix.h"
#include "graphics/grinternal.h"
#include "graphics/opengl/gropengldraw.h"
#include "graphics/opengl/gropenglpostprocessing.h"
#include "graphics/opengl/gropenglshader.h"
#include "graphics/opengl/gropenglstate.h"
#include "graphics/opengl/gropengltexture.h"
#include "graphics/opengl/gropengltnl.h"
#include "graphics/util/uniform_structs.h"
#include "lighting/lighting.h"
#include "math/vecmat.h"
#include "mod_table/mod_table.h"
#include "render/3d.h"
#include "ShaderProgram.h"
#include <jansson.h>
#include <md5.h>
#include <jansson.h>
SCP_vector<opengl_shader_t> GL_shader;
@@ -66,14 +64,12 @@ struct opengl_uniform_block_binding {
};
opengl_uniform_block_binding GL_uniform_blocks[] = {
{uniform_block_type::Lights, "lightData"},
{uniform_block_type::ModelData, "modelData"},
{uniform_block_type::NanoVGData, "NanoVGUniformData"},
{uniform_block_type::DecalInfo, "decalInfoData"},
{uniform_block_type::DecalGlobals, "decalGlobalData"},
{uniform_block_type::DeferredGlobals, "globalDeferredData"},
{uniform_block_type::Matrices, "matrixData"},
{uniform_block_type::GenericData, "genericData"},
{ uniform_block_type::Lights, "lightData" },
{ uniform_block_type::ModelData, "modelData" },
{ uniform_block_type::NanoVGData, "NanoVGUniformData" },
{ uniform_block_type::DecalInfo, "decalInfoData" },
{ uniform_block_type::DecalGlobals, "decalGlobalData" },
{ uniform_block_type::DeferredGlobals, "globalDeferredData" },
};
/**
@@ -85,7 +81,7 @@ static opengl_shader_type_t GL_shader_types[] = {
{ SDR_TYPE_MODEL, "main-v.sdr", "main-f.sdr", "main-g.sdr",
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD, opengl_vert_attrib::NORMAL, opengl_vert_attrib::TANGENT, opengl_vert_attrib::MODEL_ID }, "Model Rendering" },
{ SDR_TYPE_EFFECT_PARTICLE, "effect-v.sdr", "effect-f.sdr", "effect-g.sdr",
{ SDR_TYPE_EFFECT_PARTICLE, "effect-v.sdr", "effect-particle-f.sdr", "effect-screen-g.sdr",
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD, opengl_vert_attrib::RADIUS, opengl_vert_attrib::COLOR }, "Particle Effects" },
{ SDR_TYPE_EFFECT_DISTORTION, "effect-distort-v.sdr", "effect-distort-f.sdr", 0,
@@ -133,7 +129,7 @@ static opengl_shader_type_t GL_shader_types[] = {
{ SDR_TYPE_BATCHED_BITMAP, "batched-v.sdr", "batched-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD, opengl_vert_attrib::COLOR }, "Batched bitmaps" },
{ SDR_TYPE_DEFAULT_MATERIAL, "default-material-v.sdr", "default-material-f.sdr", nullptr,
{ SDR_TYPE_DEFAULT_MATERIAL, "passthrough-v.sdr", "default-material-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD, opengl_vert_attrib::COLOR }, "Default material" },
{ SDR_TYPE_NANOVG, "nanovg-v.sdr", "nanovg-f.sdr", nullptr,
@@ -164,63 +160,109 @@ static opengl_shader_type_t GL_shader_types[] = {
* When adding a new shader variant for a shader, list all associated uniforms and attributes here
*/
static opengl_shader_variant_t GL_shader_variants[] = {
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_LIGHT, "FLAG_LIGHT", {}, "Lighting"},
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_LIGHT, "FLAG_LIGHT",
{ },
"Lighting" },
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_FOG, "FLAG_FOG", {}, "Fog Effect"},
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_FOG, "FLAG_FOG",
{ },
"Fog Effect" },
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_DIFFUSE_MAP, "FLAG_DIFFUSE_MAP", {}, "Diffuse Mapping"},
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_DIFFUSE_MAP, "FLAG_DIFFUSE_MAP",
{ },
"Diffuse Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_GLOW_MAP, "FLAG_GLOW_MAP",
{ },
"Glow Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_SPEC_MAP, "FLAG_SPEC_MAP",
{ },
"Specular Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_NORMAL_MAP, "FLAG_NORMAL_MAP",
{ },
"Normal Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_HEIGHT_MAP, "FLAG_HEIGHT_MAP",
{ },
"Parallax Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_ENV_MAP, "FLAG_ENV_MAP",
{ },
"Environment Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_ANIMATED, "FLAG_ANIMATED",
{ },
"Animated Effects" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_MISC_MAP, "FLAG_MISC_MAP",
{ },
"Utility mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_TEAMCOLOR, "FLAG_TEAMCOLOR",
{ },
"Team Colors" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_DEFERRED, "FLAG_DEFERRED",
{ },
"Deferred lighting" },
{ SDR_TYPE_MODEL, true, SDR_FLAG_MODEL_SHADOW_MAP, "FLAG_SHADOW_MAP",
{ },
"Shadow Mapping" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_SHADOWS, "FLAG_SHADOWS",
{ },
"Shadows" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_THRUSTER, "FLAG_THRUSTER",
{ },
"Thruster scaling" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_TRANSFORM, "FLAG_TRANSFORM",
{ },
"Submodel Transforms" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_CLIP, "FLAG_CLIP",
{ },
"Clip Plane" },
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_GLOW_MAP, "FLAG_GLOW_MAP", {}, "Glow Mapping"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_SPEC_MAP, "FLAG_SPEC_MAP", {}, "Specular Mapping"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_NORMAL_MAP, "FLAG_NORMAL_MAP", {}, "Normal Mapping"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_HEIGHT_MAP, "FLAG_HEIGHT_MAP", {}, "Parallax Mapping"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_ENV_MAP, "FLAG_ENV_MAP", {}, "Environment Mapping"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_ANIMATED, "FLAG_ANIMATED", {}, "Animated Effects"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_MISC_MAP, "FLAG_MISC_MAP", {}, "Utility mapping"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_TEAMCOLOR, "FLAG_TEAMCOLOR", {}, "Team Colors"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_DEFERRED, "FLAG_DEFERRED", {}, "Deferred lighting"},
{SDR_TYPE_MODEL, true, SDR_FLAG_MODEL_SHADOW_MAP, "FLAG_SHADOW_MAP", {}, "Shadow Mapping"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_SHADOWS, "FLAG_SHADOWS", {}, "Shadows"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_THRUSTER, "FLAG_THRUSTER", {}, "Thruster scaling"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_TRANSFORM, "FLAG_TRANSFORM", {}, "Submodel Transforms"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_CLIP, "FLAG_CLIP", {}, "Clip Plane"},
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_HDR, "FLAG_HDR", {}, "High Dynamic Range"},
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_HDR, "FLAG_HDR",
{ },
"High Dynamic Range" },
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_AMBIENT_MAP, "FLAG_AMBIENT_MAP",
{ }, "Ambient Occlusion Map"},
{ },
"Ambient Occlusion Map" },
{SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_NORMAL_ALPHA, "FLAG_NORMAL_ALPHA", {}, "Normal Alpha"},
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_NORMAL_ALPHA, "FLAG_NORMAL_ALPHA",
{ },
"Normal Alpha" },
{SDR_TYPE_MODEL, true, SDR_FLAG_MODEL_THICK_OUTLINES, "FLAG_THICK_OUTLINE", {}, "Thick outlines"},
{ SDR_TYPE_MODEL, true, SDR_FLAG_MODEL_THICK_OUTLINES, "FLAG_THICK_OUTLINE",
{ },
"Thick outlines" },
{SDR_TYPE_EFFECT_PARTICLE,
true,
SDR_FLAG_PARTICLE_POINT_GEN,
"FLAG_EFFECT_GEOMETRY",
{opengl_vert_attrib::UVEC},
"Geometry shader point-based particles"},
{ SDR_TYPE_EFFECT_PARTICLE, true, SDR_FLAG_PARTICLE_POINT_GEN, "FLAG_EFFECT_GEOMETRY",
{ opengl_vert_attrib::UVEC },
"Geometry shader point-based particles" },
{ SDR_TYPE_POST_PROCESS_BLUR, false, SDR_FLAG_BLUR_HORIZONTAL, "PASS_0",
{ },
"Horizontal blur pass" },
{ SDR_TYPE_POST_PROCESS_BLUR, false, SDR_FLAG_BLUR_VERTICAL, "PASS_1",
{ },
"Vertical blur pass" },
{SDR_TYPE_POST_PROCESS_BLUR, false, SDR_FLAG_BLUR_HORIZONTAL, "PASS_0", {}, "Horizontal blur pass"},
{ SDR_TYPE_NANOVG, false, SDR_FLAG_NANOVG_EDGE_AA, "EDGE_AA",
{ },
"NanoVG edge anti-alias" },
{SDR_TYPE_POST_PROCESS_BLUR, false, SDR_FLAG_BLUR_VERTICAL, "PASS_1", {}, "Vertical blur pass"},
{SDR_TYPE_NANOVG, false, SDR_FLAG_NANOVG_EDGE_AA, "EDGE_AA", {}, "NanoVG edge anti-alias"},
{SDR_TYPE_DECAL, false, SDR_FLAG_DECAL_USE_NORMAL_MAP, "USE_NORMAL_MAP", {}, "Decal use scene normal map"},
{ SDR_TYPE_DECAL, false, SDR_FLAG_DECAL_USE_NORMAL_MAP, "USE_NORMAL_MAP",
{ },
"Decal use scene normal map" },
};
static const int GL_num_shader_variants = sizeof(GL_shader_variants) / sizeof(opengl_shader_variant_t);
@@ -273,7 +315,7 @@ void opengl_shader_set_current(int handle)
opengl_shader_set_current(&GL_shader[handle]);
}
size_t opengl_get_shader_idx(shader_type shader_t, unsigned int flags)
size_t opengl_get_shader_idx(shader_type shader_t, unsigned int flags)
{
auto found = GL_shader_map.find(shader_descriptor_t(shader_t, flags));
if (found != GL_shader_map.end()) {
@@ -308,7 +350,7 @@ void opengl_delete_shader(int sdr_handle)
GL_shader_map.erase(shader_descriptor_t(victim.shader, victim.flags));
GL_shader[sdr_handle].program.reset();
GL_shader[sdr_handle].flags = 0;
GL_shader[sdr_handle].flags2 = 0;
GL_shader[sdr_handle].shader = NUM_SHADER_TYPES;
@@ -572,9 +614,9 @@ static bool load_cached_shader_binary(opengl::ShaderProgram* program, const SCP_
nprintf(("ShaderCache", "Binary file does not exist.\n"));
return false;
}
GR_DEBUG_SCOPE("Loading cached shader");
SCP_vector<uint8_t> buffer;
int length = cfilelength(binary_fp);
buffer.resize((size_t) length);
@@ -605,7 +647,7 @@ static void cache_program_binary(GLuint program, const SCP_string& hash) {
if (!do_shader_caching()) {
return;
}
GR_DEBUG_SCOPE("Saving shader binary");
GLint size;
@@ -659,16 +701,16 @@ static void cache_program_binary(GLuint program, const SCP_string& hash) {
static void opengl_set_default_uniforms(const opengl_shader_t& sdr) {
switch (sdr.shader) {
case SDR_TYPE_DEFERRED_LIGHTING:
Current_shader->program->Uniforms.setTextureUniform("ColorBuffer", 0);
Current_shader->program->Uniforms.setTextureUniform("NormalBuffer", 1);
Current_shader->program->Uniforms.setTextureUniform("PositionBuffer", 2);
Current_shader->program->Uniforms.setTextureUniform("SpecBuffer", 3);
Current_shader->program->Uniforms.setTextureUniform("shadow_map", 4);
Current_shader->program->Uniforms.setUniformi("ColorBuffer", 0);
Current_shader->program->Uniforms.setUniformi("NormalBuffer", 1);
Current_shader->program->Uniforms.setUniformi("PositionBuffer", 2);
Current_shader->program->Uniforms.setUniformi("SpecBuffer", 3);
Current_shader->program->Uniforms.setUniformi("shadow_map", 4);
break;
case SDR_TYPE_PASSTHROUGH_RENDER:
Current_shader->program->Uniforms.setTextureUniform("baseMap", 0);
Current_shader->program->Uniforms.setTextureUniform("clipEnabled", 0);
Current_shader->program->Uniforms.setUniformi("baseMap", 0);
Current_shader->program->Uniforms.setUniformi("clipEnabled", 0);
break;
default:
@@ -965,71 +1007,76 @@ void opengl_shader_set_passthrough(bool textured, bool hdr)
{
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_PASSTHROUGH_RENDER, 0));
gr_matrix_set_uniforms();
if ( textured ) {
Current_shader->program->Uniforms.setUniformi("noTexturing", 0);
} else {
Current_shader->program->Uniforms.setUniformi("noTexturing", 1);
}
opengl_set_generic_uniform_data<graphics::generic_data::passthrough_data>(
[=](graphics::generic_data::passthrough_data* data) {
data->noTexturing = textured ? 0 : 1;
data->srgb = hdr ? 1 : 0;
});
Current_shader->program->Uniforms.setUniformi("alphaTexture", 0);
Current_shader->program->Uniforms.setUniformi("srgb", hdr ? 1 : 0);
Current_shader->program->Uniforms.setUniformf("intensity", 1.0f);
Current_shader->program->Uniforms.setUniformf("alphaThreshold", GL_alpha_threshold);
Current_shader->program->Uniforms.setUniform4f("color", 1.0f, 1.0f, 1.0f, 1.0f);
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
}
void opengl_shader_set_default_material(bool textured, bool alpha, vec4* clr, float color_scale, uint32_t array_index,
const material::clip_plane& clip_plane)
void opengl_shader_set_default_material(bool textured, bool alpha, vec4 *clr, float color_scale, uint32_t array_index, const material::clip_plane& clip_plane)
{
Current_shader->program->Uniforms.setTextureUniform("baseMap", 0);
Current_shader->program->Uniforms.setUniformi("baseMap", 0);
opengl_set_generic_uniform_data<graphics::generic_data::default_material_data>(
[=](graphics::generic_data::default_material_data* data) {
if (textured) {
data->noTexturing = 0;
data->baseMapIndex = array_index;
} else {
data->noTexturing = 1;
// array_index is probably not valid here
data->baseMapIndex = 0;
}
if ( textured ) {
Current_shader->program->Uniforms.setUniformi("noTexturing", 0);
Current_shader->program->Uniforms.setUniformi("baseMapIndex", array_index);
} else {
Current_shader->program->Uniforms.setUniformi("noTexturing", 1);
// array_index is probably not valid here
Current_shader->program->Uniforms.setUniformi("baseMapIndex", 0);
}
if (alpha) {
data->alphaTexture = 1;
} else {
data->alphaTexture = 0;
}
if ( alpha ) {
Current_shader->program->Uniforms.setUniformi("alphaTexture", 1);
} else {
Current_shader->program->Uniforms.setUniformi("alphaTexture", 0);
}
if (High_dynamic_range) {
data->srgb = 1;
data->intensity = color_scale;
} else {
data->srgb = 0;
data->intensity = 1.0f;
}
if ( High_dynamic_range ) {
Current_shader->program->Uniforms.setUniformi("srgb", 1);
Current_shader->program->Uniforms.setUniformf("intensity", color_scale);
} else {
Current_shader->program->Uniforms.setUniformi("srgb", 0);
Current_shader->program->Uniforms.setUniformf("intensity", 1.0f);
}
data->alphaThreshold = GL_alpha_threshold;
Current_shader->program->Uniforms.setUniformf("alphaThreshold", GL_alpha_threshold);
if (clr != nullptr) {
data->color = *clr;
} else {
data->color.xyzw.x = 1.0f;
data->color.xyzw.y = 1.0f;
data->color.xyzw.z = 1.0f;
data->color.xyzw.w = 1.0f;
}
if ( clr != NULL ) {
Current_shader->program->Uniforms.setUniform4f("color", *clr);
} else {
Current_shader->program->Uniforms.setUniform4f("color", 1.0f, 1.0f, 1.0f, 1.0f);
}
if (clip_plane.enabled) {
data->clipEnabled = 1;
if (clip_plane.enabled) {
Current_shader->program->Uniforms.setUniformi("clipEnabled", 1);
vec4 clip_equation;
clip_equation.xyzw.x = clip_plane.normal.xyz.x;
clip_equation.xyzw.y = clip_plane.normal.xyz.y;
clip_equation.xyzw.z = clip_plane.normal.xyz.z;
clip_equation.xyzw.w = -vm_vec_dot(&clip_plane.normal, &clip_plane.position);
vec4 clip_equation;
clip_equation.xyzw.x = clip_plane.normal.xyz.x;
clip_equation.xyzw.y = clip_plane.normal.xyz.y;
clip_equation.xyzw.z = clip_plane.normal.xyz.z;
clip_equation.xyzw.w = -vm_vec_dot(&clip_plane.normal, &clip_plane.position);
data->clipEquation = clip_equation;
data->modelMatrix = gr_model_matrix_stack.get_transform();
} else {
data->clipEnabled = 0;
}
});
Current_shader->program->Uniforms.setUniform4f("clipEquation", clip_equation);
Current_shader->program->Uniforms.setUniformMatrix4f("modelMatrix", gr_model_matrix_stack.get_transform());
} else {
Current_shader->program->Uniforms.setUniformi("clipEnabled", 0);
}
gr_matrix_set_uniforms();
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
}
+12 -20
View File
@@ -1,29 +1,34 @@
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
#ifndef _GROPENGLSHADER_H
#define _GROPENGLSHADER_H
#include "globalincs/pstypes.h"
#include "graphics/2d.h"
#include "graphics/material.h"
#include "graphics/opengl/gropengl.h"
#include "graphics/util/UniformBuffer.h"
#include "graphics/material.h"
#include <string>
#include <glad/glad.h>
namespace opengl {
// Forward definition to avoid cyclic dependency
class ShaderProgram;
} // namespace opengl
}
enum shader_stage { SDR_STAGE_VERTEX, SDR_STAGE_FRAGMENT, SDR_STAGE_GEOMETRY };
enum shader_stage {
SDR_STAGE_VERTEX,
SDR_STAGE_FRAGMENT,
SDR_STAGE_GEOMETRY
};
struct opengl_vert_attrib {
enum attrib_id {
@@ -155,18 +160,5 @@ void opengl_shader_set_passthrough(bool textured, bool hdr);
void opengl_shader_set_default_material(bool textured, bool alpha, vec4* clr, float color_scale, uint32_t array_index, const material::clip_plane& clip_plane);
template <typename T, typename DataCallback>
void opengl_set_generic_uniform_data(DataCallback cb)
{
auto buffer = gr_get_uniform_buffer(uniform_block_type::GenericData, 1, sizeof(T));
auto bufferPtr = buffer.aligner().addTypedElement<T>();
cb(bufferPtr);
buffer.submitData();
gr_bind_uniform_buffer(uniform_block_type::GenericData, buffer.getBufferOffset(0), sizeof(T),
buffer.bufferHandle());
}
#endif // _GROPENGLSHADER_H
+2
View File
@@ -45,7 +45,9 @@ GLint GL_max_renderbuffer_size = 0;
extern int GLOWMAP;
extern int SPECMAP;
extern int CLOAKMAP;
extern int ENVMAP;
extern int Interp_multitex_cloakmap;
static SCP_vector<float> anisotropic_value_enumerator()
{
+134 -154
View File
@@ -37,6 +37,7 @@
#include "weapon/trails.h"
extern int GLOWMAP;
extern int CLOAKMAP;
extern int SPECMAP;
extern int SPECGLOSSMAP;
extern int NORMMAP;
@@ -89,8 +90,7 @@ static opengl_vertex_bind GL_array_binding_data[] =
struct opengl_buffer_object {
GLuint buffer_id;
GLenum type;
GLenum gl_usage;
BufferUsageHint usage;
GLenum usage;
size_t size;
GLuint texture; // for texture buffer objects
@@ -121,9 +121,7 @@ static GLenum convertUsageHint(BufferUsageHint usage) {
return GL_DYNAMIC_DRAW;
case BufferUsageHint::Streaming:
return GL_STREAM_DRAW;
case BufferUsageHint::PersistentMapping:
return GL_NONE; // Dummy value
default:
default:
UNREACHABLE("Unhandled enum value!");
return GL_INVALID_ENUM;
}
@@ -188,16 +186,12 @@ static GLenum convertComparisionFunction(ComparisionFunction func) {
return mode;
}
int opengl_create_buffer_object(GLenum type, GLenum gl_usage, BufferUsageHint usage)
int opengl_create_buffer_object(GLenum type, GLenum usage)
{
GR_DEBUG_SCOPE("Create buffer object");
Assertion(usage != BufferUsageHint::PersistentMapping || GLAD_GL_ARB_buffer_storage != 0,
"Persistent mapping is not supported by this OpenGL implementation!");
opengl_buffer_object buffer_obj;
buffer_obj.gl_usage = gl_usage;
buffer_obj.usage = usage;
buffer_obj.type = type;
buffer_obj.size = 0;
@@ -248,7 +242,7 @@ GLuint opengl_buffer_get_id(GLenum expected_type, int handle) {
return buffer_obj.buffer_id;
}
void gr_opengl_update_buffer_data(int handle, size_t size, const void* data)
void gr_opengl_update_buffer_data(int handle, size_t size, void* data)
{
// This has to be verified by the caller or else we will run into OPenGL errors
Assertion(size > 0, "Buffer updates must include some data!");
@@ -262,20 +256,31 @@ void gr_opengl_update_buffer_data(int handle, size_t size, const void* data)
opengl_bind_buffer_object(handle);
if (buffer_obj.usage == BufferUsageHint::PersistentMapping) {
Assertion(buffer_obj.size == 0, "Tried to resize a buffer for persistent mapping! This is not allowed.");
Assertion(GLAD_GL_ARB_buffer_storage != 0, "Persistent mapping was used when it wasn't supported!");
glBufferStorage(buffer_obj.type, size, data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
} else {
glBufferData(buffer_obj.type, size, data, buffer_obj.gl_usage);
}
if (size <= buffer_obj.size && buffer_obj.type == GL_UNIFORM_BUFFER) {
// Uniform buffer can use unsychronized buffer mapping since those are always synchronized by us
// We also don't care about the previous data and tell OpenGL to map the buffer unsynchronized.
auto ptr = glMapBufferRange(buffer_obj.type,
0,
size,
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
if (ptr == nullptr) {
// Something went wrong, try subdata instead
glBufferSubData(buffer_obj.type, 0, size, data);
} else {
memcpy(ptr, data, size);
GL_vertex_data_in -= buffer_obj.size;
buffer_obj.size = size;
GL_vertex_data_in += buffer_obj.size;
glUnmapBuffer(buffer_obj.type);
}
} else {
GL_vertex_data_in -= buffer_obj.size;
buffer_obj.size = size;
GL_vertex_data_in += buffer_obj.size;
glBufferData(buffer_obj.type, size, data, buffer_obj.usage);
}
}
void gr_opengl_update_buffer_data_offset(int handle, size_t offset, size_t size, const void* data)
void gr_opengl_update_buffer_data_offset(int handle, size_t offset, size_t size, void* data)
{
GR_DEBUG_SCOPE("Update buffer data with offset");
@@ -284,46 +289,10 @@ void gr_opengl_update_buffer_data_offset(int handle, size_t offset, size_t size,
opengl_buffer_object &buffer_obj = GL_buffer_objects[handle];
Assertion(buffer_obj.usage != BufferUsageHint::PersistentMapping,
"Persistently mapped buffers may not be updated!");
opengl_bind_buffer_object(handle);
glBufferSubData(buffer_obj.type, offset, size, data);
}
void* gr_opengl_map_buffer(int handle)
{
GR_DEBUG_SCOPE("Map buffer");
Assert(handle >= 0);
Assert((size_t)handle < GL_buffer_objects.size());
auto& buffer_obj = GL_buffer_objects[handle];
Assertion(buffer_obj.usage == BufferUsageHint::PersistentMapping,
"Buffer mapping is only supported for persistently mapped buffers!");
Assertion(GLAD_GL_ARB_buffer_storage != 0, "Persistent mapping is not available in this OpenGL context!");
opengl_bind_buffer_object(handle);
return glMapBufferRange(buffer_obj.type, 0, buffer_obj.size,
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
}
void gr_opengl_flush_mapped_buffer(int handle, size_t offset, size_t size)
{
GR_DEBUG_SCOPE("Flush mapped buffer");
Assert(handle >= 0);
Assert((size_t)handle < GL_buffer_objects.size());
auto& buffer_obj = GL_buffer_objects[handle];
Assertion(buffer_obj.usage == BufferUsageHint::PersistentMapping,
"Buffer mapping is only supported for persistently mapped buffers!");
Assertion(GLAD_GL_ARB_buffer_storage != 0, "Persistent mapping is not available in this OpenGL context!");
opengl_bind_buffer_object(handle);
glFlushMappedBufferRange(buffer_obj.type, offset, size);
}
void gr_opengl_delete_buffer(int handle)
{
@@ -367,7 +336,7 @@ void gr_opengl_delete_buffer(int handle)
int gr_opengl_create_buffer(BufferType type, BufferUsageHint usage)
{
return opengl_create_buffer_object(convertBufferType(type), convertUsageHint(usage), usage);
return opengl_create_buffer_object(convertBufferType(type), convertUsageHint(usage));
}
void gr_opengl_bind_uniform_buffer(uniform_block_type bind_point, size_t offset, size_t size, int buffer) {
@@ -392,8 +361,7 @@ void gr_opengl_bind_uniform_buffer(uniform_block_type bind_point, size_t offset,
int opengl_create_texture_buffer_object()
{
// create the buffer
int buffer_object_handle =
opengl_create_buffer_object(GL_TEXTURE_BUFFER, GL_DYNAMIC_DRAW, BufferUsageHint::Dynamic);
int buffer_object_handle = opengl_create_buffer_object(GL_TEXTURE_BUFFER, GL_DYNAMIC_DRAW);
opengl_check_for_errors();
@@ -766,7 +734,8 @@ void opengl_tnl_set_material(material* material_info, bool set_base_map, bool se
if (!clip_params.enabled) {
GL_state.ClipDistance(0, false);
} else {
Assertion(Current_shader != nullptr && (Current_shader->shader == SDR_TYPE_MODEL
Assertion(Current_shader != NULL && (Current_shader->shader == SDR_TYPE_MODEL
|| Current_shader->shader == SDR_TYPE_PASSTHROUGH_RENDER
|| Current_shader->shader == SDR_TYPE_DEFAULT_MATERIAL),
"Clip planes are not supported by this shader!");
@@ -818,6 +787,7 @@ void opengl_tnl_set_material(material* material_info, bool set_base_map, bool se
void opengl_tnl_set_model_material(model_material *material_info)
{
float u_scale, v_scale;
int render_pass = 0;
opengl_tnl_set_material(material_info, false, false);
@@ -839,78 +809,98 @@ void opengl_tnl_set_model_material(model_material *material_info)
uint32_t array_index;
if ( Current_shader->flags & SDR_FLAG_MODEL_DIFFUSE_MAP ) {
Current_shader->program->Uniforms.setTextureUniform("sBasemap", 0);
Current_shader->program->Uniforms.setUniformi("sBasemap", render_pass);
gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 0);
gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass);
++render_pass;
}
if ( Current_shader->flags & SDR_FLAG_MODEL_GLOW_MAP ) {
Current_shader->program->Uniforms.setTextureUniform("sGlowmap", 1);
Current_shader->program->Uniforms.setUniformi("sGlowmap", render_pass);
gr_opengl_tcache_set(material_info->get_texture_map(TM_GLOW_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 1);
gr_opengl_tcache_set(material_info->get_texture_map(TM_GLOW_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass);
++render_pass;
}
if ( Current_shader->flags & SDR_FLAG_MODEL_SPEC_MAP ) {
Current_shader->program->Uniforms.setTextureUniform("sSpecmap", 2);
Current_shader->program->Uniforms.setUniformi("sSpecmap", render_pass);
if ( material_info->get_texture_map(TM_SPEC_GLOSS_TYPE) > 0 ) {
gr_opengl_tcache_set(material_info->get_texture_map(TM_SPEC_GLOSS_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 2);
gr_opengl_tcache_set(material_info->get_texture_map(TM_SPEC_GLOSS_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass);
} else {
gr_opengl_tcache_set(material_info->get_texture_map(TM_SPECULAR_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 2);
gr_opengl_tcache_set(material_info->get_texture_map(TM_SPECULAR_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass);
}
++render_pass;
if ( Current_shader->flags & SDR_FLAG_MODEL_ENV_MAP ) {
Current_shader->program->Uniforms.setTextureUniform("sEnvmap", 3);
Current_shader->program->Uniforms.setUniformi("sEnvmap", render_pass);
gr_opengl_tcache_set(ENVMAP, TCACHE_TYPE_CUBEMAP, &u_scale, &v_scale, &array_index, 3);
gr_opengl_tcache_set(ENVMAP, TCACHE_TYPE_CUBEMAP, &u_scale, &v_scale, &array_index, render_pass);
Assertion(array_index == 0, "Cube map arrays are not supported yet!");
++render_pass;
}
}
if ( Current_shader->flags & SDR_FLAG_MODEL_NORMAL_MAP ) {
Current_shader->program->Uniforms.setTextureUniform("sNormalmap", 4);
Current_shader->program->Uniforms.setUniformi("sNormalmap", render_pass);
gr_opengl_tcache_set(material_info->get_texture_map(TM_NORMAL_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 4);
gr_opengl_tcache_set(material_info->get_texture_map(TM_NORMAL_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass);
++render_pass;
}
if ( Current_shader->flags & SDR_FLAG_MODEL_HEIGHT_MAP ) {
Current_shader->program->Uniforms.setTextureUniform("sHeightmap", 5);
Current_shader->program->Uniforms.setUniformi("sHeightmap", render_pass);
gr_opengl_tcache_set(material_info->get_texture_map(TM_HEIGHT_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 5);
gr_opengl_tcache_set(material_info->get_texture_map(TM_HEIGHT_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass);
++render_pass;
}
if ( Current_shader->flags & SDR_FLAG_MODEL_AMBIENT_MAP ) {
Current_shader->program->Uniforms.setTextureUniform("sAmbientmap", 6);
Current_shader->program->Uniforms.setUniformi("sAmbientmap", render_pass);
gr_opengl_tcache_set(material_info->get_texture_map(TM_AMBIENT_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 6);
gr_opengl_tcache_set(material_info->get_texture_map(TM_AMBIENT_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass);
++render_pass;
}
if ( Current_shader->flags & SDR_FLAG_MODEL_MISC_MAP ) {
Current_shader->program->Uniforms.setTextureUniform("sMiscmap", 7);
Current_shader->program->Uniforms.setUniformi("sMiscmap", render_pass);
gr_opengl_tcache_set(material_info->get_texture_map(TM_MISC_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 7);
gr_opengl_tcache_set(material_info->get_texture_map(TM_MISC_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass);
++render_pass;
}
if ( Current_shader->flags & SDR_FLAG_MODEL_SHADOWS ) {
Current_shader->program->Uniforms.setTextureUniform("shadow_map", 8);
Current_shader->program->Uniforms.setUniformi("shadow_map", render_pass);
GL_state.Texture.Enable(8, GL_TEXTURE_2D_ARRAY, Shadow_map_texture);
GL_state.Texture.Enable(render_pass, GL_TEXTURE_2D_ARRAY, Shadow_map_texture);
++render_pass; // bump!
}
if ( Current_shader->flags & SDR_FLAG_MODEL_ANIMATED ) {
Current_shader->program->Uniforms.setTextureUniform("sFramebuffer", 9);
Current_shader->program->Uniforms.setUniformi("sFramebuffer", render_pass);
if ( Scene_framebuffer_in_frame ) {
GL_state.Texture.Enable(9, GL_TEXTURE_2D, Scene_effect_texture);
GL_state.Texture.Enable(render_pass, GL_TEXTURE_2D, Scene_effect_texture);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
} else {
GL_state.Texture.Enable(9, GL_TEXTURE_2D, Framebuffer_fallback_texture_id);
GL_state.Texture.Enable(render_pass, GL_TEXTURE_2D, Framebuffer_fallback_texture_id);
}
++render_pass;
}
if ( Current_shader->flags & SDR_FLAG_MODEL_TRANSFORM ) {
Current_shader->program->Uniforms.setTextureUniform("transform_tex", 10);
GL_state.Texture.Enable(10, GL_TEXTURE_BUFFER, opengl_get_transform_buffer_texture());
Current_shader->program->Uniforms.setUniformi("transform_tex", render_pass);
GL_state.Texture.Enable(render_pass, GL_TEXTURE_BUFFER, opengl_get_transform_buffer_texture());
++render_pass;
}
if ( Deferred_lighting ) {
@@ -923,28 +913,25 @@ void opengl_tnl_set_material_particle(particle_material * material_info)
{
opengl_tnl_set_material(material_info, true);
gr_matrix_set_uniforms();
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
opengl_set_generic_uniform_data<graphics::generic_data::effect_data>(
[&](graphics::generic_data::effect_data* data) {
data->window_width = (float)gr_screen.max_w;
data->window_height = (float)gr_screen.max_h;
data->nearZ = Min_draw_distance;
data->farZ = Max_draw_distance;
data->srgb = High_dynamic_range ? 1 : 0;
data->blend_alpha = material_info->get_blend_mode() != ALPHA_BLEND_ADDITIVE;
Current_shader->program->Uniforms.setUniformi("baseMap", 0);
Current_shader->program->Uniforms.setUniformi("depthMap", 1);
Current_shader->program->Uniforms.setUniformf("window_width", (float)gr_screen.max_w);
Current_shader->program->Uniforms.setUniformf("window_height", (float)gr_screen.max_h);
Current_shader->program->Uniforms.setUniformf("nearZ", Min_draw_distance);
Current_shader->program->Uniforms.setUniformf("farZ", Max_draw_distance);
Current_shader->program->Uniforms.setUniformi("srgb", High_dynamic_range ? 1 : 0);
Current_shader->program->Uniforms.setUniformi("blend_alpha", material_info->get_blend_mode() != ALPHA_BLEND_ADDITIVE);
if (Cmdline_no_deferred_lighting) {
data->linear_depth = 0;
} else {
data->linear_depth = 1;
}
});
if ( Cmdline_no_deferred_lighting ) {
Current_shader->program->Uniforms.setUniformi("linear_depth", 0);
} else {
Current_shader->program->Uniforms.setUniformi("linear_depth", 1);
}
Current_shader->program->Uniforms.setTextureUniform("baseMap", 0);
Current_shader->program->Uniforms.setTextureUniform("depthMap", 1);
if (!Cmdline_no_deferred_lighting) {
if ( !Cmdline_no_deferred_lighting ) {
Assert(Scene_position_texture != 0);
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_position_texture);
@@ -954,52 +941,48 @@ void opengl_tnl_set_material_particle(particle_material * material_info)
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_depth_texture);
}
}
void opengl_tnl_set_material_batched(batched_bitmap_material* material_info)
{
void opengl_tnl_set_material_batched(batched_bitmap_material* material_info) {
// This material assumes that the array index is supplied via the vertex attributes
opengl_tnl_set_material(material_info, true);
opengl_set_generic_uniform_data<graphics::generic_data::batched_data>(
[&](graphics::generic_data::batched_data* data) {
data->intensity = material_info->get_color_scale();
data->color = material_info->get_color();
});
Current_shader->program->Uniforms.setUniformf("intensity", material_info->get_color_scale());
gr_matrix_set_uniforms();
Current_shader->program->Uniforms.setUniform4f("color", material_info->get_color());
Current_shader->program->Uniforms.setTextureUniform("baseMap", 0);
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
Current_shader->program->Uniforms.setUniformi("baseMap", 0);
}
void opengl_tnl_set_material_distortion(distortion_material* material_info)
{
opengl_tnl_set_material(material_info, true);
gr_matrix_set_uniforms();
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
Current_shader->program->Uniforms.setTextureUniform("baseMap", 0);
Current_shader->program->Uniforms.setTextureUniform("depthMap", 1);
Current_shader->program->Uniforms.setUniformi("baseMap", 0);
Current_shader->program->Uniforms.setUniformi("depthMap", 1);
Current_shader->program->Uniforms.setUniformf("window_width", (float)gr_screen.max_w);
Current_shader->program->Uniforms.setUniformf("window_height", (float)gr_screen.max_h);
Current_shader->program->Uniforms.setUniformf("nearZ", Min_draw_distance);
Current_shader->program->Uniforms.setUniformf("farZ", Max_draw_distance);
Current_shader->program->Uniforms.setUniformi("frameBuffer", 2);
opengl_set_generic_uniform_data<graphics::generic_data::effect_distort_data>(
[&](graphics::generic_data::effect_distort_data* data) {
data->window_width = (float)gr_screen.max_w;
data->window_height = (float)gr_screen.max_h;
if (material_info->get_thruster_rendering()) {
data->use_offset = 1.0f;
} else {
data->use_offset = 0.0f;
}
});
Current_shader->program->Uniforms.setTextureUniform("frameBuffer", 2);
GL_state.Texture.Enable(2, GL_TEXTURE_2D, Scene_effect_texture);
Current_shader->program->Uniforms.setTextureUniform("distMap", 3);
if (material_info->get_thruster_rendering()) {
Current_shader->program->Uniforms.setUniformi("distMap", 3);
if(material_info->get_thruster_rendering()) {
GL_state.Texture.Enable(3, GL_TEXTURE_2D, Distortion_texture[!Distortion_switch]);
Current_shader->program->Uniforms.setUniformf("use_offset", 1.0f);
} else {
// Disable this texture unit
GL_state.Texture.Enable(3, GL_TEXTURE_2D, 0);
Current_shader->program->Uniforms.setUniformf("use_offset", 0.0f);
}
Assert(Scene_depth_texture != 0);
@@ -1010,11 +993,12 @@ void opengl_tnl_set_material_distortion(distortion_material* material_info)
void opengl_tnl_set_material_movie(movie_material* material_info) {
opengl_tnl_set_material(material_info, false);
gr_matrix_set_uniforms();
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
Current_shader->program->Uniforms.setTextureUniform("ytex", 0);
Current_shader->program->Uniforms.setTextureUniform("utex", 1);
Current_shader->program->Uniforms.setTextureUniform("vtex", 2);
Current_shader->program->Uniforms.setUniformi("ytex", 0);
Current_shader->program->Uniforms.setUniformi("utex", 1);
Current_shader->program->Uniforms.setUniformi("vtex", 2);
float u_scale, v_scale;
uint32_t index;
@@ -1031,7 +1015,7 @@ void opengl_tnl_set_material_movie(movie_material* material_info) {
void opengl_tnl_set_material_nanovg(nanovg_material* material_info) {
opengl_tnl_set_material(material_info, true);
Current_shader->program->Uniforms.setTextureUniform("nvg_tex", 0);
Current_shader->program->Uniforms.setUniformi("nvg_tex", 0);
}
void opengl_tnl_set_material_decal(decal_material* material_info) {
@@ -1046,7 +1030,7 @@ void opengl_tnl_set_material_decal(decal_material* material_info) {
&v_scale,
&array_index,
0)) {
Current_shader->program->Uniforms.setTextureUniform("diffuseMap", 0);
Current_shader->program->Uniforms.setUniformi("diffuseMap", 0);
}
if (gr_opengl_tcache_set(material_info->get_texture_map(TM_GLOW_TYPE),
@@ -1055,7 +1039,7 @@ void opengl_tnl_set_material_decal(decal_material* material_info) {
&v_scale,
&array_index,
1)) {
Current_shader->program->Uniforms.setTextureUniform("glowMap", 1);
Current_shader->program->Uniforms.setUniformi("glowMap", 1);
}
if (gr_opengl_tcache_set(material_info->get_texture_map(TM_NORMAL_TYPE),
@@ -1064,15 +1048,15 @@ void opengl_tnl_set_material_decal(decal_material* material_info) {
&v_scale,
&array_index,
2)) {
Current_shader->program->Uniforms.setTextureUniform("normalMap", 2);
Current_shader->program->Uniforms.setUniformi("normalMap", 2);
}
GL_state.Texture.Enable(3, GL_TEXTURE_2D, Scene_depth_texture);
Current_shader->program->Uniforms.setTextureUniform("gDepthBuffer", 3);
Current_shader->program->Uniforms.setUniformi("gDepthBuffer", 3);
if (Current_shader->flags & SDR_FLAG_DECAL_USE_NORMAL_MAP) {
GL_state.Texture.Enable(4, GL_TEXTURE_2D, Scene_normal_texture);
Current_shader->program->Uniforms.setTextureUniform("gNormalBuffer", 4);
Current_shader->program->Uniforms.setUniformi("gNormalBuffer", 4);
}
}
@@ -1087,25 +1071,21 @@ void opengl_tnl_set_rocketui_material(interface_material* material_info)
opengl_tnl_set_material(material_info, false);
Current_shader->program->Uniforms.setTextureUniform("baseMap", 0);
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", modelViewMatrix);
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
Current_shader->program->Uniforms.setUniformi("textured", material_info->is_textured() ? GL_TRUE : GL_FALSE);
Current_shader->program->Uniforms.setUniformi("baseMap", 0);
uint32_t baseMapIndex = 0;
if (material_info->is_textured()) {
float u_scale, v_scale;
uint32_t array_index;
if (!gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), material_info->get_texture_type(),
&u_scale, &v_scale, &baseMapIndex)) {
&u_scale, &v_scale, &array_index)) {
mprintf(("WARNING: Error setting bitmap texture (%i)!\n", material_info->get_texture_map(TM_BASE_TYPE)));
}
Current_shader->program->Uniforms.setUniformi("baseMapIndex", array_index);
}
opengl_set_generic_uniform_data<graphics::generic_data::rocketui_data>(
[&](graphics::generic_data::rocketui_data* data) {
data->modelViewMatrix = modelViewMatrix;
data->projMatrix = gr_projection_matrix;
data->textured = material_info->is_textured() ? GL_TRUE : GL_FALSE;
data->baseMapIndex = baseMapIndex;
});
}
void gr_opengl_set_viewport(int x, int y, int width, int height) {
+2 -5
View File
@@ -16,7 +16,6 @@
#include "globalincs/pstypes.h"
#include "gropengl.h"
#include "gropenglshader.h"
#include "graphics/shadows.h"
#include "model/model.h"
@@ -47,12 +46,10 @@ struct opengl_vertex_bind {
int gr_opengl_create_buffer(BufferType type, BufferUsageHint usage);
void opengl_bind_buffer_object(int handle);
void gr_opengl_update_buffer_data(int handle, size_t size, const void* data);
void gr_opengl_update_buffer_data_offset(int handle, size_t offset, size_t size, const void* data);
void gr_opengl_update_buffer_data(int handle, size_t size, void* data);
void gr_opengl_update_buffer_data_offset(int handle, size_t offset, size_t size, void* data);
void gr_opengl_delete_buffer(int handle);
void gr_opengl_bind_uniform_buffer(uniform_block_type bind_point, size_t offset, size_t size, int buffer);
void* gr_opengl_map_buffer(int handle);
void gr_opengl_flush_mapped_buffer(int handle, size_t offset, size_t size);
/**
* @brief Retrieves the OpenGL handle of a generic buffer handle
+35 -23
View File
@@ -22,20 +22,20 @@
#include "tracing/tracing.h"
#ifndef NDEBUG
// That is a wrapper function for log prints to be availiable for nanovg components. For now it is stb_truetype.h
// Planted by ksotar with blessing from asarium
extern "C" {
void nvgOldCPrintf(SCP_FORMAT_STRING const char *message, ...) {
if (LoggingEnabled) {
SCP_string buf;
va_list args;
va_start(args, message);
vsprintf(buf, message, args);
va_end(args);
outwnd_printf2("%s", message);
}
SCP_string buf;
va_list args;
va_start(args, message);
vsprintf(buf, message, args);
va_end(args);
outwnd_printf2("%s", message);
}
}
#endif
namespace {
@@ -427,13 +427,13 @@ void NanoVGRenderer::renderFlush() {
gr_set_viewport(0, 0, gr_screen.max_w, gr_screen.max_h);
_uniformBuffer = gr_get_uniform_buffer(uniform_block_type::NanoVGData, _uniformData.size());
_uniformBuffer = gr_get_uniform_buffer(uniform_block_type::NanoVGData);
// This copies the uniform data from our vector into the uniform buffer aligner
for (auto& uniform : _uniformData) {
memcpy(_uniformBuffer.aligner().addTypedElement<nanovg_draw_data>(), &uniform, sizeof(uniform));
memcpy(_uniformBuffer->aligner().addTypedElement<nanovg_draw_data>(), &uniform, sizeof(uniform));
}
_uniformBuffer.submitData();
_uniformBuffer->submitData();
gr_update_buffer_data(_vertexBuffer, sizeof(NVGvertex) * _vertices.size(), _vertices.data());
for (auto& drawCall : _drawCalls) {
@@ -453,6 +453,8 @@ void NanoVGRenderer::renderFlush() {
}
}
_uniformBuffer->finished();
// Reset all data again
renderCancel();
}
@@ -659,8 +661,10 @@ void NanoVGRenderer::drawTriangles(const DrawCall& call) {
auto mat = _trianglesMaterial;
materialSetTexture(mat, call.image);
gr_bind_uniform_buffer(uniform_block_type::NanoVGData, _uniformBuffer.getAlignerElementOffset(call.uniformIndex),
sizeof(nanovg_draw_data), _uniformBuffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
_uniformBuffer->aligner().getOffset(call.uniformIndex),
sizeof(nanovg_draw_data),
_uniformBuffer->bufferHandle());
gr_render_nanovg(&mat, PRIM_TYPE_TRIS, &_vertexLayout, call.triangleOffset, call.triangleCount, _vertexBuffer);
}
@@ -671,8 +675,10 @@ void NanoVGRenderer::drawFill(const DrawCall& call) {
auto mat = _fillShapeMaterial;
mat.set_texture_map(TM_BASE_TYPE, -1);
gr_bind_uniform_buffer(uniform_block_type::NanoVGData, _uniformBuffer.getAlignerElementOffset(call.uniformIndex),
sizeof(nanovg_draw_data), _uniformBuffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
_uniformBuffer->aligner().getOffset(call.uniformIndex),
sizeof(nanovg_draw_data),
_uniformBuffer->bufferHandle());
auto pathOffset = call.pathOffset;
for (size_t i = 0; i < call.pathCount; ++i) {
@@ -687,8 +693,9 @@ void NanoVGRenderer::drawFill(const DrawCall& call) {
mat = _fillAntiAliasMaterial;
materialSetTexture(mat, call.image);
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
_uniformBuffer.getAlignerElementOffset(call.uniformIndex + 1), sizeof(nanovg_draw_data),
_uniformBuffer.bufferHandle());
_uniformBuffer->aligner().getOffset(call.uniformIndex + 1),
sizeof(nanovg_draw_data),
_uniformBuffer->bufferHandle());
// Draw fringes
for (size_t i = 0; i < call.pathCount; ++i) {
@@ -711,8 +718,10 @@ void NanoVGRenderer::drawConvexFill(const DrawCall& call) {
auto mat = _triangleFillMaterial;
materialSetTexture(mat, call.image);
gr_bind_uniform_buffer(uniform_block_type::NanoVGData, _uniformBuffer.getAlignerElementOffset(call.uniformIndex),
sizeof(nanovg_draw_data), _uniformBuffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
_uniformBuffer->aligner().getOffset(call.uniformIndex),
sizeof(nanovg_draw_data),
_uniformBuffer->bufferHandle());
auto pathOffset = call.pathOffset;
for (size_t i = 0; i < call.pathCount; ++i) {
@@ -743,8 +752,9 @@ void NanoVGRenderer::drawStroke(const DrawCall& call) {
auto mat = _strokeFillMaterial;
materialSetTexture(mat, call.image);
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
_uniformBuffer.getAlignerElementOffset(call.uniformIndex + 1), sizeof(nanovg_draw_data),
_uniformBuffer.bufferHandle());
_uniformBuffer->aligner().getOffset(call.uniformIndex + 1),
sizeof(nanovg_draw_data),
_uniformBuffer->bufferHandle());
auto pathOffset = call.pathOffset;
@@ -759,8 +769,10 @@ void NanoVGRenderer::drawStroke(const DrawCall& call) {
}
// Draw anti-aliased pixels.
gr_bind_uniform_buffer(uniform_block_type::NanoVGData, _uniformBuffer.getAlignerElementOffset(call.uniformIndex),
sizeof(nanovg_draw_data), _uniformBuffer.bufferHandle());
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
_uniformBuffer->aligner().getOffset(call.uniformIndex),
sizeof(nanovg_draw_data),
_uniformBuffer->bufferHandle());
mat = _strokeAntiaiasMaterial;
materialSetTexture(mat, call.image);
for (size_t i = 0; i < call.pathCount; ++i) {
+1 -1
View File
@@ -71,7 +71,7 @@ class NanoVGRenderer {
int _vertexBuffer = -1;
vertex_layout _vertexLayout;
util::UniformBuffer _uniformBuffer;
util::UniformBuffer* _uniformBuffer = nullptr;
nanovg_material _trianglesMaterial;
nanovg_material _triangleFillMaterial;
+10 -13
View File
@@ -431,8 +431,10 @@ typedef signed int stbtt_int32;
typedef char stbtt__check_size32[sizeof(stbtt_int32) == 4 ? 1 : -1];
typedef char stbtt__check_size16[sizeof(stbtt_int16) == 2 ? 1 : -1];
// Function from NanoVGRenderer.cpp to provide log printing capabilities here.
extern void nvgOldCPrintf(const char *string, ...);
#ifndef NDEBUG
// Function from NanoVGRenderer.cpp to provide log printing capabilities here.
extern void nvgOldCPrintf(const char *string, ...);
#endif
// e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
#ifndef STBTT_ifloor
#include <math.h>
@@ -1503,9 +1505,11 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
stbtt_uint16 offset, start;
stbtt_uint16 item = (stbtt_uint16)((search - endCount) >> 1);
if (unicode_codepoint > ttUSHORT(data + endCount + 2 * item)) {
nvgOldCPrintf("WARNING: A font character is probably missing. Unicode decimal index is %d.\n", unicode_codepoint);
}
#ifndef NDEBUG
if (unicode_codepoint > ttUSHORT(data + endCount + 2 * item)) {
nvgOldCPrintf("WARNING: A font character is probably missing. Unicode decimal index is %d.\n", unicode_codepoint);
}
#endif
STBTT_assert((unicode_codepoint <= ttUSHORT(data + endCount + 2 * item)) &&
" \
Looks like the font file you're using misses a character. Search the log for 'WARNING: A font character is probably missing.' \
@@ -2126,13 +2130,6 @@ static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, st
#ifdef __GNUC__
#if __has_include(<features.h>)
#include <features.h>
#ifndef __GNUC_PREREQ
#if defined __GNUC__ && defined __GNUC_MINOR__
#define __GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#else
#define __GNUC_PREREQ(maj, min) 0
#endif
#endif
#if __GNUC_PREREQ(8, 0)
__attribute__((fallthrough));
#endif
@@ -4939,4 +4936,4 @@ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/
*/
+1 -1
View File
@@ -41,7 +41,7 @@ void convert_model_material(model_uniform_data* data_out,
data_out->modelMatrix = scaled_matrix;
data_out->viewMatrix = gr_view_matrix;
vm_matrix4_x_matrix4(&data_out->modelViewMatrix, &gr_view_matrix, &scaled_matrix);
vm_matrix4_x_matrix4(&data_out->modelViewMatrix, &data_out->viewMatrix, &data_out->modelMatrix);
data_out->projMatrix = gr_projection_matrix;
data_out->textureMatrix = gr_texture_matrix;
+39 -30
View File
@@ -3,8 +3,7 @@
#include "UniformAligner.h"
namespace graphics {
namespace util {
namespace {
size_t alignSize(size_t size, size_t align) {
if (align == 0) {
@@ -19,43 +18,51 @@ size_t alignSize(size_t size, size_t align) {
return size + align - remainder;
}
UniformAligner::UniformAligner() = default;
UniformAligner::UniformAligner(uint8_t* buffer, size_t buffer_size, size_t dataSize, size_t headerSize,
size_t element_alignment)
: _requiredAlignment(element_alignment), _buffer(buffer), _buffer_size(buffer_size), _dataSize(dataSize),
_headerSize(headerSize)
{
_buffer_offset = alignSize(_headerSize, _requiredAlignment); // Set the initial offset to the first data element
}
void* UniformAligner::addElement()
{
Assertion(_buffer_offset + _dataSize <= _buffer_size,
"Not enough space in the buffer for adding another element! "
"Check the number of elements the buffer was allocated with!");
auto el_offset = _buffer_offset;
namespace graphics {
namespace util {
_buffer_offset += alignSize(_dataSize, _requiredAlignment);
UniformAligner::UniformAligner(size_t dataSize, size_t headerSize) :
_numElements(0), _dataSize(dataSize), _headerSize(headerSize) {
// Make sure that the header space is already reserved
resize(0);
}
void UniformAligner::setAlignment(size_t align) {
_requiredAlignment = align;
// Clear the buffer since changing the alignment invalidates the stored data
clear();
}
void UniformAligner::resize(size_t num_elements) {
size_t final_size =
alignSize(_headerSize, _requiredAlignment) + alignSize(_dataSize, _requiredAlignment) * num_elements;
_buffer.resize(final_size);
_numElements = num_elements;
}
void* UniformAligner::addElement() {
_buffer.insert(_buffer.end(), alignSize(_dataSize, _requiredAlignment), 0);
++_numElements;
return reinterpret_cast<void*>(_buffer + el_offset);
return getElement(_numElements - 1);
}
void* UniformAligner::getElement(size_t index) {
size_t offset = alignSize(_headerSize, _requiredAlignment) + alignSize(_dataSize, _requiredAlignment) * index;
Assertion(offset < _buffer_size, "Invalid index specified!");
Assertion(offset < _buffer.size(), "Invalid index specified!");
return reinterpret_cast<void*>(_buffer + offset);
return reinterpret_cast<void*>(_buffer.data() + offset);
}
size_t UniformAligner::getOffset(size_t index) {
size_t offset = alignSize(_headerSize, _requiredAlignment) + alignSize(_dataSize, _requiredAlignment) * index;
Assertion(offset < _buffer_size, "Invalid index specified!");
Assertion(offset < _buffer.size(), "Invalid index specified!");
return offset;
}
void* UniformAligner::nextElement(void* currentEl) {
auto current = reinterpret_cast<uint8_t*>(currentEl);
uint8_t* current = reinterpret_cast<uint8_t*>(currentEl);
current += alignSize(_dataSize, _requiredAlignment);
@@ -64,15 +71,17 @@ void* UniformAligner::nextElement(void* currentEl) {
size_t UniformAligner::getNumElements() {
return _numElements;
}
size_t UniformAligner::getSize() { return _buffer_size; }
void* UniformAligner::getData() { return _buffer; }
size_t UniformAligner::getCurrentOffset() { return getOffset(_numElements - 1); }
size_t UniformAligner::getBufferSize(size_t num_elements, size_t alignment, size_t dataSize, size_t headerSize)
{
auto alignedHeaderSize = alignSize(headerSize, alignment);
auto alignedElementSize = alignSize(dataSize, alignment);
return alignedHeaderSize + num_elements * alignedElementSize;
size_t UniformAligner::getSize() {
return _buffer.size();
}
void* UniformAligner::getData() {
return _buffer.data();
}
void UniformAligner::clear() {
resize(0);
}
size_t UniformAligner::getCurrentOffset() {
return getOffset(getNumElements() - 1);
}
}
}
+13 -37
View File
@@ -9,8 +9,6 @@
namespace graphics {
namespace util {
size_t alignSize(size_t size, size_t align);
/**
* @brief Aligns data so that each element starts at a specific offset. Useful for storing uniform buffer data
*/
@@ -20,29 +18,26 @@ class UniformAligner {
size_t _requiredAlignment = 1;
uint8_t* _buffer = nullptr;
size_t _buffer_size = 0;
size_t _buffer_offset = 0;
size_t _numElements = 0;
std::vector<uint8_t> _buffer;
size_t _numElements;
size_t _dataSize = 0;
size_t _headerSize = 0;
public:
UniformAligner(size_t dataSize, size_t headerSize = 0);
public:
UniformAligner();
UniformAligner(uint8_t* buffer, size_t buffer_size, size_t dataSize, size_t headerSize, size_t element_alignment);
void setAlignment(size_t align);
void resize(size_t num_elements);
void clear();
void* addElement();
template <typename T>
T* addTypedElement()
{
template<typename T>
T* addTypedElement() {
Assertion(sizeof(T) == _dataSize,
"Sizes of template parameter and runtime size do not match! This probably uses the wrong type.");
#if HAVE_STD_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_copyable<T>::value, "Element type must be trivially copyable!");
#endif
"Sizes of template parameter and runtime size do not match! This probably uses the wrong type.");
return reinterpret_cast<T*>(addElement());
}
@@ -50,11 +45,8 @@ class UniformAligner {
template<typename THeader>
THeader* getHeader() {
Assertion(sizeof(THeader) == _headerSize, "Header size does not match requested header type!");
#if HAVE_STD_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_copyable<THeader>::value, "Header type must be trivially copyable!");
#endif
return reinterpret_cast<THeader*>(_buffer);
return reinterpret_cast<THeader*>(_buffer.data());
}
void* getElement(size_t index);
@@ -63,9 +55,6 @@ class UniformAligner {
T* getTypedElement(size_t index) {
Assertion(sizeof(T) == _dataSize,
"Sizes of template parameter and runtime size do not match! This probably uses the wrong type.");
#if HAVE_STD_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_copyable<T>::value, "Element type must be trivially copyable!");
#endif
return reinterpret_cast<T*>(getElement(index));
}
@@ -82,9 +71,6 @@ class UniformAligner {
T* nextTypedElement(T* currentEl) {
Assertion(sizeof(T) == _dataSize,
"Sizes of template parameter and runtime size do not match! This probably uses the wrong type.");
#if HAVE_STD_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_copyable<T>::value, "Element type must be trivially copyable!");
#endif
return reinterpret_cast<T*>(nextElement(reinterpret_cast<void*>(currentEl)));
}
@@ -100,16 +86,6 @@ class UniformAligner {
size_t getSize();
void* getData();
/**
* @brief Determine the size a buffer must have for the specified parameters
* @param num_elements The number of elements to be stored in the buffer
* @param alignment The required alignment for the start of the individual elements
* @param dataSize The size of one data element.
* @param headerSize The size of the header data
* @return The size in bytes required for storing all the data
*/
static size_t getBufferSize(size_t num_elements, size_t alignment, size_t dataSize, size_t headerSize = 0);
};
}
+64 -16
View File
@@ -1,24 +1,72 @@
#include "UniformBuffer.h"
#include "UniformBufferManager.h"
namespace graphics {
namespace util {
UniformBuffer::UniformBuffer() = default;
UniformBuffer::UniformBuffer(UniformBufferManager* parent, size_t parent_offset, void* data_buffer, size_t buffer_size,
size_t element_size, size_t header_size, size_t element_alignment)
: _parent(parent), _parent_offset(parent_offset),
_aligner(reinterpret_cast<uint8_t*>(data_buffer), buffer_size, element_size, header_size, element_alignment)
{
// Cache the buffer handle here since the active handle may change between now and when bind buffer range is called
// if the buffer needs to be resized
_buffer_handle = _parent->getActiveBufferHandle();
UniformBuffer::UniformBuffer(size_t element_size, size_t header_size) : _aligner(element_size, header_size) {
int offsetAlignment;
bool success = gr_get_property(gr_property::UNIFORM_BUFFER_OFFSET_ALIGNMENT, &offsetAlignment);
Assertion(success, "Uniform buffer usage requires a backend which allows to query the offset alignment!");
_aligner.setAlignment(static_cast<size_t>(offsetAlignment));
// This uses Dynamic since that matches our usage pattern the closest (update once and then use multiple times)
_buffer_obj = gr_create_buffer(BufferType::Uniform, BufferUsageHint::Dynamic);
Assertion(_buffer_obj >= 0, "Creation of buffer object failed!");
}
UniformBuffer::~UniformBuffer() = default;
void UniformBuffer::submitData() { _parent->submitData(_aligner.getData(), _aligner.getSize(), _parent_offset); }
int UniformBuffer::bufferHandle() { return _buffer_handle; }
size_t UniformBuffer::getBufferOffset(size_t localOffset) { return _parent_offset + localOffset; }
size_t UniformBuffer::getAlignerElementOffset(size_t index) { return getBufferOffset(_aligner.getOffset(index)); }
size_t UniformBuffer::getCurrentAlignerOffset() { return getBufferOffset(_aligner.getCurrentOffset()); }
UniformBuffer::~UniformBuffer() {
gr_delete_buffer(_buffer_obj);
if (_sync_obj != nullptr) {
gr_sync_delete(_sync_obj);
}
}
void UniformBuffer::submitData() {
if (_aligner.getSize() == 0) {
// No data to submit, return now to avoid causing graphics errors
return;
}
gr_update_buffer_data(_buffer_obj, _aligner.getSize(), _aligner.getData());
}
void UniformBuffer::finished() {
Assertion(_sync_obj == nullptr, "Can't finish using uniform buffer while it's still in use!");
// We use fences to determine if the GPU is still using this buffer. That allows us to use multiple buffers and
// avoid implicit synchronization which might be performed by the driver otherwise.
_sync_obj = gr_sync_fence();
// Uniform data is single-use only so we can discard the old data of the aligner
_aligner.clear();
}
bool UniformBuffer::isInUse() {
if (_sync_obj == nullptr) {
// Probably was signaled before, just assume that this means that the buffer is not in use anymore
return false;
}
if (gr_sync_wait(_sync_obj, 0)) {
// Fence was signaled => buffer is not in use anymore
// Delete the sync object since we don't need it anymore
gr_sync_delete(_sync_obj);
_sync_obj = nullptr;
return false;
}
// Fence still exists and has not been signaled yet. The buffer is still in use
return true;
}
UniformBuffer::UniformBuffer(UniformBuffer&& other) SCP_NOEXCEPT : _aligner(0, 0) {
*this = std::move(other);
}
UniformBuffer& UniformBuffer::operator=(UniformBuffer&& other) SCP_NOEXCEPT {
std::swap(_buffer_obj, other._buffer_obj);
std::swap(_aligner, other._aligner);
std::swap(_sync_obj, other._sync_obj);
return *this;
}
}
}
+20 -44
View File
@@ -7,79 +7,55 @@
namespace graphics {
namespace util {
class UniformBufferManager;
/**
* @brief Manages a uniform buffer memory range
* @brief Manages a single uniform buffer
*
* This class will be used by the uniform buffer manager for allowing user code direct access to uniform buffer memory.
* This also contains a UniformAligner which can be used for making sure that the data is aligned properly for GPU
* access.
* This is a wrapper around a buffer handle from the graphics system which also provides access to a uniform data
* aligner. It also manages the fence object which detects if this buffer is still in use or can be reused by other
* rendering operations.
*/
class UniformBuffer {
UniformBufferManager* _parent = nullptr;
size_t _parent_offset = 0;
int _buffer_handle = -1;
int _buffer_obj = -1;
UniformAligner _aligner;
public:
UniformBuffer();
UniformBuffer(UniformBufferManager* parent, size_t parent_offset, void* data_buffer, size_t buffer_size,
size_t element_size, size_t header_size, size_t element_alignment);
gr_sync _sync_obj = nullptr;
public:
UniformBuffer(size_t element_size, size_t header_size = 0);
~UniformBuffer();
UniformBuffer(const UniformBuffer&) = delete;
UniformBuffer& operator=(const UniformBuffer&) = delete;
UniformBuffer(UniformBuffer&&) = default;
UniformBuffer& operator=(UniformBuffer&&) = default;
UniformBuffer(UniformBuffer&& other) SCP_NOEXCEPT;
UniformBuffer& operator=(UniformBuffer&& other) SCP_NOEXCEPT;
inline UniformAligner& aligner() {
return _aligner;
}
/**
* @brief Gets the buffer handle for use with gr_bind_uniform_buffer.
* @return The buffer handle
*/
int bufferHandle();
inline int bufferHandle() {
return _buffer_obj;
}
/**
* @brief Submits the data from the uniform aligner to the underlying buffer object.
*
* This should be called when you are done building the uniform data.
*/
void submitData();
/**
* @brief Given the offset into the memory buffer, returns the total offset in the buffer object
* @brief Signal that the code is done using this uniform buffer
*
* This should be used for retrieving the correct offset for gr_bind_uniform_buffer.
*
* @param localOffset The offset into the local memory buffer (e.g. the return value of
* UniformAligner::getCurrentOffset)
* @return The absolute offset in the uniform buffer object.
* This is used for synchronizing access to this buffer. After this call is finished and until the data has been
* consumed by the GPU, this buffer is considered to the "in use".
*/
size_t getBufferOffset(size_t localOffset);
void finished();
/**
* @brief Gets the absolute offset to the specified element in the aligner
* This should be used for retrieving the correct offset for gr_bind_uniform_buffer.
*
* @param index The element index to be retrieved
* @return The absolute offset in the uniform buffer object.
* @brief Determines if the buffer is still in use by the GPU
* @return @c true if the GPU may still be using this buffer, @c false if not
*/
size_t getAlignerElementOffset(size_t index);
/**
* @brief Gets the absolute offset of the current element in the aligner
* This should be used for retrieving the correct offset for gr_bind_uniform_buffer.
*
* @return The absolute offset in the uniform buffer object.
*/
size_t getCurrentAlignerOffset();
bool isInUse();
};
}
+35 -158
View File
@@ -3,12 +3,9 @@
#include "UniformBufferManager.h"
#include "uniform_structs.h"
#include "tracing/tracing.h"
namespace {
size_t getElementSize(uniform_block_type type)
{
size_t getElementSize(uniform_block_type type) {
switch (type) {
case uniform_block_type::Lights:
return sizeof(graphics::deferred_light_data);
@@ -18,8 +15,6 @@ size_t getElementSize(uniform_block_type type)
return sizeof(graphics::nanovg_draw_data);
case uniform_block_type::DecalInfo:
return sizeof(graphics::decal_info);
case uniform_block_type::Matrices:
return sizeof(graphics::matrix_uniforms);
case uniform_block_type::NUM_BLOCK_TYPES:
default:
UNREACHABLE("Invalid block type encountered!");
@@ -27,8 +22,7 @@ size_t getElementSize(uniform_block_type type)
}
}
size_t getHeaderSize(uniform_block_type type)
{
size_t getHeaderSize(uniform_block_type type) {
switch (type) {
case uniform_block_type::Lights:
return sizeof(graphics::deferred_global_data);
@@ -36,8 +30,6 @@ size_t getHeaderSize(uniform_block_type type)
return sizeof(graphics::decal_globals);
case uniform_block_type::ModelData:
case uniform_block_type::NanoVGData:
case uniform_block_type::Matrices:
case uniform_block_type::GenericData:
return 0;
case uniform_block_type::NUM_BLOCK_TYPES:
default:
@@ -46,165 +38,50 @@ size_t getHeaderSize(uniform_block_type type)
}
}
} // namespace
}
namespace graphics {
namespace util {
UniformBufferManager::UniformBufferManager()
{
bool success = gr_get_property(gr_property::UNIFORM_BUFFER_OFFSET_ALIGNMENT, &_offset_alignment);
Assertion(success, "Uniform buffer usage requires a backend which allows to query the offset alignment!");
_use_persistent_mapping = gr_is_capable(CAPABILITY_PERSISTENT_BUFFER_MAPPING);
_segment_fences.fill(nullptr);
changeSegmentSize(4096);
UniformBufferManager::UniformBufferManager(uniform_block_type uniform_type) : _type(uniform_type) {
}
UniformBufferManager::~UniformBufferManager()
{
if (_active_uniform_buffer >= 0) {
gr_delete_buffer(_active_uniform_buffer);
_active_uniform_buffer = -1;
UniformBuffer* UniformBufferManager::getBuffer() {
if (!_retiredBuffers.empty()) {
// Reuse one of the free buffers
auto buffer = _retiredBuffers.back();
// Sanity check
Assertion(!buffer->isInUse(), "Retired buffer is in use!");
_retiredBuffers.pop_back();
_usedBuffers.push_back(buffer);
return buffer;
}
for (auto& fence : _segment_fences) {
if (fence != nullptr) {
gr_sync_delete(fence);
fence = nullptr;
// No free buffers available, create a new one
std::unique_ptr<UniformBuffer> buffer(new UniformBuffer(getElementSize(_type), getHeaderSize(_type)));
auto ptr = buffer.get();
_buffers.push_back(std::move(buffer));
_usedBuffers.push_back(ptr);
return ptr;
}
void UniformBufferManager::retireBuffers() {
GR_DEBUG_SCOPE("Retiring buffers of buffer manager");
for (auto& buffer : _usedBuffers) {
if (!buffer->isInUse()) {
// This buffer will be retired soon so add it to the list before removing it from the used list
_retiredBuffers.push_back(buffer);
}
}
for (auto& buffer : _retired_buffers) {
gr_sync_delete(std::get<0>(buffer));
gr_delete_buffer(std::get<1>(buffer));
// The shadow buffer pointer will be deleted automatically
}
_retired_buffers.clear();
// Remove the buffers from the list
_usedBuffers.erase(std::remove_if(_usedBuffers.begin(), _usedBuffers.end(), [](UniformBuffer* buffer) {
return !buffer->isInUse();
}), _usedBuffers.end());
}
void UniformBufferManager::onFrameEnd()
{
GR_DEBUG_SCOPE("Performing uniform frame end operations");
if (_segment_offset > _segment_size) {
// We needed more data than what is available in the segment
changeSegmentSize(_segment_offset);
} else {
// Set up the fence for the currently active segment
_segment_fences[_active_segment] = gr_sync_fence();
// Move the current segment to the next one
_active_segment = (_active_segment + 1) % NUM_SEGMENTS;
_segment_offset = 0;
// Now we need to wait until the segment is available again. In most cases this should succeed immediately.
if (_segment_fences[_active_segment] != nullptr) {
int i = 0;
while (i < 10 && !gr_sync_wait(_segment_fences[_active_segment], 500000000)) {
// This isn't good!
mprintf(("Missed uniform fence deadline!!\n"));
++i;
}
gr_sync_delete(_segment_fences[_active_segment]);
_segment_fences[_active_segment] = nullptr;
if (i == 10) {
// I don't know how to handle this properly but this probably means that something went wrong with the
// GPU
Error(LOCATION, "Failed to wait until uniform range is available! Get a coder.");
}
}
}
while (!_retired_buffers.empty()) {
if (gr_sync_wait(std::get<0>(_retired_buffers.front()), 0)) {
// Fence was signaled => buffer is not in use anymore
// Delete the sync object since we don't need it anymore
gr_sync_delete(std::get<0>(_retired_buffers.front()));
gr_delete_buffer(std::get<1>(_retired_buffers.front()));
// This will automatically clean up the shadow buffer pointer
_retired_buffers.erase(_retired_buffers.begin());
} else {
// The first fence element was not signaled yet so all the other fences also haven't been signaled yet
break;
}
}
}
UniformBuffer UniformBufferManager::getUniformBuffer(uniform_block_type type, size_t num_elements,
size_t element_size_override)
{
if (element_size_override == 0) {
element_size_override = getElementSize(type);
}
auto size = UniformAligner::getBufferSize(num_elements, (size_t)_offset_alignment, element_size_override,
getHeaderSize(type));
auto end_offset = _segment_offset + size;
auto absolute_end = _segment_size * _active_segment + end_offset;
if (absolute_end >= _active_buffer_size) {
// This new element uses too much memory to fit into the active buffer so we need to allocate a new one right
// now. It may happen that we use more than the segment size but that is not an issue since the frame-end code
// will reallocate the buffer if that happens.
// We don't really know how much we are going to need here so 2 times the current amount seems like a good idea
changeSegmentSize(_segment_size * 2);
// Try the stuff above again.
return getUniformBuffer(type, num_elements, element_size_override);
}
auto data_offset = _segment_size * _active_segment + _segment_offset;
_segment_offset = end_offset;
// Even in the persistent mapping case we still use a temporary buffer since writing to GPU memory is not very fast
// when doing a lot of small writes (e.g. when building model uniform data). Instead we use a shadow buffer and
// do a single memcpy when we are done
return UniformBuffer(this, data_offset, _shadow_uniform_buffer.get() + data_offset, size, element_size_override,
getHeaderSize(type), static_cast<size_t>(_offset_alignment));
}
void UniformBufferManager::changeSegmentSize(size_t new_size)
{
if (_active_uniform_buffer >= 0) {
// Retire the old buffer first
_retired_buffers.emplace_back(gr_sync_fence(), _active_uniform_buffer, std::move(_shadow_uniform_buffer));
}
// The current fences are meaningless now so we need to delete them
for (auto& fence : _segment_fences) {
if (fence != nullptr) {
gr_sync_delete(fence);
fence = nullptr;
}
}
_active_buffer_size = new_size * NUM_SEGMENTS;
_shadow_uniform_buffer.reset(new uint8_t[_active_buffer_size]);
_active_uniform_buffer = gr_create_buffer(
BufferType::Uniform, _use_persistent_mapping ? BufferUsageHint::PersistentMapping : BufferUsageHint::Dynamic);
gr_update_buffer_data(_active_uniform_buffer, _active_buffer_size, nullptr);
if (_use_persistent_mapping) {
_buffer_ptr = gr_map_buffer(_active_uniform_buffer);
}
_active_segment = 0;
_segment_size = new_size;
_segment_offset = 0;
}
void UniformBufferManager::submitData(void* buffer, size_t data_size, size_t offset)
{
if (_use_persistent_mapping) {
auto buffer_dest = reinterpret_cast<void*>(reinterpret_cast<uint8_t*>(_buffer_ptr) + offset);
memcpy(buffer_dest, buffer, data_size);
// The data is already in the buffer but we still need to flush the memory range
gr_flush_mapped_buffer(_active_uniform_buffer, offset, data_size);
} else {
gr_update_buffer_data_offset(_active_uniform_buffer, offset, data_size, buffer);
}
}
int UniformBufferManager::getActiveBufferHandle() { return _active_uniform_buffer; }
size_t UniformBufferManager::getBufferSize() { return _active_buffer_size; }
size_t UniformBufferManager::getCurrentlyUsedSize() { return _segment_offset; }
} // namespace util
} // namespace graphics
Loaded 100 of 305 files, more files were not shown because too many files have changed in this diff. Show more