mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
Compare commits
198
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c084a432d4 | ||
|
|
5135cded94 | ||
|
|
519d1f59f8 | ||
|
|
b9be2ad85e | ||
|
|
7121a3f748 | ||
|
|
7439cf2cc3 | ||
|
|
570dc5f3de | ||
|
|
620fdbde08 | ||
|
|
fdb7e41ed4 | ||
|
|
f286363748 | ||
|
|
1520a21062 | ||
|
|
cdc831b163 | ||
|
|
18718aee74 | ||
|
|
c8a5ebe45c | ||
|
|
29dd3e1057 | ||
|
|
bca6f95621 | ||
|
|
e2010aeda1 | ||
|
|
22f3463397 | ||
|
|
283e1555ba | ||
|
|
fe8ce74037 | ||
|
|
c43fa8c9a8 | ||
|
|
5c7fce41f1 | ||
|
|
0985091f6a | ||
|
|
2da7c4e761 | ||
|
|
6f109508d0 | ||
|
|
e84919fa88 | ||
|
|
684354c8bd | ||
|
|
45c3ee0b3c | ||
|
|
89eea8e5d3 | ||
|
|
32730fc362 | ||
|
|
1c8f07b012 | ||
|
|
892f0a831a | ||
|
|
6b573bdbf6 | ||
|
|
0e9ad8623b | ||
|
|
f5edccd98f | ||
|
|
007e7118f2 | ||
|
|
ae41e355ac | ||
|
|
43d51792f2 | ||
|
|
f739a3e5c1 | ||
|
|
33c3f556a4 | ||
|
|
490464b656 | ||
|
|
d526300483 | ||
|
|
3f3b284dcf | ||
|
|
e0992ed88e | ||
|
|
3997237a11 | ||
|
|
1c12349990 | ||
|
|
5f10b68118 | ||
|
|
91edcc4b8c | ||
|
|
4139cd890c | ||
|
|
8fa96aeaf3 | ||
|
|
282ca0b0dd | ||
|
|
d3b1871837 | ||
|
|
6f7ca147dd | ||
|
|
ee391940d2 | ||
|
|
23dbfa5655 | ||
|
|
8f1f308591 | ||
|
|
cc456855e5 | ||
|
|
0853c5bf7a | ||
|
|
96de072bff | ||
|
|
2f0f2d7669 | ||
|
|
1c5a361d50 | ||
|
|
44072c026c | ||
|
|
8cb9d311d7 | ||
|
|
bdec29f247 | ||
|
|
4e1b366f9f | ||
|
|
de2d1ec602 | ||
|
|
50e365a66c | ||
|
|
a954a04cf8 | ||
|
|
030bbeb622 | ||
|
|
6b7df053fa | ||
|
|
b8c135d162 | ||
|
|
b067e1ac66 | ||
|
|
eabead6d41 | ||
|
|
ec50baa9d1 | ||
|
|
66f7bc4f50 | ||
|
|
44b7d5a4bd | ||
|
|
caebad7077 | ||
|
|
0caa65a74f | ||
|
|
ff05816e11 | ||
|
|
da326f31f6 | ||
|
|
376a01e82b | ||
|
|
dc2ce094fc | ||
|
|
74a0346e0d | ||
|
|
3b0d20aaf2 | ||
|
|
a0951f4e28 | ||
|
|
3da2b99144 | ||
|
|
c9df8a13f1 | ||
|
|
247d5c453c | ||
|
|
5b8e89f37d | ||
|
|
f6083b680a | ||
|
|
fde7fdd854 | ||
|
|
64531798e7 | ||
|
|
ecd1cfe59c | ||
|
|
638bcacb71 | ||
|
|
4fc82ba334 | ||
|
|
7ebd00e6f5 | ||
|
|
fc41984a75 | ||
|
|
45b5399f08 | ||
|
|
fe15752f5e | ||
|
|
c0a7be50b4 | ||
|
|
bb8fcd428e | ||
|
|
641aa329a5 | ||
|
|
d86332a9d9 | ||
|
|
d8e88c1644 | ||
|
|
1926d3c341 | ||
|
|
c502d9bdf7 | ||
|
|
20835adef6 | ||
|
|
af5e834250 | ||
|
|
e9051933b9 | ||
|
|
bb48ea9c61 | ||
|
|
939be80c30 | ||
|
|
732ada474b | ||
|
|
23b5320ec4 | ||
|
|
e3f67146b1 | ||
|
|
cacee6e5b8 | ||
|
|
90c6c91e4f | ||
|
|
0748ac191c | ||
|
|
98cb4b6400 | ||
|
|
48d1797009 | ||
|
|
50ea017e59 | ||
|
|
c42cd25b89 | ||
|
|
75099171ef | ||
|
|
809d11e1a8 | ||
|
|
dadc65178d | ||
|
|
52b17c3f8a | ||
|
|
28722d7402 | ||
|
|
bf4243c0b0 | ||
|
|
9dd6d9c874 | ||
|
|
53a3b2b1c7 | ||
|
|
2dc2295a59 | ||
|
|
582c144cf7 | ||
|
|
e32cadd06a | ||
|
|
ed6ac7060e | ||
|
|
7029e4a10f | ||
|
|
4d2cf1d2e0 | ||
|
|
d31b2a971b | ||
|
|
74cf0b839d | ||
|
|
7f286b726d | ||
|
|
b0da0ea404 | ||
|
|
ca301fdb04 | ||
|
|
04244ec1ee | ||
|
|
84b15afa8a | ||
|
|
a7063152b7 | ||
|
|
5f938169af | ||
|
|
8763b06c77 | ||
|
|
90a97021f5 | ||
|
|
3c6015f6b0 | ||
|
|
ca4fcc84ea | ||
|
|
94e74cb15f | ||
|
|
3daa819042 | ||
|
|
4bb31f4e1b | ||
|
|
87c5544b7b | ||
|
|
4914c4a452 | ||
|
|
0b33a44004 | ||
|
|
1f98551b12 | ||
|
|
463caecf03 | ||
|
|
2f3f061e75 | ||
|
|
0c0c4ddaef | ||
|
|
3fb2f97b43 | ||
|
|
66daf6ba24 | ||
|
|
a13b503b83 | ||
|
|
43a29b4dec | ||
|
|
1c2d8a3b47 | ||
|
|
aa0a1ae3ed | ||
|
|
1d12157a07 | ||
|
|
ae026f83ca | ||
|
|
facf17a222 | ||
|
|
bf99541c58 | ||
|
|
34391ebe21 | ||
|
|
93f71ec202 | ||
|
|
e504f6b59e | ||
|
|
133821952f | ||
|
|
d7602ec9d1 | ||
|
|
fe5dbeccaa | ||
|
|
d7e40d2bcc | ||
|
|
0251fd347f | ||
|
|
1cce2d70a3 | ||
|
|
68f5b7d524 | ||
|
|
036d5ed780 | ||
|
|
c109562c40 | ||
|
|
0334b3c287 | ||
|
|
9039081fa7 | ||
|
|
73a5ac7665 | ||
|
|
6c2e419825 | ||
|
|
c2c2042a38 | ||
|
|
da08ba5932 | ||
|
|
bc14149e84 | ||
|
|
6ceb2a276c | ||
|
|
d8537843ab | ||
|
|
539cad66e7 | ||
|
|
b042b27310 | ||
|
|
8ee447d8c2 | ||
|
|
8a36fc138c | ||
|
|
0b2695e9e4 | ||
|
|
362645ce27 | ||
|
|
10ab4a00f5 | ||
|
|
5ce6c251ff | ||
|
|
a3651026b1 |
No files matched your search
+16
-13
@@ -1,25 +1,27 @@
|
||||
---
|
||||
Language: Cpp
|
||||
Standard: Cpp11
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
@@ -50,15 +52,17 @@ ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^(<.*\.(h|hh|hpp)>)$' # Includes of external libraries
|
||||
Priority: 4
|
||||
- Regex: '^(<.*>)$' # standard library includes (won't match deprecated C headers)
|
||||
Priority: 5
|
||||
- Regex: '^"[^/]*\.(h)"$' # Local includes
|
||||
- Regex: '^(<.*>)$' # standard library includes (won't match deprecated C headers)
|
||||
Priority: 6
|
||||
- Regex: '^"globalincs\/.*\.h"$' # globalincs always come first
|
||||
Priority: 1
|
||||
- Regex: '^".*\.(h)"$' # standard engine includes
|
||||
- Regex: '^"[^/]*\.(h)"$' # Local includes
|
||||
Priority: 2
|
||||
- Regex: '.*' # Catch all in case something is unhandled above
|
||||
- Regex: '^".*\.(h)"$' # standard engine includes
|
||||
Priority: 3
|
||||
- Regex: '.*' # Catch all in case something is unhandled above
|
||||
Priority: 4
|
||||
IncludeIsMainRegex: '$'
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 4
|
||||
@@ -93,8 +97,7 @@ SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: ForIndentation
|
||||
UseTab: ForContinuationAndIndentation
|
||||
...
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/build
|
||||
/.git
|
||||
@@ -5,3 +5,7 @@ indent_style = tab
|
||||
|
||||
[*.sdr]
|
||||
indent_style = tab
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
@@ -76,15 +76,8 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [MSVC, MinGW]
|
||||
compiler: [MSVC]
|
||||
arch: [Win32, x64]
|
||||
exclude:
|
||||
- configuration: Debug
|
||||
compiler: MinGW
|
||||
arch: x64
|
||||
- configuration: Release
|
||||
compiler: MinGW
|
||||
arch: x64
|
||||
name: Windows
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
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 }}
|
||||
@@ -257,3 +257,4 @@ 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
@@ -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 FS2DOWNLOADS_USER and FS2DOWNLOADS_PASSWORD
|
||||
- secure: "h6GbMX2jLsW1bS9fCM9fthOSJ1nfQQIRWi6EUH2p8u4NFLD5Bfi/C8JhQPKHUzyo3wvKkSHl+PsW7bgr1oXLusRwAur/dtv2N3imqvtbfIz305b00hZlsvbcYmQmUzQFSAdOGShK57JJ5aKQKccaUBP25KqB7Q+JaqBRdaMBS54="
|
||||
- secure: "fUDAPAUUaaYZy8I4zU3SJ0JcK7aw4eb6eTdaEr7LyNyTMSfPgwY6P1MrbSQC0lJNQIUQ5ffjdxE5g7D7OYpoJF9L14ni4UY8t2QASt7kmpgcYihmjeuYy8FQXgmFG8CTxiWBPKTybZJ7voQcvIvRaNG7b2wM9PMfc5lRIondB6c="
|
||||
# These declarations set DATACORDER_USER and DATACORDER_PASSWORD
|
||||
- secure: "dpBH/dDN3bmU/NFlh+2v9isNx9wX0ocoRy+W+kBXRH32sosUGp26REhMqgVRpBNP5oxPBU8ic5bEogxAYWCB+0xUygBbkxAwyMPgoA34s0OXdTCY/ofw14ni8qqV2Ffy7fQJbP/jkMURyiMHx3kBTxNv3YjxKJqLnOuOMlQLpT8="
|
||||
- secure: "tLMRBD1Ufp5iKNwlqPDVbbuczgusaXNoBJyAnPATpJq2YwlkW4j3PqP9rW5vd85+52xam2EOP20w9PoBR5J6FLdiXRu4Lf7yCEhSHFAgowVqQj8QcJpPlyXr90bM4emFGrGqpdxVwxyQ5AFhKwLuEZKsI14GYLN+UMEwpNCMing="
|
||||
deploy:
|
||||
- provider: releases
|
||||
api_key:
|
||||
|
||||
@@ -117,6 +117,10 @@ 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)
|
||||
@@ -125,6 +129,8 @@ 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)
|
||||
@@ -197,3 +203,5 @@ 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}")
|
||||
+3
-2
@@ -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-RC1] - 2019-08-29 ([Thread](https://www.hard-light.net/forums/index.php?topic=95868.0))
|
||||
## [19.0.0] - 2020-01-25 ([Thread](https://www.hard-light.net/forums/index.php?topic=96226.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,6 +21,7 @@ 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!
|
||||
|
||||
@@ -1993,4 +1994,4 @@ NOTE:
|
||||
|
||||
# generated by cvs2cl.pl
|
||||
# cvs2cl.pl -r -S --utc -f ChangeLog2
|
||||
```
|
||||
```
|
||||
+12
-14
@@ -40,25 +40,23 @@ deploy:
|
||||
NightlyBuild: true # deploy on nightly push only
|
||||
|
||||
- provider: FTP
|
||||
protocol: ftp
|
||||
host: swc.fs2downloads.com
|
||||
username:
|
||||
secure: EXg2ADoKzMduZF90ip2Q0g==
|
||||
protocol: sftp
|
||||
host: porphyrion.feralhosting.com
|
||||
username:
|
||||
secure: 36+bVD8eJgI0BVbi7TZ4zQ==
|
||||
password:
|
||||
secure: x0LL0uY9yBAQ7JTARhQ6AA==
|
||||
folder: swc.fs2downloads.com/builds/nightly/$(VersionName)
|
||||
beta: true
|
||||
secure: CrzmDVca8AGG08iWPA1gOD4Ge06+wJ3rcBagBGclwYQ=
|
||||
folder: www/datacorder.porphyrion.feralhosting.com/public_html/builds/nightly/$(VersionName)
|
||||
on:
|
||||
NightlyBuild: true # deploy on nightly push only
|
||||
|
||||
- provider: FTP
|
||||
protocol: ftp
|
||||
host: swc.fs2downloads.com
|
||||
username:
|
||||
secure: EXg2ADoKzMduZF90ip2Q0g==
|
||||
protocol: sftp
|
||||
host: porphyrion.feralhosting.com
|
||||
username:
|
||||
secure: 36+bVD8eJgI0BVbi7TZ4zQ==
|
||||
password:
|
||||
secure: x0LL0uY9yBAQ7JTARhQ6AA==
|
||||
folder: swc.fs2downloads.com/builds/test/$(VersionName)
|
||||
beta: true
|
||||
secure: CrzmDVca8AGG08iWPA1gOD4Ge06+wJ3rcBagBGclwYQ=
|
||||
folder: www/datacorder.porphyrion.feralhosting.com/public_html/builds/test/$(VersionName)
|
||||
on:
|
||||
TestBuild: true # deploy on test build push only
|
||||
@@ -77,13 +77,13 @@ cd /tmp/builds
|
||||
|
||||
for file in *; do
|
||||
if [ "$TEST_BUILD" = true ]; then
|
||||
# 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
|
||||
# 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
|
||||
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 fs2downloads
|
||||
curl -k "ftp://swc.fs2downloads.com/swc.fs2downloads.com/builds/nightly/$VERSION_NAME/" --user "$FS2DOWNLOADS_USER:$FS2DOWNLOADS_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
|
||||
fi
|
||||
done
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
HERE=$(dirname $(readlink -f "${0}"))
|
||||
export LD_LIBRARY_PATH="${HERE}"/lib:"$LD_LIBRARY_PATH"
|
||||
"${HERE}"/bin/$<TARGET_FILE_NAME:Freespace2> $@
|
||||
exec "${HERE}"/bin/$<TARGET_FILE_NAME:Freespace2> $@
|
||||
@@ -8,8 +8,7 @@
|
||||
#cmakedefine SCP_HAVE_MAX_ALIGN_T
|
||||
#cmakedefine SCP_HAVE_STD_MAX_ALIGN_T
|
||||
|
||||
#cmakedefine SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE
|
||||
#cmakedefine SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE_ARRAY
|
||||
#cmakedefine01 HAVE_STD_IS_TRIVIALLY_COPYABLE
|
||||
|
||||
#cmakedefine01 IS_64BIT
|
||||
|
||||
|
||||
+4
-4
@@ -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 3)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 8)
|
||||
set_if_not_defined(FSO_VERSION_BUILD 1)
|
||||
set_if_not_defined(FSO_VERSION_MAJOR 20)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 1)
|
||||
set_if_not_defined(FSO_VERSION_BUILD 0)
|
||||
|
||||
# A numeric revision e.g. the CI build number
|
||||
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}")
|
||||
+13
-1
@@ -28,7 +28,9 @@ TARGET_LINK_LIBRARIES(code PUBLIC ${JPEG_LIBS})
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC sdl2)
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ffmpeg)
|
||||
if (FSO_BUILD_WITH_FFMPEG)
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ffmpeg)
|
||||
endif()
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC utfcpp)
|
||||
|
||||
@@ -43,6 +45,8 @@ 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)
|
||||
@@ -79,6 +83,14 @@ 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)
|
||||
|
||||
|
||||
+18
-16
@@ -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'",
|
||||
mprintf(("Ship '%s' told to fly to target ship '%s'\n",
|
||||
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 < static_cast<int>(Ship_info.size()));
|
||||
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < 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 < static_cast<int>(Ship_info.size()));
|
||||
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < 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,33 +5506,35 @@ 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 == NULL ) {
|
||||
if ( aip->targeted_subsys == nullptr ) {
|
||||
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) )
|
||||
@@ -5634,7 +5636,7 @@ int ai_fire_primary_weapon(object *objp)
|
||||
ai_info *aip;
|
||||
object *enemy_objp;
|
||||
|
||||
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()));
|
||||
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < ship_info_size());
|
||||
|
||||
aip = &Ai_info[shipp->ai_index];
|
||||
|
||||
@@ -6060,7 +6062,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 < static_cast<int>(Ship_info.size()));
|
||||
Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < ship_info_size());
|
||||
|
||||
// Select secondary weapon.
|
||||
current_bank = swp->current_secondary_bank;
|
||||
@@ -10683,7 +10685,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.", 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.\n", goal_ship_class_name, aip->path_length, goal_dock_path_name));
|
||||
}
|
||||
|
||||
aip->submode = AIS_DOCK_1;
|
||||
|
||||
+1
-1
@@ -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", Ships[aip->shipnum].ship_name));
|
||||
mprintf(("Unable to assign wing goal to ship %s; the ship goals are already filled to capacity\n", Ships[aip->shipnum].ship_name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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_INDEX(wip);
|
||||
int turret_weapon_class = weapon_info_get_index(wip);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// moved here from check_ok_to_fire
|
||||
|
||||
@@ -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)", asip->name, pm->n_detail_levels));
|
||||
nprintf(("Warning", "For asteroid '%s', detail level mismatch (POF needs %d)\n", 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(("Asteroid.tbl as parsed:\n"));
|
||||
mprintf(("%s", iter->c_str()));
|
||||
mprintf(("%s\n", iter->c_str()));
|
||||
}
|
||||
#endif
|
||||
Error(LOCATION,
|
||||
|
||||
@@ -218,9 +218,9 @@ bool StartAutopilot()
|
||||
if (shipp->team != Player_ship->team)
|
||||
continue;
|
||||
|
||||
Assertion((shipp->ship_info_index >= 0) && (shipp->ship_info_index < static_cast<int>(Ship_info.size())),
|
||||
Assertion((shipp->ship_info_index >= 0) && (shipp->ship_info_index < 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, static_cast<int>(Ship_info.size()));
|
||||
shipp->ship_name, shipp->ship_info_index, ship_info_size());
|
||||
ship_info *sip = &Ship_info[shipp->ship_info_index];
|
||||
|
||||
if ( !(sip->flags[Ship::Info_Flags::Support]) )
|
||||
|
||||
+30
-15
@@ -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#-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" },
|
||||
{ "-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" },
|
||||
{ "-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#-height" },
|
||||
{ "-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" },
|
||||
{ "-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#-flightshaftsoff"},
|
||||
{ "-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"},
|
||||
{ "-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#-no_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#-enable_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", "", },
|
||||
{ "-set_cpu_affinity", "Sets processor affinity to config value", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
{ "-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", },
|
||||
{ "-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", "", },
|
||||
{ "-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", },
|
||||
#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,13 +242,14 @@ 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", },
|
||||
{ "-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", },
|
||||
{ "-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", },
|
||||
{ "-noninteractive", "Disables interactive dialogs", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noninteractive", },
|
||||
{ "-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", },
|
||||
{ "-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
|
||||
|
||||
@@ -478,6 +479,8 @@ 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;
|
||||
@@ -507,6 +510,8 @@ 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);
|
||||
@@ -1872,8 +1877,6 @@ bool SetCmdlineParams()
|
||||
Gr_aa_mode = AntiAliasMode::FXAA_Low;
|
||||
}
|
||||
}
|
||||
|
||||
Gr_aa_mode_last_frame = Gr_aa_mode;
|
||||
}
|
||||
|
||||
if (smaa_arg.found()) {
|
||||
@@ -1900,6 +1903,10 @@ 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;
|
||||
|
||||
@@ -2133,6 +2140,14 @@ 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;
|
||||
|
||||
@@ -147,5 +147,7 @@ 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
|
||||
@@ -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", key));
|
||||
//mprintf(("Key used %d\n", key));
|
||||
control_used(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#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...
|
||||
@@ -32,8 +33,29 @@ 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 };
|
||||
|
||||
|
||||
@@ -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!!!"));
|
||||
mprintf(("FFMPEG: Failed to allocate samples!!!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,13 +27,15 @@ using namespace cutscene;
|
||||
|
||||
const int MAX_AUDIO_BUFFERS = 15;
|
||||
|
||||
std::unique_ptr<Decoder> findDecoder(const SCP_string& name, const PlaybackProperties& properties) {
|
||||
std::unique_ptr<Decoder> findDecoder(__UNUSED const SCP_string& name, __UNUSED const PlaybackProperties& properties) {
|
||||
#ifdef WITH_FFMPEG
|
||||
{
|
||||
std::unique_ptr<Decoder> ffmpeg(new ::cutscene::ffmpeg::FFMPEGDecoder());
|
||||
if (ffmpeg->initialize(name, properties)) {
|
||||
return ffmpeg;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -468,10 +468,9 @@ 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;
|
||||
|
||||
@@ -3,9 +3,15 @@
|
||||
|
||||
in vec4 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2DArray baseMap;
|
||||
uniform float intensity;
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
vec4 color;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
in vec4 vertPosition;
|
||||
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;
|
||||
};
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
vec4 color;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
fragTexCoord = vec4(vertTexCoord.xyz, 0.0);
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
|
||||
in vec4 fragTexCoord;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D bloomed;
|
||||
uniform float bloom_intensity;
|
||||
uniform int levels;
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
float bloom_intensity;
|
||||
int levels;
|
||||
};
|
||||
|
||||
void main() {
|
||||
vec4 color_out = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
float factor = 0.0;
|
||||
@@ -14,4 +21,4 @@ void main() {
|
||||
color_out.rgb /= factor;
|
||||
color_out.rgb *= bloom_intensity;
|
||||
fragOut0 = color_out;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,16 @@
|
||||
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()
|
||||
@@ -20,15 +27,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,12 +6,23 @@ in vec4 fragColor;
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2DArray baseMap;
|
||||
uniform int baseMapIndex;
|
||||
uniform int alphaTexture;
|
||||
uniform int noTexturing;
|
||||
uniform int srgb;
|
||||
uniform float intensity;
|
||||
uniform float alphaThreshold;
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
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,8 +2,11 @@
|
||||
#include "lighting.sdr"
|
||||
|
||||
in vec4 vertPosition;
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projMatrix;
|
||||
|
||||
layout (std140) uniform matrixData {
|
||||
mat4 modelViewMatrix;
|
||||
mat4 projMatrix;
|
||||
};
|
||||
|
||||
layout (std140) uniform lightData {
|
||||
vec3 diffuseLightColor;
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
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,9 +5,18 @@ in float vertRadius;
|
||||
out vec4 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
out float fragOffset;
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projMatrix;
|
||||
uniform float use_offset;
|
||||
|
||||
layout (std140) uniform matrixData {
|
||||
mat4 modelViewMatrix;
|
||||
mat4 projMatrix;
|
||||
};
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
float window_width;
|
||||
float window_height;
|
||||
float use_offset;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projMatrix * modelViewMatrix * vertPosition;
|
||||
|
||||
+15
-9
@@ -1,21 +1,27 @@
|
||||
|
||||
#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);
|
||||
+8
-1
@@ -1,14 +1,21 @@
|
||||
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;
|
||||
uniform mat4 projMatrix;
|
||||
|
||||
layout (std140) uniform matrixData {
|
||||
mat4 modelViewMatrix;
|
||||
mat4 projMatrix;
|
||||
};
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec3 forward_vec = vec3(0.0, 0.0, 1.0);
|
||||
@@ -1,7 +1,9 @@
|
||||
|
||||
in vec4 vertPosition;
|
||||
in vec4 vertTexCoord;
|
||||
in vec4 vertColor;
|
||||
in float vertRadius;
|
||||
|
||||
#ifdef FLAG_EFFECT_GEOMETRY
|
||||
in vec3 vertUvec;
|
||||
out vec3 geoUvec;
|
||||
@@ -14,28 +16,25 @@ in float vertRadius;
|
||||
out vec4 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
#endif
|
||||
#ifdef FLAG_EFFECT_DISTORTION
|
||||
out float fragOffset;
|
||||
uniform float use_offset;
|
||||
#endif
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projMatrix;
|
||||
|
||||
layout (std140) uniform matrixData {
|
||||
mat4 modelViewMatrix;
|
||||
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_DISTORTION
|
||||
fragOffset = vertRadius * use_offset;
|
||||
#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
|
||||
}
|
||||
@@ -2,16 +2,20 @@
|
||||
#include "gamma.sdr"
|
||||
|
||||
in vec4 fragTexCoord;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D depth_tex;
|
||||
|
||||
uniform float fog_start;
|
||||
uniform float fog_scale;
|
||||
uniform vec3 fog_color;
|
||||
uniform float zNear;
|
||||
uniform float zFar;
|
||||
layout (std140) uniform genericData {
|
||||
vec3 fog_color;
|
||||
float fog_start;
|
||||
|
||||
float fog_scale;
|
||||
float zNear;
|
||||
float zFar;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
|
||||
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);
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
|
||||
in vec4 fragTexCoord;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D scene;
|
||||
uniform sampler2D cockpit;
|
||||
uniform vec2 sun_pos;
|
||||
uniform float density;
|
||||
uniform float weight;
|
||||
uniform float falloff;
|
||||
uniform float intensity;
|
||||
uniform float cp_intensity;
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
vec2 sun_pos;
|
||||
float density;
|
||||
float weight;
|
||||
float falloff;
|
||||
float intensity;
|
||||
float cp_intensity;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 step = vec2( fragTexCoord.st - sun_pos.xy );
|
||||
@@ -29,4 +36,4 @@ void main()
|
||||
}
|
||||
fragOut0 = sum * intensity;
|
||||
fragOut0.a = 1.0;
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,13 @@
|
||||
in vec4 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D baseMap;
|
||||
uniform int noTexturing;
|
||||
uniform int srgb;
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
int noTexturing;
|
||||
int srgb;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
@@ -3,21 +3,15 @@ in vec4 vertTexCoord;
|
||||
in vec4 vertColor;
|
||||
out vec4 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projMatrix;
|
||||
uniform vec4 color;
|
||||
|
||||
uniform mat4 modelMatrix;
|
||||
uniform bool clipEnabled;
|
||||
uniform vec4 clipEquation;
|
||||
layout (std140) uniform matrixData {
|
||||
mat4 modelViewMatrix;
|
||||
mat4 projMatrix;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
fragTexCoord = vertTexCoord;
|
||||
fragColor = vertColor * color;
|
||||
fragColor = vertColor;
|
||||
gl_Position = projMatrix * modelViewMatrix * vertPosition;
|
||||
|
||||
if (clipEnabled) {
|
||||
gl_ClipDistance[0] = dot(clipEquation, modelMatrix * vertPosition);
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,25 @@
|
||||
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
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
in vec4 vertPosition;
|
||||
in vec4 vertTexCoord;
|
||||
out vec4 fragTexCoord;
|
||||
out float blurSize;
|
||||
uniform float bsize;
|
||||
void main()
|
||||
{
|
||||
fragTexCoord = vertTexCoord;
|
||||
gl_Position = vertPosition;
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,15 @@ in vec4 fragColor;
|
||||
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform bool textured;
|
||||
uniform sampler2DArray baseMap;
|
||||
uniform int baseMapIndex;
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
mat4 modelViewMatrix;
|
||||
mat4 projMatrix;
|
||||
|
||||
bool textured;
|
||||
int baseMapIndex;
|
||||
};
|
||||
|
||||
void main() {
|
||||
if (textured) {
|
||||
|
||||
@@ -6,8 +6,13 @@ in vec2 vertTexCoord;
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projMatrix;
|
||||
layout (std140) uniform genericData {
|
||||
mat4 modelViewMatrix;
|
||||
mat4 projMatrix;
|
||||
|
||||
bool textured;
|
||||
int baseMapIndex;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
in vec4 vertPosition;
|
||||
in vec4 vertTexCoord;
|
||||
out vec4 fragTexCoord;
|
||||
void main()
|
||||
{
|
||||
fragTexCoord = vertTexCoord;
|
||||
gl_Position = vertPosition;
|
||||
}
|
||||
@@ -1,14 +1,27 @@
|
||||
|
||||
#include "gamma.sdr"
|
||||
|
||||
const float EMISSIVE_GAIN = 2.0;
|
||||
|
||||
in vec4 fragImpactUV;
|
||||
in float fragNormOffset;
|
||||
uniform vec4 color;
|
||||
uniform sampler2DArray shieldMap;
|
||||
uniform int shieldMapIndex;
|
||||
uniform int srgb;
|
||||
|
||||
out vec4 fragOut0;
|
||||
#define EMISSIVE_GAIN 2.0
|
||||
|
||||
uniform sampler2DArray shieldMap;
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
mat4 shieldModelViewMatrix;
|
||||
mat4 shieldProjMatrix;
|
||||
|
||||
vec3 hitNormal;
|
||||
int srgb;
|
||||
|
||||
vec4 color;
|
||||
|
||||
int shieldMapIndex;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
if(fragNormOffset < 0.0) discard;
|
||||
|
||||
@@ -1,12 +1,28 @@
|
||||
|
||||
in vec4 vertPosition;
|
||||
in vec3 vertNormal;
|
||||
|
||||
out vec4 fragImpactUV;
|
||||
out float fragNormOffset;
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projMatrix;
|
||||
uniform vec3 hitNormal;
|
||||
uniform mat4 shieldModelViewMatrix;
|
||||
uniform mat4 shieldProjMatrix;
|
||||
|
||||
|
||||
layout (std140) uniform matrixData {
|
||||
mat4 modelViewMatrix;
|
||||
mat4 projMatrix;
|
||||
};
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
mat4 shieldModelViewMatrix;
|
||||
mat4 shieldProjMatrix;
|
||||
|
||||
vec3 hitNormal;
|
||||
int srgb;
|
||||
|
||||
vec4 color;
|
||||
|
||||
int shieldMapIndex;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projMatrix * modelViewMatrix * vertPosition;
|
||||
@@ -15,4 +31,4 @@ void main()
|
||||
fragImpactUV = shieldProjMatrix * shieldModelViewMatrix * vertPosition;
|
||||
fragImpactUV += 1.0f;
|
||||
fragImpactUV *= 0.5f;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
layout (std140) uniform genericData {
|
||||
vec2 smaa_rt_metrics;
|
||||
};
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
layout (std140) uniform genericData {
|
||||
vec2 smaa_rt_metrics;
|
||||
};
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
layout (std140) uniform genericData {
|
||||
vec2 smaa_rt_metrics;
|
||||
};
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
layout (std140) uniform genericData {
|
||||
vec2 smaa_rt_metrics;
|
||||
};
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
layout (std140) uniform genericData {
|
||||
vec2 smaa_rt_metrics;
|
||||
};
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
uniform vec2 smaa_rt_metrics;
|
||||
layout (std140) uniform genericData {
|
||||
vec2 smaa_rt_metrics;
|
||||
};
|
||||
|
||||
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
|
||||
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
uniform sampler2D tex;
|
||||
uniform float exposure;
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
float exposure;
|
||||
};
|
||||
|
||||
vec3 Uncharted2Tonemapping(vec3 hdr_color)
|
||||
{
|
||||
float A = 0.15;
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
in vec4 vertPosition;
|
||||
in vec4 vertTexCoord;
|
||||
out vec4 fragTexCoord;
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projMatrix;
|
||||
|
||||
layout (std140) uniform matrixData {
|
||||
mat4 modelViewMatrix;
|
||||
mat4 projMatrix;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
fragTexCoord = vertTexCoord;
|
||||
gl_Position = projMatrix * modelViewMatrix * vertPosition;
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,7 @@ 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
|
||||
*/
|
||||
@@ -73,7 +74,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 < static_cast<int>(Ship_info.size()))) {
|
||||
} else if ((ship_class >= 0) && (ship_class < 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;
|
||||
|
||||
+44
-15
@@ -1,17 +1,15 @@
|
||||
/*
|
||||
* 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"
|
||||
@@ -19,12 +17,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
|
||||
@@ -38,6 +36,23 @@ 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)
|
||||
@@ -517,7 +532,7 @@ void event_music_do_frame()
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// event_music_level_init()
|
||||
// event_music_level_start()
|
||||
//
|
||||
// Called at the start of a mission (level). Sets up the pattern data, and kicks off the
|
||||
// first track to play().
|
||||
@@ -525,7 +540,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_init(int force_soundtrack)
|
||||
void event_music_level_start(int force_soundtrack)
|
||||
{
|
||||
int i;
|
||||
SOUNDTRACK_INFO *strack;
|
||||
@@ -543,8 +558,7 @@ void event_music_level_init(int force_soundtrack)
|
||||
|
||||
if (Event_music_inited == FALSE)
|
||||
return;
|
||||
|
||||
|
||||
|
||||
if (force_soundtrack != -1)
|
||||
Current_soundtrack_num = force_soundtrack;
|
||||
|
||||
@@ -629,7 +643,7 @@ void event_music_first_pattern()
|
||||
}
|
||||
|
||||
if ( Event_music_level_inited == FALSE ) {
|
||||
event_music_level_init();
|
||||
event_music_level_start();
|
||||
}
|
||||
|
||||
if ( Event_music_level_inited == FALSE ) { //-V581
|
||||
@@ -690,6 +704,7 @@ 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;
|
||||
@@ -1455,7 +1470,7 @@ void event_music_enable()
|
||||
Event_music_enabled = TRUE;
|
||||
|
||||
if ( Event_music_level_inited == FALSE ) {
|
||||
event_music_level_init();
|
||||
event_music_level_start();
|
||||
// start the first pattern to play (delayed)
|
||||
if ( Game_mode & GM_IN_MISSION ) {
|
||||
event_music_first_pattern();
|
||||
@@ -1594,7 +1609,7 @@ int event_music_next_soundtrack(int delta)
|
||||
new_soundtrack = 0;
|
||||
|
||||
event_music_level_close();
|
||||
event_music_level_init(new_soundtrack);
|
||||
event_music_level_start(new_soundtrack);
|
||||
|
||||
return Current_soundtrack_num;
|
||||
}
|
||||
@@ -1619,7 +1634,7 @@ void event_sexp_change_soundtrack(char *name)
|
||||
|
||||
event_music_level_close();
|
||||
Current_soundtrack_num = -1;
|
||||
event_music_level_init(new_soundtrack);
|
||||
event_music_level_start(new_soundtrack);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
@@ -1706,6 +1721,20 @@ 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
|
||||
@@ -97,7 +97,7 @@ extern int Num_soundtracks;
|
||||
|
||||
void event_music_init();
|
||||
void event_music_close();
|
||||
void event_music_level_init(int force_soundtrack = -1);
|
||||
void event_music_level_start(int force_soundtrack = -1);
|
||||
void event_music_level_close();
|
||||
void event_music_do_frame();
|
||||
void event_music_disable();
|
||||
@@ -129,4 +129,10 @@ 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__ */
|
||||
+28
-20
@@ -1207,29 +1207,37 @@ void parse_sound_table(const char* filename)
|
||||
// parse flyby sound section
|
||||
if (optional_string("#Flyby Sounds Start"))
|
||||
{
|
||||
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()))
|
||||
// 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"))
|
||||
{
|
||||
for (i = 0; i < Species_info.size(); i++)
|
||||
char species_name_tag[NAME_LENGTH + 2];
|
||||
stuff_string_until(species_name_tag, ":", NAME_LENGTH + 2);
|
||||
|
||||
if (species_name_tag[0] != '$')
|
||||
{
|
||||
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++;
|
||||
}
|
||||
error_display(0, "Unexpected token tag %s", species_name_tag);
|
||||
advance_to_eoln(nullptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
@@ -45,6 +45,12 @@
|
||||
#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;
|
||||
|
||||
@@ -226,12 +232,17 @@ extern int Global_error_count;
|
||||
// To debug printf do this:
|
||||
// mprintf(( "Error opening %s\n", filename ));
|
||||
#ifndef NDEBUG
|
||||
#define mprintf(args) outwnd_printf2 args
|
||||
#define nprintf(args) outwnd_printf args
|
||||
constexpr bool LoggingEnabled = true;
|
||||
#else
|
||||
#define mprintf(args)
|
||||
#define nprintf(args)
|
||||
#ifdef SCP_RELEASE_LOGGING
|
||||
constexpr bool LoggingEnabled = true;
|
||||
#else
|
||||
constexpr bool LoggingEnabled = false;
|
||||
#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__
|
||||
|
||||
@@ -446,7 +457,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 && defined(SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE)
|
||||
#if SCP_COMPILER_CXX_AUTO_TYPE && SCP_COMPILER_CXX_STATIC_ASSERT && 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)
|
||||
@@ -528,12 +539,18 @@ namespace std
|
||||
#define memmove memmove_if_trivial_else_error
|
||||
|
||||
template<typename T, typename U>
|
||||
void *memmove_if_trivial_else_error(T *memmove_dest, U *memmove_src, size_t count)
|
||||
inline 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;
|
||||
|
||||
@@ -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,9 +287,60 @@ 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];
|
||||
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();
|
||||
|
||||
// Call this with:
|
||||
// 0 - lowest
|
||||
|
||||
@@ -147,6 +147,9 @@ SCP_string get_version_string()
|
||||
case GR_OPENGL:
|
||||
str += " OpenGL";
|
||||
break;
|
||||
case GR_VULKAN:
|
||||
str += " Vulkan";
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
|
||||
@@ -53,7 +53,7 @@ struct version {
|
||||
int build = 0;
|
||||
int revision = 0;
|
||||
|
||||
version() {}
|
||||
version() = default;
|
||||
|
||||
version(int major, int minor, int build, int revision);
|
||||
|
||||
|
||||
+431
-103
@@ -1,58 +1,59 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#endif
|
||||
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
#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 "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 "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"
|
||||
|
||||
#if ( SDL_VERSION_ATLEAST(1, 2, 7) )
|
||||
#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 "SDL_cpuinfo.h"
|
||||
#endif
|
||||
|
||||
#include "SDL_surface.h"
|
||||
#include "material.h"
|
||||
|
||||
const char *Resolution_prefixes[GR_NUM_RESOLUTIONS] = { "", "2_" };
|
||||
const char* Resolution_prefixes[GR_NUM_RESOLUTIONS] = {"", "2_"};
|
||||
|
||||
screen gr_screen;
|
||||
|
||||
@@ -73,12 +74,107 @@ int Gr_inited = 0;
|
||||
|
||||
uint Gr_signature = 0;
|
||||
|
||||
float Gr_gamma = 1.8f;
|
||||
int Gr_gamma_int = 180;
|
||||
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);
|
||||
|
||||
// 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
|
||||
@@ -108,6 +204,8 @@ 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;
|
||||
@@ -219,7 +317,7 @@ static ResolutionInfo resolution_default()
|
||||
if (SDL_GetDesktopDisplayMode(VideoDisplayOption->getValue(), &mode) != 0) {
|
||||
return {};
|
||||
}
|
||||
return ResolutionInfo(mode.w, mode.h);
|
||||
return {(uint32_t)mode.w, (uint32_t)mode.h};
|
||||
}
|
||||
static bool resolution_change(const ResolutionInfo& /*info*/, bool initial)
|
||||
{
|
||||
@@ -348,6 +446,8 @@ 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();
|
||||
@@ -356,7 +456,8 @@ 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);
|
||||
|
||||
@@ -891,10 +992,23 @@ 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
|
||||
@@ -1014,12 +1128,108 @@ int gr_get_resolution_class(int width, int height)
|
||||
}
|
||||
}
|
||||
|
||||
static bool gr_init_sub(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int mode, int width, int height, int depth, float center_aspect_ratio)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -1104,26 +1314,31 @@ 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_STUB:
|
||||
rc = gr_stub_init();
|
||||
break;
|
||||
default:
|
||||
Int3(); // Invalid graphics 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
|
||||
}
|
||||
|
||||
if ( !rc ) {
|
||||
@@ -1245,6 +1460,17 @@ 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) {
|
||||
@@ -1368,6 +1594,10 @@ 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) {
|
||||
@@ -1398,6 +1628,17 @@ 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;
|
||||
@@ -1409,15 +1650,6 @@ 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);
|
||||
}
|
||||
@@ -1437,7 +1669,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);
|
||||
@@ -1446,17 +1678,11 @@ void gr_activate(int active)
|
||||
os::getMainViewport()->minimize();
|
||||
}
|
||||
|
||||
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
|
||||
if (active) {
|
||||
if (!Cmdline_fullscreen_window && !Cmdline_window) {
|
||||
gr_set_gamma(Gr_gamma);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// color stuff
|
||||
@@ -1994,7 +2220,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!", idx));
|
||||
mprintf(("Sorted index list missing index %d!\n", idx));
|
||||
Int3();
|
||||
return idx;
|
||||
}
|
||||
@@ -2377,26 +2603,53 @@ 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;
|
||||
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());
|
||||
}
|
||||
|
||||
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!
|
||||
Script_system.RunCondition(CHA_ONFRAME);
|
||||
//WMC - Do scripting reset stuff
|
||||
// WMC - Do conditional hooks. Yippee!
|
||||
OnFrameHook->run();
|
||||
// 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();
|
||||
|
||||
@@ -2413,32 +2666,13 @@ 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(); }
|
||||
|
||||
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();
|
||||
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);
|
||||
}
|
||||
|
||||
SCP_vector<DisplayData> gr_enumerate_displays()
|
||||
@@ -2597,10 +2831,104 @@ 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);
|
||||
}
|
||||
}
|
||||
+50
-30
@@ -1,21 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _GRAPHICS_H
|
||||
#define _GRAPHICS_H
|
||||
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "globalincs/flagset.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "graphics/grinternal.h"
|
||||
#include "graphics/tmapper.h"
|
||||
#include "io/cursor.h"
|
||||
@@ -27,7 +26,10 @@ namespace graphics {
|
||||
namespace util {
|
||||
class UniformBuffer;
|
||||
class GPUMemoryHeap;
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace graphics
|
||||
namespace scripting {
|
||||
class OverridableHook;
|
||||
}
|
||||
|
||||
extern const float Default_min_draw_distance;
|
||||
@@ -46,16 +48,16 @@ FLAG_LIST(FramebufferEffects){Thrusters = 0, Shockwaves, NUM_VALUES};
|
||||
extern flagset<FramebufferEffects> Gr_framebuffer_effects;
|
||||
|
||||
enum class AntiAliasMode {
|
||||
None,
|
||||
None = 0,
|
||||
|
||||
FXAA_Low,
|
||||
FXAA_Medium,
|
||||
FXAA_High,
|
||||
FXAA_Low = 1,
|
||||
FXAA_Medium = 2,
|
||||
FXAA_High = 3,
|
||||
|
||||
SMAA_Low,
|
||||
SMAA_Medium,
|
||||
SMAA_High,
|
||||
SMAA_Ultra,
|
||||
SMAA_Low = 4,
|
||||
SMAA_Medium = 5,
|
||||
SMAA_High = 6,
|
||||
SMAA_Ultra = 7,
|
||||
};
|
||||
extern AntiAliasMode Gr_aa_mode;
|
||||
extern AntiAliasMode Gr_aa_mode_last_frame;
|
||||
@@ -70,6 +72,10 @@ 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;
|
||||
@@ -240,6 +246,8 @@ enum class uniform_block_type {
|
||||
DecalInfo = 3,
|
||||
DecalGlobals = 4,
|
||||
DeferredGlobals = 5,
|
||||
Matrices = 6,
|
||||
GenericData = 7,
|
||||
|
||||
NUM_BLOCK_TYPES
|
||||
};
|
||||
@@ -321,6 +329,7 @@ typedef enum gr_capability {
|
||||
CAPABILITY_POINT_PARTICLES,
|
||||
CAPABILITY_TIMESTAMP_QUERY,
|
||||
CAPABILITY_SEPARATE_BLEND_FUNCTIONS,
|
||||
CAPABILITY_PERSISTENT_BUFFER_MAPPING,
|
||||
} gr_capability;
|
||||
|
||||
enum class gr_property {
|
||||
@@ -623,11 +632,7 @@ enum class BufferType {
|
||||
Uniform
|
||||
};
|
||||
|
||||
enum class BufferUsageHint {
|
||||
Static,
|
||||
Dynamic,
|
||||
Streaming
|
||||
};
|
||||
enum class BufferUsageHint { Static, Dynamic, Streaming, PersistentMapping };
|
||||
|
||||
/**
|
||||
* @brief Type of a graphics sync object
|
||||
@@ -726,9 +731,6 @@ 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);
|
||||
|
||||
@@ -759,8 +761,10 @@ 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, void* data);
|
||||
void (*gf_update_buffer_data_offset)(int handle, size_t offset, size_t size, void* data);
|
||||
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_transform_buffer)(void* data, size_t size);
|
||||
|
||||
// postprocessing effects
|
||||
@@ -849,7 +853,8 @@ 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_OPENGL (104) // Use OpenGl hardware renderer
|
||||
#define GR_VULKAN (105) // Use Vulkan hardware renderer
|
||||
|
||||
// resolution constants - always keep resolutions in ascending order and starting from 0
|
||||
#define GR_NUM_RESOLUTIONS 2
|
||||
@@ -954,8 +959,6 @@ 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)
|
||||
@@ -990,6 +993,11 @@ 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)
|
||||
@@ -1208,7 +1216,16 @@ enum AnimatedShader {
|
||||
ANIMATED_SHADER_CLOAK = 2,
|
||||
};
|
||||
|
||||
graphics::util::UniformBuffer* gr_get_uniform_buffer(uniform_block_type type);
|
||||
/**
|
||||
* @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);
|
||||
|
||||
struct VideoModeData {
|
||||
uint32_t width = 0;
|
||||
@@ -1254,6 +1271,9 @@ 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"
|
||||
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
|
||||
#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(¶ms.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
|
||||
@@ -0,0 +1,18 @@
|
||||
#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
|
||||
@@ -96,9 +96,10 @@ void decal_draw_list::globalShutdown() {
|
||||
gr_delete_buffer(box_index_buffer);
|
||||
}
|
||||
|
||||
decal_draw_list::decal_draw_list() {
|
||||
_buffer = gr_get_uniform_buffer(uniform_block_type::DecalInfo);
|
||||
auto& aligner = _buffer->aligner();
|
||||
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();
|
||||
|
||||
// Initialize header data
|
||||
auto header = aligner.getHeader<graphics::decal_globals>();
|
||||
@@ -131,13 +132,12 @@ decal_draw_list::decal_draw_list() {
|
||||
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,20 +149,16 @@ 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);
|
||||
}
|
||||
@@ -180,7 +176,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;
|
||||
@@ -202,7 +198,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 = aligner.getCurrentOffset();
|
||||
current_draw.uniform_offset = _buffer.getBufferOffset(aligner.getCurrentOffset());
|
||||
|
||||
material_set_decal(¤t_draw.draw_mat,
|
||||
bm_get_base_frame(diffuse_bitmap),
|
||||
|
||||
@@ -15,23 +15,19 @@ class decal_draw_list {
|
||||
};
|
||||
SCP_vector<decal_draw_info> _draws;
|
||||
|
||||
util::UniformBuffer* _buffer = nullptr;
|
||||
util::UniformBuffer _buffer;
|
||||
|
||||
static bool sort_draws(const decal_draw_info& left, const decal_draw_info& right);
|
||||
|
||||
public:
|
||||
decal_draw_list();
|
||||
public:
|
||||
explicit decal_draw_list(size_t num_decals);
|
||||
~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();
|
||||
|
||||
@@ -39,5 +35,4 @@ class decal_draw_list {
|
||||
|
||||
static void globalShutdown();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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", ga->filename));
|
||||
mprintf(("Cannot find first frame for eff streaming. eff Filename: %s\n", ga->filename));
|
||||
return -1;
|
||||
}
|
||||
if (snprintf(frame_name, MAX_FILENAME_LEN, "%s_0001", ga->filename) >= MAX_FILENAME_LEN) {
|
||||
|
||||
@@ -41,7 +41,6 @@ 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.
|
||||
|
||||
+14
-13
@@ -110,13 +110,9 @@ 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*/, void* /*data*/)
|
||||
{
|
||||
}
|
||||
void gr_stub_update_buffer_data(int /*handle*/, 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_buffer_data_offset(int /*handle*/, size_t /*offset*/, size_t /*size*/, const void* /*data*/) {}
|
||||
|
||||
void gr_stub_update_transform_buffer(void* /*data*/, size_t /*size*/)
|
||||
{
|
||||
@@ -141,10 +137,6 @@ 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*/)
|
||||
{
|
||||
}
|
||||
@@ -349,6 +341,15 @@ 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*){
|
||||
}
|
||||
@@ -429,8 +430,6 @@ 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;
|
||||
@@ -461,6 +460,8 @@ 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;
|
||||
@@ -504,7 +505,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_property,void*) { return false; };
|
||||
gr_screen.gf_get_property = gr_stub_get_property;
|
||||
|
||||
gr_screen.gf_push_debug_group = gr_stub_push_debug_group;
|
||||
gr_screen.gf_pop_debug_group = gr_stub_pop_debug_group;
|
||||
|
||||
@@ -134,6 +134,8 @@ 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) {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
|
||||
#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;
|
||||
@@ -11,16 +15,17 @@ 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 matrix4 create_view_matrix(const vec3d *pos, const matrix *orient)
|
||||
static bool matrix_uniform_up_to_date = false;
|
||||
|
||||
static matrix4 create_view_matrix(const vec3d* pos, const matrix* orient)
|
||||
{
|
||||
vec3d scaled_pos;
|
||||
vec3d inv_pos;
|
||||
@@ -82,6 +87,8 @@ 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)
|
||||
@@ -104,6 +111,8 @@ 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
|
||||
@@ -127,6 +136,8 @@ 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() {
|
||||
@@ -142,6 +153,8 @@ 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)
|
||||
@@ -154,8 +167,6 @@ 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
|
||||
|
||||
@@ -177,6 +188,8 @@ 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()
|
||||
@@ -189,7 +202,8 @@ void gr_end_view_matrix()
|
||||
|
||||
modelview_matrix_depth = 1;
|
||||
htl_view_matrix_set = false;
|
||||
gr_env_texture_matrix_set = false;
|
||||
|
||||
matrix_uniform_up_to_date = false;
|
||||
}
|
||||
|
||||
// set a view and projection matrix for a 2D element
|
||||
@@ -228,6 +242,8 @@ 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
|
||||
@@ -252,6 +268,8 @@ 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;
|
||||
@@ -269,6 +287,8 @@ 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()
|
||||
@@ -283,6 +303,8 @@ 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) {
|
||||
@@ -300,6 +322,8 @@ 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);
|
||||
@@ -312,12 +336,43 @@ 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;
|
||||
}
|
||||
+13
-3
@@ -9,14 +9,16 @@ extern matrix4 gr_projection_matrix;
|
||||
extern matrix4 gr_last_projection_matrix;
|
||||
extern matrix4 gr_env_texture_matrix;
|
||||
|
||||
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_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_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*/);
|
||||
@@ -32,3 +34,11 @@ 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();
|
||||
@@ -234,568 +234,46 @@ 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::setUniformi(const SCP_string &name, const int val)
|
||||
void opengl::ShaderUniforms::setTextureUniform(const SCP_string& name, const int texture_unit)
|
||||
{
|
||||
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 != (size_t)-1) {
|
||||
if (uniform_index != INVALID_SIZE) {
|
||||
Assert(uniform_index < _uniforms.size());
|
||||
|
||||
uniform_bind *bind_info = &_uniforms[uniform_index];
|
||||
uniform_bind* bind_info = &_uniforms[uniform_index];
|
||||
|
||||
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;
|
||||
if (bind_info->value == texture_unit) {
|
||||
return;
|
||||
}
|
||||
|
||||
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.count = 1;
|
||||
new_bind.index = _uniform_data_ints.size() - 1;
|
||||
new_bind.type = uniform_bind::INT;
|
||||
new_bind.name = name;
|
||||
new_bind.name = name;
|
||||
new_bind.value = texture_unit;
|
||||
|
||||
_uniforms.push_back(new_bind);
|
||||
|
||||
_uniform_lookup[name] = _uniforms.size() - 1;
|
||||
}
|
||||
|
||||
glUniform1i(findUniformLocation(name.c_str()), val);
|
||||
glUniform1i(findUniformLocation(name.c_str()), texture_unit);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -16,33 +16,13 @@ class ShaderUniforms {
|
||||
{
|
||||
SCP_string name;
|
||||
|
||||
enum data_type {
|
||||
INT,
|
||||
FLOAT,
|
||||
VEC2,
|
||||
VEC3,
|
||||
VEC4,
|
||||
MATRIX4
|
||||
};
|
||||
|
||||
uniform_bind::data_type type;
|
||||
size_t index;
|
||||
|
||||
int count;
|
||||
int tranpose;
|
||||
int value;
|
||||
};
|
||||
|
||||
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;
|
||||
@@ -52,20 +32,7 @@ class ShaderUniforms {
|
||||
public:
|
||||
explicit ShaderUniforms(ShaderProgram* shaderProgram);
|
||||
|
||||
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);
|
||||
void setTextureUniform(const SCP_string &name, const int texture_unit);
|
||||
};
|
||||
|
||||
enum ShaderStage {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
|
||||
#include "gropengl.h"
|
||||
|
||||
#include "gropenglbmpman.h"
|
||||
#include "gropengldeferred.h"
|
||||
#include "gropengldraw.h"
|
||||
@@ -11,29 +12,21 @@
|
||||
#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>
|
||||
@@ -60,8 +53,6 @@ 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;
|
||||
@@ -75,16 +66,6 @@ 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;
|
||||
@@ -97,74 +78,6 @@ 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;
|
||||
@@ -190,15 +103,9 @@ 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();
|
||||
|
||||
@@ -396,15 +303,6 @@ 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;
|
||||
}
|
||||
@@ -563,89 +461,6 @@ 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)
|
||||
{
|
||||
|
||||
@@ -903,113 +718,6 @@ 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;
|
||||
|
||||
@@ -1032,7 +740,7 @@ int opengl_init_display_device()
|
||||
}
|
||||
|
||||
if (Using_in_game_options) {
|
||||
switch (WindowModeOption->getValue()) {
|
||||
switch (Gr_configured_window_state) {
|
||||
case os::ViewportState::Windowed:
|
||||
// That's the default
|
||||
break;
|
||||
@@ -1084,11 +792,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -1118,8 +821,6 @@ 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;
|
||||
|
||||
@@ -1147,6 +848,8 @@ 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;
|
||||
@@ -1474,12 +1177,6 @@ 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)
|
||||
@@ -1607,6 +1304,8 @@ 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;
|
||||
@@ -1671,26 +1370,6 @@ 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;
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
|
||||
|
||||
#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/uniform_structs.h"
|
||||
#include "graphics/util/UniformBuffer.h"
|
||||
#include "tracing/tracing.h"
|
||||
#include "graphics/util/uniform_structs.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 "mission/missionparse.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "render/3d.h"
|
||||
#include "tracing/tracing.h"
|
||||
|
||||
void gr_opengl_deferred_init() {
|
||||
#include <math/bitarray.h>
|
||||
|
||||
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()
|
||||
{
|
||||
@@ -125,9 +129,18 @@ void gr_opengl_deferred_lighting_finish()
|
||||
std::stable_sort(Lights.begin(), Lights.end(), light_compare_by_type);
|
||||
using namespace graphics;
|
||||
|
||||
// Get a uniform buffer for out data
|
||||
auto buffer = gr_get_uniform_buffer(uniform_block_type::Lights);
|
||||
auto& uniformAligner = buffer->aligner();
|
||||
// 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();
|
||||
|
||||
{
|
||||
GR_DEBUG_SCOPE("Build buffer data");
|
||||
@@ -170,6 +183,9 @@ 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) {
|
||||
@@ -199,9 +215,6 @@ 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;
|
||||
@@ -210,7 +223,6 @@ 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;
|
||||
|
||||
@@ -243,14 +255,12 @@ 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,
|
||||
0,
|
||||
sizeof(graphics::deferred_global_data),
|
||||
buffer->bufferHandle());
|
||||
gr_bind_uniform_buffer(uniform_block_type::DeferredGlobals, buffer.getBufferOffset(0),
|
||||
sizeof(graphics::deferred_global_data), buffer.bufferHandle());
|
||||
|
||||
size_t element_index = 0;
|
||||
for (auto& l : Lights) {
|
||||
@@ -258,27 +268,21 @@ void gr_opengl_deferred_lighting_finish()
|
||||
|
||||
switch (l.type) {
|
||||
case Light_Type::Directional:
|
||||
gr_bind_uniform_buffer(uniform_block_type::Lights,
|
||||
uniformAligner.getOffset(element_index),
|
||||
sizeof(graphics::deferred_light_data),
|
||||
buffer->bufferHandle());
|
||||
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(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,
|
||||
uniformAligner.getOffset(element_index),
|
||||
sizeof(graphics::deferred_light_data),
|
||||
buffer->bufferHandle());
|
||||
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(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,
|
||||
uniformAligner.getOffset(element_index),
|
||||
sizeof(graphics::deferred_light_data),
|
||||
buffer->bufferHandle());
|
||||
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(element_index),
|
||||
sizeof(graphics::deferred_light_data), buffer.bufferHandle());
|
||||
|
||||
vec3d a;
|
||||
matrix orient;
|
||||
@@ -289,10 +293,8 @@ 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,
|
||||
uniformAligner.getOffset(element_index),
|
||||
sizeof(graphics::deferred_light_data),
|
||||
buffer->bufferHandle());
|
||||
gr_bind_uniform_buffer(uniform_block_type::Lights, buffer.getAlignerElementOffset(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);
|
||||
@@ -302,9 +304,6 @@ void gr_opengl_deferred_lighting_finish()
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// We don't need the buffer anymore
|
||||
buffer->finished();
|
||||
}
|
||||
|
||||
gr_end_view_matrix();
|
||||
@@ -326,13 +325,18 @@ void gr_opengl_deferred_lighting_finish()
|
||||
unsigned char r, g, b;
|
||||
neb2_get_fog_color(&r, &g, &b);
|
||||
|
||||
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);
|
||||
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;
|
||||
});
|
||||
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
} else {
|
||||
@@ -364,8 +368,7 @@ void gr_opengl_draw_deferred_light_sphere(const vec3d *position)
|
||||
{
|
||||
g3_start_instance_matrix(position, &vmd_identity_matrix, true);
|
||||
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
|
||||
gr_matrix_set_uniforms();
|
||||
|
||||
opengl_draw_sphere();
|
||||
|
||||
@@ -592,8 +595,7 @@ void gr_opengl_draw_deferred_light_cylinder(const vec3d *position, const matrix
|
||||
{
|
||||
g3_start_instance_matrix(position, orient, true);
|
||||
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
|
||||
gr_matrix_set_uniforms();
|
||||
|
||||
vertex_layout vertex_declare;
|
||||
|
||||
|
||||
@@ -611,24 +611,27 @@ 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)));
|
||||
}
|
||||
}
|
||||
|
||||
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_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();
|
||||
|
||||
opengl_render_primitives(prim_type, layout, n_verts, buffer_handle, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#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"
|
||||
@@ -23,44 +24,50 @@
|
||||
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;
|
||||
|
||||
typedef struct post_effect_t {
|
||||
enum class PostEffectUniformType {
|
||||
Invalid,
|
||||
NoiseAmount,
|
||||
Saturation,
|
||||
Brightness,
|
||||
Contrast,
|
||||
FilmGrain,
|
||||
TvStripes,
|
||||
Cutoff,
|
||||
Tint,
|
||||
Dither,
|
||||
};
|
||||
|
||||
struct post_effect_t {
|
||||
SCP_string name;
|
||||
SCP_string uniform_name;
|
||||
PostEffectUniformType uniform_type = PostEffectUniformType::Invalid;
|
||||
SCP_string define_name;
|
||||
|
||||
float intensity;
|
||||
float default_intensity;
|
||||
float div;
|
||||
float add;
|
||||
float intensity{0.0f};
|
||||
float default_intensity{0.0f};
|
||||
float div{1.0f};
|
||||
float add{0.0f};
|
||||
|
||||
vec3d rgb;
|
||||
vec3d rgb = vmd_zero_vector;
|
||||
|
||||
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;
|
||||
bool always_on{false};
|
||||
};
|
||||
|
||||
SCP_vector<post_effect_t> Post_effects;
|
||||
|
||||
@@ -95,10 +102,12 @@ 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.setUniformi("tex", 0);
|
||||
Current_shader->program->Uniforms.setUniformf("exposure", 4.0f);
|
||||
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; });
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Scene_ldr_texture, 0);
|
||||
|
||||
@@ -135,7 +144,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.setUniformi("tex", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_color_texture);
|
||||
|
||||
@@ -163,17 +172,19 @@ 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.setUniformi("tex", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("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;
|
||||
|
||||
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);
|
||||
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;
|
||||
});
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dest_tex, mipmap);
|
||||
|
||||
@@ -193,9 +204,13 @@ 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.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);
|
||||
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;
|
||||
});
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Bloom_textures[0]);
|
||||
|
||||
@@ -239,29 +254,39 @@ void gr_opengl_post_process_begin()
|
||||
Post_in_frame = true;
|
||||
}
|
||||
|
||||
void recompile_fxaa_shader() {
|
||||
if (!gr_is_fxaa_mode(Gr_aa_mode)) {
|
||||
return;
|
||||
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);
|
||||
}
|
||||
|
||||
mprintf(("Recompiling FXAA shader...\n"));
|
||||
mprintf(("Recompiling AA shader(s)...\n"));
|
||||
|
||||
// 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) );
|
||||
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) );
|
||||
|
||||
// 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);
|
||||
// then recreate it again. shader loading code will be updated with the new AA presets
|
||||
gr_opengl_maybe_create_shader(sdr, 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_fxaa_shader();
|
||||
recompile_aa_shader();
|
||||
}
|
||||
|
||||
// We only want to draw to ATTACHMENT0
|
||||
@@ -269,10 +294,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.setUniformi( "tex", 0 );
|
||||
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Scene_luminance_texture, 0);
|
||||
|
||||
@@ -281,14 +306,17 @@ 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.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));
|
||||
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);
|
||||
});
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_luminance_texture);
|
||||
|
||||
@@ -311,9 +339,7 @@ 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.setUniformi("colorTex", 0);
|
||||
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
|
||||
i2fl(Post_texture_height));
|
||||
Current_shader->program->Uniforms.setTextureUniform("colorTex", 0);
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
|
||||
|
||||
@@ -334,11 +360,9 @@ 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.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));
|
||||
Current_shader->program->Uniforms.setTextureUniform("edgesTex", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("areaTex", 1);
|
||||
Current_shader->program->Uniforms.setTextureUniform("searchTex", 2);
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Smaa_edges_tex);
|
||||
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Smaa_area_tex);
|
||||
@@ -361,10 +385,8 @@ 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.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));
|
||||
Current_shader->program->Uniforms.setTextureUniform("colorTex", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("blendTex", 1);
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
|
||||
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Smaa_blend_tex);
|
||||
@@ -395,10 +417,21 @@ 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();
|
||||
@@ -444,16 +477,24 @@ 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;
|
||||
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);
|
||||
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);
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_depth_texture);
|
||||
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Cockpit_depth_texture);
|
||||
@@ -521,7 +562,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);
|
||||
}
|
||||
@@ -529,30 +570,57 @@ void gr_opengl_post_process_end()
|
||||
opengl_shader_set_current(post_sdr_handle);
|
||||
|
||||
// basic/default uniforms
|
||||
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("tex", 0);
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_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;
|
||||
Current_shader->program->Uniforms.setTextureUniform("depth_tex", 1);
|
||||
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_depth_texture);
|
||||
|
||||
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 );
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -716,6 +784,31 @@ 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()
|
||||
{
|
||||
@@ -733,20 +826,19 @@ 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(tbuf, F_NAME, NAME_LENGTH);
|
||||
eff.name = tbuf;
|
||||
stuff_string(eff.name, F_NAME);
|
||||
|
||||
required_string("$Uniform:");
|
||||
stuff_string(tbuf, F_NAME, NAME_LENGTH);
|
||||
eff.uniform_name = tbuf;
|
||||
|
||||
SCP_string tbuf;
|
||||
stuff_string(tbuf, F_NAME);
|
||||
eff.uniform_type = mapUniformNameToType(tbuf);
|
||||
|
||||
required_string("$Define:");
|
||||
stuff_string(tbuf, F_NAME, NAME_LENGTH);
|
||||
eff.define_name = tbuf;
|
||||
stuff_string(eff.define_name, F_NAME);
|
||||
|
||||
required_string("$AlwaysOn:");
|
||||
stuff_boolean(&eff.always_on);
|
||||
@@ -885,6 +977,23 @@ 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)
|
||||
{
|
||||
|
||||
@@ -1,33 +1,35 @@
|
||||
/*
|
||||
* 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/matrix.h"
|
||||
#include "graphics/grinternal.h"
|
||||
#include "graphics/matrix.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 <md5.h>
|
||||
#include <jansson.h>
|
||||
#include <md5.h>
|
||||
|
||||
SCP_vector<opengl_shader_t> GL_shader;
|
||||
|
||||
@@ -64,12 +66,14 @@ 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::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"},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -81,7 +85,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-particle-f.sdr", "effect-screen-g.sdr",
|
||||
{ SDR_TYPE_EFFECT_PARTICLE, "effect-v.sdr", "effect-f.sdr", "effect-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,
|
||||
@@ -129,7 +133,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, "passthrough-v.sdr", "default-material-f.sdr", nullptr,
|
||||
{ SDR_TYPE_DEFAULT_MATERIAL, "default-material-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,
|
||||
@@ -160,109 +164,63 @@ 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_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_DIFFUSE_MAP, "FLAG_DIFFUSE_MAP", {}, "Diffuse Mapping"},
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_HDR, "FLAG_HDR",
|
||||
{ },
|
||||
"High Dynamic Range" },
|
||||
{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_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_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_EFFECT_PARTICLE,
|
||||
true,
|
||||
SDR_FLAG_PARTICLE_POINT_GEN,
|
||||
"FLAG_EFFECT_GEOMETRY",
|
||||
{opengl_vert_attrib::UVEC},
|
||||
"Geometry shader point-based particles"},
|
||||
|
||||
{ SDR_TYPE_NANOVG, false, SDR_FLAG_NANOVG_EDGE_AA, "EDGE_AA",
|
||||
{ },
|
||||
"NanoVG edge anti-alias" },
|
||||
{SDR_TYPE_POST_PROCESS_BLUR, false, SDR_FLAG_BLUR_HORIZONTAL, "PASS_0", {}, "Horizontal blur pass"},
|
||||
|
||||
{ SDR_TYPE_DECAL, false, SDR_FLAG_DECAL_USE_NORMAL_MAP, "USE_NORMAL_MAP",
|
||||
{ },
|
||||
"Decal use scene normal map" },
|
||||
{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"},
|
||||
};
|
||||
|
||||
static const int GL_num_shader_variants = sizeof(GL_shader_variants) / sizeof(opengl_shader_variant_t);
|
||||
@@ -315,7 +273,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()) {
|
||||
@@ -350,7 +308,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;
|
||||
@@ -614,9 +572,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);
|
||||
@@ -647,7 +605,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;
|
||||
@@ -701,16 +659,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.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);
|
||||
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);
|
||||
break;
|
||||
|
||||
case SDR_TYPE_PASSTHROUGH_RENDER:
|
||||
Current_shader->program->Uniforms.setUniformi("baseMap", 0);
|
||||
Current_shader->program->Uniforms.setUniformi("clipEnabled", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("baseMap", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("clipEnabled", 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1007,76 +965,71 @@ void opengl_shader_set_passthrough(bool textured, bool hdr)
|
||||
{
|
||||
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_PASSTHROUGH_RENDER, 0));
|
||||
|
||||
if ( textured ) {
|
||||
Current_shader->program->Uniforms.setUniformi("noTexturing", 0);
|
||||
} else {
|
||||
Current_shader->program->Uniforms.setUniformi("noTexturing", 1);
|
||||
}
|
||||
gr_matrix_set_uniforms();
|
||||
|
||||
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);
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
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.setUniformi("baseMap", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("baseMap", 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);
|
||||
}
|
||||
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 ( alpha ) {
|
||||
Current_shader->program->Uniforms.setUniformi("alphaTexture", 1);
|
||||
} else {
|
||||
Current_shader->program->Uniforms.setUniformi("alphaTexture", 0);
|
||||
}
|
||||
if (alpha) {
|
||||
data->alphaTexture = 1;
|
||||
} else {
|
||||
data->alphaTexture = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (High_dynamic_range) {
|
||||
data->srgb = 1;
|
||||
data->intensity = color_scale;
|
||||
} else {
|
||||
data->srgb = 0;
|
||||
data->intensity = 1.0f;
|
||||
}
|
||||
|
||||
Current_shader->program->Uniforms.setUniformf("alphaThreshold", GL_alpha_threshold);
|
||||
data->alphaThreshold = GL_alpha_threshold;
|
||||
|
||||
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 (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 (clip_plane.enabled) {
|
||||
Current_shader->program->Uniforms.setUniformi("clipEnabled", 1);
|
||||
if (clip_plane.enabled) {
|
||||
data->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);
|
||||
|
||||
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);
|
||||
}
|
||||
data->clipEquation = clip_equation;
|
||||
data->modelMatrix = gr_model_matrix_stack.get_transform();
|
||||
} else {
|
||||
data->clipEnabled = 0;
|
||||
}
|
||||
});
|
||||
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
|
||||
gr_matrix_set_uniforms();
|
||||
}
|
||||
|
||||
@@ -1,34 +1,29 @@
|
||||
/*
|
||||
* 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/opengl/gropengl.h"
|
||||
#include "graphics/material.h"
|
||||
#include "graphics/opengl/gropengl.h"
|
||||
#include "graphics/util/UniformBuffer.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 {
|
||||
@@ -160,5 +155,18 @@ 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
|
||||
@@ -45,9 +45,7 @@ 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()
|
||||
{
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "weapon/trails.h"
|
||||
|
||||
extern int GLOWMAP;
|
||||
extern int CLOAKMAP;
|
||||
extern int SPECMAP;
|
||||
extern int SPECGLOSSMAP;
|
||||
extern int NORMMAP;
|
||||
@@ -90,7 +89,8 @@ static opengl_vertex_bind GL_array_binding_data[] =
|
||||
struct opengl_buffer_object {
|
||||
GLuint buffer_id;
|
||||
GLenum type;
|
||||
GLenum usage;
|
||||
GLenum gl_usage;
|
||||
BufferUsageHint usage;
|
||||
size_t size;
|
||||
|
||||
GLuint texture; // for texture buffer objects
|
||||
@@ -121,7 +121,9 @@ static GLenum convertUsageHint(BufferUsageHint usage) {
|
||||
return GL_DYNAMIC_DRAW;
|
||||
case BufferUsageHint::Streaming:
|
||||
return GL_STREAM_DRAW;
|
||||
default:
|
||||
case BufferUsageHint::PersistentMapping:
|
||||
return GL_NONE; // Dummy value
|
||||
default:
|
||||
UNREACHABLE("Unhandled enum value!");
|
||||
return GL_INVALID_ENUM;
|
||||
}
|
||||
@@ -186,12 +188,16 @@ static GLenum convertComparisionFunction(ComparisionFunction func) {
|
||||
return mode;
|
||||
}
|
||||
|
||||
int opengl_create_buffer_object(GLenum type, GLenum usage)
|
||||
int opengl_create_buffer_object(GLenum type, GLenum gl_usage, BufferUsageHint 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;
|
||||
@@ -242,7 +248,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, void* data)
|
||||
void gr_opengl_update_buffer_data(int handle, size_t size, const 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!");
|
||||
@@ -256,31 +262,20 @@ void gr_opengl_update_buffer_data(int handle, size_t size, void* data)
|
||||
|
||||
opengl_bind_buffer_object(handle);
|
||||
|
||||
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);
|
||||
|
||||
glUnmapBuffer(buffer_obj.type);
|
||||
}
|
||||
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 {
|
||||
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);
|
||||
glBufferData(buffer_obj.type, size, data, buffer_obj.gl_usage);
|
||||
}
|
||||
|
||||
GL_vertex_data_in -= buffer_obj.size;
|
||||
buffer_obj.size = size;
|
||||
GL_vertex_data_in += buffer_obj.size;
|
||||
}
|
||||
|
||||
void gr_opengl_update_buffer_data_offset(int handle, size_t offset, size_t size, void* data)
|
||||
void gr_opengl_update_buffer_data_offset(int handle, size_t offset, size_t size, const void* data)
|
||||
{
|
||||
GR_DEBUG_SCOPE("Update buffer data with offset");
|
||||
|
||||
@@ -289,10 +284,46 @@ 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)
|
||||
{
|
||||
@@ -336,7 +367,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));
|
||||
return opengl_create_buffer_object(convertBufferType(type), convertUsageHint(usage), usage);
|
||||
}
|
||||
|
||||
void gr_opengl_bind_uniform_buffer(uniform_block_type bind_point, size_t offset, size_t size, int buffer) {
|
||||
@@ -361,7 +392,8 @@ 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);
|
||||
int buffer_object_handle =
|
||||
opengl_create_buffer_object(GL_TEXTURE_BUFFER, GL_DYNAMIC_DRAW, BufferUsageHint::Dynamic);
|
||||
|
||||
opengl_check_for_errors();
|
||||
|
||||
@@ -734,8 +766,7 @@ 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 != NULL && (Current_shader->shader == SDR_TYPE_MODEL
|
||||
|| Current_shader->shader == SDR_TYPE_PASSTHROUGH_RENDER
|
||||
Assertion(Current_shader != nullptr && (Current_shader->shader == SDR_TYPE_MODEL
|
||||
|| Current_shader->shader == SDR_TYPE_DEFAULT_MATERIAL),
|
||||
"Clip planes are not supported by this shader!");
|
||||
|
||||
@@ -787,7 +818,6 @@ 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);
|
||||
|
||||
@@ -809,98 +839,78 @@ 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.setUniformi("sBasemap", render_pass);
|
||||
Current_shader->program->Uniforms.setTextureUniform("sBasemap", 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;
|
||||
gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 0);
|
||||
}
|
||||
|
||||
if ( Current_shader->flags & SDR_FLAG_MODEL_GLOW_MAP ) {
|
||||
Current_shader->program->Uniforms.setUniformi("sGlowmap", render_pass);
|
||||
Current_shader->program->Uniforms.setTextureUniform("sGlowmap", 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;
|
||||
gr_opengl_tcache_set(material_info->get_texture_map(TM_GLOW_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 1);
|
||||
}
|
||||
|
||||
if ( Current_shader->flags & SDR_FLAG_MODEL_SPEC_MAP ) {
|
||||
Current_shader->program->Uniforms.setUniformi("sSpecmap", render_pass);
|
||||
Current_shader->program->Uniforms.setTextureUniform("sSpecmap", 2);
|
||||
|
||||
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, render_pass);
|
||||
gr_opengl_tcache_set(material_info->get_texture_map(TM_SPEC_GLOSS_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 2);
|
||||
} else {
|
||||
gr_opengl_tcache_set(material_info->get_texture_map(TM_SPECULAR_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass);
|
||||
gr_opengl_tcache_set(material_info->get_texture_map(TM_SPECULAR_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 2);
|
||||
}
|
||||
++render_pass;
|
||||
|
||||
if ( Current_shader->flags & SDR_FLAG_MODEL_ENV_MAP ) {
|
||||
Current_shader->program->Uniforms.setUniformi("sEnvmap", render_pass);
|
||||
Current_shader->program->Uniforms.setTextureUniform("sEnvmap", 3);
|
||||
|
||||
gr_opengl_tcache_set(ENVMAP, TCACHE_TYPE_CUBEMAP, &u_scale, &v_scale, &array_index, render_pass);
|
||||
gr_opengl_tcache_set(ENVMAP, TCACHE_TYPE_CUBEMAP, &u_scale, &v_scale, &array_index, 3);
|
||||
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.setUniformi("sNormalmap", render_pass);
|
||||
Current_shader->program->Uniforms.setTextureUniform("sNormalmap", 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;
|
||||
gr_opengl_tcache_set(material_info->get_texture_map(TM_NORMAL_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 4);
|
||||
}
|
||||
|
||||
if ( Current_shader->flags & SDR_FLAG_MODEL_HEIGHT_MAP ) {
|
||||
Current_shader->program->Uniforms.setUniformi("sHeightmap", render_pass);
|
||||
Current_shader->program->Uniforms.setTextureUniform("sHeightmap", 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;
|
||||
gr_opengl_tcache_set(material_info->get_texture_map(TM_HEIGHT_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 5);
|
||||
}
|
||||
|
||||
if ( Current_shader->flags & SDR_FLAG_MODEL_AMBIENT_MAP ) {
|
||||
Current_shader->program->Uniforms.setUniformi("sAmbientmap", render_pass);
|
||||
Current_shader->program->Uniforms.setTextureUniform("sAmbientmap", 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;
|
||||
gr_opengl_tcache_set(material_info->get_texture_map(TM_AMBIENT_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 6);
|
||||
}
|
||||
|
||||
if ( Current_shader->flags & SDR_FLAG_MODEL_MISC_MAP ) {
|
||||
Current_shader->program->Uniforms.setUniformi("sMiscmap", render_pass);
|
||||
Current_shader->program->Uniforms.setTextureUniform("sMiscmap", 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;
|
||||
gr_opengl_tcache_set(material_info->get_texture_map(TM_MISC_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, 7);
|
||||
}
|
||||
|
||||
if ( Current_shader->flags & SDR_FLAG_MODEL_SHADOWS ) {
|
||||
Current_shader->program->Uniforms.setUniformi("shadow_map", render_pass);
|
||||
Current_shader->program->Uniforms.setTextureUniform("shadow_map", 8);
|
||||
|
||||
GL_state.Texture.Enable(render_pass, GL_TEXTURE_2D_ARRAY, Shadow_map_texture);
|
||||
|
||||
++render_pass; // bump!
|
||||
GL_state.Texture.Enable(8, GL_TEXTURE_2D_ARRAY, Shadow_map_texture);
|
||||
}
|
||||
|
||||
if ( Current_shader->flags & SDR_FLAG_MODEL_ANIMATED ) {
|
||||
Current_shader->program->Uniforms.setUniformi("sFramebuffer", render_pass);
|
||||
Current_shader->program->Uniforms.setTextureUniform("sFramebuffer", 9);
|
||||
|
||||
if ( Scene_framebuffer_in_frame ) {
|
||||
GL_state.Texture.Enable(render_pass, GL_TEXTURE_2D, Scene_effect_texture);
|
||||
GL_state.Texture.Enable(9, GL_TEXTURE_2D, Scene_effect_texture);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
} else {
|
||||
GL_state.Texture.Enable(render_pass, GL_TEXTURE_2D, Framebuffer_fallback_texture_id);
|
||||
GL_state.Texture.Enable(9, GL_TEXTURE_2D, Framebuffer_fallback_texture_id);
|
||||
}
|
||||
|
||||
++render_pass;
|
||||
}
|
||||
|
||||
if ( Current_shader->flags & SDR_FLAG_MODEL_TRANSFORM ) {
|
||||
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;
|
||||
Current_shader->program->Uniforms.setTextureUniform("transform_tex", 10);
|
||||
GL_state.Texture.Enable(10, GL_TEXTURE_BUFFER, opengl_get_transform_buffer_texture());
|
||||
}
|
||||
|
||||
if ( Deferred_lighting ) {
|
||||
@@ -913,25 +923,28 @@ void opengl_tnl_set_material_particle(particle_material * material_info)
|
||||
{
|
||||
opengl_tnl_set_material(material_info, true);
|
||||
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
|
||||
gr_matrix_set_uniforms();
|
||||
|
||||
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);
|
||||
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;
|
||||
|
||||
if ( Cmdline_no_deferred_lighting ) {
|
||||
Current_shader->program->Uniforms.setUniformi("linear_depth", 0);
|
||||
} else {
|
||||
Current_shader->program->Uniforms.setUniformi("linear_depth", 1);
|
||||
}
|
||||
if (Cmdline_no_deferred_lighting) {
|
||||
data->linear_depth = 0;
|
||||
} else {
|
||||
data->linear_depth = 1;
|
||||
}
|
||||
});
|
||||
|
||||
if ( !Cmdline_no_deferred_lighting ) {
|
||||
Current_shader->program->Uniforms.setTextureUniform("baseMap", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("depthMap", 1);
|
||||
|
||||
if (!Cmdline_no_deferred_lighting) {
|
||||
Assert(Scene_position_texture != 0);
|
||||
|
||||
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_position_texture);
|
||||
@@ -941,48 +954,52 @@ 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);
|
||||
|
||||
Current_shader->program->Uniforms.setUniformf("intensity", material_info->get_color_scale());
|
||||
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.setUniform4f("color", material_info->get_color());
|
||||
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.setUniformi("baseMap", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("baseMap", 0);
|
||||
}
|
||||
|
||||
void opengl_tnl_set_material_distortion(distortion_material* material_info)
|
||||
{
|
||||
opengl_tnl_set_material(material_info, true);
|
||||
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
|
||||
gr_matrix_set_uniforms();
|
||||
|
||||
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);
|
||||
Current_shader->program->Uniforms.setTextureUniform("baseMap", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("depthMap", 1);
|
||||
|
||||
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.setUniformi("distMap", 3);
|
||||
|
||||
if(material_info->get_thruster_rendering()) {
|
||||
Current_shader->program->Uniforms.setTextureUniform("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);
|
||||
@@ -993,12 +1010,11 @@ 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);
|
||||
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix);
|
||||
Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix);
|
||||
gr_matrix_set_uniforms();
|
||||
|
||||
Current_shader->program->Uniforms.setUniformi("ytex", 0);
|
||||
Current_shader->program->Uniforms.setUniformi("utex", 1);
|
||||
Current_shader->program->Uniforms.setUniformi("vtex", 2);
|
||||
Current_shader->program->Uniforms.setTextureUniform("ytex", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("utex", 1);
|
||||
Current_shader->program->Uniforms.setTextureUniform("vtex", 2);
|
||||
|
||||
float u_scale, v_scale;
|
||||
uint32_t index;
|
||||
@@ -1015,7 +1031,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.setUniformi("nvg_tex", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("nvg_tex", 0);
|
||||
}
|
||||
|
||||
void opengl_tnl_set_material_decal(decal_material* material_info) {
|
||||
@@ -1030,7 +1046,7 @@ void opengl_tnl_set_material_decal(decal_material* material_info) {
|
||||
&v_scale,
|
||||
&array_index,
|
||||
0)) {
|
||||
Current_shader->program->Uniforms.setUniformi("diffuseMap", 0);
|
||||
Current_shader->program->Uniforms.setTextureUniform("diffuseMap", 0);
|
||||
}
|
||||
|
||||
if (gr_opengl_tcache_set(material_info->get_texture_map(TM_GLOW_TYPE),
|
||||
@@ -1039,7 +1055,7 @@ void opengl_tnl_set_material_decal(decal_material* material_info) {
|
||||
&v_scale,
|
||||
&array_index,
|
||||
1)) {
|
||||
Current_shader->program->Uniforms.setUniformi("glowMap", 1);
|
||||
Current_shader->program->Uniforms.setTextureUniform("glowMap", 1);
|
||||
}
|
||||
|
||||
if (gr_opengl_tcache_set(material_info->get_texture_map(TM_NORMAL_TYPE),
|
||||
@@ -1048,15 +1064,15 @@ void opengl_tnl_set_material_decal(decal_material* material_info) {
|
||||
&v_scale,
|
||||
&array_index,
|
||||
2)) {
|
||||
Current_shader->program->Uniforms.setUniformi("normalMap", 2);
|
||||
Current_shader->program->Uniforms.setTextureUniform("normalMap", 2);
|
||||
}
|
||||
|
||||
GL_state.Texture.Enable(3, GL_TEXTURE_2D, Scene_depth_texture);
|
||||
Current_shader->program->Uniforms.setUniformi("gDepthBuffer", 3);
|
||||
Current_shader->program->Uniforms.setTextureUniform("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.setUniformi("gNormalBuffer", 4);
|
||||
Current_shader->program->Uniforms.setTextureUniform("gNormalBuffer", 4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1071,21 +1087,25 @@ void opengl_tnl_set_rocketui_material(interface_material* material_info)
|
||||
|
||||
opengl_tnl_set_material(material_info, false);
|
||||
|
||||
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);
|
||||
Current_shader->program->Uniforms.setTextureUniform("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, &array_index)) {
|
||||
&u_scale, &v_scale, &baseMapIndex)) {
|
||||
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) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "gropengl.h"
|
||||
#include "gropenglshader.h"
|
||||
#include "graphics/shadows.h"
|
||||
#include "model/model.h"
|
||||
|
||||
@@ -46,10 +47,12 @@ 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, void* data);
|
||||
void gr_opengl_update_buffer_data_offset(int handle, size_t offset, size_t size, void* data);
|
||||
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_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
|
||||
|
||||
@@ -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, ...) {
|
||||
SCP_string buf;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(buf, message, args);
|
||||
va_end(args);
|
||||
outwnd_printf2("%s", message);
|
||||
if (LoggingEnabled) {
|
||||
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);
|
||||
_uniformBuffer = gr_get_uniform_buffer(uniform_block_type::NanoVGData, _uniformData.size());
|
||||
// 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,8 +453,6 @@ void NanoVGRenderer::renderFlush() {
|
||||
}
|
||||
}
|
||||
|
||||
_uniformBuffer->finished();
|
||||
|
||||
// Reset all data again
|
||||
renderCancel();
|
||||
}
|
||||
@@ -661,10 +659,8 @@ void NanoVGRenderer::drawTriangles(const DrawCall& call) {
|
||||
auto mat = _trianglesMaterial;
|
||||
materialSetTexture(mat, call.image);
|
||||
|
||||
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
|
||||
_uniformBuffer->aligner().getOffset(call.uniformIndex),
|
||||
sizeof(nanovg_draw_data),
|
||||
_uniformBuffer->bufferHandle());
|
||||
gr_bind_uniform_buffer(uniform_block_type::NanoVGData, _uniformBuffer.getAlignerElementOffset(call.uniformIndex),
|
||||
sizeof(nanovg_draw_data), _uniformBuffer.bufferHandle());
|
||||
|
||||
gr_render_nanovg(&mat, PRIM_TYPE_TRIS, &_vertexLayout, call.triangleOffset, call.triangleCount, _vertexBuffer);
|
||||
}
|
||||
@@ -675,10 +671,8 @@ 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->aligner().getOffset(call.uniformIndex),
|
||||
sizeof(nanovg_draw_data),
|
||||
_uniformBuffer->bufferHandle());
|
||||
gr_bind_uniform_buffer(uniform_block_type::NanoVGData, _uniformBuffer.getAlignerElementOffset(call.uniformIndex),
|
||||
sizeof(nanovg_draw_data), _uniformBuffer.bufferHandle());
|
||||
|
||||
auto pathOffset = call.pathOffset;
|
||||
for (size_t i = 0; i < call.pathCount; ++i) {
|
||||
@@ -693,9 +687,8 @@ void NanoVGRenderer::drawFill(const DrawCall& call) {
|
||||
mat = _fillAntiAliasMaterial;
|
||||
materialSetTexture(mat, call.image);
|
||||
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
|
||||
_uniformBuffer->aligner().getOffset(call.uniformIndex + 1),
|
||||
sizeof(nanovg_draw_data),
|
||||
_uniformBuffer->bufferHandle());
|
||||
_uniformBuffer.getAlignerElementOffset(call.uniformIndex + 1), sizeof(nanovg_draw_data),
|
||||
_uniformBuffer.bufferHandle());
|
||||
|
||||
// Draw fringes
|
||||
for (size_t i = 0; i < call.pathCount; ++i) {
|
||||
@@ -718,10 +711,8 @@ void NanoVGRenderer::drawConvexFill(const DrawCall& call) {
|
||||
|
||||
auto mat = _triangleFillMaterial;
|
||||
materialSetTexture(mat, call.image);
|
||||
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
|
||||
_uniformBuffer->aligner().getOffset(call.uniformIndex),
|
||||
sizeof(nanovg_draw_data),
|
||||
_uniformBuffer->bufferHandle());
|
||||
gr_bind_uniform_buffer(uniform_block_type::NanoVGData, _uniformBuffer.getAlignerElementOffset(call.uniformIndex),
|
||||
sizeof(nanovg_draw_data), _uniformBuffer.bufferHandle());
|
||||
|
||||
auto pathOffset = call.pathOffset;
|
||||
for (size_t i = 0; i < call.pathCount; ++i) {
|
||||
@@ -752,9 +743,8 @@ void NanoVGRenderer::drawStroke(const DrawCall& call) {
|
||||
auto mat = _strokeFillMaterial;
|
||||
materialSetTexture(mat, call.image);
|
||||
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
|
||||
_uniformBuffer->aligner().getOffset(call.uniformIndex + 1),
|
||||
sizeof(nanovg_draw_data),
|
||||
_uniformBuffer->bufferHandle());
|
||||
_uniformBuffer.getAlignerElementOffset(call.uniformIndex + 1), sizeof(nanovg_draw_data),
|
||||
_uniformBuffer.bufferHandle());
|
||||
|
||||
auto pathOffset = call.pathOffset;
|
||||
|
||||
@@ -769,10 +759,8 @@ void NanoVGRenderer::drawStroke(const DrawCall& call) {
|
||||
}
|
||||
|
||||
// Draw anti-aliased pixels.
|
||||
gr_bind_uniform_buffer(uniform_block_type::NanoVGData,
|
||||
_uniformBuffer->aligner().getOffset(call.uniformIndex),
|
||||
sizeof(nanovg_draw_data),
|
||||
_uniformBuffer->bufferHandle());
|
||||
gr_bind_uniform_buffer(uniform_block_type::NanoVGData, _uniformBuffer.getAlignerElementOffset(call.uniformIndex),
|
||||
sizeof(nanovg_draw_data), _uniformBuffer.bufferHandle());
|
||||
mat = _strokeAntiaiasMaterial;
|
||||
materialSetTexture(mat, call.image);
|
||||
for (size_t i = 0; i < call.pathCount; ++i) {
|
||||
|
||||
@@ -71,7 +71,7 @@ class NanoVGRenderer {
|
||||
int _vertexBuffer = -1;
|
||||
vertex_layout _vertexLayout;
|
||||
|
||||
util::UniformBuffer* _uniformBuffer = nullptr;
|
||||
util::UniformBuffer _uniformBuffer;
|
||||
|
||||
nanovg_material _trianglesMaterial;
|
||||
nanovg_material _triangleFillMaterial;
|
||||
|
||||
@@ -431,10 +431,8 @@ 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];
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Function from NanoVGRenderer.cpp to provide log printing capabilities here.
|
||||
extern void nvgOldCPrintf(const char *string, ...);
|
||||
#endif
|
||||
// Function from NanoVGRenderer.cpp to provide log printing capabilities here.
|
||||
extern void nvgOldCPrintf(const char *string, ...);
|
||||
// e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
|
||||
#ifndef STBTT_ifloor
|
||||
#include <math.h>
|
||||
@@ -1505,11 +1503,9 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
|
||||
stbtt_uint16 offset, start;
|
||||
stbtt_uint16 item = (stbtt_uint16)((search - endCount) >> 1);
|
||||
|
||||
#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
|
||||
if (unicode_codepoint > ttUSHORT(data + endCount + 2 * item)) {
|
||||
nvgOldCPrintf("WARNING: A font character is probably missing. Unicode decimal index is %d.\n", unicode_codepoint);
|
||||
}
|
||||
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.' \
|
||||
@@ -2130,6 +2126,13 @@ 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
|
||||
@@ -4936,4 +4939,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.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
*/
|
||||
@@ -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, &data_out->viewMatrix, &data_out->modelMatrix);
|
||||
vm_matrix4_x_matrix4(&data_out->modelViewMatrix, &gr_view_matrix, &scaled_matrix);
|
||||
data_out->projMatrix = gr_projection_matrix;
|
||||
data_out->textureMatrix = gr_texture_matrix;
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
#include "UniformAligner.h"
|
||||
|
||||
namespace {
|
||||
namespace graphics {
|
||||
namespace util {
|
||||
|
||||
size_t alignSize(size_t size, size_t align) {
|
||||
if (align == 0) {
|
||||
@@ -18,51 +19,43 @@ 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!");
|
||||
|
||||
namespace graphics {
|
||||
namespace util {
|
||||
auto el_offset = _buffer_offset;
|
||||
|
||||
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);
|
||||
_buffer_offset += alignSize(_dataSize, _requiredAlignment);
|
||||
++_numElements;
|
||||
|
||||
return getElement(_numElements - 1);
|
||||
return reinterpret_cast<void*>(_buffer + el_offset);
|
||||
}
|
||||
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.data() + offset);
|
||||
return reinterpret_cast<void*>(_buffer + 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) {
|
||||
uint8_t* current = reinterpret_cast<uint8_t*>(currentEl);
|
||||
auto current = reinterpret_cast<uint8_t*>(currentEl);
|
||||
|
||||
current += alignSize(_dataSize, _requiredAlignment);
|
||||
|
||||
@@ -71,17 +64,15 @@ void* UniformAligner::nextElement(void* currentEl) {
|
||||
size_t UniformAligner::getNumElements() {
|
||||
return _numElements;
|
||||
}
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@
|
||||
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
|
||||
*/
|
||||
@@ -18,26 +20,29 @@ class UniformAligner {
|
||||
|
||||
size_t _requiredAlignment = 1;
|
||||
|
||||
std::vector<uint8_t> _buffer;
|
||||
size_t _numElements;
|
||||
uint8_t* _buffer = nullptr;
|
||||
size_t _buffer_size = 0;
|
||||
|
||||
size_t _buffer_offset = 0;
|
||||
size_t _numElements = 0;
|
||||
|
||||
size_t _dataSize = 0;
|
||||
size_t _headerSize = 0;
|
||||
public:
|
||||
UniformAligner(size_t dataSize, size_t headerSize = 0);
|
||||
|
||||
void setAlignment(size_t align);
|
||||
|
||||
void resize(size_t num_elements);
|
||||
|
||||
void clear();
|
||||
public:
|
||||
UniformAligner();
|
||||
UniformAligner(uint8_t* buffer, size_t buffer_size, size_t dataSize, size_t headerSize, size_t element_alignment);
|
||||
|
||||
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.");
|
||||
"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*>(addElement());
|
||||
}
|
||||
@@ -45,8 +50,11 @@ 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.data());
|
||||
return reinterpret_cast<THeader*>(_buffer);
|
||||
}
|
||||
|
||||
void* getElement(size_t index);
|
||||
@@ -55,6 +63,9 @@ 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));
|
||||
}
|
||||
@@ -71,6 +82,9 @@ 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)));
|
||||
}
|
||||
@@ -86,6 +100,16 @@ 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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,72 +1,24 @@
|
||||
#include "UniformBuffer.h"
|
||||
#include "UniformBufferManager.h"
|
||||
|
||||
namespace graphics {
|
||||
namespace util {
|
||||
|
||||
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;
|
||||
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() {
|
||||
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;
|
||||
}
|
||||
|
||||
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()); }
|
||||
}
|
||||
}
|
||||
@@ -7,55 +7,79 @@
|
||||
namespace graphics {
|
||||
namespace util {
|
||||
|
||||
class UniformBufferManager;
|
||||
|
||||
/**
|
||||
* @brief Manages a single uniform buffer
|
||||
* @brief Manages a uniform buffer memory range
|
||||
*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
class UniformBuffer {
|
||||
int _buffer_obj = -1;
|
||||
UniformBufferManager* _parent = nullptr;
|
||||
size_t _parent_offset = 0;
|
||||
|
||||
int _buffer_handle = -1;
|
||||
|
||||
UniformAligner _aligner;
|
||||
|
||||
gr_sync _sync_obj = nullptr;
|
||||
public:
|
||||
UniformBuffer(size_t element_size, size_t header_size = 0);
|
||||
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);
|
||||
~UniformBuffer();
|
||||
|
||||
UniformBuffer(const UniformBuffer&) = delete;
|
||||
UniformBuffer& operator=(const UniformBuffer&) = delete;
|
||||
|
||||
UniformBuffer(UniformBuffer&& other) SCP_NOEXCEPT;
|
||||
UniformBuffer& operator=(UniformBuffer&& other) SCP_NOEXCEPT;
|
||||
UniformBuffer(UniformBuffer&&) = default;
|
||||
UniformBuffer& operator=(UniformBuffer&&) = default;
|
||||
|
||||
inline UniformAligner& aligner() {
|
||||
return _aligner;
|
||||
}
|
||||
|
||||
inline int bufferHandle() {
|
||||
return _buffer_obj;
|
||||
}
|
||||
/**
|
||||
* @brief Gets the buffer handle for use with gr_bind_uniform_buffer.
|
||||
* @return The buffer handle
|
||||
*/
|
||||
int bufferHandle();
|
||||
|
||||
/**
|
||||
* @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 Signal that the code is done using this uniform buffer
|
||||
* @brief Given the offset into the memory buffer, returns the total offset in the 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".
|
||||
* 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.
|
||||
*/
|
||||
void finished();
|
||||
size_t getBufferOffset(size_t localOffset);
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @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.
|
||||
*/
|
||||
bool isInUse();
|
||||
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();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
#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);
|
||||
@@ -15,6 +18,8 @@ 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!");
|
||||
@@ -22,7 +27,8 @@ 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);
|
||||
@@ -30,6 +36,8 @@ 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:
|
||||
@@ -38,50 +46,165 @@ 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!");
|
||||
|
||||
UniformBufferManager::UniformBufferManager(uniform_block_type uniform_type) : _type(uniform_type) {
|
||||
_use_persistent_mapping = gr_is_capable(CAPABILITY_PERSISTENT_BUFFER_MAPPING);
|
||||
|
||||
_segment_fences.fill(nullptr);
|
||||
changeSegmentSize(4096);
|
||||
}
|
||||
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;
|
||||
UniformBufferManager::~UniformBufferManager()
|
||||
{
|
||||
if (_active_uniform_buffer >= 0) {
|
||||
gr_delete_buffer(_active_uniform_buffer);
|
||||
_active_uniform_buffer = -1;
|
||||
}
|
||||
|
||||
// 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& fence : _segment_fences) {
|
||||
if (fence != nullptr) {
|
||||
gr_sync_delete(fence);
|
||||
fence = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the buffers from the list
|
||||
_usedBuffers.erase(std::remove_if(_usedBuffers.begin(), _usedBuffers.end(), [](UniformBuffer* buffer) {
|
||||
return !buffer->isInUse();
|
||||
}), _usedBuffers.end());
|
||||
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();
|
||||
}
|
||||
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
Reference in new issue
Block a user