Compare commits
89 commits
Author | SHA1 | Date | |
---|---|---|---|
|
f3cd3f31d0 | ||
|
b050991ed2 | ||
|
f82569568b | ||
|
0691c5010f | ||
|
e63fbe66b8 | ||
|
a8fc1cee8f | ||
|
b0e3f59c07 | ||
|
19b2070c19 | ||
|
49fc3d70c2 | ||
|
42cfb157a2 | ||
|
06d919b410 | ||
|
8fd317ab4c | ||
|
08c81e5693 | ||
|
0f4b6e7245 | ||
|
2b20aadda5 | ||
|
b78becde4c | ||
|
dda5e3f499 | ||
|
e1e443dbe1 | ||
|
c8f09d4ac7 | ||
|
da119a30c6 | ||
|
8a6cef6c71 | ||
|
c41ac185cc | ||
|
15285e268a | ||
|
60e670f12a | ||
|
384fd0cca1 | ||
|
4aef5c1dd4 | ||
|
57a75f8b08 | ||
|
3ee8ef55ef | ||
|
c30bff8c67 | ||
|
a18b9e6bad | ||
|
cc5f1d9fd2 | ||
|
63963058df | ||
|
63b84a8b8e | ||
|
a97caf0836 | ||
|
f3192be0f8 | ||
|
565d3e3fc1 | ||
|
46cb46630d | ||
|
0110a624a3 | ||
|
79f046abf7 | ||
|
a0d7198dd0 | ||
|
46052a9526 | ||
|
2d068377ae | ||
|
ab333c68c3 | ||
|
92310f66f0 | ||
|
eefdd8343e | ||
|
09b1ede069 | ||
|
e3795a36e0 | ||
|
c23d819f5e | ||
|
a0b52bd700 | ||
|
ce4e6f076f | ||
|
56c1a093e5 | ||
|
a04b1a5670 | ||
|
3d921a0aa5 | ||
|
b8e701b5e1 | ||
|
d94bb42d50 | ||
|
218813efb3 | ||
|
373f59c484 | ||
|
47d803b4fe | ||
|
8bddc84e62 | ||
|
5c9d9ff53c | ||
|
3ad384a0da | ||
|
76a9fdcebe | ||
|
fb3f0cc2b4 | ||
|
af13c20614 | ||
|
21f2e3a56a | ||
|
81cab591da | ||
|
97edc598c1 | ||
|
c142dac6f7 | ||
|
81ba620984 | ||
|
7354fff406 | ||
|
3a6210b154 | ||
|
6181f24c44 | ||
|
19f28e3c2d | ||
|
08a8945bdf | ||
|
01ea89ab3b | ||
|
b3be9f7b31 | ||
|
1a1962088d | ||
|
5d3f143220 | ||
|
0b0a08d7c4 | ||
|
60ec3141cf | ||
|
9f21cea354 | ||
|
9dffb367e2 | ||
|
6bcd18e269 | ||
|
c7ad16103b | ||
|
e0e772ef92 | ||
|
0af60549ab | ||
|
872905f300 | ||
|
8863c36067 | ||
|
2f9e52a804 |
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Report a problem with dhewm3
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- NOTE: Please check the existing bug reports first to find out if it has already been reported. In that case, just add a comment there with your additional information -->
|
||||
|
||||
**Describe the bug**
|
||||
A short description of what the bug is.
|
||||
|
||||
**Your System**
|
||||
- What **operating system** are you using, what CPU and GPU, which GPU driver version?
|
||||
- What **version of dhewm3** are you using? (Also: Official download? Package from Linux distro? MacSourcePorts? Did you compile yourself?)
|
||||
|
||||
**To Reproduce**
|
||||
Describe how to reproduce the bug
|
||||
- if it happens while playing: What mod (base game, RoE, or some 3rd-party mod), which level, what do you do there to trigger the bug
|
||||
- After opening the console (`Shift`+`Esc`) you can enter `map` to print the current map name and `where` to print the coordinates in the level
|
||||
- if it happens in the menu or similar: describe the steps to trigger the bug
|
||||
|
||||
**Expected and actual behavior**
|
||||
A clear and concise description of what you expected to happen and what happens instead
|
||||
|
||||
**Additional information**
|
||||
If applicable, add screenshots or a video to help explain your problem.
|
||||
Please attach [dhewm3log.txt](https://github.com/dhewm/dhewm3/wiki/FAQ#where-do-i-find-the-config-files-and-savegames-and-dhewm3logtxt)
|
||||
A **savegame** also often helps to more quickly reproduce a bug
|
21
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for dhewm3
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- NOTE: Please check the existing feature requests first to see if it has already been reported. In that case, just add a comment there with your additional information/ideas -->
|
||||
|
||||
**Describe the feature you want**
|
||||
A clear and concise description of what the feature is supposed to do.
|
||||
Add screenshots or illustrations or whatever if you think it helps explaining.
|
||||
|
||||
**What problem does it solve?**
|
||||
Describe what problem the feature would solve, or how it would improve the game and,
|
||||
if a similar feature already exists, why it's not sufficient.
|
||||
|
||||
**Additional information**
|
||||
If you have ideas how it could be implemented, or what other open source projects to check out that already have the feature, or links with information about the feature or any other additional information, post it here.
|
68
.github/workflows/linux.yml
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
name: Testbuild for Linux
|
||||
run-name: testbuild_linux
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_ubuntu_x86_64:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- env: ubuntu
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install libgl1-mesa-dev libsdl2-dev libopenal-dev libcurl4-openssl-dev cmake ninja-build
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
# -DFORCE_COLORED_OUTPUT=ON ? didn't seem to work, or at least not visible on website
|
||||
cmake -G Ninja -DDEDICATED=ON ../neo/
|
||||
ninja
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
export PKGDIR="dhewm3-linux-$(git rev-parse --short HEAD)"
|
||||
echo "pkgname=$PKGDIR" >> $GITHUB_ENV
|
||||
mkdir -p publish/$PKGDIR/base
|
||||
mkdir publish/$PKGDIR/d3xp
|
||||
# Copy release assets
|
||||
cd build
|
||||
cp dhewm3 dhewm3ded base.so d3xp.so ../publish/$PKGDIR/
|
||||
cd ..
|
||||
# Copy misc assets
|
||||
cp base/gamepad.cfg publish/$PKGDIR/base/
|
||||
cp base/gamepad-d3xp.cfg publish/$PKGDIR/d3xp/
|
||||
cp COPYING.txt publish/$PKGDIR/
|
||||
# TODO: prepend to README that executables must be set executable? (and maybe commit, build, arch etc)
|
||||
echo "dhewm3 for 64bit (amd64 aka x86_64 aka x64) Linux, built $(date)" > publish/$PKGDIR/README.txt
|
||||
echo -e "from ${{ github.ref_name }} commit ${{ github.sha }}\n" >> publish/$PKGDIR/README.txt
|
||||
echo "!!! Note that you must set dhewm3(ded) executable !!!" >> publish/$PKGDIR/README.txt
|
||||
echo "! In a Terminal, in this directory, run:" >> publish/$PKGDIR/README.txt
|
||||
echo " chmod 755 dhewm3 dhewm3ded" >> publish/$PKGDIR/README.txt
|
||||
echo -e "(this is because of limitations in Githubs Workflow Actions)\n" >> publish/$PKGDIR/README.txt
|
||||
cat README.md >> publish/$PKGDIR/README.txt
|
||||
cp Changelog.md publish/$PKGDIR/Changelog.txt
|
||||
cp Configuration.md publish/$PKGDIR/Configuration.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.pkgname }}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
63
.github/workflows/macos.yml
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
name: Testbuild for MacOS
|
||||
run-name: testbuild_macos
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_macos_aarch64:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- env: macos
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
brew update
|
||||
brew install sdl2 openal-soft
|
||||
# not installing make and cmake, cmake is installed by default, make doesn't seem to be needed
|
||||
# when using cmake --build
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
# Note: not building dedicated server because it's not supported on Macs
|
||||
cmake -DOPENAL_LIBRARY="/opt/homebrew/opt/openal-soft/lib/libopenal.dylib" -DOPENAL_INCLUDE_DIR="/opt/homebrew/opt/openal-soft/include" -S neo/ -B build
|
||||
cmake --build build
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
export PKGDIR="dhewm3-macos-$(git rev-parse --short HEAD)"
|
||||
echo "pkgname=$PKGDIR" >> $GITHUB_ENV
|
||||
mkdir -p publish/$PKGDIR/base
|
||||
mkdir publish/$PKGDIR/d3xp
|
||||
# Copy release assets
|
||||
cd build
|
||||
cp -r dhewm3.app ../publish/$PKGDIR/
|
||||
cp base.dylib d3xp.dylib ../publish/$PKGDIR/
|
||||
cd ..
|
||||
# Copy misc assets
|
||||
cp base/gamepad.cfg publish/$PKGDIR/base/
|
||||
cp base/gamepad-d3xp.cfg publish/$PKGDIR/d3xp/
|
||||
cp COPYING.txt publish/$PKGDIR/
|
||||
cp README.md publish/$PKGDIR/README.txt
|
||||
cp Changelog.md publish/$PKGDIR/Changelog.txt
|
||||
cp Configuration.md publish/$PKGDIR/Configuration.txt
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.pkgname }}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
159
.github/workflows/win_msvc.yml
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
name: Testbuild for x86 and x86_64 Windows
|
||||
run-name: testbuild_windows
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_win_x86_msvc:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
# use git bash for for all steps (unless specified otherwise per step)
|
||||
shell: bash
|
||||
strategy:
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
# Download and extract dhewm3-libs
|
||||
#echo $PWD # /d/a/dhewm3/dhewm3
|
||||
# as the repo will be cloned into the directory we're currently in (O_o)
|
||||
# go one directory up to D:\a\dhewm3\ and put the dhewm3libs there
|
||||
cd ..
|
||||
# https://github.com/dhewm/dhewm3-libs/archive/refs/heads/master.zip
|
||||
# for some reason the following downloads an empty file, so use the other URL I got from
|
||||
# "Copy Download Link" in Firefox (after downloading the file there) instead
|
||||
#curl -o dhewm3libs.zip https://github.com/dhewm/dhewm3-libs/archive/refs/heads/master.zip
|
||||
curl -o dhewm3libs.zip https://codeload.github.com/dhewm/dhewm3-libs/zip/refs/heads/master
|
||||
# only unpack the stuff needed (no x86_64 stuff, no docs from share/)
|
||||
unzip dhewm3libs.zip "dhewm3-libs-master/i686-w64-mingw32/**" -x "dhewm3-libs-master/i686-w64-mingw32/share/**"
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
# build with cmake and visual studio
|
||||
#echo $PWD # /d/a/dhewm3/dhewm3
|
||||
# NOTE: not setting -G "Visual Studio 17 2022" so it just uses the default VS version it can find
|
||||
cmake -A Win32 -DDHEWM3LIBS="../dhewm3-libs-master/i686-w64-mingw32/" -DDEDICATED=ON -DTOOLS=ON -S neo/ -B build
|
||||
time cmake --build build/ --config RelWithDebInfo
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
export PKGDIR="dhewm3-win32-$(git rev-parse --short HEAD)"
|
||||
echo "pkgname=$PKGDIR" >> $GITHUB_ENV
|
||||
mkdir -p publish/$PKGDIR/base
|
||||
mkdir publish/$PKGDIR/d3xp
|
||||
# debug symbols (*.pdb) are put in a separate zip
|
||||
mkdir -p debug-syms/$PKGDIR
|
||||
# Copy release assets
|
||||
cd build/RelWithDebInfo
|
||||
cp dhewm3.exe dhewm3ded.exe base.dll d3xp.dll ../../publish/$PKGDIR/
|
||||
cp -r *.pdb ../../debug-syms/$PKGDIR/
|
||||
cd ../..
|
||||
# Copy misc assets
|
||||
cp base/gamepad.cfg publish/$PKGDIR/base/
|
||||
cp base/gamepad-d3xp.cfg publish/$PKGDIR/d3xp/
|
||||
cp COPYING.txt publish/$PKGDIR/
|
||||
echo "dhewm3 for 32bit (x86) Windows, built $(date)" > publish/$PKGDIR/README.txt
|
||||
echo -e "from ${{ github.ref_name }} commit ${{ github.sha }}\n" >> publish/$PKGDIR/README.txt
|
||||
cat README.md >> publish/$PKGDIR/README.txt
|
||||
cp Changelog.md publish/$PKGDIR/Changelog.txt
|
||||
cp Configuration.md publish/$PKGDIR/Configuration.txt
|
||||
# copy runtime libraries (SDL, OpenAL, cURL)
|
||||
cd ../dhewm3-libs-master/i686-w64-mingw32/bin/
|
||||
cp OpenAL32.dll SDL2.dll libcurl-4.dll ../../../dhewm3/publish/$PKGDIR/
|
||||
cd -
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.pkgname }}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
||||
- name: Upload testbuild debug symbols
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.pkgname }}-debugsyms
|
||||
path: debug-syms/
|
||||
if-no-files-found: error
|
||||
build_win_x86_64_msvc:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
# use git bash for for all steps (unless specified otherwise per step)
|
||||
shell: bash
|
||||
strategy:
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
# Download and extract dhewm3-libs
|
||||
#echo $PWD # /d/a/dhewm3/dhewm3
|
||||
# as the repo will be cloned into the directory we're currently in (O_o)
|
||||
# go one directory up to D:\a\dhewm3\ and put the dhewm3libs there
|
||||
cd ..
|
||||
# https://github.com/dhewm/dhewm3-libs/archive/refs/heads/master.zip
|
||||
# for some reason the following downloads an empty file, so use the other URL I got from
|
||||
# "Copy Download Link" in Firefox (after downloading the file there) instead
|
||||
#curl -o dhewm3libs.zip https://github.com/dhewm/dhewm3-libs/archive/refs/heads/master.zip
|
||||
curl -o dhewm3libs.zip https://codeload.github.com/dhewm/dhewm3-libs/zip/refs/heads/master
|
||||
# only unpack the stuff needed (no i686 stuff, no docs from share/)
|
||||
unzip dhewm3libs.zip "dhewm3-libs-master/x86_64-w64-mingw32/**" -x "dhewm3-libs-master/x86_64-w64-mingw32/share/**"
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
# build with cmake and visual studio
|
||||
#echo $PWD # /d/a/dhewm3/dhewm3
|
||||
# NOTE: not setting -G "Visual Studio 17 2022" so it just uses the default VS version it can find
|
||||
cmake -A x64 -DDHEWM3LIBS="../dhewm3-libs-master/x86_64-w64-mingw32/" -DDEDICATED=ON -DTOOLS=ON -S neo/ -B build
|
||||
time cmake --build build/ --config RelWithDebInfo
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
export PKGDIR="dhewm3-win64-$(git rev-parse --short HEAD)"
|
||||
echo "pkgname=$PKGDIR" >> $GITHUB_ENV
|
||||
#echo "PKGDIR is $PKGDIR"
|
||||
mkdir -p publish/$PKGDIR/base
|
||||
mkdir publish/$PKGDIR/d3xp
|
||||
# debug symbols (*.pdb) are put in a separate zip
|
||||
mkdir -p debug-syms/$PKGDIR
|
||||
# Copy release assets
|
||||
cd build/RelWithDebInfo
|
||||
cp dhewm3.exe dhewm3ded.exe base.dll d3xp.dll ../../publish/$PKGDIR/
|
||||
cp -r *.pdb ../../debug-syms/$PKGDIR/
|
||||
cd ../..
|
||||
# Copy misc assets
|
||||
cp base/gamepad.cfg publish/$PKGDIR/base/
|
||||
cp base/gamepad-d3xp.cfg publish/$PKGDIR/d3xp/
|
||||
cp COPYING.txt publish/$PKGDIR/
|
||||
echo "dhewm3 for 64bit (amd64 aka x86_64 aka x64) Windows, built $(date)" > publish/$PKGDIR/README.txt
|
||||
echo -e "from ${{ github.ref_name }} commit ${{ github.sha }}\n" >> publish/$PKGDIR/README.txt
|
||||
cat README.md >> publish/$PKGDIR/README.txt
|
||||
cp Changelog.md publish/$PKGDIR/Changelog.txt
|
||||
cp Configuration.md publish/$PKGDIR/Configuration.txt
|
||||
# copy runtime libraries (SDL, OpenAL, cURL)
|
||||
cd ../dhewm3-libs-master/x86_64-w64-mingw32/bin/
|
||||
cp OpenAL32.dll SDL2.dll libcurl-4.dll ../../../dhewm3/publish/$PKGDIR/
|
||||
cd -
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.pkgname }}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
||||
- name: Upload testbuild debug symbols
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.pkgname }}-debugsyms
|
||||
path: debug-syms/
|
||||
if-no-files-found: error
|
51
Changelog.md
|
@ -4,7 +4,49 @@ dhewm3 Changelog
|
|||
Note: Numbers starting with a "#" like #330 refer to the bugreport with that number
|
||||
at https://github.com/dhewm/dhewm3/issues/
|
||||
|
||||
1.5.4 (WIP)
|
||||
1.5.5 (WIP)
|
||||
------------------------------------------------------------------------
|
||||
|
||||
* Enable/disable Soft Particles when **loading** a graphics quality preset (only enabled in Ultra preset,
|
||||
though you can still configure it independently like before; #604)
|
||||
* Support BC7-compressed (BPTC) .dds textures. They offer better quality than the older S3TC/DXT/BC1-3
|
||||
texture compression standard that Doom3 always supported. Mostly relevant for high-res retexturing
|
||||
packs, because they offer similar quality as uncompressed TGAs while being smaller, using only
|
||||
a quarter of the VRAM (TGA: 4 bytes per pixel, BC7: 1 byte per pixel) and loading *significantly*
|
||||
faster because mipmaps are contained and don't have to be generated on load.
|
||||
If you have such DDS files and want to use them (instead of TGAs), you must set
|
||||
`image_usePrecompressedTextures 1` and `image_useNormalCompression 1`.
|
||||
If you want to *create* .dds files with BC7 texture data, you can use any common texture compression
|
||||
tool, **except** for **normalmaps**, those must be created with my [**customized bc7enc**](https://github.com/DanielGibson/bc7enc_rdo)
|
||||
with the `-r2a` flag! *(Because Doom3 requires that normalmaps have the red channel moved into the
|
||||
alpha channel, id confusingly called that "RXGB", and AFAIK no other tool supports that for BC7.)*
|
||||
Just like the old DXT .dds files, they must be in the `dds/` subdirectory of a mod (either directly
|
||||
in the filesystem or in a .pk4).
|
||||
* Support SDL3 (SDL2 and, to some degree, SDL1.2 are also still supported)
|
||||
* Fix bugs on 64bit Big Endian platforms (#472, #625)
|
||||
* Fixes for high-poly models (use heap allocation instead of `alloca()` for big buffers; #528)
|
||||
* Fix building dhewm3ded with newer OpenAL Soft headers (#633)
|
||||
* Better support for High-DPI mice:
|
||||
- Don't ignore mouse input on fast movement ("ridiculous mouse delta"; #616)
|
||||
- Allow setting sensitivity to values `< 1` in the dhewm3 settings menu to allow sane speeds
|
||||
for looking around with High-DPI mice (otherwise it might be way too fast)
|
||||
* Fix a crash (assertion) on start with ImGui if `SDL_GetWindowDisplayIndex()`
|
||||
or `SDL_GetDisplayDPI()` failed and the `imgui_scale` CVar was set to the default value of `-1`
|
||||
(setting it to `1` worked around the bug; #632)
|
||||
* Updated Dear ImGui to 1.91.4
|
||||
* Fix scaling of Grabber cursor in Resurrection of Evil in non-4:3 resolutions (#637)
|
||||
* Add `com_disableAutoSaves` CVar: If set to `1`, Autosaves (when starting a level) are disabled (#620)
|
||||
* Add support for "nospecular" parm of lights, enabled by setting `"allow_nospecular" "1"` in a maps
|
||||
worldspawn, or by setting the `r_allowNoSpecular` CVar to `1`.
|
||||
Note that this required changing the format of demos. dhewm3 can still play old demos, but ones
|
||||
recorded with current dhewm3 are not compatible with older dhewm3 versions, original Doom3 or
|
||||
other source ports (unless they do the same change).
|
||||
* Make sure macOS doesn't show popups for key-alternatives when pressing a key for longer while ingame
|
||||
* Windows: Show error MessageBox if dhewm3log.txt can't be created on startup (#544)
|
||||
* Running a timedemo with sound disabled (`s_noSound 1`) doesn't crash anymore (#163)
|
||||
* Show some OpenGL/GPU information in the *Video Options* tab of the *dhewm3 Settings Menu*
|
||||
|
||||
1.5.4 (2024-08-03)
|
||||
------------------------------------------------------------------------
|
||||
|
||||
* A brand new settings menu that uses [Dear ImGui](https://github.com/ocornut/imgui).
|
||||
|
@ -16,7 +58,10 @@ Note: Numbers starting with a "#" like #330 refer to the bugreport with that num
|
|||
Needs SDL2 and C++11.
|
||||
* "Soft" Particles (that don't "cut" into geometry but fade smoothly), based on code from The Dark Mod
|
||||
2.04. Can be enabled/disabled with `r_useSoftParticles`, is applied automatically for all appropriate
|
||||
particles (view-aligned, using additive or alpha blending and not too small)
|
||||
particles (view-aligned, using additive or alpha blending and not too small).
|
||||
**NOTE** that on some systems Soft Particles noticeably slow down rendering. If dhewm3 doesn't run
|
||||
as smoothly as you'd expect, try disabling them (`r_useSoftParticles 0` or in the new *Settings Menu*
|
||||
under *Video Options* -> *Use Soft Particles*)
|
||||
* `r_enableDepthCapture`: Enable capturing depth buffer to texture, needed for the soft particles.
|
||||
Can be used in custom materials by using the `"_currentDepth"` texture
|
||||
* Replaced dependency on (external) zlib with integrated [miniz](https://github.com/richgel999/miniz)
|
||||
|
@ -221,7 +266,7 @@ Note: Numbers starting with a "#" like #330 refer to the bugreport with that num
|
|||
(it did so if one of the paths, like `fs_cdpath`, was empty)
|
||||
* Don't use translation in Autosave filenames (#305)
|
||||
- In the Spanish translation all the Alpha Lab autosaves got the same name,
|
||||
now the autosave name is based on the mapename instead which is distinct
|
||||
now the autosave name is based on the mapname instead which is distinct
|
||||
|
||||
|
||||
1.5.0 (2018-12-15)
|
||||
|
|
|
@ -179,6 +179,11 @@ This can be configured with the following CVars:
|
|||
|
||||
## Other CVars added in dhewm3
|
||||
|
||||
- `com_disableAutoSaves` if set to `1`, no Autosaves are created when starting a level, and when
|
||||
restarting a level no attempt to load one will be made. Defaults to `0` (Autosaves *are* created)
|
||||
- `com_numQuicksaves` how many Quicksaves to keep - when creating a Quicksave, the oldest one gets
|
||||
overwritten. Defaults to `4`
|
||||
|
||||
- `g_hitEffect` if set to `1` (the default), mess up player camera when taking damage.
|
||||
Set to `0` if you don't like that effect.
|
||||
|
||||
|
@ -220,6 +225,11 @@ This can be configured with the following CVars:
|
|||
- `r_useCarmacksReverse` Use Z-Fail ("Carmack's Reverse") when rendering shadows (default `1`)
|
||||
- `r_useStencilOpSeparate` Use glStencilOpSeparate() (if available) when rendering shadow (default `1`)
|
||||
- `r_scaleMenusTo43` Render full-screen menus in 4:3 by adding black bars on the left/right if necessary (default `1`)
|
||||
- `r_supportNoSpecular` Allow using the "nospecular" parm of lights under certain circumstances. If set to:
|
||||
- `0` "nospecular" will always be ignored, as it's the case in Vanilla Doom3
|
||||
- `1` "nospecular" is always used, even in old maps where it changes what they look like
|
||||
- `-1` (the default) "nospecular" is only used in (new) maps that explicitly enable it
|
||||
by setting `"allow_nospecular" "1"` in the worldspawn, existing maps continue to ignore it
|
||||
- `r_glDebugContext` Enable OpenGL debug context and printing warnings/errors from the graphics driver.
|
||||
Changing that CVar requires a `vid_restart` (or set it as startup argument)
|
||||
|
||||
|
|
791
docs/GUIs.md
Normal file
|
@ -0,0 +1,791 @@
|
|||
# Doom3 GUIs and dhewm3's Extensions
|
||||
|
||||
Doom3 supports creating GUIs in their own scripting language.
|
||||
They're used for menus like the main menu or the PDA, for the HUD and also for the interactive
|
||||
(and sometimes non-interactive) user interfaces you see in the game itself.
|
||||
|
||||
iddevnet has an introduction to Doom3 GUIs: https://iddevnet.dhewm3.org/doom3/guis.html
|
||||
The ModWiki has more information, see https://modwiki.dhewm3.org/GUI_scripting and the linked pages.
|
||||
Apart from this, the .gui files shipped with Doom3 can be used as a reference.
|
||||
|
||||
[The DarkMod](https://www.thedarkmod.com) has excellent documentation on GUI scripting in their wiki,
|
||||
see https://wiki.thedarkmod.com/index.php?title=GUI_Scripting_Language and the articles linked there.
|
||||
Some of the information found there is specific to The DarkMod (due to their own changes
|
||||
and enhancements), but a lot of it applies to standard Doom3 and dhewm3 as well, and frankly I haven't
|
||||
seen any better or more comprehensive documentation of this topic yet.
|
||||
|
||||
dhewm3 includes a GUI editor (at least on Windows), but I think it doesn't even support all features
|
||||
of the original Doom3 GUIs, and it definitely doesn't support dhewm3s extensions. It might however
|
||||
still be useful to draft your GUI so you can later improve it by editing its script.
|
||||
|
||||
Furthermore, you can find some tutorials at:
|
||||
* https://www.moddb.com/games/doom-iii/tutorials/doom-3-gui-scripting-tutorials
|
||||
* https://www.moddb.com/games/doom-iii/tutorials/creating-a-new-hud
|
||||
* https://www.moddb.com/games/doom-iii/tutorials/making-a-loading-screen
|
||||
|
||||
The primary purpose of **this article** is to document dhewm3's extensions/improvements to this system.
|
||||
For this it will also describe some basics, but it is *not* a good introduction to learn GUI scripting,
|
||||
for that check out the links above.
|
||||
|
||||
## Doom3 GUIs
|
||||
|
||||
The [iddevnet article](https://iddevnet.dhewm3.org/doom3/guis.html) says
|
||||
|
||||
> After working with the Doom 3 GUIs a while you will both love and hate them.
|
||||
|
||||
That is definitely true. On the one hand, Doom3's GUI system is quite powerful, but on the other
|
||||
hand it is really verbose (the Doom3 main menu script has over 22 thousand lines of code!) and has
|
||||
annoying limitations.
|
||||
|
||||
The core limitation is that they use a fixed resolution of 640x480 internally, which kinda implies
|
||||
assuming that players screens have a 4:3 aspect ratio.
|
||||
*Side note: On the one hand, hardcoding a 4:3 resolution in 2004 isn't that surprising, as back then
|
||||
most people had a 4:3 CRT display, or maybe a 5:4 LCD display (close enough to still look ok).
|
||||
On the other hand, [John Carmack already used a 1920x1080 widescreen display in 1995](https://www.themarysue.com/1995-john-carmack-quake-monitor/)
|
||||
so he could've known better...*
|
||||
|
||||
First some **terminology**:
|
||||
- **screen:** This will refer to your **actual screen** (and its resolution) if you play in fullscreen mode,
|
||||
**or the Doom3 (operating-system-level) window** if you play in windowed mode.
|
||||
So if you play in a 1680x1050 window, the *screen size* (as used in this article) is 1680x1050
|
||||
physical pixels, even if your actual screen (display) is 1920x1200 or whatever. I call this
|
||||
screen (size) instead of window (size) to avoid confusion between Doom3's window and the windows
|
||||
*within* Doom3 that are created with GUI scripts.
|
||||
- **physical pixel:** One actual pixel on your display. If you play at FullHD resolution, Doom3 has
|
||||
1920x1080 physical pixels. GUI scripts are completely unaware of physical pixels.
|
||||
- **virtual pixel:** (My word for) a virtual pixel within Doom3's 640x480 GUI coordinate system,
|
||||
does (usually) not correspond to just one physical pixel. All coordinates and sizes of UI elements
|
||||
in Doom3 GUIs are in virtual pixels.
|
||||
- **ingame GUI:** a GUI in the game, rendered onto ingame geometry, like panels that open doors.
|
||||
- **fullscreen GUI:** a GUI that's rendered "flatly" on the screen, not within the game world.
|
||||
Examples: HUD, main menu, PDA, crosshair
|
||||
- **menu:** *Interactive* fullscreen GUI like the main menu or the PDA: Unlike *non-interactive*
|
||||
fullscreen GUIs (like HUD, crosshair) you get a mouse cursor when they're shown, so you can click things.
|
||||
|
||||
640x480 does *not* mean that it's necessarily pixelly: You can use images with higher resolutions and
|
||||
when the GUI is scaled up for your display, the images (and lines and fonts) are rendered at the
|
||||
current resolution. And because the GUIs use floats to represent coordinates, you can position GUI
|
||||
elements at arbitrary (within 640x480 ...) positions like `20.5, 54.321`.
|
||||
|
||||
*By the way:* The coordinate `(0, 0)` represents the upper left corner of the Doom3 window (or screen
|
||||
in fullscreen mode, or ingame display for ingame GUIs), and `(640, 480)` lower right corner.
|
||||
|
||||
A `rect` represents a rectangle within the GUI, as `rect x_coordinate, y_coordinate, width, height`,
|
||||
relative to the parent windowDef.
|
||||
So `rect 50, 30.5, 64, 42` is a rectangle that starts at *x coordinate `50`* (fifty virtual pixels to the right,
|
||||
from the parents upper left corner), *y coordinate `30.5`* (thirty and a half virtual pixels down)
|
||||
that is *`64` virtual pixels wide* and has a height of *`42` virtual pixels*.
|
||||
|
||||
Example:
|
||||
|
||||
```c++
|
||||
// the outer windowDef is always called Desktop.
|
||||
// all other windowDefs of this .gui file must be within the Desktop.
|
||||
windowDef Desktop {
|
||||
rect 0, 0, 640, 480 // this windowDef fills the whole screen
|
||||
backcolor 0.5, 0.5, 0.5, 1 // grey background
|
||||
background "gui/grid1" // a simple 2x2 grid texture, resolution 64x64 pixels
|
||||
// repeat the texture based on its size and the Desktop size (640x480)
|
||||
// => it's repeated 10 times to the right and 7.5 times (480/64) down
|
||||
naturalmatscale 1
|
||||
|
||||
windowDef Outer {
|
||||
// this windowDef starts at virtual pixel coordinate (20, 30)
|
||||
// with a size of 300x300 virtual pixels
|
||||
rect 20, 30, 300, 300
|
||||
backcolor 0, 0, 1, 0.5 // half-translucent blue background
|
||||
|
||||
windowDef Inner {
|
||||
// this windowDef starts at (global) virtual coordinates (25, 35)
|
||||
// (because it's contained in and thus placed relative to Outer)
|
||||
// width: 60 virtual pixels, height: 80 virtual pixels
|
||||
rect 5, 5, 60, 80
|
||||
backcolor 1, 0, 0, 1 // solid red background
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
This code results in the following GUI (open with `testGUI guis/example.gui`):
|
||||

|
||||
|
||||
### Ingame User Interfaces
|
||||
|
||||
GUIs used ingame like *Super Turbo Turkey Puncher 3*, panels to open doors etc aren't too problematic,
|
||||
because their size doesn't change, **unlike** user's displays (used to be 4:3, now 16:9 or another
|
||||
widescreen format) or the Doom3 window size in general, which can be set to any resolution.
|
||||
|
||||
Non-4:3 GUIs in the game are a bit of a PITA, but possible (and easy enough once you know how).
|
||||
Imagine you want to put an interactive 1:2 (portrait mode) display in your level.
|
||||
|
||||
1. Set `rect 0, 0, 240, 480` in your GUI's `windowDef Desktop` and only use that area.
|
||||
2. In the level editor, create a brush with that aspect ratio (e.g. 64 units high and 32 units wide).
|
||||
3. On *one* face of that brush, set `textures/common/entityGui`.
|
||||
4. In the Surface Inspector, click "Fit" and check what values it shows for Horizontal and Vertical
|
||||
Scale (e.g. 0.5 and 1).
|
||||
5. Replace the *Horizontal Scale* value with the value of itself multiplied with `640/240`
|
||||
(e.g. `0.5 * 640/240 = 1.333`; I'll explain the value below).
|
||||
5. Convert the brush to `func_static`.
|
||||
6. In the Entity Inspector, add key `gui` and value `guis/myingamethingy.gui` (or however you called it).
|
||||
7. Done!
|
||||
|
||||
So, why is the horizontal scale multiplied with `640/240` (2.6667)?
|
||||
|
||||
The `entityGui` texture represents a full 640x480 GUI. So if a face is fully covered by that texture
|
||||
(but only once, without repetitions, like you get when clicking "Fit" in the Surface Inspector),
|
||||
the whole (virtual 640x480) GUI is shown on the face - and if that face doesn't have a 4:3 aspect ratio,
|
||||
the GUI will be stretched.
|
||||
|
||||
But you want a 1:2 GUI and thus your `windowDef Desktop` only uses 240 of the 640 virtual pixels as
|
||||
width (`rect 0, 0, 240, 480`), because 480 * 1/2 = 240.
|
||||
However, you want these 240/640 virtual pixels to cover the whole face, of course.
|
||||
To achieve this, the `entityGui` texture must be stretched accordingly, and **the factor to stretch
|
||||
240 virtual pixels to 640 virtual pixels is 640/240**. So that's the factor the *Horizontal Scale*
|
||||
must be multiplied with.
|
||||
|
||||
If you instead want a **2:3 GUI**, you'd use `rect 0, 0, 320, 480` (480 * 2/3 = 320) for your Desktop and,
|
||||
again after fitting the `entityGUI` texture to the face, multiply its *Horizontal Scale* with 320/640.
|
||||
|
||||
If on the other hand you want something **wider** than 4:3, you'd mess with the *vertical* sizes instead.
|
||||
For example, if you want a **16:9 GUI** in the game, you'd use `rect 0, 0, 640, 360`, because you
|
||||
want to use the full width (640) and instead decrease the height *(otherwise you'd have to reduce
|
||||
both width and height, because you can't go higher than 640x480)*.
|
||||
Height `360` because *640 * 9/16 = 360* (it's 9/16 instead of 16/9 because this time we're modifying
|
||||
the vertical resolution).
|
||||
In the *Surface Inspector*, you'd again first click *Fit*, but this time you multiply the
|
||||
_**Vertical** Scale_ and you'd multiply it with *480/360* (the factor to stretch 360 vertical pixels
|
||||
to 480 vertical pixels).
|
||||
|
||||
Note that this should work with Vanilla Doom3 as well.
|
||||
|
||||
### Fullscreen GUIs (Menus, HUD)
|
||||
|
||||
Fullscreen GUIs like the main menu and the HUD cause more headaches. As mentioned before, Doom3
|
||||
assumes 4:3 resolutions, so when the screen *(or Doom3 window in windowed mode)* has a widescreen
|
||||
resolution, the menus get stretched.
|
||||
|
||||
The example GUI shown above looks like this on a wide screen:
|
||||

|
||||
Note how the background grid is not square and neither is the blue `windowDef`, even though it
|
||||
has a size of 300x300 virtual pixels.
|
||||
|
||||
You can't just create a widescreen GUI by using the trick described for ingame UIs, because you have
|
||||
no way to tell Doom3 how to scale the GUI - menus always assume 640x480 and if your desktop is
|
||||
smaller than that, the rest of the screen will remain black (and it is still stretched).
|
||||
Besides, your 16:9 widescreen GUI would still only work with 16:9 screens (or windows), not with 4:3
|
||||
or 32:9, so what's the point...
|
||||
|
||||
So with Classic Doom3 you're stuck with 4:3 menus that get stretched to whatever aspect ratio
|
||||
your screen uses.
|
||||
Luckily, dhewm3 has some improvements :)
|
||||
|
||||
## dhewm3 Extensions for the Doom3 GUI system
|
||||
|
||||
dhewm3 has several features to better support non-4:3 resolutions.
|
||||
|
||||
### Scaling of mMenus to 4:3 with Letter-Boxing
|
||||
|
||||
*dhewm3* scales fullscreen menus like the main menu and the PDA to 4:3 regardless of the resolution,
|
||||
leaving **black bars on the left and the right**, or if you happen to use a portrait resolution like
|
||||
9:16, it will have black bars on top and bottom ("Pillar-boxing" or "Letter-boxing").
|
||||
This feature is controlled with the `r_scaleMenusTo43` CVar: If set to `1` (the default), fullscreen
|
||||
menus are scaled to 4:3, setting it to `0` restores the old behavior of stretching the menus over
|
||||
the whole screen.
|
||||
|
||||
This is what the example GUI from above looks like when letter-boxed (or actually pillar-boxed):
|
||||

|
||||
*Note: The `testGUI` console command does not support letterboxing, I had to replace the main menu
|
||||
with the test menu to take this screenshot.*
|
||||
|
||||
For the HUD this unfortunately was not an option, because it also handles fullscreen effects like
|
||||
tinting the screen red when you're hit, with empty bars on the left/right that would look bad -
|
||||
so the HUD continued to be stretched *(except for the crosshair, it's a separate GUI that
|
||||
can be unstretched)*.
|
||||
|
||||
It's possible to explicitly enable scaling to 4:3 for non-interactive fullscreen GUIs (even if it's
|
||||
not a Menu and thus is not scaled to 4:3 by default) by setting `scaleto43 1` in its `windowDef Desktop`.
|
||||
This can also be set through code (so I didn't have to ship a modified crosshair GUI script),
|
||||
like this:
|
||||
|
||||
```c++
|
||||
idUserInterface* ui = ...; // wherever it comes from in your code
|
||||
ui->SetStateBool("scaleto43", true);
|
||||
ui->StateChanged(gameLocal.time);
|
||||
```
|
||||
|
||||
*Note* that you can not generally inject variables into GUIs from C++ like that, dhewm3 has
|
||||
special code to make the "scaleto43" case work.
|
||||
Also note that most GUIs except for the main menu store things in savegames, for them this hack
|
||||
must also be applied after loading a savegame.
|
||||
See [commit 5070b8c7](https://github.com/dhewm/dhewm3-sdk/commit/5070b8c7ec6f3a8ba1cb4123de37732f9cd9437f)
|
||||
for a full example.
|
||||
|
||||
Since dhewm3 1.5.5 *(or, if it hasn't been released yet, the current code in Git)* this also works
|
||||
the other way around: You can set `scaleto43 0` in a GUI's `windowDef Desktop` (or do it via code
|
||||
as shown above) to explicitly *disable* this scaling and letter-boxing for a menu, even if that
|
||||
feature is generally enabled (`r_scaleMenusTo43 1`), so that particlar menu *is* stretched over the
|
||||
whole screen.
|
||||
|
||||
### Aspect-Ratio-Independent GUIs Covering the whole Screen, with CstDoom3's Anchors
|
||||
|
||||
Also since dhewm3 1.5.5 *(or, if it hasn't been released yet, the current code in Git)*, the
|
||||
"HUD Aspect Correction" code from [CstDoom3 2.0](https://www.moddb.com/mods/cstdoom3) has been
|
||||
merged and more features were added to that like supporting menus (in CstDoom3 you couldn't properly
|
||||
click buttons in such a GUI, so it was only used for non-interactive fullscreen GUIs like the HUD).
|
||||
|
||||
CstDoom3 introduced some new "Window Register" variables to windowDefs.
|
||||
The most important one is **cstAnchor**. It allows "anchoring" windowDefs to specific points of the
|
||||
screen, so they stay there, no matter what resolution or aspect ratio the screen has.
|
||||
|
||||
There are two types of anchors:
|
||||
1. Anchors that ensure that the windowDef is always rendered unstretched (like it would on 4:3 screens),
|
||||
but at specific position of the screen (like top left corner or center)
|
||||
2. Anchors whose windowDefs are only stretched in one direction and keep their configured size *(as it
|
||||
would be on 4:3 screen, it's still based on the 640x480 virtual pixel system)* in the other direction.
|
||||
This allows, for example, to create a windowDef that is centered vertically with a height 120
|
||||
virtual pixels, but is stretched over the whole screen horizontally.
|
||||
|
||||
Both kinds of anchors will ensure that an anchored 640x480 `windowDef` always touches at least two
|
||||
opposing borders of the screen - either the right and left one, or the top and bottom one.
|
||||
Of course, they may (depending on the kind of anchor and screens aspect ratio) additionally touch
|
||||
one or both of the other borders as well.
|
||||
|
||||
The full list from `_cst_anchor.pd`, note that when it says "scale to 4:3" it means
|
||||
*"if the windowDef was 640x480 virtual pixels, it'd always be scaled keep 4:3 aspect ratio".*
|
||||
|
||||
```c
|
||||
// don't anchor to anything, stretch over whole screen
|
||||
// (the default, you'll probably don't set this explicitly)
|
||||
#define CST_ANCHOR_NONE -1
|
||||
|
||||
// anchor to top left corner, scale to 4:3
|
||||
#define CST_ANCHOR_TOP_LEFT 0
|
||||
// anchor to top center, scale to 4:3
|
||||
#define CST_ANCHOR_TOP_CENTER 1
|
||||
// anchor to top right corner, scale to 4:3
|
||||
#define CST_ANCHOR_TOP_RIGHT 2
|
||||
|
||||
// anchor to the center of the left window border, scale to 4:3
|
||||
#define CST_ANCHOR_CENTER_LEFT 3
|
||||
|
||||
// anchor to the center of the screen, scale to 4:3
|
||||
// (if used with "rect 0, 0, 640, 480", that will always touch
|
||||
// either the left/right or upper/lower window borders,
|
||||
// depending on the aspect ratio of Doom3's current resolution)
|
||||
#define CST_ANCHOR_CENTER_CENTER 4
|
||||
|
||||
// anchor to the center of the right window border, scale to 4:3
|
||||
#define CST_ANCHOR_CENTER_RIGHT 5
|
||||
|
||||
// anchor to bottom left corner, scale to 4:3
|
||||
#define CST_ANCHOR_BOTTOM_LEFT 6
|
||||
// anchor to bottom center, scale to 4:3
|
||||
#define CST_ANCHOR_BOTTOM_CENTER 7
|
||||
// anchor to bottom right corner, scale to 4:3
|
||||
#define CST_ANCHOR_BOTTOM_RIGHT 8
|
||||
|
||||
// anchor to the top of the screen, stretch over whole width
|
||||
#define CST_ANCHOR_TOP 9
|
||||
// anchor to the vertical center of the screen, stretch over whole width
|
||||
#define CST_ANCHOR_VCENTER 10
|
||||
// anchor to the bottom of the screen, stretch over whole width
|
||||
#define CST_ANCHOR_BOTTOM 11
|
||||
|
||||
// anchor to the left border of the screen, stretch over whole height
|
||||
#define CST_ANCHOR_LEFT 12
|
||||
// anchor to the horizontal center of the screen, stretch over whole height
|
||||
#define CST_ANCHOR_HCENTER 13
|
||||
// anchor to the right border of the screen, stretch over whole height
|
||||
#define CST_ANCHOR_RIGHT 14
|
||||
```
|
||||
|
||||
What does this mean exactly/how does it look like?
|
||||
|
||||
#### Aspect-Ratio-Preserving Anchors
|
||||
|
||||
Simple example:
|
||||
|
||||
```c++
|
||||
// this include is needed for the CST_ANCHOR_* constants
|
||||
#include "guis/_cst_anchor.pd"
|
||||
windowDef Desktop {
|
||||
rect 0, 0, 640, 480
|
||||
// this disables dhewm3's standard scaling of menus to 4:3
|
||||
// so dhewm3 doesn't do letter-boxing the Desktop gets stretched
|
||||
// over whole screen instead and we can place anchored stuff there.
|
||||
scaleto43 0
|
||||
|
||||
// add a grid background with natural scale
|
||||
// to visualize what is and isn't distorted
|
||||
background "gui/grid1"
|
||||
naturalmatscale 1
|
||||
|
||||
windowDef AnchoredArea {
|
||||
cstAnchor CST_ANCHOR_TOP_LEFT // where to anchor this area
|
||||
rect 0, 0, 640, 480 // cover the whole virtual area
|
||||
backcolor 0, 0, 1, 1 // blue background
|
||||
// again a grid with natural scale
|
||||
// (but finer, to easier tell it apart from Desktop grid)
|
||||
background "gui/grid2"
|
||||
naturalmatscale 1
|
||||
|
||||
windowDef URCorner {
|
||||
// just a yellow square in the lower right corner
|
||||
rect 580, 420, 50, 50
|
||||
backcolor 1, 1, 0, 1 // yellow
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If the screen is tall, anchoring to top-left looks like this:
|
||||

|
||||
|
||||
If the screen is wide, anchoring to top-left looks like this:
|
||||

|
||||
|
||||
If the screen has 4:3 aspect ratio, anchoring to top-left looks like this:
|
||||

|
||||
|
||||
Note how:
|
||||
* In non 4:3 modes he `Desktop` is stretched (=> its grid isn't square).
|
||||
* The `AnchorArea` retains its 4:3 aspect ratio and fills as much of the screen (or dhewm3 window)
|
||||
as possible without stretching, staying at the *top* or *left* border of the screen, like the name
|
||||
`CST_ANCHOR_TOP_LEFT` suggests.
|
||||
* The mouse cursor is not stretched either.
|
||||
* The `URCorner` child of `AnchoredArea` always is where it should be (moves and scales with its parent).
|
||||
* When the screen has a 4:3 resolution, the `AnchoredArea` has the same size as the `Desktop`
|
||||
and covers it completely.
|
||||
- This is true for **all** anchor types: A 640x480 windowDef always covers the whole screen if the
|
||||
screen has a 4:3 resolution.
|
||||
|
||||
All aspect-ratio preserving anchors (as schematics):
|
||||
|
||||
* `CST_ANCHOR_TOP_LEFT`:
|
||||
 
|
||||
* `CST_ANCHOR_TOP_CENTER`:
|
||||
 
|
||||
* `CST_ANCHOR_TOP_RIGHT`:
|
||||
 
|
||||
* `CST_ANCHOR_CENTER_LEFT`:
|
||||
 
|
||||
* `CST_ANCHOR_CENTER_CENTER`:
|
||||
 
|
||||
* `CST_ANCHOR_CENTER_RIGHT`:
|
||||
 
|
||||
* `CST_ANCHOR_BOTTOM_LEFT`:
|
||||
 
|
||||
* `CST_ANCHOR_BOTTOM_CENTER`:
|
||||
 
|
||||
* `CST_ANCHOR_BOTTOM_RIGHT`:
|
||||
 
|
||||
|
||||
#### Stretching Anchors
|
||||
|
||||
These anchors do *not* preserve the aspect ratio of a windowDef, but stretch it over the whole screen,
|
||||
either horizontally or vertically.
|
||||
If it's stretched horizontally, then its height will be the same as it would for an unstretched counterpart
|
||||
and if it's stretched vertically, its width will be the same as it would be for an unstretched counterpart.
|
||||
|
||||
##### Horizontally Stretching Anchors
|
||||
|
||||
Here's an example showing both a stretched `CST_ANCHOR_TOP` area and, for comparison, another area
|
||||
over it that's anchored to the top left corner (in an aspect-ratio preserving way).
|
||||
|
||||
```c++
|
||||
#include "guis/_cst_anchor.pd"
|
||||
windowDef Desktop {
|
||||
scaleto43 0
|
||||
|
||||
rect 0, 0, 640, 480 // cover the whole screen
|
||||
backcolor 0.5, 0.5, 0.5, 1 // grey background
|
||||
menugui 1 // this is a fullscreen menu
|
||||
|
||||
background "gui/grid1" // grid background to show what is and isn't distorted
|
||||
naturalmatscale 1 // natural scale so when the windowDef isn't stretched, the grid is square
|
||||
|
||||
windowDef AnchoredArea {
|
||||
cstAnchor CST_ANCHOR_TOP // this area is anchored to the top border of the screen
|
||||
rect 0, 0, 640, 480 // cover the whole virtual area
|
||||
backcolor 0, 0, 1, 1 // blue background
|
||||
background "gui/grid2" // again a grid (but finer, to easier tell it apart from Desktop grid)
|
||||
naturalmatscale 1 // again natural scale
|
||||
|
||||
windowDef URCorner {
|
||||
// yellow square in lower right corner of this are
|
||||
// (well, it's square when this windowDef isn't stretched)
|
||||
rect 580, 420, 50, 50
|
||||
backcolor 1, 1, 0, 1 // yellow
|
||||
}
|
||||
}
|
||||
|
||||
windowDef AnchoredAreaNotStretched {
|
||||
// half-translucent full-sized area anchored to top left corner,
|
||||
// it's aspect ratio is preserved. will look green on the blue background
|
||||
cstAnchor CST_ANCHOR_TOP_LEFT
|
||||
rect 0, 0, 640, 480
|
||||
backcolor 1, 1, 0, 0.5 // it's half translucent yellow
|
||||
// Note: this one doesn't have it's own grid, at this point you hopefully believe
|
||||
// that this kind of anchor preserves the aspect ratio ;)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here's what it looks like at different screen aspect ratios:
|
||||
|
||||

|
||||
 
|
||||

|
||||
|
||||
The half-translucent yellow (and thus green) area is the unstretched comparison area that uses
|
||||
`CST_ANCHOR_TOP_LEFT`, the blue one with the grid (that looks green where covered by the former one)
|
||||
is the area that uses the stretching `CST_ANCHOR_TOP`.
|
||||
As before, the grey area with the bigger grid is the `windowDef Desktop` area that's stretched over
|
||||
the whole screen.
|
||||
|
||||
Note how:
|
||||
|
||||
* For wide screen resolutions, `CST_ANCHOR_TOP` behaves just like using no anchor at all:
|
||||
It gets stretched horizontally. That's why the grey background is not visible at all
|
||||
on the wide screenshot (and the 4:3 screenshot).
|
||||
* For tall screen resolutions, `CST_ANCHOR_TOP` behaves just like `CST_ANCHOR_TOP_LEFT`
|
||||
(or top center or top right): It's a 4:3 area filling the top of the screen (that's why the top area
|
||||
is green on those screenshots: The half-translucent yellow area completely covers the blue area).
|
||||
* Like with all anchors, at 4:3 screen resolutions, a 640x480 `windowDef` using `CST_ANCHOR_TOP`
|
||||
fills the whole screen.
|
||||
|
||||
When using `CST_ANCHOR_VCENTER` for the blue area (`AnchoredArea`) and `CST_ANCHOR_CENTER_RIGHT`
|
||||
for the yellow/green area (`AnchoredAreaNotStretched`), it looks like this:
|
||||
|
||||

|
||||

|
||||
|
||||
*(Note that the wide version looks a bit different because this time I anchored the unstretched
|
||||
yellow/green `windowDef` to the right instead of to the left.)*
|
||||
|
||||
* For wide screen resolutions, `CST_ANCHOR_VCENTER` just fills the whole screen, stretched horizontally
|
||||
(just like `CST_ANCHOR_TOP` and `CST_ANCHOR_BOTTOM` or no anchor at all).
|
||||
* For tall screen resolutions, `CST_ANCHOR_VCENTER` behaves just like `CST_ANCHOR_CENTER_RIGHT`
|
||||
(or `CST_ANCHOR_CENTER_LEFT` or `CST_ANCHOR_CENTER_CENTER`): It's a 4:3 area that uses the full
|
||||
width and the height that preserves the 4:3 aspect ratio for that width.
|
||||
* This means that `CST_ANCHOR_VCENTER` always has the same height and vertical position as the
|
||||
`CST_ANCHOR_CENTER_*` anchors *(if their `windowDef` has same the rect...)*, but may be wider.
|
||||
- **Generally:** For the same screen resolution, all the aspect-ratio-preserving anchors and the
|
||||
anchors that stretch horizontally have the same height if their windowDefs use the same rect.
|
||||
|
||||
##### Vertically Stretching Anchors
|
||||
|
||||
The remaining anchors (`CST_ANCHOR_LEFT`, `CST_ANCHOR_HCENTER`, `CST_ANCHOR_RIGHT`) stretch vertically.
|
||||
|
||||
Example with `CST_ANCHOR_LEFT` for the blue area and `CST_ANCHOR_BOTTOM_LEFT` for the
|
||||
aspect-ratio preserving yellow/green area with the finer grid - *Note* that the *solid yellow square*
|
||||
is part/a child of the blue area, though!
|
||||
|
||||

|
||||

|
||||
|
||||
Observations:
|
||||
|
||||
* For wide resolutions, `CST_ANCHOR_LEFT` behaves the same as `CST_ANCHOR_BOTTOM_LEFT`
|
||||
(or `CST_ANCHOR_CENTER_LEFT` or `CST_ANCHOR_TOP_LEFT`): A 4:3 area that uses the full height and
|
||||
the corresponding width that preserves the aspect ratio, aligned to the left border of the screen.
|
||||
* For tall resolutions, it has the same *width* as `CST_ANCHOR_BOTTOM_LEFT`, but the *height*
|
||||
stretches over the whole screen, looking the same as using no anchor at all.
|
||||
|
||||
**Generally:** `CST_ANCHOR_LEFT`, `CST_ANCHOR_HCENTER`, `CST_ANCHOR_RIGHT` use the same width as
|
||||
the aspect-ratio preserving anchors (that use the same `rect`), but their height is stretched to
|
||||
use the full height of the screen.
|
||||
|
||||
As you probably already guessed, for tall screens `CST_ANCHOR_LEFT`, `CST_ANCHOR_HCENTER` and
|
||||
`CST_ANCHOR_RIGHT` behave the same, but for wide screen they're anchored to different horizontal
|
||||
positions (left border, right border or center).
|
||||
|
||||
#### Summary for Basic Usage of CstDoom3 Anchors
|
||||
|
||||
What has been presented so far already lets you place GUI elements (`windowDefs` or other widgets)
|
||||
on all parts of the screen, without them getting stretched (or only getting stretched in one direction).
|
||||
|
||||
Keep in mind that you always operate in that 640x480 virtual pixel coordinate system, no matter
|
||||
where your `windowDef` is anchored.
|
||||
This means for example that, just like in "classic" Doom3 GUIs, if you want to place a 100x50 rectangle
|
||||
centered at the right screen border, your `windowDef` needs to use `rect 540, 215, 100, 50`:
|
||||
|
||||
* x position `540` because it should start 100 virtual pixels left of the right screen border, which
|
||||
has x position 540 (640-100 = 540).
|
||||
* y position `215` because the virtual height is 480 virtual pixels, so center is at 240 pixels
|
||||
and to center that rectangle with height 50 there you have to go 25 pixels up: 480/2 - 50/2 = 215
|
||||
|
||||
It's just that, unlike in original Doom3, you can now anchor that to `CST_ANCHOR_CENTER_RIGHT`, so
|
||||
your rectangle is always at the center of the right border *with the correct aspect ratio*
|
||||
(i.e. unstretched), no matter what aspect ratio your screen uses.
|
||||
|
||||
Some other basic things:
|
||||
|
||||
* Don't forget to `#include "guis/_cst_anchor.pd"` at the beginning of your GUI script if you want
|
||||
to use the anchors.
|
||||
- This also means that you need to make sure you have that file in the first place ;)
|
||||
* In dhewm3, remember to set `scaleto43 0` in your `windowDef Desktop` if you want to use anchors,
|
||||
so you can use the whole screen (no letterboxing).
|
||||
* You should only set `cstAnchor` in `windowDefs` that are direct children of `windowDef Desktop`.
|
||||
- **But** not in the `Desktop` itself!
|
||||
* All child defs of an anchored `windowDef` (another `windowDef` or `listDef` or `choiceDef` etc)
|
||||
are automatically anchored to the same point and scaled in the same way etc, so you can write them
|
||||
just like you would in a "classic" Doom3 GUI.
|
||||
* The `cst_hudAdjustAspect` CVar enables/disables (all) anchoring. In CstDoom3 it's disabled (`0`) by
|
||||
default, in dhewm3 it's enabled (`1`) by default. If anchoring is disabled, anchored windowDefs are
|
||||
still rendered, but they'll be stretched and positioned just like they would if you hadn't set an anchor.
|
||||
* In CstDoom3 you can only use anchors for non-interactive GUIs (like the HUD), dhewm3 also allows
|
||||
using anchors in fullscreen menus like that main menu, the PDA or the restart window.
|
||||
* You can easily test your GUIs by entering `testGUI guis/mygui.gui` in the console (adjust the path
|
||||
and name of your GUI accordingly). Pressing `Esc` exits it.
|
||||
* If you have edited your GUI, you don't have to restart Doom3, you can just enter `reloadGuis` in
|
||||
the console and they will be reloaded so you can test your latest changes.
|
||||
|
||||
### More CstDoom3 Anchor Features
|
||||
|
||||
CstDoom3 introduced two more features that I haven't mentioned yet.
|
||||
|
||||
#### `cstAnchorTo` and `cstAnchorFactor` for Transitions between Anchors
|
||||
|
||||
Two new Window Register variables I haven't mentioned yet are **`cstAnchorTo`** and **`cstAnchorFactor`**.
|
||||
To be honest, I haven't used them myself yet so I'll just post the description that *fva*,
|
||||
the CstDoom3 author, sent us:
|
||||
|
||||
> Besides `cstAnchor`, there are two other "Window Register" variables: `cstAnchorTo` and `cstAnchorFactor`.
|
||||
> These should be used if you want to transition a window smoothly from one anchor to another.
|
||||
> `cstAnchorTo` is the destination anchor and can be assigned any of the values that can be assigned
|
||||
> to `cstAnchor`.
|
||||
> `cstAnchorFactor` is a number from 0.0 to 1.0 that controls the interpolation between `cstAnchor`
|
||||
> and `cstAnchorTo`. If `cstAnchorTo` is set to `CST_ANCHOR_NONE` (this is the default), then the
|
||||
> interpolation scheme is disabled. In CstDoom3, these variables are used to handle the hud
|
||||
> animations when picking up a pda or video disc, and when a new email is received (like when you
|
||||
> click on Download on those monitors in Mars City 1).
|
||||
> After the interpolation is complete (that is, after you varied `cstAnchorFactor` from 0 to 1),
|
||||
> you should change `cstAnchor` to the destination value (that is, the value assigned to
|
||||
> `cstAnchorTo`) and then set `cstAnchorTo` to `CST_ANCHOR_NONE`.
|
||||
|
||||
#### `cstNoClipBackground` to Break Out of Parent `windowDef`
|
||||
|
||||
The **second** feature is that you can set **`cstNoClipBackground 1`** as "Window Register" variable
|
||||
of a `windowDef`.
|
||||
It allows a `windowDef` to be bigger than its parent, without being cut off at the parent's borders.
|
||||
This even allows you to use more than 640x480 virtual pixels after all! (Not for the `Desktop` though.)
|
||||
|
||||
Virtual pixels still have the same size as before, but for example if your `windowDef` is anchored
|
||||
to the left border, you could use X coordinates > 640 to render things that will only be visible
|
||||
in widescreen modes. In fact, it's even possible to use negative X coordinates to enhance the `windowDef`
|
||||
to the left (more useful when anchored to the right screen border or the center).
|
||||
|
||||
**However** you should **_not_ use `cstNoClipBackground`** with windowDefs that
|
||||
**interact with the mousecursor!**
|
||||
The cursor coordinates will be wonky and it probably won't work very well.
|
||||
I'd suggest using `cstNoClipBackground 1` only together with `noevents 1`.
|
||||
|
||||
I think it's still very useful for backgrounds and similar non-interactive elements of the GUI.
|
||||
In fact, what would be the point in using it for interactive ones - buttons etc tend to be a lot
|
||||
smaller and are better suited to be anchored to specific locations.
|
||||
|
||||
But then again - this could be a lot more useful if we knew the aspect ratio or screen size, right?
|
||||
This leads us to the next chapter..
|
||||
|
||||
### dhewm3 Extensions for the Anchor System
|
||||
|
||||
Two changes that don't need much explaining are that in dhewm3, unlike in CstDoom3, you can use
|
||||
anchors in interactive GUIs (that have clickable buttons etc) and that anchored renderDefs have the
|
||||
correct aspect-ratio.
|
||||
|
||||
#### New GUI Variables for Anchoring
|
||||
|
||||
Another change is that there are some new GUI variables that are set (and updated) from the engine
|
||||
code based on the current screen resolution:
|
||||
|
||||
* `gui::cstAspectRatio`: The screen aspect ratio (for 16:9 it's 16/9 = 1.7777).
|
||||
* `gui::cstWidth`: The screen width in unstretched **virtual** pixels.
|
||||
- For aspect ratios **wider** than 4:3, it's `480 * gui::cstAspectRatio`, otherwise just `640`.
|
||||
* `gui::cstHeight`: The screen height in unstretched **virtual** pixels.
|
||||
- For aspect ratios **narrower** than 4:3, it's `640 / gui::cstAspectRatio`, otherwise just `480`.
|
||||
* `gui::cstHorPad`: The horizontal padding between the left or right screen border and a 640x480
|
||||
`windowDef` anchored to `CST_ANCHOR_CENTER_CENTER`. It's just `(gui::cstWidth - 640)/2`,
|
||||
provided for convenience.
|
||||
- For tall screen resolutions, it's `0`.
|
||||
* `gui::cstVertPad`: The vertical padding between the top or bottom screen border and a 640x480
|
||||
`windowDef` anchored to `CST_ANCHOR_CENTER_CENTER`. It's just `(gui::cstHeight - 480)/2`,
|
||||
provided for convenience.
|
||||
- For widescreen resolutions, it's `0`.
|
||||
|
||||
A nice thing about Doom3 GUIs is that you can use these variables in windowDefs, and those
|
||||
will be updated automatically when the variable changes (well, at least for the `rect`, didn't test
|
||||
it for anything else).
|
||||
With this you can do neat things like this:
|
||||
|
||||
```c++
|
||||
#include "guis/_cst_anchor.pd"
|
||||
windowDef Desktop {
|
||||
rect 0, 0, 640, 480 // cover the whole screen
|
||||
scaleto43 0 // no letterboxing
|
||||
backcolor 0, 0, 0, 1 // black, or whatever
|
||||
menugui 1
|
||||
|
||||
windowDef BackGround {
|
||||
cstAnchor CST_ANCHOR_TOP_LEFT
|
||||
rect 0, 0, "gui::cstWidth", "gui::cstHeight"
|
||||
cstNoClipBackground 1 // so this windowDef can actually be > 640x480..
|
||||
noevents 1 // .. which means it should take no events
|
||||
|
||||
// set a texture that tiles (repeats endlessly and seamlessly in both directions)
|
||||
background "gui/grid1"
|
||||
|
||||
// this makes the texture repeat based on its size (in real pixels)
|
||||
// and the windowDefs size (in virtual pixels),
|
||||
// preserving the textures aspect ratio
|
||||
naturalmatscale 1
|
||||
}
|
||||
|
||||
// ... your other windowDefs with buttons and whatever else your GUI needs
|
||||
}
|
||||
```
|
||||
|
||||
This sets an unstretched(!) background texture over the whole screen, repeating as aften as
|
||||
necessary to fit the screen. Wouldn't have been possible without the new variables and CstDoom3's
|
||||
anchor system!
|
||||
|
||||
Another usecase is to display things only in the "letter-box" bars, if you anchor the main part
|
||||
of your menu to the center (especially useful when modifying existing comples GUIs, like the Doom3
|
||||
mainmenu, to be widescreen-friendly). For example, if your existing menu has a half-translucent
|
||||
grey bar on the bottom of the centered area (kinda like the doom3 main menu...), and you want to
|
||||
continue that to the borders of the screen, you could add something like:
|
||||
|
||||
```c++
|
||||
windowDef LowerGreyBarLeft {
|
||||
cstAnchor CST_ANCHOR_CENTER_LEFT
|
||||
// assuming the position is 400 virtual pixels down
|
||||
// and it should be 40 virtual pixels high
|
||||
rect 0, 400, "gui::cstHorPad", 40
|
||||
|
||||
// in case the screen is so wide that the left bar
|
||||
// is wider than 640 virtual pixels
|
||||
cstNoClipBackground 1
|
||||
// no events with cstNoClipBackground; this is just for optics anyway
|
||||
noevents 1
|
||||
backcolor 0.6, 0.6, 0.6, 0.2 // or whatever color
|
||||
}
|
||||
|
||||
windowDef LowerGreyBarRight {
|
||||
cstAnchor CST_ANCHOR_CENTER_RIGHT
|
||||
// again, 400 virtual pixels down, 40 virtual pixels wide
|
||||
rect 640 - "gui::cstHorPad", 400, "gui::cstHorPad", 40
|
||||
|
||||
cstNoClipBackground 1 // stretch as wide as needed
|
||||
noevents 1
|
||||
backcolor 0.6, 0.6, 0.6, 0.2 // or whatever color
|
||||
}
|
||||
```
|
||||
|
||||
If the screen has an aspect ratio of 4:3 or narrower (taller), `"gui::cstHorPad"` will be `0`
|
||||
and those windowDefs will be invisible.
|
||||
|
||||
Also note how you can't only use the variable in the rect, but even do calculations with it,
|
||||
like `640 - "gui::cstHorPad"`! Pretty cool IMHO (and Doom3 already supported this, dhewm3 only
|
||||
added new variables).
|
||||
|
||||
#### New Named Event CstScreenSizeChange
|
||||
|
||||
Related to the new variables, dhewm3 adds a new Named Event `CstScreenSizeChange` that gets
|
||||
called whenever the variables are updated (i.e. the screen/Doom3 window has been resized or
|
||||
resolution switched).
|
||||
Note that it does not get called before (or when) the GUI is opened/activated, but only if the
|
||||
screen size changes while the GUI is opened.
|
||||
You can use it if you want to do specific things when the aspect ratio has changed, that can't be
|
||||
handled by just the automatically updated `windowDef` `rect` using the variables.
|
||||
|
||||
Example:
|
||||
|
||||
```c++
|
||||
onNamedEvent CstScreenSizeChange {
|
||||
set "print" "Called CstScreenSizeChange - Width:" "gui::cstWidth" "Height:" "gui::cstHeight";
|
||||
// and show or hide elements or whatever you want to do here
|
||||
}
|
||||
```
|
||||
|
||||
#### Debug Printing from Scripts into Doom3 Console
|
||||
|
||||
Oh right, this **debug printing function** with `set "print"` has also been added to dhewm3, it will
|
||||
print lines like
|
||||
`GUI debug: Called CstScreenSizeChange - Width: 768.000000 Height: 480.000000`
|
||||
to the Doom3 Console (and dhewm3log.txt).
|
||||
|
||||
It can be used in event handlers (all those `onWhatever` things like `onActivate`, `onAction` etc)
|
||||
and can have an arbitrary number of arguments of any kind (literals, variables,windowDef properties, ...)
|
||||
or type (strings, floats, rects, colors, vec4, ...).
|
||||
Example:
|
||||
|
||||
```c++
|
||||
#include "guis/_cst_anchor.pd"
|
||||
windowDef Desktop {
|
||||
rect 0, 0, 640, 480
|
||||
scaleto43 0
|
||||
menugui 1
|
||||
backcolor 0.5, 0.5, 0.5, 1
|
||||
|
||||
windowDef SomethingAnchored {
|
||||
// just a blue rect that's always 20 virtual pixels from the borders
|
||||
cstAnchor CST_ANCHOR_TOP_LEFT
|
||||
rect 20, 20, "gui::cstWidth" - 40, "gui::cstHeight" - 40
|
||||
cstNoClipBackground 1
|
||||
noevents 1
|
||||
backcolor 0, 0, 1, 1
|
||||
}
|
||||
|
||||
windowDef Button {
|
||||
cstAnchor CST_ANCHOR_CENTER_CENTER
|
||||
rect 100, 50, 200, 50
|
||||
backcolor 1, 0, 0, 1
|
||||
text "Click me!"
|
||||
|
||||
onAction {
|
||||
set "print" "Just some string, now a number:" 42 "blue rect:" "$SomethingAnchored::rect"
|
||||
"aspectratio:" "gui::cstAspectRatio" "my color:" "$backcolor";
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Which, when clicking the button, prints something like:
|
||||
`GUI debug: Just some string, now a number: 42 blue rect: 20 20 728 440 aspectratio: 1.600000 my color: 0.5 0.5 0.5 1`
|
||||
|
||||
#### Using `naturalmatscale` with `matscalex` and `matscaley`
|
||||
|
||||
So far one could only use *either* `naturalmatscale` *or* `matscalex`/`matscaley`.
|
||||
|
||||
`"naturalmatscale 1"` lets a texture repeat in its native size, so if you have a 64x32 texture
|
||||
and a 320x160 windowDef, it will be repeated 5 times in each direction.
|
||||
If you resize the windowDef to 384x160, it will repeat the texture 6 times horizontally
|
||||
(and still 5 times vertically).
|
||||
|
||||
In dhewm3 1.5.5 *(or current git..)*, `matscalex`/`matscaley` allow scaling that texture.
|
||||
If both values are set to 2, (and `naturalmatscale` to `1`) the 64x32 texture in a 384x160 windowDef
|
||||
will be repeated 12 times horizontally and 10 times vertically, at half the size per direction.
|
||||
*Without* `naturalmatscale` it would be repeated 2 times in each direction, no matter how big
|
||||
the windowDef is.
|
||||
|
||||
### Hints for Making Existing GUIs Widescreen-Compatible
|
||||
|
||||
* If you have a complex 4:3 GUI (like Doom3's main menu) it's quite possible that it would be
|
||||
very hard to make it actually use the whole screenspace, especially interactive stuff like buttons.
|
||||
**Just anchor them to the center** (`CST_ANCHOR_CENTER_CENTER`) and extend only the background to the
|
||||
sides (or top/bottom).
|
||||
It's easiest if you can just put everything (except for the background) in one new
|
||||
`windowDef CenteredMainArea {...}` that's anchored to the center, but sometimes that's not really
|
||||
feasible because for example event handlers interact with the background (or event handlers in the
|
||||
Desktop interact with the stuff that are now in the new `windowDef CenteredMainArea`) and fixing
|
||||
them all up to use the correct names (for example with `CenteredMainArea::` prepended) would
|
||||
be too much work. In that case anchor the required top level ones individually.
|
||||
* If the **mouse cursor looks stretched** *(I think it can happen if the last windowDef isn't anchored?)*,
|
||||
it helps to put an otherwise empty windowDef at the end of the GUI (last element of
|
||||
the Desktop) and anchor it to the center (or some other aspect-ratio-preserving point), like:
|
||||
```c++
|
||||
windowDef FakeDesktop {
|
||||
rect 0, 0, 640, 480 // full size
|
||||
cstAnchor CST_ANCHOR_CENTER_CENTER // anchored
|
||||
// otherwise empty
|
||||
}
|
||||
```
|
61
docs/img/d3gui-cst-bl-high.svg
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="120"
|
||||
height="160"
|
||||
viewBox="0 0 31.749999 42.333333"
|
||||
version="1.1"
|
||||
id="svg2623"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="d3gui-cst-bl-high.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview2625"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="true"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="43.375"
|
||||
inkscape:cy="89.375"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1384"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="33"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2629" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2620" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#808080;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none;fill-opacity:1"
|
||||
id="rect2631"
|
||||
width="31.75"
|
||||
height="42.333332"
|
||||
x="0"
|
||||
y="0" />
|
||||
<rect
|
||||
style="fill:#0000ff;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none"
|
||||
id="rect2627"
|
||||
width="31.75"
|
||||
height="23.8125"
|
||||
x="-3.7599551e-15"
|
||||
y="18.520834" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
BIN
docs/img/d3gui-cst-center-high.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
docs/img/d3gui-cst-center-wide.png
Normal file
After Width: | Height: | Size: 22 KiB |
61
docs/img/d3gui-cst-cl-high.svg
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="120"
|
||||
height="160"
|
||||
viewBox="0 0 31.749999 42.333333"
|
||||
version="1.1"
|
||||
id="svg2623"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="d3gui-cst-cl-high.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview2625"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="true"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="43.375"
|
||||
inkscape:cy="89.375"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1384"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="33"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2629" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2620" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#808080;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none;fill-opacity:1"
|
||||
id="rect2631"
|
||||
width="31.75"
|
||||
height="42.333332"
|
||||
x="0"
|
||||
y="0" />
|
||||
<rect
|
||||
style="fill:#0000ff;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none"
|
||||
id="rect2627"
|
||||
width="31.75"
|
||||
height="23.8125"
|
||||
x="0"
|
||||
y="9.260417" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
BIN
docs/img/d3gui-cst-left-high.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
docs/img/d3gui-cst-left-wide.png
Normal file
After Width: | Height: | Size: 59 KiB |
63
docs/img/d3gui-cst-tc-wide.svg
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="240"
|
||||
height="120"
|
||||
viewBox="0 0 63.500012 31.75"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="d3gui-cst-tc-wide.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="true"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="21.125"
|
||||
inkscape:cy="95.375"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1384"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="33"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid113"
|
||||
originx="0"
|
||||
originy="0" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#808080;fill-opacity:1;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="rect111"
|
||||
width="63.5"
|
||||
height="31.749998"
|
||||
x="5.1748577e-07"
|
||||
y="5.1748583e-07" />
|
||||
<rect
|
||||
style="fill:#0000ff;fill-opacity:1;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="rect954"
|
||||
width="42.333332"
|
||||
height="31.75"
|
||||
x="10.583334"
|
||||
y="-1.0587912e-22" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
BIN
docs/img/d3gui-cst-tl-43.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
BIN
docs/img/d3gui-cst-tl-high.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
31
docs/img/d3gui-cst-tl-high.svg
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="120"
|
||||
height="160"
|
||||
viewBox="0 0 31.749999 42.333333"
|
||||
version="1.1"
|
||||
id="svg2623"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs2620" />
|
||||
<g
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#808080;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none;fill-opacity:1"
|
||||
id="rect2631"
|
||||
width="31.75"
|
||||
height="42.333332"
|
||||
x="0"
|
||||
y="0" />
|
||||
<rect
|
||||
style="fill:#0000ff;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none"
|
||||
id="rect2627"
|
||||
width="31.75"
|
||||
height="23.8125"
|
||||
x="2.0341508e-08"
|
||||
y="2.0341512e-08" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 779 B |
BIN
docs/img/d3gui-cst-tl-wide.png
Normal file
After Width: | Height: | Size: 14 KiB |
63
docs/img/d3gui-cst-tl-wide.svg
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="240"
|
||||
height="120"
|
||||
viewBox="0 0 63.500012 31.75"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="d3gui-cst-tl-wide.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="true"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="21.125"
|
||||
inkscape:cy="95.375"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1384"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="33"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid113"
|
||||
originx="0"
|
||||
originy="0" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#808080;fill-opacity:1;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="rect111"
|
||||
width="63.5"
|
||||
height="31.749998"
|
||||
x="5.1748577e-07"
|
||||
y="5.1748583e-07" />
|
||||
<rect
|
||||
style="fill:#0000ff;fill-opacity:1;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="rect954"
|
||||
width="42.333332"
|
||||
height="31.75"
|
||||
x="5.6509089e-07"
|
||||
y="5.6509089e-07" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
BIN
docs/img/d3gui-cst-top-43.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
docs/img/d3gui-cst-top-high.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
docs/img/d3gui-cst-top-higher.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
docs/img/d3gui-cst-top-wide.png
Normal file
After Width: | Height: | Size: 11 KiB |
63
docs/img/d3gui-cst-tr-wide.svg
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="240"
|
||||
height="120"
|
||||
viewBox="0 0 63.500012 31.75"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
sodipodi:docname="d3gui-cst-tr-wide.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="true"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="21.125"
|
||||
inkscape:cy="95.375"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1384"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="33"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid113"
|
||||
originx="0"
|
||||
originy="0" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#808080;fill-opacity:1;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="rect111"
|
||||
width="63.5"
|
||||
height="31.749998"
|
||||
x="5.1748577e-07"
|
||||
y="5.1748583e-07" />
|
||||
<rect
|
||||
style="fill:#0000ff;fill-opacity:1;stroke:#dfdfdf;stroke-width:0;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="rect954"
|
||||
width="42.333332"
|
||||
height="31.75"
|
||||
x="21.166668"
|
||||
y="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
BIN
docs/img/d3gui-example-16_9-letterbox.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
docs/img/d3gui-example-16_9.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
docs/img/d3gui-example-4_3.png
Normal file
After Width: | Height: | Size: 19 KiB |
|
@ -46,17 +46,19 @@ set(DHEWM3BINARY "dhewm3")
|
|||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(GNUInstallDirs OPTIONAL RESULT_VARIABLE GNUINSTALLDIRS)
|
||||
include(TestBigEndian)
|
||||
|
||||
option(CORE "Build the core" ON)
|
||||
option(BASE "Build the base game code" ON)
|
||||
option(D3XP "Build the d3xp game code" ON)
|
||||
if(MSVC)
|
||||
option(TOOLS "Build the tools game code (Visual Studio+SDL2 only)" OFF)
|
||||
option(TOOLS "Build the tools game code (Visual Studio+SDL2/SDL3 only)" OFF)
|
||||
endif()
|
||||
option(DEDICATED "Build the dedicated server" OFF)
|
||||
option(ONATIVE "Optimize for the host CPU" OFF)
|
||||
option(SDL2 "Use SDL2 instead of SDL1.2" ON)
|
||||
option(IMGUI "Build with Dear ImGui integration - requires SDL2 and C++11" ON)
|
||||
option(SDL3 "Use SDL3 instead of SDL2 or SDL1.2" OFF)
|
||||
option(IMGUI "Build with Dear ImGui integration - requires SDL2/SDL3 and C++11" ON)
|
||||
option(REPRODUCIBLE_BUILD "Replace __DATE__ and __TIME__ by hardcoded values for reproducible builds" OFF)
|
||||
|
||||
option(HARDLINK_GAME "Compile gamecode into executable (no game DLLs)" OFF)
|
||||
|
@ -193,7 +195,19 @@ endif()
|
|||
find_package(OpenAL REQUIRED)
|
||||
include_directories(${OPENAL_INCLUDE_DIR})
|
||||
|
||||
if (SDL2)
|
||||
if (SDL3)
|
||||
if(SDL2)
|
||||
message(WARNING "You enabled both SDL2 and SDL3. Only one can be used at a time, disabling SDL2")
|
||||
set(SDL2 OFF CACHE BOOL "Use SDL2 (make sure SDL3 is disabled!)" FORCE)
|
||||
endif()
|
||||
# 1. Look for a SDL3 package,
|
||||
# 2. look for the SDL3-shared component, and
|
||||
# 3. fail if the shared component cannot be found.
|
||||
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3-shared)
|
||||
# TODO: include dirs?
|
||||
set(SDLx_LIBRARY SDL3::SDL3)
|
||||
add_definitions(-DD3_SDL3=1)
|
||||
elseif (SDL2)
|
||||
# skip SDL2main
|
||||
if(APPLE OR WIN32)
|
||||
set(SDL2_BUILDING_LIBRARY TRUE)
|
||||
|
@ -217,12 +231,12 @@ if(REPRODUCIBLE_BUILD)
|
|||
endif()
|
||||
|
||||
if(IMGUI)
|
||||
if(SDL2)
|
||||
if(SDL2 OR SDL3)
|
||||
# we need C++11 for ImGui
|
||||
set (CMAKE_CXX_STANDARD 11)
|
||||
message(STATUS "Dear ImGui integration enabled")
|
||||
else()
|
||||
message(WARNING "Disabling IMGUI because SDL1.2 is used - it needs SDL2!")
|
||||
message(WARNING "Disabling IMGUI because SDL1.2 is used - it needs SDL2 or SDL3!")
|
||||
set(IMGUI OFF)
|
||||
add_definitions(-DIMGUI_DISABLE)
|
||||
endif()
|
||||
|
@ -271,19 +285,6 @@ if(NOT WIN32)
|
|||
else()
|
||||
message(WARNING "libbacktrace wasn't found. It's not required but recommended, because it provides useful backtraces if dhewm3 crashes")
|
||||
endif()
|
||||
|
||||
# check if our SDL2 supports X11 in SDL_syswm so we can use it for DPI scaling ImGui
|
||||
if(SDL2)
|
||||
set(CMAKE_REQUIRED_LIBRARIES SDL2)
|
||||
check_c_source_compiles( "#include <SDL_syswm.h>
|
||||
int main() { SDL_SysWMinfo wmInfo = {}; wmInfo.info.x11.display = NULL; return 0; }" HAVE_SDL_X11)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
if(HAVE_SDL_X11)
|
||||
message(STATUS "This SDL2 has X11 support")
|
||||
add_definitions(-DD3_SDL_X11)
|
||||
endif()
|
||||
endif()
|
||||
endif() # NOT WIN32
|
||||
|
||||
# check if this is some kind of clang (Clang, AppleClang, whatever)
|
||||
|
@ -300,6 +301,15 @@ unset(compiler_id_lower)
|
|||
|
||||
endif() # not MSVC
|
||||
|
||||
TEST_BIG_ENDIAN(is_big_endian)
|
||||
if(is_big_endian)
|
||||
message(STATUS "Detected Big Endian architecture, setting -DD3_IS_BIG_ENDIAN=1")
|
||||
add_definitions(-DD3_IS_BIG_ENDIAN=1)
|
||||
else()
|
||||
message(STATUS "Detected Little Endian architecture, setting -DD3_IS_BIG_ENDIAN=0")
|
||||
add_definitions(-DD3_IS_BIG_ENDIAN=0)
|
||||
endif()
|
||||
|
||||
# compiler specific flags
|
||||
if(D3_COMPILER_IS_GCC_OR_CLANG)
|
||||
add_compile_options(-pipe)
|
||||
|
@ -319,11 +329,18 @@ if(D3_COMPILER_IS_GCC_OR_CLANG)
|
|||
endif ()
|
||||
endif ()
|
||||
|
||||
if(cpu STREQUAL "e2k" AND CMAKE_COMPILER_IS_GNUCC)
|
||||
# O3 on E2K mcst-lcc approximately equal to O2 at X86/ARM gcc
|
||||
set(OPT_LEVEL "-O3")
|
||||
else()
|
||||
set(OPT_LEVEL "-O2")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG "-g -ggdb -D_DEBUG -O0")
|
||||
set(CMAKE_C_FLAGS_DEBUGALL "-g -ggdb -D_DEBUG")
|
||||
set(CMAKE_C_FLAGS_PROFILE "-g -ggdb -D_DEBUG -O1 -fno-omit-frame-pointer")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2 -fno-math-errno -fno-trapping-math -ffinite-math-only -fomit-frame-pointer")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -ggdb -O2 -fno-math-errno -fno-trapping-math -ffinite-math-only -fno-omit-frame-pointer")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${OPT_LEVEL} -fno-math-errno -fno-trapping-math -ffinite-math-only -fomit-frame-pointer")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -ggdb ${OPT_LEVEL} -fno-math-errno -fno-trapping-math -ffinite-math-only -fno-omit-frame-pointer")
|
||||
set(CMAKE_C_FLAGS_MINSIZEREL "-Os -fno-math-errno -fno-trapping-math -ffinite-math-only -fomit-frame-pointer")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUGALL ${CMAKE_C_FLAGS_DEBUGALL})
|
||||
|
@ -799,8 +816,14 @@ set(src_idlib
|
|||
add_globbed_headers(src_idlib "idlib")
|
||||
|
||||
if(IMGUI)
|
||||
set(src_imgui
|
||||
libs/imgui/backends/imgui_impl_sdl2.cpp
|
||||
|
||||
if(SDL3)
|
||||
set(src_imgui libs/imgui/backends/imgui_impl_sdl3.cpp)
|
||||
else()
|
||||
set(src_imgui libs/imgui/backends/imgui_impl_sdl2.cpp)
|
||||
endif()
|
||||
|
||||
set(src_imgui ${src_imgui}
|
||||
libs/imgui/backends/imgui_impl_opengl2.cpp
|
||||
|
||||
libs/imgui/imgui.h
|
||||
|
@ -1152,9 +1175,13 @@ elseif(WIN32)
|
|||
sys/win32/win_net.cpp
|
||||
sys/win32/win_shared.cpp
|
||||
sys/win32/win_syscon.cpp
|
||||
sys/win32/SDL_win32_main.c
|
||||
)
|
||||
|
||||
if(NOT SDL2 AND NOT SDL3)
|
||||
# only SDL1.2 still uses SDL_win32_main.c
|
||||
set(src_sys_base ${src_sys_base} sys/win32/SDL_win32_main.c)
|
||||
endif()
|
||||
|
||||
# adding the few relevant headers in sys/ manually..
|
||||
set(src_sys_base ${src_sys_base}
|
||||
sys/platform.h
|
||||
|
@ -1195,6 +1222,9 @@ include_directories(${CMAKE_BINARY_DIR})
|
|||
include_directories(${CMAKE_SOURCE_DIR})
|
||||
|
||||
add_library(idlib STATIC ${src_idlib})
|
||||
if(SDL3)
|
||||
target_link_libraries(idlib SDL3::Headers) # so it can use SDL_Endian.h
|
||||
endif()
|
||||
if (AROS)
|
||||
add_library(dll STATIC ${src_arosdll})
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "i386")
|
||||
|
|
|
@ -319,7 +319,10 @@ void idCollisionModelManagerLocal::TranslateTrmEdgeThroughPolygon( cm_traceWork_
|
|||
dist = normal * trmEdge->start;
|
||||
d1 = normal * start - dist;
|
||||
d2 = normal * end - dist;
|
||||
f1 = d1 / ( d1 - d2 );
|
||||
float d1d2diff = d1 - d2;
|
||||
// DG: d1 - d2 was 0 in some weird case, which caused f1 to be INF,
|
||||
// which caused NaN mayhem all over the place
|
||||
f1 = ( fabsf(d1d2diff) > idMath::FLT_EPSILON ) ? d1 / d1d2diff : 0.0f;
|
||||
//assert( f1 >= 0.0f && f1 <= 1.0f );
|
||||
tw->trace.c.point = start + f1 * ( end - start );
|
||||
// if retrieving contacts
|
||||
|
|
|
@ -26,8 +26,6 @@ If you have questions concerning this license or the applicable additional terms
|
|||
===========================================================================
|
||||
*/
|
||||
|
||||
#include <SDL_endian.h>
|
||||
|
||||
#include "sys/platform.h"
|
||||
#include "idlib/LangDict.h"
|
||||
#include "idlib/Timer.h"
|
||||
|
@ -527,7 +525,12 @@ void idGameLocal::SaveGame( idFile *f ) {
|
|||
savegame.WriteString( D3_ARCH ); // CPU architecture (e.g. "x86" or "x86_64") - from CMake
|
||||
savegame.WriteString( ENGINE_VERSION );
|
||||
savegame.WriteShort( (short)sizeof(void*) ); // tells us if it's from a 32bit (4) or 64bit system (8)
|
||||
savegame.WriteShort( SDL_BYTEORDER ) ; // SDL_LIL_ENDIAN or SDL_BIG_ENDIAN
|
||||
#if D3_IS_BIG_ENDIAN
|
||||
const short byteOrder = 4321; // SDL_BIG_ENDIAN
|
||||
#else
|
||||
const short byteOrder = 1234; // SDL_LIL_ENDIAN
|
||||
#endif
|
||||
savegame.WriteShort( byteOrder ) ;
|
||||
// DG end
|
||||
|
||||
// go through all entities and threads and add them to the object list
|
||||
|
|
|
@ -3228,13 +3228,22 @@ void idPlayer::DrawHUD( idUserInterface *_hud ) {
|
|||
if ( cursor && weapon.GetEntity()->ShowCrosshair() ) {
|
||||
|
||||
#ifdef _D3XP
|
||||
bool wantScaleTo43 = true; // DG: for fixing scaling of grabber cursor
|
||||
if ( weapon.GetEntity()->GetGrabberState() == 1 || weapon.GetEntity()->GetGrabberState() == 2 ) {
|
||||
cursor->SetStateString( "grabbercursor", "1" );
|
||||
cursor->SetStateString( "combatcursor", "0" );
|
||||
// DG: while the grabbercursor is active, the cursor must not be scaled because
|
||||
// (unlike with the regular crosshair) that distorts it when not using 4:3
|
||||
wantScaleTo43 = false;
|
||||
} else {
|
||||
cursor->SetStateString( "grabbercursor", "0" );
|
||||
cursor->SetStateString( "combatcursor", "1" );
|
||||
}
|
||||
// DG: update scaleto43 state if necessary
|
||||
if ( cursor->GetStateBool( "scaleto43" ) != wantScaleTo43 ) {
|
||||
cursor->SetStateBool( "scaleto43", wantScaleTo43 );
|
||||
cursor->StateChanged( gameLocal.realClientTime );
|
||||
}
|
||||
#endif
|
||||
|
||||
cursor->Redraw( gameLocal.realClientTime );
|
||||
|
|
|
@ -694,8 +694,44 @@ void idPlayerView::RenderPlayerView( idUserInterface *hud ) {
|
|||
ScreenFade();
|
||||
|
||||
if ( net_clientLagOMeter.GetBool() && lagoMaterial && gameLocal.isClient ) {
|
||||
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
renderSystem->DrawStretchPic( 10.0f, 380.0f, 64.0f, 64.0f, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial );
|
||||
//#modified-fva; BEGIN
|
||||
float x = 10.0f;
|
||||
float y = 380.0f;
|
||||
float w = 64.0f;
|
||||
float h = 64.0f;
|
||||
if (cvarSystem->GetCVarBool("cst_hudAdjustAspect")) {
|
||||
// similar to CST_ANCHOR_BOTTOM_LEFT
|
||||
int glWidth, glHeight;
|
||||
renderSystem->GetGLSettings(glWidth, glHeight);
|
||||
if (glWidth > 0 && glHeight > 0) {
|
||||
float glAspectRatio = (float)glWidth / (float)glHeight;
|
||||
|
||||
const float vidWidth = SCREEN_WIDTH;
|
||||
const float vidHeight = SCREEN_HEIGHT;
|
||||
const float vidAspectRatio = (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT;
|
||||
|
||||
float modWidth = vidWidth;
|
||||
float modHeight = vidHeight;
|
||||
if (glAspectRatio >= vidAspectRatio) {
|
||||
modWidth = modHeight * glAspectRatio;
|
||||
} else {
|
||||
modHeight = modWidth / glAspectRatio;
|
||||
}
|
||||
|
||||
float xScale = vidWidth / modWidth;
|
||||
float yScale = vidHeight / modHeight;
|
||||
float xOffset = 0.0f;
|
||||
float yOffset = vidHeight * (1.0f - yScale);
|
||||
|
||||
x = x * xScale + xOffset;
|
||||
y = y * yScale + yOffset;
|
||||
w *= xScale;
|
||||
h *= yScale;
|
||||
}
|
||||
}
|
||||
renderSystem->SetColor4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
renderSystem->DrawStretchPic(x, y, w, h, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial);
|
||||
//#modified-fva; END
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -539,9 +539,6 @@ const char *idAnim::AddFrameCommand( const idDeclModelDef *modelDef, int framenu
|
|||
}
|
||||
fc.type = FC_MUZZLEFLASH;
|
||||
fc.string = new idStr( token );
|
||||
} else if ( token == "muzzle_flash" ) {
|
||||
fc.type = FC_MUZZLEFLASH;
|
||||
fc.string = new idStr( "" );
|
||||
} else if ( token == "create_missile" ) {
|
||||
if( !src.ReadTokenOnLine( &token ) ) {
|
||||
return "Unexpected end of line";
|
||||
|
|
|
@ -444,10 +444,10 @@ idClass::new
|
|||
#endif
|
||||
|
||||
void * idClass::operator new( size_t s ) {
|
||||
int *p;
|
||||
intptr_t *p;
|
||||
|
||||
s += sizeof( int );
|
||||
p = (int *)Mem_Alloc( s );
|
||||
s += sizeof( intptr_t );
|
||||
p = (intptr_t *)Mem_Alloc( s );
|
||||
*p = s;
|
||||
memused += s;
|
||||
numobjects++;
|
||||
|
@ -455,7 +455,7 @@ void * idClass::operator new( size_t s ) {
|
|||
#ifdef ID_DEBUG_UNINITIALIZED_MEMORY
|
||||
unsigned int *ptr = (unsigned int *)p;
|
||||
int size = s;
|
||||
assert( ( size & 3 ) == 0 );
|
||||
assert( ( size & (sizeof(intptr_t) - 1) ) == 0 );
|
||||
size >>= 3;
|
||||
for ( int i = 1; i < size; i++ ) {
|
||||
ptr[i] = 0xcdcdcdcd;
|
||||
|
@ -466,10 +466,10 @@ void * idClass::operator new( size_t s ) {
|
|||
}
|
||||
|
||||
void * idClass::operator new( size_t s, int, int, char *, int ) {
|
||||
int *p;
|
||||
intptr_t *p;
|
||||
|
||||
s += sizeof( int );
|
||||
p = (int *)Mem_Alloc( s );
|
||||
s += sizeof( intptr_t );
|
||||
p = (intptr_t *)Mem_Alloc( s );
|
||||
*p = s;
|
||||
memused += s;
|
||||
numobjects++;
|
||||
|
@ -477,7 +477,7 @@ void * idClass::operator new( size_t s, int, int, char *, int ) {
|
|||
#ifdef ID_DEBUG_UNINITIALIZED_MEMORY
|
||||
unsigned int *ptr = (unsigned int *)p;
|
||||
int size = s;
|
||||
assert( ( size & 3 ) == 0 );
|
||||
assert( ( size & (sizeof(intptr_t) - 1) ) == 0 );
|
||||
size >>= 3;
|
||||
for ( int i = 1; i < size; i++ ) {
|
||||
ptr[i] = 0xcdcdcdcd;
|
||||
|
@ -497,10 +497,10 @@ idClass::delete
|
|||
================
|
||||
*/
|
||||
void idClass::operator delete( void *ptr ) {
|
||||
int *p;
|
||||
intptr_t *p;
|
||||
|
||||
if ( ptr ) {
|
||||
p = ( ( int * )ptr ) - 1;
|
||||
p = ( ( intptr_t * )ptr ) - 1;
|
||||
memused -= *p;
|
||||
numobjects--;
|
||||
Mem_Free( p );
|
||||
|
@ -508,10 +508,10 @@ void idClass::operator delete( void *ptr ) {
|
|||
}
|
||||
|
||||
void idClass::operator delete( void *ptr, int, int, char *, int ) {
|
||||
int *p;
|
||||
intptr_t *p;
|
||||
|
||||
if ( ptr ) {
|
||||
p = ( ( int * )ptr ) - 1;
|
||||
p = ( ( intptr_t * )ptr ) - 1;
|
||||
memused -= *p;
|
||||
numobjects--;
|
||||
Mem_Free( p );
|
||||
|
|
|
@ -65,7 +65,7 @@ const char *ui_skinArgs[] = { "skins/characters/player/marine_mp", "skins/char
|
|||
const char *ui_teamArgs[] = { "Red", "Blue", NULL };
|
||||
|
||||
struct gameVersion_s {
|
||||
gameVersion_s( void ) { sprintf( string, "%s.%d%s %s-%s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_OS, BUILD_CPU, ID__DATE__, ID__TIME__ ); }
|
||||
gameVersion_s( void ) { sprintf( string, "%s.%d%s %s-%s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_OS, D3_ARCH, ID__DATE__, ID__TIME__ ); }
|
||||
char string[256];
|
||||
} gameVersion;
|
||||
|
||||
|
|
|
@ -785,11 +785,22 @@ void idInterpreter::CallEvent( const function_t *func, int argsize ) {
|
|||
switch( format[ i ] ) {
|
||||
case D_EVENT_INTEGER :
|
||||
var.intPtr = ( int * )&localstack[ start + pos ];
|
||||
( *( int * )&data[ i ] ) = int( *var.floatPtr );
|
||||
//( *( int * )&data[ i ] ) = int( *var.floatPtr );
|
||||
// DG: for int/intrptr_t arguments, the callbacks from Callbacks.cpp pass
|
||||
// data[i] directly, not *(int*)&data[i] or some nonsense like that
|
||||
// so the integer must be assigned to the intptr_t for the value to be
|
||||
// passed correctly, esp. on 64bit Big Endian machines.
|
||||
data[ i ] = int( *var.floatPtr );
|
||||
break;
|
||||
|
||||
case D_EVENT_FLOAT :
|
||||
var.intPtr = ( int * )&localstack[ start + pos ];
|
||||
// NOTE: floats are the only type not passed as int or pointer in intptr_t,
|
||||
// but as float-data in the first 4 bytes of data[i].
|
||||
// So (unlike in the other cases), here this awkward code casting &data[i]
|
||||
// to another pointer type is actually necessary (same in CallSysEvent()).
|
||||
// In the other cases one could also use `data[i] = (intptr_t)var.blaPtr;`
|
||||
// (not doing those changes here now to minimize potential merge conflicts)
|
||||
( *( float * )&data[ i ] ) = *var.floatPtr;
|
||||
break;
|
||||
|
||||
|
@ -915,7 +926,12 @@ void idInterpreter::CallSysEvent( const function_t *func, int argsize ) {
|
|||
switch( format[ i ] ) {
|
||||
case D_EVENT_INTEGER :
|
||||
source.intPtr = ( int * )&localstack[ start + pos ];
|
||||
*( int * )&data[ i ] = int( *source.floatPtr );
|
||||
//*( int * )&data[ i ] = int( *source.floatPtr );
|
||||
// DG: for int/intrptr_t arguments, the callbacks from Callbacks.cpp pass
|
||||
// data[i] directly, not *(int*)&data[i] or some nonsense like that
|
||||
// so the integer must be assigned to the intptr_t for the value to be
|
||||
// passed correctly, esp. on 64bit Big Endian machines.
|
||||
data[ i ] = int( *source.floatPtr );
|
||||
break;
|
||||
|
||||
case D_EVENT_FLOAT :
|
||||
|
|
|
@ -146,7 +146,26 @@ ID_INLINE void idInterpreter::Push( intptr_t value ) {
|
|||
if ( localstackUsed + sizeof( intptr_t ) > LOCALSTACK_SIZE ) {
|
||||
Error( "Push: locals stack overflow\n" );
|
||||
}
|
||||
*( intptr_t * )&localstack[ localstackUsed ] = value;
|
||||
// DG: fix for 64bit Big Endian machines
|
||||
//*( intptr_t * )&localstack[ localstackUsed ] = value;
|
||||
int val = value;
|
||||
assert(value == val && "I really assumed that value would always fit into 32bit");
|
||||
// dhewm3 used to store these values on localstack[] as intptr_t, even though
|
||||
// they always seem to be int32. Unfortunately, all the code reading localstack[]
|
||||
// gets the pointer to &localstack[ localstackUsed ] and then interprets that
|
||||
// as int* or float* or whatever.
|
||||
// So with 64bit machines it's stored as the wrong size (intptr_t is int64, int is int32),
|
||||
// and on Big Endian the values are just 0 (or UINT_MAX if value < 0) - on Little Endian
|
||||
// the first 4 bytes are the ones with actual data so the bug was hidden).
|
||||
// To fix this, now a regular itn is stored at `&localstack[ localstackUsed ]`,
|
||||
// as expected by the code using localstack[].
|
||||
// TODO: once this has been tested more (and the assertion above has never triggered),
|
||||
// change idInterpreter::Push() to take a regular int argument instead of intptr_t.
|
||||
int *stackVar = ( int * )&localstack[ localstackUsed ];
|
||||
*stackVar = val;
|
||||
|
||||
// even though a 32bit int is put onto the stack, increase it by sizeof(intptr_t)
|
||||
// so it remains aligned to multiples of the native pointer size
|
||||
localstackUsed += sizeof( intptr_t );
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,12 @@ If you have questions concerning this license or the applicable additional terms
|
|||
===========================================================================
|
||||
*/
|
||||
|
||||
#include <SDL.h>
|
||||
#include "sys/sys_sdl.h"
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
// DG: compat with SDL2
|
||||
#define SDL_setenv SDL_setenv_unsafe
|
||||
#endif
|
||||
|
||||
#include "sys/platform.h"
|
||||
#include "idlib/containers/HashTable.h"
|
||||
|
@ -77,7 +82,7 @@ typedef enum {
|
|||
#endif
|
||||
|
||||
struct version_s {
|
||||
version_s( void ) { sprintf( string, "%s.%d%s %s-%s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_OS, BUILD_CPU, ID__DATE__, ID__TIME__ ); }
|
||||
version_s( void ) { sprintf( string, "%s.%d%s %s-%s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_OS, D3_ARCH, ID__DATE__, ID__TIME__ ); }
|
||||
char string[256];
|
||||
} version;
|
||||
|
||||
|
@ -1414,6 +1419,7 @@ bool OSX_GetCPUIdentification( int& cpuId, bool& oldArchitecture );
|
|||
void Com_ExecMachineSpec_f( const idCmdArgs &args ) {
|
||||
// DG: add an optional "nores" argument for "don't change the resolution" (r_mode)
|
||||
bool nores = args.Argc() > 1 && idStr::Icmp( args.Argv(1), "nores" ) == 0;
|
||||
cvarSystem->SetCVarInteger( "r_useSoftParticles", 0, CVAR_ARCHIVE ); // DG: disable soft particles for all but ultra
|
||||
if ( com_machineSpec.GetInteger() == 3 ) { // ultra
|
||||
//cvarSystem->SetCVarInteger( "image_anisotropy", 1, CVAR_ARCHIVE ); DG: redundant, set again below
|
||||
cvarSystem->SetCVarInteger( "image_lodbias", 0, CVAR_ARCHIVE );
|
||||
|
@ -1436,6 +1442,7 @@ void Com_ExecMachineSpec_f( const idCmdArgs &args ) {
|
|||
cvarSystem->SetCVarInteger( "r_mode", 5, CVAR_ARCHIVE );
|
||||
cvarSystem->SetCVarInteger( "image_useNormalCompression", 0, CVAR_ARCHIVE );
|
||||
cvarSystem->SetCVarInteger( "r_multiSamples", 0, CVAR_ARCHIVE );
|
||||
cvarSystem->SetCVarInteger( "r_useSoftParticles", 1, CVAR_ARCHIVE ); // DG: enable soft particles for ultra preset
|
||||
} else if ( com_machineSpec.GetInteger() == 2 ) { // high
|
||||
cvarSystem->SetCVarString( "image_filter", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE );
|
||||
//cvarSystem->SetCVarInteger( "image_anisotropy", 1, CVAR_ARCHIVE ); DG: redundant, set again below
|
||||
|
@ -1456,7 +1463,7 @@ void Com_ExecMachineSpec_f( const idCmdArgs &args ) {
|
|||
cvarSystem->SetCVarInteger( "s_maxSoundsPerShader", 0, CVAR_ARCHIVE );
|
||||
cvarSystem->SetCVarInteger( "image_useNormalCompression", 0, CVAR_ARCHIVE );
|
||||
if ( !nores ) // DG: added optional "nores" argument
|
||||
cvarSystem->SetCVarInteger( "", 4, CVAR_ARCHIVE );
|
||||
cvarSystem->SetCVarInteger( "r_mode", 4, CVAR_ARCHIVE );
|
||||
cvarSystem->SetCVarInteger( "r_multiSamples", 0, CVAR_ARCHIVE );
|
||||
} else if ( com_machineSpec.GetInteger() == 1 ) { // medium
|
||||
cvarSystem->SetCVarString( "image_filter", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE );
|
||||
|
@ -2681,13 +2688,27 @@ void idCommonLocal::LoadGameDLL( void ) {
|
|||
// there was no gamelib for this mod, use default one from base game
|
||||
if (!gameDLL) {
|
||||
common->Printf( "\n" );
|
||||
common->Warning( "couldn't load mod-specific %s, defaulting to base game's library!\n", dll );
|
||||
sys->DLL_GetFileName(BASE_GAMEDIR, dll, sizeof(dll));
|
||||
LoadGameDLLbyName(dll, s);
|
||||
|
||||
const char *fs_base = cvarSystem->GetCVarString("fs_game_base");
|
||||
if (fs_base && fs_base[0]) {
|
||||
common->Warning( "couldn't load mod-specific %s, defaulting to library of fs_game_base (%s)!\n", dll, fs_base);
|
||||
sys->DLL_GetFileName(fs_base, dll, sizeof(dll));
|
||||
LoadGameDLLbyName(dll, s);
|
||||
if ( !gameDLL ) {
|
||||
common->Warning( "couldn't load fs_game_base lib %s either, defaulting to base game's library!\n", dll);
|
||||
}
|
||||
} else {
|
||||
common->Warning( "couldn't load mod-specific %s, defaulting to base game's library!\n", dll );
|
||||
}
|
||||
|
||||
if ( !gameDLL ) {
|
||||
sys->DLL_GetFileName(BASE_GAMEDIR, dll, sizeof(dll));
|
||||
LoadGameDLLbyName(dll, s);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !gameDLL ) {
|
||||
common->FatalError( "couldn't load game dynamic library" );
|
||||
common->FatalError( "couldn't load game dynamic library '%s'", dll );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2797,7 +2818,12 @@ void idCommonLocal::SetMachineSpec( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
static unsigned int AsyncTimer(unsigned int interval, void *) {
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
static Uint32 AsyncTimer(void * /*userdata*/, SDL_TimerID /* timerID */, Uint32 interval)
|
||||
#else // SDL2 or SDL1.2
|
||||
static unsigned int AsyncTimer(unsigned int interval, void *)
|
||||
#endif
|
||||
{
|
||||
common->Async();
|
||||
Sys_TriggerEvent(TRIGGER_EVENT_ONE);
|
||||
|
||||
|
@ -2937,7 +2963,9 @@ void idCommonLocal::Init( int argc, char **argv ) {
|
|||
// we want to use the SDL event queue for dedicated servers. That
|
||||
// requires video to be initialized, so we just use the dummy
|
||||
// driver for headless boxen
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_SetHint(SDL_HINT_VIDEO_DRIVER, "dummy");
|
||||
#elif SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
SDL_setenv("SDL_VIDEODRIVER", "dummy", 1);
|
||||
#else
|
||||
char dummy[] = "SDL_VIDEODRIVER=dummy\0";
|
||||
|
@ -2945,13 +2973,19 @@ void idCommonLocal::Init( int argc, char **argv ) {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
if ( ! SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) )
|
||||
{
|
||||
if ( SDL_Init(SDL_INIT_VIDEO) ) { // retry without joystick/gamepad if it failed
|
||||
Sys_Printf( "WARNING: Couldn't get SDL gamepad support! Gamepads won't work!\n" );
|
||||
} else
|
||||
#elif SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) != 0)
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) == 0) { // retry without joystick/gamecontroller if it failed
|
||||
Sys_Printf( "WARNING: Couldn't get SDL gamecontroller support! Gamepads won't work!\n" );
|
||||
} else
|
||||
#else
|
||||
#else // SDL1.2
|
||||
if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) != 0) // no gamecontroller support in SDL1
|
||||
{
|
||||
#endif
|
||||
|
@ -3003,14 +3037,22 @@ void idCommonLocal::Init( int argc, char **argv ) {
|
|||
idCVar::RegisterStaticVars();
|
||||
|
||||
// print engine version
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
int sdlv = SDL_GetVersion();
|
||||
int sdlvmaj = SDL_VERSIONNUM_MAJOR(sdlv);
|
||||
int sdlvmin = SDL_VERSIONNUM_MINOR(sdlv);
|
||||
int sdlvmicro = SDL_VERSIONNUM_MICRO(sdlv);
|
||||
Printf( "%s using SDL v%d.%d.%d\n", version.string, sdlvmaj, sdlvmin, sdlvmicro );
|
||||
#else
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
SDL_version sdlv;
|
||||
SDL_GetVersion(&sdlv);
|
||||
#else
|
||||
#else
|
||||
SDL_version sdlv = *SDL_Linked_Version();
|
||||
#endif
|
||||
#endif
|
||||
Printf( "%s using SDL v%u.%u.%u\n",
|
||||
version.string, sdlv.major, sdlv.minor, sdlv.patch );
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
Printf( "SDL video driver: %s\n", SDL_GetCurrentVideoDriver() );
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <algorithm> // std::sort - TODO: replace with something custom..
|
||||
|
||||
#include <SDL.h> // to show display size
|
||||
#include "sys/sys_sdl.h"
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
|
@ -1546,7 +1546,7 @@ static void DrawOptions(CVarOption options[], int numOptions)
|
|||
static CVarOption controlOptions[] = {
|
||||
|
||||
CVarOption("Mouse Settings"),
|
||||
CVarOption("sensitivity", "Sensitivity", OT_FLOAT, 1.0f, 30.0f),
|
||||
CVarOption("sensitivity", "Sensitivity", OT_FLOAT, 0.01f, 30.0f),
|
||||
CVarOption("m_smooth", "Smoothing Samples", OT_INT, 1, 8),
|
||||
CVarOption("in_nograb", "Don't grab Mouse Cursor (for debugging/testing)", OT_BOOL),
|
||||
CVarOption("m_invertLook", [](idCVar& cvar) {
|
||||
|
@ -1674,7 +1674,8 @@ static CVarOption videoOptionsImmediately[] = {
|
|||
D3::ImGuiHooks::ShowWarningOverlay( "Capturing the Depth Buffer was disabled.\nEnabled it because soft particles need it!" );
|
||||
}
|
||||
}
|
||||
AddCVarOptionTooltips( cvar );
|
||||
const char* descr = "! Can slow down rendering !\nSoften particle transitions when player walks through them or they cross solid geometry. Needs r_enableDepthCapture.";
|
||||
AddCVarOptionTooltips( cvar, descr );
|
||||
} ),
|
||||
|
||||
CVarOption( "Advanced Options" ),
|
||||
|
@ -1705,6 +1706,8 @@ static int initialMode = 0;
|
|||
static int initialCustomVidRes[2];
|
||||
static int initialMSAAmode = 0;
|
||||
static int qualityPreset = 0;
|
||||
static bool initialUsePrecomprTextures = false;
|
||||
static int initialUseNormalCompr = false;
|
||||
|
||||
static void SetVideoStuffFromCVars()
|
||||
{
|
||||
|
@ -1733,6 +1736,9 @@ static void SetVideoStuffFromCVars()
|
|||
if ( qualityPreset == -1 )
|
||||
qualityPreset = 1; // default to medium Quality
|
||||
}
|
||||
|
||||
initialUsePrecomprTextures = globalImages->image_usePrecompressedTextures.GetBool();
|
||||
initialUseNormalCompr = globalImages->image_useNormalCompression.GetInteger();
|
||||
}
|
||||
|
||||
static bool VideoHasResettableChanges()
|
||||
|
@ -1753,6 +1759,12 @@ static bool VideoHasResettableChanges()
|
|||
if ( initialMSAAmode != r_multiSamples.GetInteger() ) {
|
||||
return true;
|
||||
}
|
||||
if ( initialUsePrecomprTextures != globalImages->image_usePrecompressedTextures.GetBool() ) {
|
||||
return true;
|
||||
}
|
||||
if ( initialUseNormalCompr != globalImages->image_useNormalCompression.GetInteger() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1774,13 +1786,29 @@ static bool VideoHasApplyableChanges()
|
|||
return true;
|
||||
}
|
||||
|
||||
if ( initialUsePrecomprTextures != globalImages->image_usePrecompressedTextures.GetBool() ) {
|
||||
return true;
|
||||
}
|
||||
// Note: value of image_useNormalCompression is only relevant if image_usePrecompressedTextures is enabled
|
||||
if ( initialUsePrecomprTextures
|
||||
&& initialUseNormalCompr != globalImages->image_useNormalCompression.GetInteger() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void ApplyVideoSettings()
|
||||
{
|
||||
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "vid_restart partial\n" );
|
||||
const char* cmd = "vid_restart partial\n";
|
||||
if ( initialUsePrecomprTextures != globalImages->image_usePrecompressedTextures.GetBool()
|
||||
|| initialUseNormalCompr != globalImages->image_useNormalCompression.GetInteger() )
|
||||
{
|
||||
// these need a full restart (=> textures must be reloaded)
|
||||
cmd = "vid_restart\n";
|
||||
}
|
||||
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, cmd );
|
||||
}
|
||||
|
||||
static void VideoResetChanges()
|
||||
|
@ -1793,6 +1821,8 @@ static void VideoResetChanges()
|
|||
r_fullscreenDesktop.SetBool( initialFullscreenDesktop );
|
||||
|
||||
r_multiSamples.SetInteger( initialMSAAmode );
|
||||
globalImages->image_usePrecompressedTextures.SetBool( initialUsePrecomprTextures );
|
||||
globalImages->image_useNormalCompression.SetInteger( initialUseNormalCompr );
|
||||
}
|
||||
|
||||
static void InitVideoOptionsMenu()
|
||||
|
@ -1902,9 +1932,15 @@ static void DrawVideoOptionsMenu()
|
|||
}
|
||||
|
||||
// resolution info text
|
||||
int sdlDisplayIdx = SDL_GetWindowDisplayIndex( SDL_GL_GetCurrentWindow() );
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
// in SDL3 it's a Display ID, in SDL2 a Display Index, in both cases the value
|
||||
// can be fed into SDL_GetDisplayBounds()
|
||||
SDL_DisplayID sdlDisplayId_x = SDL_GetDisplayForWindow( SDL_GL_GetCurrentWindow() );
|
||||
#else // SDL2
|
||||
int sdlDisplayId_x = SDL_GetWindowDisplayIndex( SDL_GL_GetCurrentWindow() );
|
||||
#endif
|
||||
SDL_Rect displayRect = {};
|
||||
SDL_GetDisplayBounds( sdlDisplayIdx, &displayRect );
|
||||
SDL_GetDisplayBounds( sdlDisplayId_x, &displayRect );
|
||||
if ( (int)glConfig.winWidth != glConfig.vidWidth ) {
|
||||
ImGui::TextDisabled( "Current Resolution: %g x %g (Physical: %d x %d)",
|
||||
glConfig.winWidth, glConfig.winHeight, glConfig.vidWidth, glConfig.vidHeight );
|
||||
|
@ -1930,6 +1966,36 @@ static void DrawVideoOptionsMenu()
|
|||
}
|
||||
AddCVarOptionTooltips( r_multiSamples, "Note: Not all GPUs/drivers support all modes, esp. not 16x!" );
|
||||
|
||||
bool usePreComprTex = globalImages->image_usePrecompressedTextures.GetBool();
|
||||
if ( ImGui::Checkbox( "Use precompressed textures", &usePreComprTex ) ) {
|
||||
globalImages->image_usePrecompressedTextures.SetBool(usePreComprTex);
|
||||
// by default I guess people also want compressed normal maps when using this
|
||||
// especially relevant for retexturing packs that only ship BC7 DDS files
|
||||
// (otherwise the lowres TGA normalmaps would be used)
|
||||
if ( usePreComprTex ) {
|
||||
cvarSystem->SetCVarInteger( "image_useNormalCompression", 2 );
|
||||
}
|
||||
}
|
||||
const char* descr = "Use precompressed (.dds) textures. Faster loading, use less VRAM, possibly worse image quality.\n"
|
||||
"May also be used by highres retexturing packs for BC7-compressed textures (there image quality is not impaired)";
|
||||
AddCVarOptionTooltips( globalImages->image_usePrecompressedTextures, descr );
|
||||
|
||||
ImGui::BeginDisabled( !usePreComprTex );
|
||||
bool useNormalCompr = globalImages->image_useNormalCompression.GetBool();
|
||||
ImGui::Dummy( ImVec2(16, 0) );
|
||||
ImGui::SameLine();
|
||||
if ( ImGui::Checkbox( "Use precompressed normalmaps", &useNormalCompr ) ) {
|
||||
// image_useNormalCompression 1 is not supported by modern GPUs
|
||||
globalImages->image_useNormalCompression.SetInteger(useNormalCompr ? 2 : 0);
|
||||
}
|
||||
if ( usePreComprTex ) {
|
||||
const char* descr = "Also use precompressed textures for normalmaps";
|
||||
AddCVarOptionTooltips( globalImages->image_useNormalCompression, descr );
|
||||
} else {
|
||||
AddTooltip( "Can only be used if precompressed textures are enabled!" );
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
// Apply Button
|
||||
if ( !VideoHasApplyableChanges() ) {
|
||||
ImGui::BeginDisabled();
|
||||
|
@ -1962,6 +2028,25 @@ static void DrawVideoOptionsMenu()
|
|||
// options that take effect immediately, just by modifying their CVar:
|
||||
|
||||
DrawOptions( videoOptionsImmediately, IM_ARRAYSIZE(videoOptionsImmediately) );
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if ( ImGui::TreeNode("OpenGL Info") ) {
|
||||
ImGui::BeginDisabled();
|
||||
|
||||
ImGui::Text( "OpenGL vendor: %s", glConfig.vendor_string );
|
||||
ImGui::Text( "OpenGL renderer: %s", glConfig.renderer_string );
|
||||
ImGui::Text( "OpenGL version: %s", glConfig.version_string );
|
||||
|
||||
if ( glConfig.glDebugOutputAvailable && glConfig.haveDebugContext ) {
|
||||
ImGui::Text( " using an OpenGL debug context to show warnings from the OpenGL driver" );
|
||||
}
|
||||
|
||||
ImGui::EndDisabled();
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
AddTooltip( "Click to show information about the currently used Graphics Card (GPU)" );
|
||||
}
|
||||
}
|
||||
|
||||
static idStrList alDevices;
|
||||
|
|
|
@ -41,12 +41,12 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#define GAME_NAME "dhewm 3" // appears in errors
|
||||
#endif
|
||||
|
||||
#define ENGINE_VERSION "dhewm3 1.5.4" // printed in console, used for window title
|
||||
#define ENGINE_VERSION "dhewm3 1.5.5pre" // printed in console, used for window title
|
||||
|
||||
#ifdef ID_REPRODUCIBLE_BUILD
|
||||
// for reproducible builds we hardcode values that would otherwise come from __DATE__ and __TIME__
|
||||
// NOTE: remember to update esp. the date for (pre-) releases and RCs and the like
|
||||
#define ID__DATE__ "Aug 03 2024"
|
||||
#define ID__DATE__ "Aug 15 2024"
|
||||
#define ID__TIME__ "13:37:42"
|
||||
|
||||
#else // not reproducible build, use __DATE__ and __TIME__ macros
|
||||
|
@ -93,7 +93,8 @@ If you have questions concerning this license or the applicable additional terms
|
|||
// NOTE: a seperate core savegame version and game savegame version could be useful
|
||||
// 16: Doom v1.1
|
||||
// 17: Doom v1.2 / D3XP. Can still read old v16 with defaults for new data
|
||||
#define SAVEGAME_VERSION 17
|
||||
// 18: dhewm3 with CstDoom3 anchored window support - can still read v16 and v17, unless gamedata changed
|
||||
#define SAVEGAME_VERSION 18
|
||||
|
||||
// <= Doom v1.1: 1. no DS_VERSION token ( default )
|
||||
// Doom v1.2: 2
|
||||
|
|
|
@ -60,6 +60,8 @@ idCVar idSessionLocal::com_guid( "com_guid", "", CVAR_SYSTEM | CVAR_ARCHIVE | CV
|
|||
|
||||
idCVar idSessionLocal::com_numQuicksaves( "com_numQuicksaves", "4", CVAR_SYSTEM|CVAR_ARCHIVE|CVAR_INTEGER,
|
||||
"number of quicksaves to keep before overwriting the oldest", 1, 99 );
|
||||
idCVar idSessionLocal::com_disableAutoSaves( "com_disableAutoSaves", "0", CVAR_SYSTEM|CVAR_ARCHIVE|CVAR_BOOL,
|
||||
"Don't create Autosaves when entering a new map" );
|
||||
|
||||
idSessionLocal sessLocal;
|
||||
idSession *session = &sessLocal;
|
||||
|
@ -1246,8 +1248,8 @@ void idSessionLocal::MoveToNewMap( const char *mapName ) {
|
|||
|
||||
ExecuteMapChange();
|
||||
|
||||
if ( !mapSpawnData.serverInfo.GetBool("devmap") ) {
|
||||
// Autosave at the beginning of the level
|
||||
if ( !com_disableAutoSaves.GetBool() && !mapSpawnData.serverInfo.GetBool("devmap") ) {
|
||||
// Autosave at the beginning of the level - DG: unless disabled with "com_disableAutoSaves 1"
|
||||
|
||||
// DG: set an explicit savename to avoid problems with autosave names
|
||||
// (they were translated which caused problems like all alpha labs parts
|
||||
|
@ -2128,8 +2130,7 @@ bool idSessionLocal::LoadGame( const char *saveName ) {
|
|||
// check the version, if it doesn't match, cancel the loadgame,
|
||||
// but still load the map with the persistant playerInfo from the header
|
||||
// so that the player doesn't lose too much progress.
|
||||
if ( savegameVersion != SAVEGAME_VERSION &&
|
||||
!( savegameVersion == 16 && SAVEGAME_VERSION == 17 ) ) { // handle savegame v16 in v17
|
||||
if ( savegameVersion < 16 || savegameVersion > SAVEGAME_VERSION ) { // dhewm3 supports savegames with v16 - v18
|
||||
common->Warning( "Savegame Version mismatch: aborting loadgame and starting level with persistent data" );
|
||||
loadingSaveGame = false;
|
||||
fileSystem->CloseFile( savegameFile );
|
||||
|
|
|
@ -186,6 +186,7 @@ public:
|
|||
static idCVar com_wipeSeconds;
|
||||
static idCVar com_guid;
|
||||
static idCVar com_numQuicksaves;
|
||||
static idCVar com_disableAutoSaves;
|
||||
|
||||
static idCVar gui_configServerRate;
|
||||
|
||||
|
|
|
@ -482,8 +482,9 @@ void idSessionLocal::HandleRestartMenuCommands( const char *menuCommand ) {
|
|||
}
|
||||
|
||||
if ( !idStr::Icmp( cmd, "restart" ) ) {
|
||||
if ( !LoadGame( GetAutoSaveName( mapSpawnData.serverInfo.GetString("si_map") ) ) ) {
|
||||
// If we can't load the autosave then just restart the map
|
||||
if ( com_disableAutoSaves.GetBool() // DG: support com_disableAutoSaves
|
||||
|| !LoadGame( GetAutoSaveName( mapSpawnData.serverInfo.GetString("si_map") ) ) ) {
|
||||
// If we can't load the autosave (or they're disabled) then just restart the map
|
||||
MoveToNewMap( mapSpawnData.serverInfo.GetString("si_map") );
|
||||
}
|
||||
continue;
|
||||
|
|
|
@ -677,8 +677,17 @@ void idUsercmdGenLocal::MouseMove( void ) {
|
|||
historyCounter++;
|
||||
|
||||
if ( idMath::Fabs( mx ) > 1000 || idMath::Fabs( my ) > 1000 ) {
|
||||
Sys_DebugPrintf( "idUsercmdGenLocal::MouseMove: Ignoring ridiculous mouse delta.\n" );
|
||||
mx = my = 0;
|
||||
// DG: This caused problems with High-DPI mice - there those values can legitimately happen.
|
||||
// If it turns out that spurious big values happen for other reasons, we'll
|
||||
// need a smarter check. Leaving the Sys_DebugPrintf() here to make detecting
|
||||
// those cases easier, but added a static bool so High DPI mice don't spam the log.
|
||||
static bool warningShown = false;
|
||||
if ( !warningShown ) {
|
||||
warningShown = true;
|
||||
Sys_DebugPrintf( "idUsercmdGenLocal::MouseMove: Detected ridiculous mouse delta (expected with High DPI mice, though!).\n" );
|
||||
}
|
||||
|
||||
//mx = my = 0;
|
||||
}
|
||||
|
||||
mx *= sensitivity.GetFloat();
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#endif
|
||||
|
||||
// FIXME: why not just set this to int64_t?
|
||||
#if !defined(_WIN32) && defined(Z_LARGE64)
|
||||
#if !defined(_WIN32) && defined(__USE_LARGEFILE64)
|
||||
#define z_off64_t off64_t
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
|
|
|
@ -26,8 +26,6 @@ If you have questions concerning this license or the applicable additional terms
|
|||
===========================================================================
|
||||
*/
|
||||
|
||||
#include <SDL_endian.h>
|
||||
|
||||
#include "sys/platform.h"
|
||||
#include "idlib/LangDict.h"
|
||||
#include "idlib/Timer.h"
|
||||
|
@ -469,7 +467,12 @@ void idGameLocal::SaveGame( idFile *f ) {
|
|||
savegame.WriteString( D3_ARCH ); // CPU architecture (e.g. "x86" or "x86_64") - from CMake
|
||||
savegame.WriteString( ENGINE_VERSION );
|
||||
savegame.WriteShort( (short)sizeof(void*) ); // tells us if it's from a 32bit (4) or 64bit system (8)
|
||||
savegame.WriteShort( SDL_BYTEORDER ) ; // SDL_LIL_ENDIAN or SDL_BIG_ENDIAN
|
||||
#if D3_IS_BIG_ENDIAN
|
||||
const short byteOrder = 4321; // SDL_BIG_ENDIAN
|
||||
#else
|
||||
const short byteOrder = 1234; // SDL_LIL_ENDIAN
|
||||
#endif
|
||||
savegame.WriteShort( byteOrder ) ;
|
||||
// DG end
|
||||
|
||||
// go through all entities and threads and add them to the object list
|
||||
|
|
|
@ -721,7 +721,43 @@ void idPlayerView::RenderPlayerView( idUserInterface *hud ) {
|
|||
}
|
||||
|
||||
if ( net_clientLagOMeter.GetBool() && lagoMaterial && gameLocal.isClient ) {
|
||||
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
renderSystem->DrawStretchPic( 10.0f, 380.0f, 64.0f, 64.0f, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial );
|
||||
//#modified-fva; BEGIN
|
||||
float x = 10.0f;
|
||||
float y = 380.0f;
|
||||
float w = 64.0f;
|
||||
float h = 64.0f;
|
||||
if (cvarSystem->GetCVarBool("cst_hudAdjustAspect")) {
|
||||
// similar to CST_ANCHOR_BOTTOM_LEFT
|
||||
int glWidth, glHeight;
|
||||
renderSystem->GetGLSettings(glWidth, glHeight);
|
||||
if (glWidth > 0 && glHeight > 0) {
|
||||
float glAspectRatio = (float)glWidth / (float)glHeight;
|
||||
|
||||
const float vidWidth = SCREEN_WIDTH;
|
||||
const float vidHeight = SCREEN_HEIGHT;
|
||||
const float vidAspectRatio = (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT;
|
||||
|
||||
float modWidth = vidWidth;
|
||||
float modHeight = vidHeight;
|
||||
if (glAspectRatio >= vidAspectRatio) {
|
||||
modWidth = modHeight * glAspectRatio;
|
||||
} else {
|
||||
modHeight = modWidth / glAspectRatio;
|
||||
}
|
||||
|
||||
float xScale = vidWidth / modWidth;
|
||||
float yScale = vidHeight / modHeight;
|
||||
float xOffset = 0.0f;
|
||||
float yOffset = vidHeight * (1.0f - yScale);
|
||||
|
||||
x = x * xScale + xOffset;
|
||||
y = y * yScale + yOffset;
|
||||
w *= xScale;
|
||||
h *= yScale;
|
||||
}
|
||||
}
|
||||
renderSystem->SetColor4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
renderSystem->DrawStretchPic(x, y, w, h, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial);
|
||||
//#modified-fva; END
|
||||
}
|
||||
}
|
||||
|
|
|
@ -539,9 +539,6 @@ const char *idAnim::AddFrameCommand( const idDeclModelDef *modelDef, int framenu
|
|||
}
|
||||
fc.type = FC_MUZZLEFLASH;
|
||||
fc.string = new idStr( token );
|
||||
} else if ( token == "muzzle_flash" ) {
|
||||
fc.type = FC_MUZZLEFLASH;
|
||||
fc.string = new idStr( "" );
|
||||
} else if ( token == "create_missile" ) {
|
||||
if( !src.ReadTokenOnLine( &token ) ) {
|
||||
return "Unexpected end of line";
|
||||
|
|
|
@ -444,10 +444,10 @@ idClass::new
|
|||
#endif
|
||||
|
||||
void * idClass::operator new( size_t s ) {
|
||||
int *p;
|
||||
intptr_t *p;
|
||||
|
||||
s += sizeof( int );
|
||||
p = (int *)Mem_Alloc( s );
|
||||
s += sizeof( intptr_t );
|
||||
p = (intptr_t *)Mem_Alloc( s );
|
||||
*p = s;
|
||||
memused += s;
|
||||
numobjects++;
|
||||
|
@ -455,7 +455,7 @@ void * idClass::operator new( size_t s ) {
|
|||
#ifdef ID_DEBUG_UNINITIALIZED_MEMORY
|
||||
unsigned int *ptr = (unsigned int *)p;
|
||||
int size = s;
|
||||
assert( ( size & 3 ) == 0 );
|
||||
assert( ( size & (sizeof(intptr_t) - 1) ) == 0 );
|
||||
size >>= 3;
|
||||
for ( int i = 1; i < size; i++ ) {
|
||||
ptr[i] = 0xcdcdcdcd;
|
||||
|
@ -466,10 +466,10 @@ void * idClass::operator new( size_t s ) {
|
|||
}
|
||||
|
||||
void * idClass::operator new( size_t s, int, int, char *, int ) {
|
||||
int *p;
|
||||
intptr_t *p;
|
||||
|
||||
s += sizeof( int );
|
||||
p = (int *)Mem_Alloc( s );
|
||||
s += sizeof( intptr_t );
|
||||
p = (intptr_t *)Mem_Alloc( s );
|
||||
*p = s;
|
||||
memused += s;
|
||||
numobjects++;
|
||||
|
@ -477,7 +477,7 @@ void * idClass::operator new( size_t s, int, int, char *, int ) {
|
|||
#ifdef ID_DEBUG_UNINITIALIZED_MEMORY
|
||||
unsigned int *ptr = (unsigned int *)p;
|
||||
int size = s;
|
||||
assert( ( size & 3 ) == 0 );
|
||||
assert( ( size & (sizeof(intptr_t) - 1) ) == 0 );
|
||||
size >>= 3;
|
||||
for ( int i = 1; i < size; i++ ) {
|
||||
ptr[i] = 0xcdcdcdcd;
|
||||
|
@ -497,10 +497,10 @@ idClass::delete
|
|||
================
|
||||
*/
|
||||
void idClass::operator delete( void *ptr ) {
|
||||
int *p;
|
||||
intptr_t *p;
|
||||
|
||||
if ( ptr ) {
|
||||
p = ( ( int * )ptr ) - 1;
|
||||
p = ( ( intptr_t * )ptr ) - 1;
|
||||
memused -= *p;
|
||||
numobjects--;
|
||||
Mem_Free( p );
|
||||
|
@ -508,10 +508,10 @@ void idClass::operator delete( void *ptr ) {
|
|||
}
|
||||
|
||||
void idClass::operator delete( void *ptr, int, int, char *, int ) {
|
||||
int *p;
|
||||
intptr_t *p;
|
||||
|
||||
if ( ptr ) {
|
||||
p = ( ( int * )ptr ) - 1;
|
||||
p = ( ( intptr_t * )ptr ) - 1;
|
||||
memused -= *p;
|
||||
numobjects--;
|
||||
Mem_Free( p );
|
||||
|
|
|
@ -55,7 +55,7 @@ const char *ui_skinArgs[] = { "skins/characters/player/marine_mp", "skins/char
|
|||
const char *ui_teamArgs[] = { "Red", "Blue", NULL };
|
||||
|
||||
struct gameVersion_s {
|
||||
gameVersion_s( void ) { sprintf( string, "%s.%d%s %s-%s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_OS, BUILD_CPU, ID__DATE__, ID__TIME__ ); }
|
||||
gameVersion_s( void ) { sprintf( string, "%s.%d%s %s-%s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_OS, D3_ARCH, ID__DATE__, ID__TIME__ ); }
|
||||
char string[256];
|
||||
} gameVersion;
|
||||
|
||||
|
|
|
@ -785,11 +785,22 @@ void idInterpreter::CallEvent( const function_t *func, int argsize ) {
|
|||
switch( format[ i ] ) {
|
||||
case D_EVENT_INTEGER :
|
||||
var.intPtr = ( int * )&localstack[ start + pos ];
|
||||
( *( int * )&data[ i ] ) = int( *var.floatPtr );
|
||||
//( *( int * )&data[ i ] ) = int( *var.floatPtr );
|
||||
// DG: for int/intrptr_t arguments, the callbacks from Callbacks.cpp pass
|
||||
// data[i] directly, not *(int*)&data[i] or some nonsense like that
|
||||
// so the integer must be assigned to the intptr_t for the value to be
|
||||
// passed correctly, esp. on 64bit Big Endian machines.
|
||||
data[ i ] = int( *var.floatPtr );
|
||||
break;
|
||||
|
||||
case D_EVENT_FLOAT :
|
||||
var.intPtr = ( int * )&localstack[ start + pos ];
|
||||
// NOTE: floats are the only type not passed as int or pointer in intptr_t,
|
||||
// but as float-data in the first 4 bytes of data[i].
|
||||
// So (unlike in the other cases), here this awkward code casting &data[i]
|
||||
// to another pointer type is actually necessary (same in CallSysEvent()).
|
||||
// In the other cases one could also use `data[i] = (intptr_t)var.blaPtr;`
|
||||
// (not doing those changes here now to minimize potential merge conflicts)
|
||||
( *( float * )&data[ i ] ) = *var.floatPtr;
|
||||
break;
|
||||
|
||||
|
@ -915,7 +926,12 @@ void idInterpreter::CallSysEvent( const function_t *func, int argsize ) {
|
|||
switch( format[ i ] ) {
|
||||
case D_EVENT_INTEGER :
|
||||
source.intPtr = ( int * )&localstack[ start + pos ];
|
||||
*( int * )&data[ i ] = int( *source.floatPtr );
|
||||
//*( int * )&data[ i ] = int( *source.floatPtr );
|
||||
// DG: for int/intrptr_t arguments, the callbacks from Callbacks.cpp pass
|
||||
// data[i] directly, not *(int*)&data[i] or some nonsense like that
|
||||
// so the integer must be assigned to the intptr_t for the value to be
|
||||
// passed correctly, esp. on 64bit Big Endian machines.
|
||||
data[ i ] = int( *source.floatPtr );
|
||||
break;
|
||||
|
||||
case D_EVENT_FLOAT :
|
||||
|
|
|
@ -146,7 +146,26 @@ ID_INLINE void idInterpreter::Push( intptr_t value ) {
|
|||
if ( localstackUsed + sizeof( intptr_t ) > LOCALSTACK_SIZE ) {
|
||||
Error( "Push: locals stack overflow\n" );
|
||||
}
|
||||
*( intptr_t * )&localstack[ localstackUsed ] = value;
|
||||
// DG: fix for 64bit Big Endian machines
|
||||
//*( intptr_t * )&localstack[ localstackUsed ] = value;
|
||||
int val = value;
|
||||
assert(value == val && "I really assumed that value would always fit into 32bit");
|
||||
// dhewm3 used to store these values on localstack[] as intptr_t, even though
|
||||
// they always seem to be int32. Unfortunately, all the code reading localstack[]
|
||||
// gets the pointer to &localstack[ localstackUsed ] and then interprets that
|
||||
// as int* or float* or whatever.
|
||||
// So with 64bit machines it's stored as the wrong size (intptr_t is int64, int is int32),
|
||||
// and on Big Endian the values are just 0 (or UINT_MAX if value < 0) - on Little Endian
|
||||
// the first 4 bytes are the ones with actual data so the bug was hidden).
|
||||
// To fix this, now a regular itn is stored at `&localstack[ localstackUsed ]`,
|
||||
// as expected by the code using localstack[].
|
||||
// TODO: once this has been tested more (and the assertion above has never triggered),
|
||||
// change idInterpreter::Push() to take a regular int argument instead of intptr_t.
|
||||
int *stackVar = ( int * )&localstack[ localstackUsed ];
|
||||
*stackVar = val;
|
||||
|
||||
// even though a 32bit int is put onto the stack, increase it by sizeof(intptr_t)
|
||||
// so it remains aligned to multiples of the native pointer size
|
||||
localstackUsed += sizeof( intptr_t );
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,24 @@ __inline void operator delete[]( void *p ) {
|
|||
#endif /* ID_DEBUG_MEMORY */
|
||||
|
||||
|
||||
// allocate SIZE bytes, aligned to 16 bytes - possibly on the stack (like _alloca16())
|
||||
// if it's too big (> ID_MAX_ALLOCA_SIZE, 1MB), it gets allocated on the Heap instead.
|
||||
// ON_STACK should be a bool and will be set to true if it was allocated on the stack
|
||||
// and false if it was allocated on the heap.
|
||||
// if ON_STACK is false, you must free this with Mem_FreeA() or Mem_Free16()!
|
||||
// (just pass your ON_STACK bool to Mem_FreeA() and it will do the right thing)
|
||||
#define Mem_MallocA( SIZE, ON_STACK ) \
|
||||
( (SIZE) < ID_MAX_ALLOCA_SIZE ? ( ON_STACK=true, _alloca16(SIZE) ) : ( ON_STACK=false, Mem_Alloc16(SIZE) ) )
|
||||
|
||||
// free memory allocated with Mem_MallocA()
|
||||
ID_INLINE void Mem_FreeA( void* ptr, bool onStack )
|
||||
{
|
||||
if( !onStack ) {
|
||||
Mem_Free16( ptr );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
|
|
@ -35,7 +35,32 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <SDL_endian.h>
|
||||
#ifdef D3_SDL3
|
||||
#include <SDL3/SDL_endian.h>
|
||||
// some defines for backwards-compat with SDL2
|
||||
#define SDL_SwapBE16(X) SDL_Swap16BE(X)
|
||||
#define SDL_SwapLE16(X) SDL_Swap16LE(X)
|
||||
#define SDL_SwapBE32(X) SDL_Swap32BE(X)
|
||||
#define SDL_SwapLE32(X) SDL_Swap32LE(X)
|
||||
#else // SDL1.2 or SDL2
|
||||
#include <SDL_endian.h>
|
||||
#endif
|
||||
|
||||
#ifndef D3_IS_BIG_ENDIAN
|
||||
#error "D3_IS_BIG_ENDIAN should be defined by the build system (CMake)!"
|
||||
#endif
|
||||
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
#if D3_IS_BIG_ENDIAN != 1
|
||||
#error "CMake (which sets D3_IS_BIG_ENDIAN) and SDL disagree about the endianess! CMake says little, SDL says big"
|
||||
#endif
|
||||
#elif SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
#if D3_IS_BIG_ENDIAN != 0
|
||||
#error "CMake (which sets D3_IS_BIG_ENDIAN) and SDL disagree about the endianess! CMake says big, SDL says little"
|
||||
#endif
|
||||
#else
|
||||
#error "According to SDL, endianess is neither Big nor Little - dhewm3 doesn't support other byteorders!"
|
||||
#endif
|
||||
|
||||
#include "sys/platform.h"
|
||||
#include "idlib/math/Vector.h"
|
||||
|
|
|
@ -100,8 +100,8 @@ idODE_Midpoint::~idODE_Midpoint
|
|||
=============
|
||||
*/
|
||||
idODE_Midpoint::~idODE_Midpoint( void ) {
|
||||
delete tmpState;
|
||||
delete derivatives;
|
||||
delete[] tmpState;
|
||||
delete[] derivatives;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -157,11 +157,11 @@ idODE_RK4::~idODE_RK4
|
|||
=============
|
||||
*/
|
||||
idODE_RK4::~idODE_RK4( void ) {
|
||||
delete tmpState;
|
||||
delete d1;
|
||||
delete d2;
|
||||
delete d3;
|
||||
delete d4;
|
||||
delete[] tmpState;
|
||||
delete[] d1;
|
||||
delete[] d2;
|
||||
delete[] d3;
|
||||
delete[] d4;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -230,12 +230,12 @@ idODE_RK4Adaptive::~idODE_RK4Adaptive
|
|||
=============
|
||||
*/
|
||||
idODE_RK4Adaptive::~idODE_RK4Adaptive( void ) {
|
||||
delete tmpState;
|
||||
delete d1;
|
||||
delete d1half;
|
||||
delete d2;
|
||||
delete d3;
|
||||
delete d4;
|
||||
delete[] tmpState;
|
||||
delete[] d1;
|
||||
delete[] d1half;
|
||||
delete[] d2;
|
||||
delete[] d3;
|
||||
delete[] d4;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
1
neo/libs/imgui/.gitignore
vendored
|
@ -3,6 +3,7 @@
|
|||
|
||||
## Dear ImGui artifacts
|
||||
imgui.ini
|
||||
imgui*.ini
|
||||
|
||||
## General build artifacts
|
||||
*.o
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2024 Omar Cornut
|
||||
Copyright (c) 2014-2025 Omar Cornut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Issues:
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12).
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: The renderer is suboptimal as we need to convert vertices manually.
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
|
||||
|
@ -20,6 +20,10 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-01-06: Avoid calling al_set_mouse_cursor() repeatedly since it appears to leak on on X11 (#8256).
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||
// 2022-11-30: Renderer: Restoring using al_draw_indexed_prim() when Allegro version is >= 5.2.5.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||
|
@ -62,8 +66,8 @@
|
|||
#ifdef _WIN32
|
||||
#include <allegro5/allegro_windows.h>
|
||||
#endif
|
||||
#define ALLEGRO_HAS_CLIPBOARD (ALLEGRO_VERSION_INT >= ((5 << 24) | (1 << 16) | (12 << 8))) // Clipboard only supported from Allegro 5.1.12
|
||||
#define ALLEGRO_HAS_DRAW_INDEXED_PRIM (ALLEGRO_VERSION_INT >= ((5 << 24) | (2 << 16) | ( 5 << 8))) // DX9 implementation of al_draw_indexed_prim() got fixed in Allegro 5.2.5
|
||||
#define ALLEGRO_HAS_CLIPBOARD ((ALLEGRO_VERSION_INT & ~ALLEGRO_UNSTABLE_BIT) >= ((5 << 24) | (1 << 16) | (12 << 8))) // Clipboard only supported from Allegro 5.1.12
|
||||
#define ALLEGRO_HAS_DRAW_INDEXED_PRIM ((ALLEGRO_VERSION_INT & ~ALLEGRO_UNSTABLE_BIT) >= ((5 << 24) | (2 << 16) | ( 5 << 8))) // DX9 implementation of al_draw_indexed_prim() got fixed in Allegro 5.2.5
|
||||
|
||||
// Visual Studio warnings
|
||||
#ifdef _MSC_VER
|
||||
|
@ -92,6 +96,7 @@ struct ImGui_ImplAllegro5_Data
|
|||
ALLEGRO_MOUSE_CURSOR* MouseCursorInvisible;
|
||||
ALLEGRO_VERTEX_DECL* VertexDecl;
|
||||
char* ClipboardTextData;
|
||||
ImGuiMouseCursor LastCursor;
|
||||
|
||||
ImVector<ImDrawVertAllegro> BufVertices;
|
||||
ImVector<int> BufIndices;
|
||||
|
@ -146,14 +151,14 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
|
||||
ImVector<ImDrawVertAllegro>& vertices = bd->BufVertices;
|
||||
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM
|
||||
vertices.resize(cmd_list->VtxBuffer.Size);
|
||||
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
|
||||
vertices.resize(draw_list->VtxBuffer.Size);
|
||||
for (int i = 0; i < draw_list->VtxBuffer.Size; i++)
|
||||
{
|
||||
const ImDrawVert* src_v = &cmd_list->VtxBuffer[i];
|
||||
const ImDrawVert* src_v = &draw_list->VtxBuffer[i];
|
||||
ImDrawVertAllegro* dst_v = &vertices[i];
|
||||
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
|
||||
}
|
||||
|
@ -163,21 +168,21 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||
// FIXME-OPT: Allegro doesn't support 16-bit indices.
|
||||
// You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices.
|
||||
// Otherwise, we convert them from 16-bit to 32-bit at runtime here, which works perfectly but is a little wasteful.
|
||||
bd->BufIndices.resize(cmd_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
|
||||
bd->BufIndices[i] = (int)cmd_list->IdxBuffer.Data[i];
|
||||
bd->BufIndices.resize(draw_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < draw_list->IdxBuffer.Size; ++i)
|
||||
bd->BufIndices[i] = (int)draw_list->IdxBuffer.Data[i];
|
||||
indices = bd->BufIndices.Data;
|
||||
}
|
||||
else if (sizeof(ImDrawIdx) == 4)
|
||||
{
|
||||
indices = (const int*)cmd_list->IdxBuffer.Data;
|
||||
indices = (const int*)draw_list->IdxBuffer.Data;
|
||||
}
|
||||
#else
|
||||
// Allegro's implementation of al_draw_indexed_prim() for DX9 was broken until 5.2.5. Unindex buffers ourselves while converting vertex format.
|
||||
vertices.resize(cmd_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < cmd_list->IdxBuffer.Size; i++)
|
||||
vertices.resize(draw_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < draw_list->IdxBuffer.Size; i++)
|
||||
{
|
||||
const ImDrawVert* src_v = &cmd_list->VtxBuffer[cmd_list->IdxBuffer[i]];
|
||||
const ImDrawVert* src_v = &draw_list->VtxBuffer[draw_list->IdxBuffer[i]];
|
||||
ImDrawVertAllegro* dst_v = &vertices[i];
|
||||
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
|
||||
}
|
||||
|
@ -185,9 +190,9 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||
|
||||
// Render command lists
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
|
@ -195,7 +200,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplAllegro5_SetupRenderState(draw_data);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -291,7 +296,7 @@ void ImGui_ImplAllegro5_InvalidateDeviceObjects()
|
|||
}
|
||||
|
||||
#if ALLEGRO_HAS_CLIPBOARD
|
||||
static const char* ImGui_ImplAllegro5_GetClipboardText(void*)
|
||||
static const char* ImGui_ImplAllegro5_GetClipboardText(ImGuiContext*)
|
||||
{
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
if (bd->ClipboardTextData)
|
||||
|
@ -300,14 +305,16 @@ static const char* ImGui_ImplAllegro5_GetClipboardText(void*)
|
|||
return bd->ClipboardTextData;
|
||||
}
|
||||
|
||||
static void ImGui_ImplAllegro5_SetClipboardText(void*, const char* text)
|
||||
static void ImGui_ImplAllegro5_SetClipboardText(ImGuiContext*, const char* text)
|
||||
{
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
al_set_clipboard_text(bd->Display, text);
|
||||
}
|
||||
#endif
|
||||
|
||||
static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code);
|
||||
ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
|
||||
{
|
||||
switch (key_code)
|
||||
{
|
||||
|
@ -433,6 +440,7 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
|
|||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
|
||||
bd->Display = display;
|
||||
bd->LastCursor = ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE;
|
||||
|
||||
// Create custom vertex declaration.
|
||||
// Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 floats.
|
||||
|
@ -447,9 +455,9 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
|
|||
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
|
||||
|
||||
#if ALLEGRO_HAS_CLIPBOARD
|
||||
io.SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplAllegro5_GetClipboardText;
|
||||
io.ClipboardUserData = nullptr;
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText;
|
||||
platform_io.Platform_GetClipboardTextFn = ImGui_ImplAllegro5_GetClipboardText;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -563,9 +571,16 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
|
|||
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
|
||||
|
||||
// Hide OS mouse cursor if imgui is drawing it
|
||||
if (io.MouseDrawCursor)
|
||||
imgui_cursor = ImGuiMouseCursor_None;
|
||||
|
||||
if (bd->LastCursor == imgui_cursor)
|
||||
return;
|
||||
bd->LastCursor = imgui_cursor;
|
||||
if (imgui_cursor == ImGuiMouseCursor_None)
|
||||
{
|
||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||
al_set_mouse_cursor(bd->Display, bd->MouseCursorInvisible);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Issues:
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12).
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
|||
struct ALLEGRO_DISPLAY;
|
||||
union ALLEGRO_EVENT;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display);
|
||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_NewFrame();
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||
// Missing features:
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: Clipboard support.
|
||||
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [ ] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||
// [ ] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||
// Important:
|
||||
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
||||
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||
// Missing features:
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: Clipboard support.
|
||||
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [ ] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||
// [ ] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||
// Important:
|
||||
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
||||
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
||||
|
@ -28,6 +28,7 @@
|
|||
struct ANativeWindow;
|
||||
struct AInputEvent;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplAndroid_Init(ANativeWindow* window);
|
||||
IMGUI_IMPL_API int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event);
|
||||
IMGUI_IMPL_API void ImGui_ImplAndroid_Shutdown();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -15,6 +15,8 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-01-06: DirectX10: Expose selected render state in ImGui_ImplDX10_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-10-07: DirectX10: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
|
@ -80,7 +82,7 @@ static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
|
|||
}
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx)
|
||||
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* device)
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
|
||||
|
@ -92,90 +94,13 @@ static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device*
|
|||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0;
|
||||
ctx->RSSetViewports(1, &vp);
|
||||
|
||||
// Bind shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
unsigned int offset = 0;
|
||||
ctx->IASetInputLayout(bd->pInputLayout);
|
||||
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->VSSetShader(bd->pVertexShader);
|
||||
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
ctx->PSSetShader(bd->pPixelShader);
|
||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
ctx->GSSetShader(nullptr);
|
||||
|
||||
// Setup render state
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||
ctx->RSSetState(bd->pRasterizerState);
|
||||
}
|
||||
|
||||
// Render function
|
||||
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ID3D10Device* ctx = bd->pd3dDevice;
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D10_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
if (ctx->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D10_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||
if (ctx->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy and convert all vertices into a single contiguous buffer
|
||||
ImDrawVert* vtx_dst = nullptr;
|
||||
ImDrawIdx* idx_dst = nullptr;
|
||||
bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
|
||||
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
}
|
||||
bd->pVB->Unmap();
|
||||
bd->pIB->Unmap();
|
||||
device->RSSetViewports(1, &vp);
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
void* mapped_resource;
|
||||
if (bd->pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) == S_OK)
|
||||
{
|
||||
void* mapped_resource;
|
||||
if (bd->pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||
return;
|
||||
VERTEX_CONSTANT_BUFFER_DX10* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX10*)mapped_resource;
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
|
@ -192,6 +117,82 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
|||
bd->pVertexConstantBuffer->Unmap();
|
||||
}
|
||||
|
||||
// Setup shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
unsigned int offset = 0;
|
||||
device->IASetInputLayout(bd->pInputLayout);
|
||||
device->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
device->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
device->VSSetShader(bd->pVertexShader);
|
||||
device->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
device->PSSetShader(bd->pPixelShader);
|
||||
device->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
device->GSSetShader(nullptr);
|
||||
|
||||
// Setup render state
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
device->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||
device->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||
device->RSSetState(bd->pRasterizerState);
|
||||
}
|
||||
|
||||
// Render function
|
||||
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ID3D10Device* device = bd->pd3dDevice;
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D10_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
if (device->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D10_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||
if (device->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy and convert all vertices into a single contiguous buffer
|
||||
ImDrawVert* vtx_dst = nullptr;
|
||||
ImDrawIdx* idx_dst = nullptr;
|
||||
bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
|
||||
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
bd->pVB->Unmap();
|
||||
bd->pIB->Unmap();
|
||||
|
||||
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||
struct BACKUP_DX10_STATE
|
||||
{
|
||||
|
@ -217,24 +218,31 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
|||
};
|
||||
BACKUP_DX10_STATE old = {};
|
||||
old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||
ctx->RSGetState(&old.RS);
|
||||
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||
ctx->PSGetSamplers(0, 1, &old.PSSampler);
|
||||
ctx->PSGetShader(&old.PS);
|
||||
ctx->VSGetShader(&old.VS);
|
||||
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||
ctx->GSGetShader(&old.GS);
|
||||
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||
ctx->IAGetInputLayout(&old.InputLayout);
|
||||
device->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||
device->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||
device->RSGetState(&old.RS);
|
||||
device->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||
device->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||
device->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||
device->PSGetSamplers(0, 1, &old.PSSampler);
|
||||
device->PSGetShader(&old.PS);
|
||||
device->VSGetShader(&old.VS);
|
||||
device->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||
device->GSGetShader(&old.GS);
|
||||
device->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||
device->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||
device->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||
device->IAGetInputLayout(&old.InputLayout);
|
||||
|
||||
// Setup desired DX state
|
||||
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
|
||||
ImGui_ImplDX10_SetupRenderState(draw_data, device);
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplDX10_RenderState render_state;
|
||||
render_state.Device = bd->pd3dDevice;
|
||||
render_state.SamplerDefault = bd->pFontSampler;
|
||||
render_state.VertexConstantBuffer = bd->pVertexConstantBuffer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
|
@ -243,18 +251,18 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
|||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
|
||||
ImGui_ImplDX10_SetupRenderState(draw_data, device);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -266,34 +274,35 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
|||
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
device->RSSetScissorRects(1, &r);
|
||||
|
||||
// Bind texture, Draw
|
||||
ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->GetTexID();
|
||||
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
||||
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||
device->PSSetShaderResources(0, 1, &texture_srv);
|
||||
device->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
|
||||
// Restore modified DX state
|
||||
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
|
||||
ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release();
|
||||
ctx->GSSetShader(old.GS); if (old.GS) old.GS->Release();
|
||||
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||
device->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||
device->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||
device->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||
device->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||
device->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||
device->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||
device->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||
device->PSSetShader(old.PS); if (old.PS) old.PS->Release();
|
||||
device->VSSetShader(old.VS); if (old.VS) old.VS->Release();
|
||||
device->GSSetShader(old.GS); if (old.GS) old.GS->Release();
|
||||
device->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||
device->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||
device->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||
device->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||
device->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_CreateFontsTexture()
|
||||
|
@ -340,21 +349,16 @@ static void ImGui_ImplDX10_CreateFontsTexture()
|
|||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
||||
}
|
||||
|
||||
// Create texture sampler
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
static void ImGui_ImplDX10_DestroyFontsTexture()
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
if (bd->pFontTextureView)
|
||||
{
|
||||
D3D10_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
bd->pFontTextureView->Release();
|
||||
bd->pFontTextureView = nullptr;
|
||||
ImGui::GetIO().Fonts->SetTexID(0); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -507,6 +511,22 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
|
|||
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||
}
|
||||
|
||||
// Create texture sampler
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
{
|
||||
D3D10_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
}
|
||||
|
||||
ImGui_ImplDX10_CreateFontsTexture();
|
||||
|
||||
return true;
|
||||
|
@ -518,8 +538,9 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
|
|||
if (!bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX10_DestroyFontsTexture();
|
||||
|
||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||
|
@ -581,7 +602,7 @@ void ImGui_ImplDX10_NewFrame()
|
|||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX10_Init()?");
|
||||
|
||||
if (!bd->pFontSampler)
|
||||
if (!bd->pVertexShader)
|
||||
ImGui_ImplDX10_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -18,14 +18,27 @@
|
|||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct ID3D10Device;
|
||||
struct ID3D10SamplerState;
|
||||
struct ID3D10Buffer;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX10_Init(ID3D10Device* device);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX10_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX10_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX10_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplDX10_RenderState
|
||||
{
|
||||
ID3D10Device* Device;
|
||||
ID3D10SamplerState* SamplerDefault;
|
||||
ID3D10Buffer* VertexConstantBuffer;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -15,12 +16,15 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-01-06: DirectX11: Expose VertexConstantBuffer in ImGui_ImplDX11_RenderState. Reset projection matrix in ImDrawCallback_ResetRenderState handler.
|
||||
// 2024-10-07: DirectX11: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-10-07: DirectX11: Expose selected render state in ImGui_ImplDX11_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
||||
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
|
||||
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
|
||||
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX11_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
|
||||
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
|
||||
|
@ -81,7 +85,7 @@ static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
|||
}
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
|
||||
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
|
||||
|
@ -93,29 +97,50 @@ static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceC
|
|||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0;
|
||||
ctx->RSSetViewports(1, &vp);
|
||||
device_ctx->RSSetViewports(1, &vp);
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||
if (device_ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) == S_OK)
|
||||
{
|
||||
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
float T = draw_data->DisplayPos.y;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||
float mvp[4][4] =
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||
};
|
||||
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||
device_ctx->Unmap(bd->pVertexConstantBuffer, 0);
|
||||
}
|
||||
|
||||
// Setup shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
unsigned int offset = 0;
|
||||
ctx->IASetInputLayout(bd->pInputLayout);
|
||||
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
ctx->GSSetShader(nullptr, nullptr, 0);
|
||||
ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
device_ctx->IASetInputLayout(bd->pInputLayout);
|
||||
device_ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
device_ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
device_ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
device_ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||
device_ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
device_ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||
device_ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
device_ctx->GSSetShader(nullptr, nullptr, 0);
|
||||
device_ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
device_ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
device_ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
|
||||
// Setup blend state
|
||||
// Setup render state
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||
ctx->RSSetState(bd->pRasterizerState);
|
||||
device_ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||
device_ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||
device_ctx->RSSetState(bd->pRasterizerState);
|
||||
}
|
||||
|
||||
// Render function
|
||||
|
@ -126,7 +151,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||
return;
|
||||
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ID3D11DeviceContext* ctx = bd->pd3dDeviceContext;
|
||||
ID3D11DeviceContext* device = bd->pd3dDeviceContext;
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
|
@ -159,44 +184,22 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
|
||||
if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||
if (device->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||
return;
|
||||
if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||
if (device->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||
return;
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
}
|
||||
ctx->Unmap(bd->pVB, 0);
|
||||
ctx->Unmap(bd->pIB, 0);
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||
if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||
return;
|
||||
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
float T = draw_data->DisplayPos.y;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||
float mvp[4][4] =
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||
};
|
||||
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||
ctx->Unmap(bd->pVertexConstantBuffer, 0);
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
device->Unmap(bd->pVB, 0);
|
||||
device->Unmap(bd->pIB, 0);
|
||||
|
||||
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||
struct BACKUP_DX11_STATE
|
||||
|
@ -225,26 +228,35 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||
};
|
||||
BACKUP_DX11_STATE old = {};
|
||||
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||
ctx->RSGetState(&old.RS);
|
||||
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||
ctx->PSGetSamplers(0, 1, &old.PSSampler);
|
||||
device->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||
device->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||
device->RSGetState(&old.RS);
|
||||
device->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||
device->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||
device->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||
device->PSGetSamplers(0, 1, &old.PSSampler);
|
||||
old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
|
||||
ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
|
||||
ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
|
||||
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||
ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
|
||||
device->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
|
||||
device->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
|
||||
device->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||
device->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
|
||||
|
||||
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||
ctx->IAGetInputLayout(&old.InputLayout);
|
||||
device->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||
device->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||
device->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||
device->IAGetInputLayout(&old.InputLayout);
|
||||
|
||||
// Setup desired DX state
|
||||
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
|
||||
ImGui_ImplDX11_SetupRenderState(draw_data, device);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplDX11_RenderState render_state;
|
||||
render_state.Device = bd->pd3dDevice;
|
||||
render_state.DeviceContext = bd->pd3dDeviceContext;
|
||||
render_state.SamplerDefault = bd->pFontSampler;
|
||||
render_state.VertexConstantBuffer = bd->pVertexConstantBuffer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
|
@ -253,18 +265,18 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
|
||||
ImGui_ImplDX11_SetupRenderState(draw_data, device);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -276,36 +288,37 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
device->RSSetScissorRects(1, &r);
|
||||
|
||||
// Bind texture, Draw
|
||||
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
|
||||
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
||||
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||
device->PSSetShaderResources(0, 1, &texture_srv);
|
||||
device->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
|
||||
// Restore modified DX state
|
||||
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
|
||||
device->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||
device->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||
device->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||
device->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||
device->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||
device->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||
device->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||
device->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
|
||||
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
|
||||
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
|
||||
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||
ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
|
||||
device->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
|
||||
device->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||
device->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
|
||||
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
|
||||
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||
device->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||
device->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||
device->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||
device->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_CreateFontsTexture()
|
||||
|
@ -352,21 +365,16 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
|||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
||||
}
|
||||
|
||||
// Create texture sampler
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
static void ImGui_ImplDX11_DestroyFontsTexture()
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
if (bd->pFontTextureView)
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
bd->pFontTextureView->Release();
|
||||
bd->pFontTextureView = nullptr;
|
||||
ImGui::GetIO().Fonts->SetTexID(0); // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,6 +527,22 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||
}
|
||||
|
||||
// Create texture sampler
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
}
|
||||
|
||||
ImGui_ImplDX11_CreateFontsTexture();
|
||||
|
||||
return true;
|
||||
|
@ -530,8 +554,9 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
|
|||
if (!bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX11_DestroyFontsTexture();
|
||||
|
||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -19,14 +20,28 @@
|
|||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
struct ID3D11SamplerState;
|
||||
struct ID3D11Buffer;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX11_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplDX11_RenderState
|
||||
{
|
||||
ID3D11Device* Device;
|
||||
ID3D11DeviceContext* DeviceContext;
|
||||
ID3D11SamplerState* SamplerDefault;
|
||||
ID3D11Buffer* VertexConstantBuffer;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
|
|
@ -3,15 +3,11 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||
// To build this on 32-bit systems:
|
||||
// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
|
||||
// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
|
||||
// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
|
||||
// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
|
||||
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -23,6 +19,13 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-12-09: DirectX12: Let user specifies the DepthStencilView format by setting ImGui_ImplDX12_InitInfo::DSVFormat.
|
||||
// 2024-11-15: DirectX12: *BREAKING CHANGE* Changed ImGui_ImplDX12_Init() signature to take a ImGui_ImplDX12_InitInfo struct. Legacy ImGui_ImplDX12_Init() signature is still supported (will obsolete).
|
||||
// 2024-11-15: DirectX12: *BREAKING CHANGE* User is now required to pass function pointers to allocate/free SRV Descriptors. We provide convenience legacy fields to pass a single descriptor, matching the old API, but upcoming features will want multiple.
|
||||
// 2024-10-23: DirectX12: Unmap() call specify written range. The range is informational and may be used by debug tools.
|
||||
// 2024-10-07: DirectX12: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-10-07: DirectX12: Expose selected render state in ImGui_ImplDX12_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-10-07: DirectX12: Compiling with '#define ImTextureID=ImU64' is unnecessary now that dear imgui defaults ImTextureID to u64 instead of void*.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
|
@ -53,23 +56,33 @@
|
|||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||
#endif
|
||||
|
||||
// DirectX data
|
||||
// DirectX12 data
|
||||
struct ImGui_ImplDX12_RenderBuffers;
|
||||
|
||||
struct ImGui_ImplDX12_Texture
|
||||
{
|
||||
ID3D12Resource* pTextureResource;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||
};
|
||||
|
||||
struct ImGui_ImplDX12_Data
|
||||
{
|
||||
ImGui_ImplDX12_InitInfo InitInfo;
|
||||
ID3D12Device* pd3dDevice;
|
||||
ID3D12RootSignature* pRootSignature;
|
||||
ID3D12PipelineState* pPipelineState;
|
||||
DXGI_FORMAT RTVFormat;
|
||||
ID3D12Resource* pFontTextureResource;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||
DXGI_FORMAT DSVFormat;
|
||||
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
||||
UINT numFramesInFlight;
|
||||
|
||||
ImGui_ImplDX12_RenderBuffers* pFrameResources;
|
||||
UINT frameIndex;
|
||||
|
||||
ImGui_ImplDX12_Texture FontTexture;
|
||||
bool LegacySingleDescriptorUsed;
|
||||
|
||||
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); frameIndex = UINT_MAX; }
|
||||
};
|
||||
|
||||
|
@ -95,7 +108,7 @@ struct VERTEX_CONSTANT_BUFFER_DX12
|
|||
};
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr)
|
||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* command_list, ImGui_ImplDX12_RenderBuffers* fr)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
|
||||
|
@ -125,7 +138,7 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
|
|||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0.0f;
|
||||
ctx->RSSetViewports(1, &vp);
|
||||
command_list->RSSetViewports(1, &vp);
|
||||
|
||||
// Bind shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
|
@ -135,21 +148,21 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
|
|||
vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset;
|
||||
vbv.SizeInBytes = fr->VertexBufferSize * stride;
|
||||
vbv.StrideInBytes = stride;
|
||||
ctx->IASetVertexBuffers(0, 1, &vbv);
|
||||
command_list->IASetVertexBuffers(0, 1, &vbv);
|
||||
D3D12_INDEX_BUFFER_VIEW ibv;
|
||||
memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW));
|
||||
ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress();
|
||||
ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
|
||||
ctx->IASetIndexBuffer(&ibv);
|
||||
ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->SetPipelineState(bd->pPipelineState);
|
||||
ctx->SetGraphicsRootSignature(bd->pRootSignature);
|
||||
ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
|
||||
command_list->IASetIndexBuffer(&ibv);
|
||||
command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
command_list->SetPipelineState(bd->pPipelineState);
|
||||
command_list->SetGraphicsRootSignature(bd->pRootSignature);
|
||||
command_list->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
|
||||
|
||||
// Setup blend factor
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
ctx->OMSetBlendFactor(blend_factor);
|
||||
command_list->OMSetBlendFactor(blend_factor);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -161,7 +174,7 @@ static inline void SafeRelease(T*& res)
|
|||
}
|
||||
|
||||
// Render function
|
||||
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx)
|
||||
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* command_list)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
|
@ -222,9 +235,9 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||
}
|
||||
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
// During Map() we specify a null read range (as per DX12 API, this is informational and for tooling only)
|
||||
void* vtx_resource, *idx_resource;
|
||||
D3D12_RANGE range;
|
||||
memset(&range, 0, sizeof(D3D12_RANGE));
|
||||
D3D12_RANGE range = { 0, 0 };
|
||||
if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK)
|
||||
return;
|
||||
if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK)
|
||||
|
@ -233,17 +246,30 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
|
||||
// During Unmap() we specify the written range (as per DX12 API, this is informational and for tooling only)
|
||||
range.End = (SIZE_T)((intptr_t)vtx_dst - (intptr_t)vtx_resource);
|
||||
IM_ASSERT(range.End == draw_data->TotalVtxCount * sizeof(ImDrawVert));
|
||||
fr->VertexBuffer->Unmap(0, &range);
|
||||
range.End = (SIZE_T)((intptr_t)idx_dst - (intptr_t)idx_resource);
|
||||
IM_ASSERT(range.End == draw_data->TotalIdxCount * sizeof(ImDrawIdx));
|
||||
fr->IndexBuffer->Unmap(0, &range);
|
||||
|
||||
// Setup desired DX state
|
||||
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
|
||||
ImGui_ImplDX12_SetupRenderState(draw_data, command_list, fr);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplDX12_RenderState render_state;
|
||||
render_state.Device = bd->pd3dDevice;
|
||||
render_state.CommandList = command_list;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
|
@ -252,18 +278,18 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
|
||||
ImGui_ImplDX12_SetupRenderState(draw_data, command_list, fr);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -273,18 +299,21 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
command_list->RSSetScissorRects(1, &r);
|
||||
|
||||
// Bind texture, Draw
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
|
||||
texture_handle.ptr = (UINT64)pcmd->GetTexID();
|
||||
ctx->SetGraphicsRootDescriptorTable(1, texture_handle);
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
command_list->SetGraphicsRootDescriptorTable(1, texture_handle);
|
||||
command_list->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
|
@ -297,6 +326,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
|||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
|
||||
// Upload texture to graphics system
|
||||
ImGui_ImplDX12_Texture* font_tex = &bd->FontTexture;
|
||||
{
|
||||
D3D12_HEAP_PROPERTIES props;
|
||||
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||
|
@ -379,7 +409,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
|||
hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
HANDLE event = CreateEvent(0, 0, 0, 0);
|
||||
HANDLE event = ::CreateEvent(0, 0, 0, 0);
|
||||
IM_ASSERT(event != nullptr);
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
|
@ -410,12 +440,12 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
|||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
fence->SetEventOnCompletion(1, event);
|
||||
WaitForSingleObject(event, INFINITE);
|
||||
::WaitForSingleObject(event, INFINITE);
|
||||
|
||||
cmdList->Release();
|
||||
cmdAlloc->Release();
|
||||
cmdQueue->Release();
|
||||
CloseHandle(event);
|
||||
::CloseHandle(event);
|
||||
fence->Release();
|
||||
uploadBuffer->Release();
|
||||
|
||||
|
@ -427,21 +457,13 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
|||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, bd->hFontSrvCpuDescHandle);
|
||||
SafeRelease(bd->pFontTextureResource);
|
||||
bd->pFontTextureResource = pTexture;
|
||||
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, font_tex->hFontSrvCpuDescHandle);
|
||||
SafeRelease(font_tex->pTextureResource);
|
||||
font_tex->pTextureResource = pTexture;
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
// READ THIS IF THE STATIC_ASSERT() TRIGGERS:
|
||||
// - Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
// - This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||
// [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
|
||||
// [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
|
||||
// [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
|
||||
// [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
|
||||
static_assert(sizeof(ImTextureID) >= sizeof(bd->hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
|
||||
io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr);
|
||||
io.Fonts->SetTexID((ImTextureID)font_tex->hFontSrvGpuDescHandle.ptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
|
@ -477,9 +499,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||
D3D12_STATIC_SAMPLER_DESC staticSampler = {};
|
||||
staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler.MipLODBias = 0.f;
|
||||
staticSampler.MaxAnisotropy = 0;
|
||||
staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||
|
@ -549,6 +571,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||
psoDesc.SampleMask = UINT_MAX;
|
||||
psoDesc.NumRenderTargets = 1;
|
||||
psoDesc.RTVFormats[0] = bd->RTVFormat;
|
||||
psoDesc.DSVFormat = bd->DSVFormat;
|
||||
psoDesc.SampleDesc.Count = 1;
|
||||
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
|
||||
|
||||
|
@ -687,8 +710,12 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
|
|||
ImGuiIO& io = ImGui::GetIO();
|
||||
SafeRelease(bd->pRootSignature);
|
||||
SafeRelease(bd->pPipelineState);
|
||||
SafeRelease(bd->pFontTextureResource);
|
||||
io.Fonts->SetTexID(0); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
|
||||
// Free SRV descriptor used by texture
|
||||
ImGui_ImplDX12_Texture* font_tex = &bd->FontTexture;
|
||||
bd->InitInfo.SrvDescriptorFreeFn(&bd->InitInfo, font_tex->hFontSrvCpuDescHandle, font_tex->hFontSrvGpuDescHandle);
|
||||
SafeRelease(font_tex->pTextureResource);
|
||||
io.Fonts->SetTexID(0); // We copied bd->hFontSrvGpuDescHandle to io.Fonts->TexID so let's clear that as well.
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
|
@ -698,8 +725,7 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
|
|||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
|
||||
bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
|
@ -707,21 +733,49 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
|
|||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplDX12_Data* bd = IM_NEW(ImGui_ImplDX12_Data)();
|
||||
bd->InitInfo = *init_info; // Deep copy
|
||||
init_info = &bd->InitInfo;
|
||||
|
||||
bd->pd3dDevice = init_info->Device;
|
||||
bd->RTVFormat = init_info->RTVFormat;
|
||||
bd->DSVFormat = init_info->DSVFormat;
|
||||
bd->numFramesInFlight = init_info->NumFramesInFlight;
|
||||
bd->pd3dSrvDescHeap = init_info->SrvDescriptorHeap;
|
||||
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx12";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
bd->pd3dDevice = device;
|
||||
bd->RTVFormat = rtv_format;
|
||||
bd->hFontSrvCpuDescHandle = font_srv_cpu_desc_handle;
|
||||
bd->hFontSrvGpuDescHandle = font_srv_gpu_desc_handle;
|
||||
bd->pFrameResources = new ImGui_ImplDX12_RenderBuffers[num_frames_in_flight];
|
||||
bd->numFramesInFlight = num_frames_in_flight;
|
||||
bd->pd3dSrvDescHeap = cbv_srv_heap;
|
||||
bd->frameIndex = UINT_MAX;
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
if (init_info->SrvDescriptorAllocFn == nullptr)
|
||||
{
|
||||
// Wrap legacy behavior of passing space for a single descriptor
|
||||
IM_ASSERT(init_info->LegacySingleSrvCpuDescriptor.ptr != 0 && init_info->LegacySingleSrvGpuDescriptor.ptr != 0);
|
||||
init_info->SrvDescriptorAllocFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_handle)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
IM_ASSERT(bd->LegacySingleDescriptorUsed == false);
|
||||
*out_cpu_handle = bd->InitInfo.LegacySingleSrvCpuDescriptor;
|
||||
*out_gpu_handle = bd->InitInfo.LegacySingleSrvGpuDescriptor;
|
||||
bd->LegacySingleDescriptorUsed = true;
|
||||
};
|
||||
init_info->SrvDescriptorFreeFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_GPU_DESCRIPTOR_HANDLE)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
IM_ASSERT(bd->LegacySingleDescriptorUsed == true);
|
||||
bd->LegacySingleDescriptorUsed = false;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allocate 1 SRV descriptor for the font texture
|
||||
IM_ASSERT(init_info->SrvDescriptorAllocFn != nullptr && init_info->SrvDescriptorFreeFn != nullptr);
|
||||
init_info->SrvDescriptorAllocFn(&bd->InitInfo, &bd->FontTexture.hFontSrvCpuDescHandle, &bd->FontTexture.hFontSrvGpuDescHandle);
|
||||
|
||||
// Create buffers with a default size (they will later be grown as needed)
|
||||
for (int i = 0; i < num_frames_in_flight; i++)
|
||||
bd->frameIndex = UINT_MAX;
|
||||
bd->pFrameResources = new ImGui_ImplDX12_RenderBuffers[bd->numFramesInFlight];
|
||||
for (int i = 0; i < (int)bd->numFramesInFlight; i++)
|
||||
{
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
|
||||
fr->IndexBuffer = nullptr;
|
||||
|
@ -733,6 +787,22 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// Legacy initialization API Obsoleted in 1.91.5
|
||||
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture, they must be in 'srv_descriptor_heap'
|
||||
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* srv_descriptor_heap, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
|
||||
{
|
||||
ImGui_ImplDX12_InitInfo init_info;
|
||||
init_info.Device = device;
|
||||
init_info.NumFramesInFlight = num_frames_in_flight;
|
||||
init_info.RTVFormat = rtv_format;
|
||||
init_info.SrvDescriptorHeap = srv_descriptor_heap;
|
||||
init_info.LegacySingleSrvCpuDescriptor = font_srv_cpu_desc_handle;
|
||||
init_info.LegacySingleSrvGpuDescriptor = font_srv_gpu_desc_handle;;
|
||||
return ImGui_ImplDX12_Init(&init_info);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ImGui_ImplDX12_Shutdown()
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
|
@ -742,6 +812,7 @@ void ImGui_ImplDX12_Shutdown()
|
|||
// Clean up windows and device objects
|
||||
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
delete[] bd->pFrameResources;
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
// See imgui_impl_dx12.cpp file for details.
|
||||
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -20,25 +21,54 @@
|
|||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include <dxgiformat.h> // DXGI_FORMAT
|
||||
#include <d3d12.h> // D3D12_CPU_DESCRIPTOR_HANDLE
|
||||
|
||||
struct ID3D12Device;
|
||||
struct ID3D12DescriptorHeap;
|
||||
struct ID3D12GraphicsCommandList;
|
||||
struct D3D12_CPU_DESCRIPTOR_HANDLE;
|
||||
struct D3D12_GPU_DESCRIPTOR_HANDLE;
|
||||
// Initialization data, for ImGui_ImplDX12_Init()
|
||||
struct ImGui_ImplDX12_InitInfo
|
||||
{
|
||||
ID3D12Device* Device;
|
||||
ID3D12CommandQueue* CommandQueue;
|
||||
int NumFramesInFlight;
|
||||
DXGI_FORMAT RTVFormat; // RenderTarget format.
|
||||
DXGI_FORMAT DSVFormat; // DepthStencilView format.
|
||||
void* UserData;
|
||||
|
||||
// cmd_list is the command list that the implementation will use to render imgui draw lists.
|
||||
// Before calling the render function, caller must prepare cmd_list by resetting it and setting the appropriate
|
||||
// render target and descriptor heap that contains font_srv_cpu_desc_handle/font_srv_gpu_desc_handle.
|
||||
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture.
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle);
|
||||
// Allocating SRV descriptors for textures is up to the application, so we provide callbacks.
|
||||
// (current version of the backend will only allocate one descriptor, future versions will need to allocate more)
|
||||
ID3D12DescriptorHeap* SrvDescriptorHeap;
|
||||
void (*SrvDescriptorAllocFn)(ImGui_ImplDX12_InitInfo* info, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_desc_handle);
|
||||
void (*SrvDescriptorFreeFn)(ImGui_ImplDX12_InitInfo* info, D3D12_CPU_DESCRIPTOR_HANDLE cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE gpu_desc_handle);
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE LegacySingleSrvCpuDescriptor; // To facilitate transition from single descriptor to allocator callback, you may use those.
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE LegacySingleSrvGpuDescriptor;
|
||||
#endif
|
||||
|
||||
ImGui_ImplDX12_InitInfo() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// Legacy initialization API Obsoleted in 1.91.5
|
||||
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture, they must be in 'srv_descriptor_heap'
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* srv_descriptor_heap, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle);
|
||||
#endif
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX12_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplDX12_RenderState
|
||||
{
|
||||
ID3D12Device* Device;
|
||||
ID3D12GraphicsCommandList* CommandList;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: IMGUI_USE_BGRA_PACKED_COLOR support, as this is the optimal color encoding for DirectX9.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -15,6 +16,7 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-10-07: DirectX9: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-02-12: DirectX9: Using RGBA format when supported by the driver to avoid CPU side conversion. (#6575)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
|
@ -51,6 +53,7 @@ struct ImGui_ImplDX9_Data
|
|||
LPDIRECT3DTEXTURE9 FontTexture;
|
||||
int VertexBufferSize;
|
||||
int IndexBufferSize;
|
||||
bool HasRgbaSupport;
|
||||
|
||||
ImGui_ImplDX9_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||
};
|
||||
|
@ -88,41 +91,45 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
|||
vp.Height = (DWORD)draw_data->DisplaySize.y;
|
||||
vp.MinZ = 0.0f;
|
||||
vp.MaxZ = 1.0f;
|
||||
bd->pd3dDevice->SetViewport(&vp);
|
||||
|
||||
LPDIRECT3DDEVICE9 device = bd->pd3dDevice;
|
||||
device->SetViewport(&vp);
|
||||
|
||||
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient), bilinear sampling.
|
||||
bd->pd3dDevice->SetPixelShader(nullptr);
|
||||
bd->pd3dDevice->SetVertexShader(nullptr);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device->SetPixelShader(nullptr);
|
||||
device->SetVertexShader(nullptr);
|
||||
device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
||||
device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
|
||||
device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
device->SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
||||
device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
|
||||
device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
|
||||
device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
device->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_CLIPPING, TRUE);
|
||||
device->SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
// Setup orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
|
@ -140,9 +147,9 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
|||
0.0f, 0.0f, 0.5f, 0.0f,
|
||||
(L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f
|
||||
} } };
|
||||
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
|
||||
device->SetTransform(D3DTS_WORLD, &mat_identity);
|
||||
device->SetTransform(D3DTS_VIEW, &mat_identity);
|
||||
device->SetTransform(D3DTS_PROJECTION, &mat_projection);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,51 +160,53 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
// Create and grow buffers if needed
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
LPDIRECT3DDEVICE9 device = bd->pd3dDevice;
|
||||
|
||||
// Create and grow buffers if needed
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
if (bd->pd3dDevice->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0)
|
||||
if (device->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0)
|
||||
return;
|
||||
}
|
||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0)
|
||||
if (device->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Backup the DX9 state
|
||||
IDirect3DStateBlock9* d3d9_state_block = nullptr;
|
||||
if (bd->pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
|
||||
IDirect3DStateBlock9* state_block = nullptr;
|
||||
if (device->CreateStateBlock(D3DSBT_ALL, &state_block) < 0)
|
||||
return;
|
||||
if (d3d9_state_block->Capture() < 0)
|
||||
if (state_block->Capture() < 0)
|
||||
{
|
||||
d3d9_state_block->Release();
|
||||
state_block->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
// Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to)
|
||||
D3DMATRIX last_world, last_view, last_projection;
|
||||
bd->pd3dDevice->GetTransform(D3DTS_WORLD, &last_world);
|
||||
bd->pd3dDevice->GetTransform(D3DTS_VIEW, &last_view);
|
||||
bd->pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection);
|
||||
device->GetTransform(D3DTS_WORLD, &last_world);
|
||||
device->GetTransform(D3DTS_VIEW, &last_view);
|
||||
device->GetTransform(D3DTS_PROJECTION, &last_projection);
|
||||
|
||||
// Allocate buffers
|
||||
CUSTOMVERTEX* vtx_dst;
|
||||
ImDrawIdx* idx_dst;
|
||||
if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
|
||||
{
|
||||
d3d9_state_block->Release();
|
||||
state_block->Release();
|
||||
return;
|
||||
}
|
||||
if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
|
||||
{
|
||||
bd->pVB->Unlock();
|
||||
d3d9_state_block->Release();
|
||||
state_block->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -207,9 +216,9 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||
// 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data;
|
||||
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_src = draw_list->VtxBuffer.Data;
|
||||
for (int i = 0; i < draw_list->VtxBuffer.Size; i++)
|
||||
{
|
||||
vtx_dst->pos[0] = vtx_src->pos.x;
|
||||
vtx_dst->pos[1] = vtx_src->pos.y;
|
||||
|
@ -220,14 +229,14 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||
vtx_dst++;
|
||||
vtx_src++;
|
||||
}
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
bd->pVB->Unlock();
|
||||
bd->pIB->Unlock();
|
||||
bd->pd3dDevice->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX));
|
||||
bd->pd3dDevice->SetIndices(bd->pIB);
|
||||
bd->pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
|
||||
device->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX));
|
||||
device->SetIndices(bd->pIB);
|
||||
device->SetFVF(D3DFVF_CUSTOMVERTEX);
|
||||
|
||||
// Setup desired DX state
|
||||
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||
|
@ -239,10 +248,10 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
|
@ -250,7 +259,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -260,26 +269,46 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||
// Apply scissor/clipping rectangle
|
||||
const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
device->SetScissorRect(&r);
|
||||
|
||||
// Bind texture, Draw
|
||||
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
|
||||
bd->pd3dDevice->SetTexture(0, texture);
|
||||
bd->pd3dDevice->SetScissorRect(&r);
|
||||
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
|
||||
device->SetTexture(0, texture);
|
||||
device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)draw_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
// Restore the DX9 transform
|
||||
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection);
|
||||
device->SetTransform(D3DTS_WORLD, &last_world);
|
||||
device->SetTransform(D3DTS_VIEW, &last_view);
|
||||
device->SetTransform(D3DTS_PROJECTION, &last_projection);
|
||||
|
||||
// Restore the DX9 state
|
||||
d3d9_state_block->Apply();
|
||||
d3d9_state_block->Release();
|
||||
state_block->Apply();
|
||||
state_block->Release();
|
||||
}
|
||||
|
||||
static bool ImGui_ImplDX9_CheckFormatSupport(LPDIRECT3DDEVICE9 pDevice, D3DFORMAT format)
|
||||
{
|
||||
LPDIRECT3D9 pd3d = nullptr;
|
||||
if (pDevice->GetDirect3D(&pd3d) != D3D_OK)
|
||||
return false;
|
||||
D3DDEVICE_CREATION_PARAMETERS param = {};
|
||||
D3DDISPLAYMODE mode = {};
|
||||
if (pDevice->GetCreationParameters(¶m) != D3D_OK || pDevice->GetDisplayMode(0, &mode) != D3D_OK)
|
||||
{
|
||||
pd3d->Release();
|
||||
return false;
|
||||
}
|
||||
// Font texture should support linear filter, color blend and write to render-target
|
||||
bool support = (pd3d->CheckDeviceFormat(param.AdapterOrdinal, param.DeviceType, mode.Format, D3DUSAGE_DYNAMIC | D3DUSAGE_QUERY_FILTER | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, format)) == D3D_OK;
|
||||
pd3d->Release();
|
||||
return support;
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
||||
|
@ -296,6 +325,7 @@ bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
|||
|
||||
bd->pd3dDevice = device;
|
||||
bd->pd3dDevice->AddRef();
|
||||
bd->HasRgbaSupport = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -314,22 +344,26 @@ void ImGui_ImplDX9_Shutdown()
|
|||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplDX9_CheckFormatSupport(IDirect3DDevice9* pDevice, D3DFORMAT format)
|
||||
// Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
|
||||
static void ImGui_ImplDX9_CopyTextureRegion(bool tex_use_colors, ImU32* src, int src_pitch, ImU32* dst, int dst_pitch, int w, int h)
|
||||
{
|
||||
IDirect3D9* pd3d = nullptr;
|
||||
if (pDevice->GetDirect3D(&pd3d) != D3D_OK)
|
||||
return false;
|
||||
D3DDEVICE_CREATION_PARAMETERS param = {};
|
||||
D3DDISPLAYMODE mode = {};
|
||||
if (pDevice->GetCreationParameters(¶m) != D3D_OK || pDevice->GetDisplayMode(0, &mode) != D3D_OK)
|
||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
const bool convert_rgba_to_bgra = (!bd->HasRgbaSupport && tex_use_colors);
|
||||
#else
|
||||
const bool convert_rgba_to_bgra = false;
|
||||
IM_UNUSED(tex_use_colors);
|
||||
#endif
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
pd3d->Release();
|
||||
return false;
|
||||
ImU32* src_p = (ImU32*)((unsigned char*)src + src_pitch * y);
|
||||
ImU32* dst_p = (ImU32*)((unsigned char*)dst + dst_pitch * y);
|
||||
if (convert_rgba_to_bgra)
|
||||
for (int x = w; x > 0; x--, src_p++, dst_p++) // Convert copy
|
||||
*dst_p = IMGUI_COL_TO_DX9_ARGB(*src_p);
|
||||
else
|
||||
memcpy(dst_p, src_p, w * 4); // Raw copy
|
||||
}
|
||||
// Font texture should support linear filter, color blend and write to render-target
|
||||
bool support = (pd3d->CheckDeviceFormat(param.AdapterOrdinal, param.DeviceType, mode.Format, D3DUSAGE_DYNAMIC | D3DUSAGE_QUERY_FILTER | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, format)) == D3D_OK;
|
||||
pd3d->Release();
|
||||
return support;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplDX9_CreateFontsTexture()
|
||||
|
@ -341,39 +375,18 @@ static bool ImGui_ImplDX9_CreateFontsTexture()
|
|||
int width, height, bytes_per_pixel;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel);
|
||||
|
||||
// Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
|
||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
const bool rgba_support = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8);
|
||||
if (!rgba_support && io.Fonts->TexPixelsUseColors)
|
||||
{
|
||||
ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel);
|
||||
for (ImU32* src = (ImU32*)pixels, *dst = dst_start, *dst_end = dst_start + (size_t)width * height; dst < dst_end; src++, dst++)
|
||||
*dst = IMGUI_COL_TO_DX9_ARGB(*src);
|
||||
pixels = (unsigned char*)dst_start;
|
||||
}
|
||||
#else
|
||||
const bool rgba_support = false;
|
||||
#endif
|
||||
|
||||
// Upload texture to graphics system
|
||||
bd->FontTexture = nullptr;
|
||||
if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, rgba_support ? D3DFMT_A8B8G8R8 : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0)
|
||||
if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, bd->HasRgbaSupport ? D3DFMT_A8B8G8R8 : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0)
|
||||
return false;
|
||||
D3DLOCKED_RECT tex_locked_rect;
|
||||
if (bd->FontTexture->LockRect(0, &tex_locked_rect, nullptr, 0) != D3D_OK)
|
||||
return false;
|
||||
for (int y = 0; y < height; y++)
|
||||
memcpy((unsigned char*)tex_locked_rect.pBits + (size_t)tex_locked_rect.Pitch * y, pixels + (size_t)width * bytes_per_pixel * y, (size_t)width * bytes_per_pixel);
|
||||
ImGui_ImplDX9_CopyTextureRegion(io.Fonts->TexPixelsUseColors, (ImU32*)pixels, width * bytes_per_pixel, (ImU32*)tex_locked_rect.pBits, (int)tex_locked_rect.Pitch, width, height);
|
||||
bd->FontTexture->UnlockRect(0);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)bd->FontTexture);
|
||||
|
||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
if (!rgba_support && io.Fonts->TexPixelsUseColors)
|
||||
ImGui::MemFree(pixels);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: IMGUI_USE_BGRA_PACKED_COLOR support, as this is the optimal color encoding for DirectX9.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -19,6 +20,7 @@
|
|||
|
||||
struct IDirect3DDevice9;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame();
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -18,8 +18,21 @@
|
|||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// About Emscripten support:
|
||||
// - Emscripten provides its own GLFW (3.2.1) implementation (syntax: "-sUSE_GLFW=3"), but Joystick is broken and several features are not supported (multiple windows, clipboard, timer, etc.)
|
||||
// - A third-party Emscripten GLFW (3.4.0) implementation (syntax: "--use-port=contrib.glfw3") fixes the Joystick issue and implements all relevant features for the browser.
|
||||
// See https://github.com/pongasoft/emscripten-glfw/blob/master/docs/Comparison.md for details.
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||
// - io.PlatformOpenInShellFn -> platform_io.Platform_OpenInShellFn
|
||||
// 2024-07-31: Added ImGui_ImplGlfw_Sleep() helper function for usage by our examples app, since GLFW doesn't provide one.
|
||||
// 2024-07-08: *BREAKING* Renamed ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback to ImGui_ImplGlfw_InstallEmscriptenCallbacks(), added GLFWWindow* parameter.
|
||||
// 2024-07-08: Emscripten: Added support for GLFW3 contrib port (GLFW 3.4.0 features + bug fixes): to enable, replace -sUSE_GLFW=3 with --use-port=contrib.glfw3 (requires emscripten 3.1.59+) (https://github.com/pongasoft/emscripten-glfw)
|
||||
// 2024-07-02: Emscripten: Added io.PlatformOpenInShellFn() handler for Emscripten versions.
|
||||
// 2023-12-19: Emscripten: Added ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback() to register canvas selector and auto-resize GLFW window.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys.
|
||||
// 2023-07-18: Inputs: Revert ignoring mouse data on GLFW_CURSOR_DISABLED as it can be used differently. User may set ImGuiConfigFLags_NoMouse if desired. (#5625, #6609)
|
||||
|
@ -96,10 +109,18 @@
|
|||
#endif
|
||||
#include <GLFW/glfw3native.h> // for glfwGetCocoaWindow()
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h> // for usleep()
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3
|
||||
#include <GLFW/emscripten_glfw3.h>
|
||||
#else
|
||||
#define EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// We gather version tests as define in order to easily see which features are version-dependent.
|
||||
|
@ -131,7 +152,7 @@ struct ImGui_ImplGlfw_Data
|
|||
ImVec2 LastValidMousePos;
|
||||
bool InstalledCallbacks;
|
||||
bool CallbacksChainForAllWindows;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
const char* CanvasSelector;
|
||||
#endif
|
||||
|
||||
|
@ -145,7 +166,7 @@ struct ImGui_ImplGlfw_Data
|
|||
GLFWcharfun PrevUserCallbackChar;
|
||||
GLFWmonitorfun PrevUserCallbackMonitor;
|
||||
#ifdef _WIN32
|
||||
WNDPROC GlfwWndProc;
|
||||
WNDPROC PrevWndProc;
|
||||
#endif
|
||||
|
||||
ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
|
@ -164,19 +185,13 @@ static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()
|
|||
}
|
||||
|
||||
// Functions
|
||||
static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data)
|
||||
{
|
||||
return glfwGetClipboardString((GLFWwindow*)user_data);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode);
|
||||
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode)
|
||||
{
|
||||
glfwSetClipboardString((GLFWwindow*)user_data, text);
|
||||
}
|
||||
|
||||
static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
|
||||
{
|
||||
switch (key)
|
||||
IM_UNUSED(scancode);
|
||||
switch (keycode)
|
||||
{
|
||||
case GLFW_KEY_TAB: return ImGuiKey_Tab;
|
||||
case GLFW_KEY_LEFT: return ImGuiKey_LeftArrow;
|
||||
|
@ -335,7 +350,7 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo
|
|||
if (bd->PrevUserCallbackScroll != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
||||
bd->PrevUserCallbackScroll(window, xoffset, yoffset);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
// Ignore GLFW events: will be processed in ImGui_ImplEmscripten_WheelCallback().
|
||||
return;
|
||||
#endif
|
||||
|
@ -344,9 +359,10 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo
|
|||
io.AddMouseWheelEvent((float)xoffset, (float)yoffset);
|
||||
}
|
||||
|
||||
// FIXME: should this be baked into ImGui_ImplGlfw_KeyToImGuiKey()? then what about the values passed to io.SetKeyEventNativeData()?
|
||||
static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
|
||||
{
|
||||
#if GLFW_HAS_GETKEYNAME && !defined(__EMSCRIPTEN__)
|
||||
#if GLFW_HAS_GETKEYNAME && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3)
|
||||
// GLFW 3.1+ attempts to "untranslate" keys, which goes the opposite of what every other framework does, making using lettered shortcuts difficult.
|
||||
// (It had reasons to do so: namely GLFW is/was more likely to be used for WASD-type game controls rather than lettered shortcuts, but IHMO the 3.1 change could have been done differently)
|
||||
// See https://github.com/glfw/glfw/issues/1502 for details.
|
||||
|
@ -357,7 +373,7 @@ static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
|
|||
GLFWerrorfun prev_error_callback = glfwSetErrorCallback(nullptr);
|
||||
const char* key_name = glfwGetKeyName(key, scancode);
|
||||
glfwSetErrorCallback(prev_error_callback);
|
||||
#if GLFW_HAS_GETERROR && !defined(__EMSCRIPTEN__) // Eat errors (see #5908)
|
||||
#if GLFW_HAS_GETERROR && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3) // Eat errors (see #5908)
|
||||
(void)glfwGetError(nullptr);
|
||||
#endif
|
||||
if (key_name && key_name[0] != 0 && key_name[1] == 0)
|
||||
|
@ -391,7 +407,7 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
|
|||
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode);
|
||||
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode, scancode);
|
||||
io.AddKeyEvent(imgui_key, (action == GLFW_PRESS));
|
||||
io.SetKeyEventNativeData(imgui_key, keycode, scancode); // To support legacy indexing (<1.87 user code)
|
||||
}
|
||||
|
@ -454,7 +470,7 @@ void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
|||
// Unused in 'master' branch but 'docking' branch will use this, so we declare it ahead of it so if you have to install callbacks you can install this one too.
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEvent* ev, void*)
|
||||
{
|
||||
// Mimic Emscripten_HandleWheel() in SDL.
|
||||
|
@ -497,7 +513,7 @@ static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wPara
|
|||
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
||||
break;
|
||||
}
|
||||
return ::CallWindowProcW(bd->GlfwWndProc, hWnd, msg, wParam, lParam);
|
||||
return ::CallWindowProcW(bd->PrevWndProc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -553,6 +569,14 @@ void ImGui_ImplGlfw_SetCallbacksChainForAllWindows(bool chain_for_all_windows)
|
|||
bd->CallbacksChainForAllWindows = chain_for_all_windows;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
|
||||
void ImGui_ImplGlfw_EmscriptenOpenURL(const char* url) { if (url) emscripten::glfw3::OpenURL(url); }
|
||||
#else
|
||||
EM_JS(void, ImGui_ImplGlfw_EmscriptenOpenURL, (const char* url), { url = url ? UTF8ToString(url) : null; if (url) window.open(url, '_blank'); });
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
@ -570,9 +594,12 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||
bd->Window = window;
|
||||
bd->Time = 0.0;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
|
||||
io.ClipboardUserData = bd->Window;
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(nullptr, text); };
|
||||
platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) { return glfwGetClipboardString(nullptr); };
|
||||
#ifdef __EMSCRIPTEN__
|
||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplGlfw_EmscriptenOpenURL(url); return true; };
|
||||
#endif
|
||||
|
||||
// Create mouse cursors
|
||||
// (By design, on X11 cursors are user configurable and some cursors may be missing. When a cursor doesn't exist,
|
||||
|
@ -603,15 +630,10 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
|
||||
if (install_callbacks)
|
||||
ImGui_ImplGlfw_InstallCallbacks(window);
|
||||
// Register Emscripten Wheel callback to workaround issue in Emscripten GLFW Emulation (#6096)
|
||||
// We intentionally do not check 'if (install_callbacks)' here, as some users may set it to false and call GLFW callback themselves.
|
||||
// FIXME: May break chaining in case user registered their own Emscripten callback?
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, false, ImGui_ImplEmscripten_WheelCallback);
|
||||
#endif
|
||||
|
||||
// Set platform dependent data in viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = (void*)bd->Window;
|
||||
#ifdef _WIN32
|
||||
main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window);
|
||||
#elif defined(__APPLE__)
|
||||
|
@ -622,11 +644,28 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||
|
||||
// Windows: register a WndProc hook so we can intercept some messages.
|
||||
#ifdef _WIN32
|
||||
bd->GlfwWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
||||
IM_ASSERT(bd->GlfwWndProc != nullptr);
|
||||
bd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
||||
IM_ASSERT(bd->PrevWndProc != nullptr);
|
||||
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||
#endif
|
||||
|
||||
// Emscripten: the same application can run on various platforms, so we detect the Apple platform at runtime
|
||||
// to override io.ConfigMacOSXBehaviors from its default (which is always false in Emscripten).
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
|
||||
if (emscripten::glfw3::IsRuntimePlatformApple())
|
||||
{
|
||||
ImGui::GetIO().ConfigMacOSXBehaviors = true;
|
||||
|
||||
// Due to how the browser (poorly) handles the Meta Key, this line essentially disables repeats when used.
|
||||
// This means that Meta + V only registers a single key-press, even if the keys are held.
|
||||
// This is a compromise for dealing with this issue in ImGui since ImGui implements key repeat itself.
|
||||
// See https://github.com/pongasoft/emscripten-glfw/blob/v3.4.0.20240817/docs/Usage.md#the-problem-of-the-super-key
|
||||
emscripten::glfw3::SetSuperPlusKeyTimeouts(10, 10);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bd->ClientApi = client_api;
|
||||
return true;
|
||||
}
|
||||
|
@ -654,18 +693,19 @@ void ImGui_ImplGlfw_Shutdown()
|
|||
|
||||
if (bd->InstalledCallbacks)
|
||||
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, false, nullptr);
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
if (bd->CanvasSelector)
|
||||
emscripten_set_wheel_callback(bd->CanvasSelector, nullptr, false, nullptr);
|
||||
#endif
|
||||
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
glfwDestroyCursor(bd->MouseCursors[cursor_n]);
|
||||
|
||||
// Windows: register a WndProc hook so we can intercept some messages.
|
||||
// Windows: restore our WndProc hook
|
||||
#ifdef _WIN32
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->GlfwWndProc);
|
||||
bd->GlfwWndProc = nullptr;
|
||||
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc);
|
||||
bd->PrevWndProc = nullptr;
|
||||
#endif
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
|
@ -682,14 +722,14 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
|||
// (those braces are here to reduce diff with multi-viewports support in 'docking' branch)
|
||||
{
|
||||
GLFWwindow* window = bd->Window;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
const bool is_window_focused = true;
|
||||
#else
|
||||
const bool is_window_focused = glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0;
|
||||
#endif
|
||||
if (is_window_focused)
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
glfwSetCursorPos(window, (double)io.MousePos.x, (double)io.MousePos.y);
|
||||
|
||||
|
@ -740,7 +780,7 @@ static void ImGui_ImplGlfw_UpdateGamepads()
|
|||
return;
|
||||
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
#if GLFW_HAS_GAMEPAD_API && !defined(__EMSCRIPTEN__)
|
||||
#if GLFW_HAS_GAMEPAD_API && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3)
|
||||
GLFWgamepadstate gamepad;
|
||||
if (!glfwGetGamepadState(GLFW_JOYSTICK_1, &gamepad))
|
||||
return;
|
||||
|
@ -814,7 +854,17 @@ void ImGui_ImplGlfw_NewFrame()
|
|||
ImGui_ImplGlfw_UpdateGamepads();
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// GLFW doesn't provide a portable sleep function
|
||||
void ImGui_ImplGlfw_Sleep(int milliseconds)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::Sleep(milliseconds);
|
||||
#else
|
||||
usleep(milliseconds * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
static EM_BOOL ImGui_ImplGlfw_OnCanvasSizeChange(int event_type, const EmscriptenUiEvent* event, void* user_data)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
|
||||
|
@ -835,7 +885,7 @@ static EM_BOOL ImGui_ImplEmscripten_FullscreenChangeCallback(int event_type, con
|
|||
|
||||
// 'canvas_selector' is a CSS selector. The event listener is applied to the first element that matches the query.
|
||||
// STRING MUST PERSIST FOR THE APPLICATION DURATION. PLEASE USE A STRING LITERAL OR ENSURE POINTER WILL STAY VALID.
|
||||
void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector)
|
||||
void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow*, const char* canvas_selector)
|
||||
{
|
||||
IM_ASSERT(canvas_selector != nullptr);
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
|
@ -847,8 +897,24 @@ void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_sel
|
|||
|
||||
// Change the size of the GLFW window according to the size of the canvas
|
||||
ImGui_ImplGlfw_OnCanvasSizeChange(EMSCRIPTEN_EVENT_RESIZE, {}, bd);
|
||||
|
||||
// Register Emscripten Wheel callback to workaround issue in Emscripten GLFW Emulation (#6096)
|
||||
// We intentionally do not check 'if (install_callbacks)' here, as some users may set it to false and call GLFW callback themselves.
|
||||
// FIXME: May break chaining in case user registered their own Emscripten callback?
|
||||
emscripten_set_wheel_callback(bd->CanvasSelector, nullptr, false, ImGui_ImplEmscripten_WheelCallback);
|
||||
}
|
||||
#endif
|
||||
#elif defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3)
|
||||
// When using --use-port=contrib.glfw3 for the GLFW implementation, you can override the behavior of this call
|
||||
// by invoking emscripten_glfw_make_canvas_resizable afterward.
|
||||
// See https://github.com/pongasoft/emscripten-glfw/blob/master/docs/Usage.md#how-to-make-the-canvas-resizable-by-the-user for an explanation
|
||||
void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow* window, const char* canvas_selector)
|
||||
{
|
||||
GLFWwindow* w = (GLFWwindow*)(EM_ASM_INT({ return Module.glfwGetWindow(UTF8ToString($0)); }, canvas_selector));
|
||||
IM_ASSERT(window == w); // Sanity check
|
||||
IM_UNUSED(w);
|
||||
emscripten_glfw_make_canvas_resizable(window, "window", nullptr);
|
||||
}
|
||||
#endif // #ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -24,15 +24,17 @@
|
|||
struct GLFWwindow;
|
||||
struct GLFWmonitor;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();
|
||||
|
||||
// Emscripten related initialization phase methods
|
||||
// Emscripten related initialization phase methods (call after ImGui_ImplGlfw_InitForOpenGL)
|
||||
#ifdef __EMSCRIPTEN__
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow* window, const char* canvas_selector);
|
||||
//static inline void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector) { ImGui_ImplGlfw_InstallEmscriptenCallbacks(nullptr, canvas_selector); } } // Renamed in 1.91.0
|
||||
#endif
|
||||
|
||||
// GLFW callbacks install
|
||||
|
@ -55,4 +57,7 @@ IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key,
|
|||
IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event);
|
||||
|
||||
// GLFW helpers
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_Sleep(int milliseconds);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
// !!! Nowadays, prefer using GLFW or SDL instead!
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// Issues:
|
||||
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
||||
// [ ] Platform: Missing horizontal mouse wheel support.
|
||||
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
// !!! Nowadays, prefer using GLFW or SDL instead!
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// Issues:
|
||||
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
||||
// [ ] Platform: Missing horizontal mouse wheel support.
|
||||
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
||||
|
@ -26,6 +26,7 @@
|
|||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplGLUT_Init();
|
||||
IMGUI_IMPL_API void ImGui_ImplGLUT_InstallFuncs();
|
||||
IMGUI_IMPL_API void ImGui_ImplGLUT_Shutdown();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -25,6 +25,7 @@
|
|||
@class MTLRenderPassDescriptor;
|
||||
@protocol MTLDevice, MTLCommandBuffer, MTLRenderCommandEncoder;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplMetal_Init(id<MTLDevice> device);
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor);
|
||||
|
@ -51,6 +52,7 @@ IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects();
|
|||
#include <Metal/Metal.hpp>
|
||||
#ifndef __OBJC__
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplMetal_Init(MTL::Device* device);
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_NewFrame(MTL::RenderPassDescriptor* renderPassDescriptor);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -15,6 +15,7 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-01-08: Metal: Fixed memory leaks when using metal-cpp (#8276, #8166) or when using multiple contexts (#7419).
|
||||
// 2022-08-23: Metal: Update deprecated property 'sampleCount'->'rasterSampleCount'.
|
||||
// 2022-07-05: Metal: Add dispatch synchronization.
|
||||
// 2022-06-30: Metal: Use __bridge for ARC based systems.
|
||||
|
@ -76,7 +77,7 @@ struct ImGui_ImplMetal_Data
|
|||
{
|
||||
MetalContext* SharedMetalContext;
|
||||
|
||||
ImGui_ImplMetal_Data() { memset(this, 0, sizeof(*this)); }
|
||||
ImGui_ImplMetal_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; }
|
||||
|
@ -142,6 +143,7 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
|||
void ImGui_ImplMetal_Shutdown()
|
||||
{
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
IM_UNUSED(bd);
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGui_ImplMetal_DestroyDeviceObjects();
|
||||
ImGui_ImplMetal_DestroyBackendData();
|
||||
|
@ -156,8 +158,11 @@ void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor)
|
|||
{
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
IM_ASSERT(bd != nil && "Context or backend not initialized! Did you call ImGui_ImplMetal_Init()?");
|
||||
#ifdef IMGUI_IMPL_METAL_CPP
|
||||
bd->SharedMetalContext.framebufferDescriptor = [[[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor]autorelease];
|
||||
#else
|
||||
bd->SharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor];
|
||||
|
||||
#endif
|
||||
if (bd->SharedMetalContext.depthStencilState == nil)
|
||||
ImGui_ImplMetal_CreateDeviceObjects(bd->SharedMetalContext.device);
|
||||
}
|
||||
|
@ -246,14 +251,14 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
|||
size_t indexBufferOffset = 0;
|
||||
for (int n = 0; n < drawData->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = drawData->CmdLists[n];
|
||||
const ImDrawList* draw_list = drawData->CmdLists[n];
|
||||
|
||||
memcpy((char*)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy((char*)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
memcpy((char*)vertexBuffer.buffer.contents + vertexBufferOffset, draw_list->VtxBuffer.Data, (size_t)draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy((char*)indexBuffer.buffer.contents + indexBufferOffset, draw_list->IdxBuffer.Data, (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
|
@ -261,7 +266,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
|||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplMetal_SetupRenderState(drawData, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, vertexBufferOffset);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -291,7 +296,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
|||
|
||||
// Bind texture, Draw
|
||||
if (ImTextureID tex_id = pcmd->GetTexID())
|
||||
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0];
|
||||
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(void*)(intptr_t)(tex_id) atIndex:0];
|
||||
|
||||
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
|
||||
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||
|
@ -302,21 +307,18 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
|||
}
|
||||
}
|
||||
|
||||
vertexBufferOffset += (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
|
||||
indexBufferOffset += (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
|
||||
vertexBufferOffset += (size_t)draw_list->VtxBuffer.Size * sizeof(ImDrawVert);
|
||||
indexBufferOffset += (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx);
|
||||
}
|
||||
|
||||
__block MetalContext* sharedMetalContext = bd->SharedMetalContext;
|
||||
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer>)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
if (bd != nullptr)
|
||||
@synchronized(bd->SharedMetalContext.bufferCache)
|
||||
{
|
||||
@synchronized(bd->SharedMetalContext.bufferCache)
|
||||
{
|
||||
[bd->SharedMetalContext.bufferCache addObject:vertexBuffer];
|
||||
[bd->SharedMetalContext.bufferCache addObject:indexBuffer];
|
||||
}
|
||||
[sharedMetalContext.bufferCache addObject:vertexBuffer];
|
||||
[sharedMetalContext.bufferCache addObject:indexBuffer];
|
||||
}
|
||||
});
|
||||
}];
|
||||
|
@ -347,7 +349,7 @@ bool ImGui_ImplMetal_CreateFontsTexture(id<MTLDevice> device)
|
|||
id <MTLTexture> texture = [device newTextureWithDescriptor:textureDescriptor];
|
||||
[texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)width, (NSUInteger)height) mipmapLevel:0 withBytes:pixels bytesPerRow:(NSUInteger)width * 4];
|
||||
bd->SharedMetalContext.fontTexture = texture;
|
||||
io.Fonts->SetTexID((__bridge void*)bd->SharedMetalContext.fontTexture); // ImTextureID == void*
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)(__bridge void*)bd->SharedMetalContext.fontTexture); // ImTextureID == ImU64
|
||||
|
||||
return (bd->SharedMetalContext.fontTexture != nil);
|
||||
}
|
||||
|
@ -367,8 +369,10 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
|||
depthStencilDescriptor.depthWriteEnabled = NO;
|
||||
depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways;
|
||||
bd->SharedMetalContext.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor];
|
||||
#ifdef IMGUI_IMPL_METAL_CPP
|
||||
[depthStencilDescriptor release];
|
||||
#endif
|
||||
ImGui_ImplMetal_CreateFontsTexture(device);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -22,6 +24,8 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
|
@ -154,6 +158,8 @@ void ImGui_ImplOpenGL2_NewFrame()
|
|||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplOpenGL2_CreateDeviceObjects();
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height)
|
||||
|
@ -230,16 +236,16 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
|||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos)));
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv)));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col)));
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
|
@ -247,7 +253,7 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
|||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -301,6 +307,8 @@ bool ImGui_ImplOpenGL2_CreateFontsTexture()
|
|||
glBindTexture(GL_TEXTURE_2D, bd->FontTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -24,6 +26,7 @@
|
|||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_NewFrame();
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [x] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
|
||||
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
||||
|
||||
// About WebGL/ES:
|
||||
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||
|
@ -22,6 +22,8 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748)
|
||||
// 2024-05-07: OpenGL: Update loader for Linux to support EGL/GLVND. (#7562)
|
||||
// 2024-04-16: OpenGL: Detect ES3 contexts on desktop based on version string, to e.g. avoid calling glPolygonMode() on them. (#7447)
|
||||
// 2024-01-09: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" and variants, fixing regression on distros missing a symlink.
|
||||
|
@ -123,6 +125,7 @@
|
|||
// Clang/GCC warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: ignore unknown flags
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used
|
||||
|
@ -134,6 +137,7 @@
|
|||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#endif
|
||||
|
||||
// GL includes
|
||||
|
@ -161,6 +165,7 @@
|
|||
// In the rest of your app/engine, you can use another loader of your choice (gl3w, glew, glad, glbinding, glext, glLoadGen, etc.).
|
||||
// If you happen to be developing a new feature for this backend (imgui_impl_opengl3.cpp):
|
||||
// - You may need to regenerate imgui_impl_opengl3_loader.h to add new symbols. See https://github.com/dearimgui/gl3w_stripped
|
||||
// Typically you would run: python3 ./gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt
|
||||
// - You can temporarily use an unstripped version. See https://github.com/dearimgui/gl3w_stripped/releases
|
||||
// Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version.
|
||||
#define IMGL3W_IMPL
|
||||
|
@ -293,13 +298,13 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||
io.BackendRendererName = "imgui_impl_opengl3";
|
||||
|
||||
// Query for GL version (e.g. 320 for GL 3.2)
|
||||
const char* gl_version_str = (const char*)glGetString(GL_VERSION);
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
// GLES 2
|
||||
bd->GlVersion = 200;
|
||||
bd->GlProfileIsES2 = true;
|
||||
#else
|
||||
// Desktop or GLES 3
|
||||
const char* gl_version_str = (const char*)glGetString(GL_VERSION);
|
||||
GLint major = 0;
|
||||
GLint minor = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||
|
@ -332,7 +337,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||
printf("GlVersion = %d, \"%s\"\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2 = %d, GlProfileIsES3 = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, gl_version_str, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
||||
printf("GlVersion = %d, \"%s\"\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2/IsEs3 = %d/%d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, gl_version_str, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||
|
@ -402,6 +407,8 @@ void ImGui_ImplOpenGL3_NewFrame()
|
|||
|
||||
if (!bd->ShaderHandle)
|
||||
ImGui_ImplOpenGL3_CreateDeviceObjects();
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
|
||||
|
@ -546,7 +553,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
|
||||
// Upload vertex/index buffers
|
||||
// - OpenGL drivers are in a very sorry state nowadays....
|
||||
|
@ -556,8 +563,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||
// - We are now back to using exclusively glBufferData(). So bd->UseBufferSubData IS ALWAYS FALSE in this code.
|
||||
// We are keeping the old code path for a while in case people finding new issues may want to test the bd->UseBufferSubData path.
|
||||
// - See https://github.com/ocornut/imgui/issues/4468 and please report any corruption issues.
|
||||
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
||||
const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
||||
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)draw_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
||||
const GLsizeiptr idx_buffer_size = (GLsizeiptr)draw_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
||||
if (bd->UseBufferSubData)
|
||||
{
|
||||
if (bd->VertexBufferSize < vtx_buffer_size)
|
||||
|
@ -570,18 +577,18 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||
bd->IndexBufferSize = idx_buffer_size;
|
||||
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, nullptr, GL_STREAM_DRAW));
|
||||
}
|
||||
GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data));
|
||||
GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data));
|
||||
GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)draw_list->VtxBuffer.Data));
|
||||
GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)draw_list->IdxBuffer.Data));
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW));
|
||||
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW));
|
||||
GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)draw_list->VtxBuffer.Data, GL_STREAM_DRAW));
|
||||
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)draw_list->IdxBuffer.Data, GL_STREAM_DRAW));
|
||||
}
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
|
@ -589,7 +596,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -677,12 +684,14 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture()
|
|||
GL_CALL(glBindTexture(GL_TEXTURE_2D, bd->FontTexture));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
#endif
|
||||
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
// Store our identifier
|
||||
// Store identifier
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
||||
|
||||
// Restore state
|
||||
|
@ -888,13 +897,15 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
|||
|
||||
// Create shaders
|
||||
const GLchar* vertex_shader_with_version[2] = { bd->GlslVersionString, vertex_shader };
|
||||
GLuint vert_handle = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint vert_handle;
|
||||
GL_CALL(vert_handle = glCreateShader(GL_VERTEX_SHADER));
|
||||
glShaderSource(vert_handle, 2, vertex_shader_with_version, nullptr);
|
||||
glCompileShader(vert_handle);
|
||||
CheckShader(vert_handle, "vertex shader");
|
||||
|
||||
const GLchar* fragment_shader_with_version[2] = { bd->GlslVersionString, fragment_shader };
|
||||
GLuint frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
GLuint frag_handle;
|
||||
GL_CALL(frag_handle = glCreateShader(GL_FRAGMENT_SHADER));
|
||||
glShaderSource(frag_handle, 2, fragment_shader_with_version, nullptr);
|
||||
glCompileShader(frag_handle);
|
||||
CheckShader(frag_handle, "fragment shader");
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [x] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
|
||||
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
||||
|
||||
// About WebGL/ES:
|
||||
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||
|
@ -29,7 +29,7 @@
|
|||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Backend API
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
|
||||
|
|
|
@ -181,6 +181,9 @@ typedef khronos_uint8_t GLubyte;
|
|||
#define GL_LINEAR 0x2601
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
#define GL_TEXTURE_WRAP_S 0x2802
|
||||
#define GL_TEXTURE_WRAP_T 0x2803
|
||||
#define GL_REPEAT 0x2901
|
||||
typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
|
||||
typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
|
||||
|
@ -231,6 +234,9 @@ GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
|
|||
GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);
|
||||
#endif
|
||||
#endif /* GL_VERSION_1_1 */
|
||||
#ifndef GL_VERSION_1_2
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
#endif /* GL_VERSION_1_2 */
|
||||
#ifndef GL_VERSION_1_3
|
||||
#define GL_TEXTURE0 0x84C0
|
||||
#define GL_ACTIVE_TEXTURE 0x84E0
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
// - Requires linking with the GameController framework ("-framework GameController").
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Clipboard support is part of core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/Pen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: IME support.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
|
@ -27,6 +27,7 @@
|
|||
@class NSEvent;
|
||||
@class NSView;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplOSX_Init(NSView* _Nonnull view);
|
||||
IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view);
|
||||
|
@ -41,6 +42,7 @@ IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view);
|
|||
// #include <AppKit/AppKit.hpp>
|
||||
#ifndef __OBJC__
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplOSX_Init(void* _Nonnull view);
|
||||
IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(void* _Nullable view);
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
// - Requires linking with the GameController framework ("-framework GameController").
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Clipboard support is part of core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/Pen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: IME support.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
|
@ -29,6 +29,11 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||
// - io.PlatformSetImeDataFn -> platform_io.Platform_SetImeDataFn
|
||||
// 2024-07-02: Update for io.SetPlatformImeDataFn() -> io.PlatformSetImeDataFn() renaming in main library.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F20 function keys. Stopped mapping F13 into PrintScreen.
|
||||
// 2023-04-09: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_Pen.
|
||||
// 2023-02-01: Fixed scroll wheel scaling for devices emitting events with hasPreciseScrollingDeltas==false (e.g. non-Apple mices).
|
||||
|
@ -80,8 +85,9 @@ struct ImGui_ImplOSX_Data
|
|||
KeyEventResponder* KeyEventResponder;
|
||||
NSTextInputContext* InputContext;
|
||||
id Monitor;
|
||||
NSWindow* Window;
|
||||
|
||||
ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); }
|
||||
ImGui_ImplOSX_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; }
|
||||
|
@ -133,7 +139,7 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
|||
|
||||
- (void)updateImePosWithView:(NSView *)view
|
||||
{
|
||||
NSWindow *window = view.window;
|
||||
NSWindow* window = view.window;
|
||||
if (!window)
|
||||
return;
|
||||
NSRect contentRect = [window contentRectForFrameRect:window.frame];
|
||||
|
@ -253,7 +259,10 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
|||
@end
|
||||
|
||||
// Functions
|
||||
static ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
|
||||
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code);
|
||||
ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
|
||||
{
|
||||
switch (key_code)
|
||||
{
|
||||
|
@ -391,6 +400,7 @@ IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(void* _Nullable view) {
|
|||
bool ImGui_ImplOSX_Init(NSView* view)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||
|
||||
|
@ -402,6 +412,9 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
|||
//io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
|
||||
bd->Observer = [ImGuiObserver new];
|
||||
bd->Window = view.window ?: NSApp.orderedWindows.firstObject;
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)bd->Window;
|
||||
|
||||
// Load cursors. Some of them are undocumented.
|
||||
bd->MouseCursorHidden = false;
|
||||
|
@ -418,14 +431,14 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
|||
// Note that imgui.cpp also include default OSX clipboard handlers which can be enabled
|
||||
// by adding '#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS' in imconfig.h and adding '-framework ApplicationServices' to your linker command-line.
|
||||
// Since we are already in ObjC land here, it is easy for us to add a clipboard handler using the NSPasteboard api.
|
||||
io.SetClipboardTextFn = [](void*, const char* str) -> void
|
||||
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* str) -> void
|
||||
{
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
[pasteboard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil];
|
||||
[pasteboard setString:[NSString stringWithUTF8String:str] forType:NSPasteboardTypeString];
|
||||
};
|
||||
|
||||
io.GetClipboardTextFn = [](void*) -> const char*
|
||||
platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) -> const char*
|
||||
{
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
NSString* available = [pasteboard availableTypeFromArray: [NSArray arrayWithObject:NSPasteboardTypeString]];
|
||||
|
@ -460,7 +473,7 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
|||
[view addSubview:bd->KeyEventResponder];
|
||||
ImGui_ImplOSX_AddTrackingArea(view);
|
||||
|
||||
io.SetPlatformImeDataFn = [](ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void
|
||||
platform_io.Platform_SetImeDataFn = [](ImGuiContext*, ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void
|
||||
{
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
if (data->WantVisible)
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
|
@ -21,6 +21,17 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-10-24: Emscripten: from SDL 2.30.9, SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f.
|
||||
// 2024-09-09: use SDL_Vulkan_GetDrawableSize() when available. (#7967, #3190)
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||
// - io.PlatformOpenInShellFn -> platform_io.Platform_OpenInShellFn
|
||||
// - io.PlatformSetImeDataFn -> platform_io.Platform_SetImeDataFn
|
||||
// 2024-08-19: Storing SDL's Uint32 WindowID inside ImGuiViewport::PlatformHandle instead of SDL_Window*.
|
||||
// 2024-08-19: ImGui_ImplSDL2_ProcessEvent() now ignores events intended for other SDL windows. (#7853)
|
||||
// 2024-07-02: Emscripten: Added io.PlatformOpenInShellFn() handler for Emscripten versions.
|
||||
// 2024-07-02: Update for io.SetPlatformImeDataFn() -> io.PlatformSetImeDataFn() renaming in main library.
|
||||
// 2024-02-14: Inputs: Handle gamepad disconnection. Added ImGui_ImplSDL2_SetGamepadMode().
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||
// 2023-04-06: Inputs: Avoid calling SDL_StartTextInput()/SDL_StopTextInput() as they don't only pertain to IME. It's unclear exactly what their relation is to IME. (#6306)
|
||||
|
@ -90,9 +101,12 @@
|
|||
// SDL
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#if defined(__APPLE__)
|
||||
#ifdef __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/em_js.h>
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__)
|
||||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1
|
||||
|
@ -100,11 +114,15 @@
|
|||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
|
||||
#endif
|
||||
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
|
||||
#if SDL_HAS_VULKAN
|
||||
#include <SDL_vulkan.h>
|
||||
#endif
|
||||
|
||||
// SDL Data
|
||||
struct ImGui_ImplSDL2_Data
|
||||
{
|
||||
SDL_Window* Window;
|
||||
Uint32 WindowID;
|
||||
SDL_Renderer* Renderer;
|
||||
Uint64 Time;
|
||||
char* ClipboardTextData;
|
||||
|
@ -135,7 +153,7 @@ static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData()
|
|||
}
|
||||
|
||||
// Functions
|
||||
static const char* ImGui_ImplSDL2_GetClipboardText(void*)
|
||||
static const char* ImGui_ImplSDL2_GetClipboardText(ImGuiContext*)
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
if (bd->ClipboardTextData)
|
||||
|
@ -144,13 +162,13 @@ static const char* ImGui_ImplSDL2_GetClipboardText(void*)
|
|||
return bd->ClipboardTextData;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text)
|
||||
static void ImGui_ImplSDL2_SetClipboardText(ImGuiContext*, const char* text)
|
||||
{
|
||||
SDL_SetClipboardText(text);
|
||||
}
|
||||
|
||||
// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow().
|
||||
static void ImGui_ImplSDL2_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeData* data)
|
||||
static void ImGui_ImplSDL2_PlatformSetImeData(ImGuiContext*, ImGuiViewport*, ImGuiPlatformImeData* data)
|
||||
{
|
||||
if (data->WantVisible)
|
||||
{
|
||||
|
@ -163,8 +181,11 @@ static void ImGui_ImplSDL2_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeDa
|
|||
}
|
||||
}
|
||||
|
||||
static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode);
|
||||
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
|
||||
{
|
||||
IM_UNUSED(scancode);
|
||||
switch (keycode)
|
||||
{
|
||||
case SDLK_TAB: return ImGuiKey_Tab;
|
||||
|
@ -286,6 +307,7 @@ static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
|
|||
case SDLK_F24: return ImGuiKey_F24;
|
||||
case SDLK_AC_BACK: return ImGuiKey_AppBack;
|
||||
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
|
||||
default: break;
|
||||
}
|
||||
return ImGuiKey_None;
|
||||
}
|
||||
|
@ -299,6 +321,12 @@ static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods)
|
|||
io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & KMOD_GUI) != 0);
|
||||
}
|
||||
|
||||
static ImGuiViewport* ImGui_ImplSDL2_GetViewportForWindowID(Uint32 window_id)
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
return (window_id == bd->WindowID) ? ImGui::GetMainViewport() : nullptr;
|
||||
}
|
||||
|
||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
|
@ -314,6 +342,8 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||
{
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->motion.windowID) == nullptr)
|
||||
return false;
|
||||
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
||||
io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
||||
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
||||
|
@ -321,6 +351,8 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||
}
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->wheel.windowID) == nullptr)
|
||||
return false;
|
||||
//IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
|
||||
#if SDL_VERSION_ATLEAST(2,0,18) // If this fails to compile on Emscripten: update to latest Emscripten!
|
||||
float wheel_x = -event->wheel.preciseX;
|
||||
|
@ -329,7 +361,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||
float wheel_x = -(float)event->wheel.x;
|
||||
float wheel_y = (float)event->wheel.y;
|
||||
#endif
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#if defined(__EMSCRIPTEN__) && !SDL_VERSION_ATLEAST(2,31,0)
|
||||
wheel_x /= 100.0f;
|
||||
#endif
|
||||
io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
||||
|
@ -339,6 +371,8 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->button.windowID) == nullptr)
|
||||
return false;
|
||||
int mouse_button = -1;
|
||||
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
|
||||
if (event->button.button == SDL_BUTTON_RIGHT) { mouse_button = 1; }
|
||||
|
@ -354,20 +388,28 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||
}
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->text.windowID) == nullptr)
|
||||
return false;
|
||||
io.AddInputCharactersUTF8(event->text.text);
|
||||
return true;
|
||||
}
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->key.windowID) == nullptr)
|
||||
return false;
|
||||
ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod);
|
||||
ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym);
|
||||
//IMGUI_DEBUG_LOG("SDL_KEY_%s : key=%d ('%s'), scancode=%d ('%s'), mod=%X\n",
|
||||
// (event->type == SDL_KEYDOWN) ? "DOWN" : "UP ", event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym), event->key.keysym.scancode, SDL_GetScancodeName(event->key.keysym.scancode), event->key.keysym.mod);
|
||||
ImGuiKey key = ImGui_ImplSDL2_KeyEventToImGuiKey(event->key.keysym.sym, event->key.keysym.scancode);
|
||||
io.AddKeyEvent(key, (event->type == SDL_KEYDOWN));
|
||||
io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
||||
return true;
|
||||
}
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->window.windowID) == nullptr)
|
||||
return false;
|
||||
// - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right.
|
||||
// - However we won't get a correct LEAVE event for a captured window.
|
||||
// - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
|
||||
|
@ -397,7 +439,11 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_JS(void, ImGui_ImplSDL2_EmscriptenOpenURL, (char const* url), { url = url ? UTF8ToString(url) : null; if (url) window.open(url, '_blank'); });
|
||||
#endif
|
||||
|
||||
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
|
@ -422,13 +468,18 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
|
|||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
|
||||
bd->Window = window;
|
||||
bd->WindowID = SDL_GetWindowID(window);
|
||||
bd->Renderer = renderer;
|
||||
bd->MouseCanUseGlobalState = mouse_can_use_global_state;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
|
||||
io.ClipboardUserData = nullptr;
|
||||
io.SetPlatformImeDataFn = ImGui_ImplSDL2_SetPlatformImeData;
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
|
||||
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
|
||||
platform_io.Platform_ClipboardUserData = nullptr;
|
||||
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL2_PlatformSetImeData;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplSDL2_EmscriptenOpenURL(url); return true; };
|
||||
#endif
|
||||
|
||||
// Gamepad handling
|
||||
bd->GamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst;
|
||||
|
@ -448,6 +499,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
|
|||
// Set platform dependent data in viewport
|
||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = (void*)(intptr_t)bd->WindowID;
|
||||
main_viewport->PlatformHandleRaw = nullptr;
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
|
@ -481,13 +533,13 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
|
|||
SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");
|
||||
#endif
|
||||
|
||||
(void)sdl_gl_context; // Unused in 'master' branch.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
|
||||
{
|
||||
IM_UNUSED(sdl_gl_context); // Viewport branch will need this.
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
return ImGui_ImplSDL2_Init(window, nullptr, sdl_gl_context);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
|
||||
|
@ -495,7 +547,7 @@ bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
|
|||
#if !SDL_HAS_VULKAN
|
||||
IM_ASSERT(0 && "Unsupported");
|
||||
#endif
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
|
||||
|
@ -503,22 +555,22 @@ bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
|
|||
#if !defined(_WIN32)
|
||||
IM_ASSERT(0 && "Unsupported");
|
||||
#endif
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window)
|
||||
{
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer)
|
||||
{
|
||||
return ImGui_ImplSDL2_Init(window, renderer);
|
||||
return ImGui_ImplSDL2_Init(window, renderer, nullptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForOther(SDL_Window* window)
|
||||
{
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_CloseGamepads();
|
||||
|
@ -557,7 +609,7 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
|||
#endif
|
||||
if (is_app_focused)
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
|
||||
|
||||
|
@ -717,6 +769,10 @@ void ImGui_ImplSDL2_NewFrame()
|
|||
w = h = 0;
|
||||
if (bd->Renderer != nullptr)
|
||||
SDL_GetRendererOutputSize(bd->Renderer, &display_w, &display_h);
|
||||
#if SDL_HAS_VULKAN
|
||||
else if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_VULKAN)
|
||||
SDL_Vulkan_GetDrawableSize(bd->Window, &display_w, &display_h);
|
||||
#endif
|
||||
else
|
||||
SDL_GL_GetDrawableSize(bd->Window, &display_w, &display_h);
|
||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
|
@ -27,6 +27,7 @@ struct SDL_Renderer;
|
|||
struct _SDL_GameController;
|
||||
typedef union SDL_Event SDL_Event;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window);
|
||||
|
@ -40,6 +41,6 @@ IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
|
|||
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||
enum ImGui_ImplSDL2_GamepadMode { ImGui_ImplSDL2_GamepadMode_AutoFirst, ImGui_ImplSDL2_GamepadMode_AutoAll, ImGui_ImplSDL2_GamepadMode_Manual };
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = NULL, int manual_gamepads_count = -1);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
// dear imgui: Platform Backend for SDL3 (*EXPERIMENTAL*)
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
// (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||
// (IMPORTANT: SDL 3.0.0 is NOT YET RELEASED. IT IS POSSIBLE THAT ITS SPECS/API WILL CHANGE BEFORE RELEASE)
|
||||
|
||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Missing features:
|
||||
// [ ] Platform: IME SUPPORT IS BROKEN IN SDL3 BECAUSE INPUTS GETS SENT TO BOTH APP AND IME + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: IME support.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -22,6 +22,23 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-10-24: Emscripten: SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f on Emscripten.
|
||||
// 2024-09-03: Update for SDL3 api changes: SDL_GetGamepads() memory ownership revert. (#7918, #7898, #7807)
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||
// - io.PlatformSetImeDataFn -> platform_io.Platform_SetImeDataFn
|
||||
// 2024-08-19: Storing SDL_WindowID inside ImGuiViewport::PlatformHandle instead of SDL_Window*.
|
||||
// 2024-08-19: ImGui_ImplSDL3_ProcessEvent() now ignores events intended for other SDL windows. (#7853)
|
||||
// 2024-07-22: Update for SDL3 api changes: SDL_GetGamepads() memory ownership change. (#7807)
|
||||
// 2024-07-18: Update for SDL3 api changes: SDL_GetClipboardText() memory ownership change. (#7801)
|
||||
// 2024-07-15: Update for SDL3 api changes: SDL_GetProperty() change to SDL_GetPointerProperty(). (#7794)
|
||||
// 2024-07-02: Update for SDL3 api changes: SDLK_x renames and SDLK_KP_x removals (#7761, #7762).
|
||||
// 2024-07-01: Update for SDL3 api changes: SDL_SetTextInputRect() changed to SDL_SetTextInputArea().
|
||||
// 2024-06-26: Update for SDL3 api changes: SDL_StartTextInput()/SDL_StopTextInput()/SDL_SetTextInputRect() functions signatures.
|
||||
// 2024-06-24: Update for SDL3 api changes: SDL_EVENT_KEY_DOWN/SDL_EVENT_KEY_UP contents.
|
||||
// 2024-06-03; Update for SDL3 api changes: SDL_SYSTEM_CURSOR_ renames.
|
||||
// 2024-05-15: Update for SDL3 api changes: SDLK_ renames.
|
||||
// 2024-04-15: Inputs: Re-enable calling SDL_StartTextInput()/SDL_StopTextInput() as SDL3 no longer enables it by default and should play nicer with IME.
|
||||
// 2024-02-13: Inputs: Fixed gamepad support. Handle gamepad disconnection. Added ImGui_ImplSDL3_SetGamepadMode().
|
||||
// 2023-11-13: Updated for recent SDL3 API changes.
|
||||
|
@ -72,10 +89,14 @@
|
|||
struct ImGui_ImplSDL3_Data
|
||||
{
|
||||
SDL_Window* Window;
|
||||
SDL_WindowID WindowID;
|
||||
SDL_Renderer* Renderer;
|
||||
Uint64 Time;
|
||||
char* ClipboardTextData;
|
||||
|
||||
// IME handling
|
||||
SDL_Window* ImeWindow;
|
||||
|
||||
// Mouse handling
|
||||
Uint32 MouseWindowID;
|
||||
int MouseButtonsDown;
|
||||
|
@ -102,22 +123,31 @@ static ImGui_ImplSDL3_Data* ImGui_ImplSDL3_GetBackendData()
|
|||
}
|
||||
|
||||
// Functions
|
||||
static const char* ImGui_ImplSDL3_GetClipboardText(void*)
|
||||
static const char* ImGui_ImplSDL3_GetClipboardText(ImGuiContext*)
|
||||
{
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
if (bd->ClipboardTextData)
|
||||
SDL_free(bd->ClipboardTextData);
|
||||
bd->ClipboardTextData = SDL_GetClipboardText();
|
||||
const char* sdl_clipboard_text = SDL_GetClipboardText();
|
||||
bd->ClipboardTextData = sdl_clipboard_text ? SDL_strdup(sdl_clipboard_text) : nullptr;
|
||||
return bd->ClipboardTextData;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_SetClipboardText(void*, const char* text)
|
||||
static void ImGui_ImplSDL3_SetClipboardText(ImGuiContext*, const char* text)
|
||||
{
|
||||
SDL_SetClipboardText(text);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeData* data)
|
||||
static void ImGui_ImplSDL3_PlatformSetImeData(ImGuiContext*, ImGuiViewport* viewport, ImGuiPlatformImeData* data)
|
||||
{
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
SDL_WindowID window_id = (SDL_WindowID)(intptr_t)viewport->PlatformHandle;
|
||||
SDL_Window* window = SDL_GetWindowFromID(window_id);
|
||||
if ((data->WantVisible == false || bd->ImeWindow != window) && bd->ImeWindow != nullptr)
|
||||
{
|
||||
SDL_StopTextInput(bd->ImeWindow);
|
||||
bd->ImeWindow = nullptr;
|
||||
}
|
||||
if (data->WantVisible)
|
||||
{
|
||||
SDL_Rect r;
|
||||
|
@ -125,17 +155,38 @@ static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeDa
|
|||
r.y = (int)data->InputPos.y;
|
||||
r.w = 1;
|
||||
r.h = (int)data->InputLineHeight;
|
||||
SDL_SetTextInputRect(&r);
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_StopTextInput();
|
||||
SDL_SetTextInputArea(window, &r, 0);
|
||||
SDL_StartTextInput(window);
|
||||
bd->ImeWindow = window;
|
||||
}
|
||||
}
|
||||
|
||||
static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode)
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode);
|
||||
ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
|
||||
{
|
||||
// Keypad doesn't have individual key values in SDL3
|
||||
switch (scancode)
|
||||
{
|
||||
case SDL_SCANCODE_KP_0: return ImGuiKey_Keypad0;
|
||||
case SDL_SCANCODE_KP_1: return ImGuiKey_Keypad1;
|
||||
case SDL_SCANCODE_KP_2: return ImGuiKey_Keypad2;
|
||||
case SDL_SCANCODE_KP_3: return ImGuiKey_Keypad3;
|
||||
case SDL_SCANCODE_KP_4: return ImGuiKey_Keypad4;
|
||||
case SDL_SCANCODE_KP_5: return ImGuiKey_Keypad5;
|
||||
case SDL_SCANCODE_KP_6: return ImGuiKey_Keypad6;
|
||||
case SDL_SCANCODE_KP_7: return ImGuiKey_Keypad7;
|
||||
case SDL_SCANCODE_KP_8: return ImGuiKey_Keypad8;
|
||||
case SDL_SCANCODE_KP_9: return ImGuiKey_Keypad9;
|
||||
case SDL_SCANCODE_KP_PERIOD: return ImGuiKey_KeypadDecimal;
|
||||
case SDL_SCANCODE_KP_DIVIDE: return ImGuiKey_KeypadDivide;
|
||||
case SDL_SCANCODE_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||
case SDL_SCANCODE_KP_MINUS: return ImGuiKey_KeypadSubtract;
|
||||
case SDL_SCANCODE_KP_PLUS: return ImGuiKey_KeypadAdd;
|
||||
case SDL_SCANCODE_KP_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case SDL_SCANCODE_KP_EQUALS: return ImGuiKey_KeypadEqual;
|
||||
default: break;
|
||||
}
|
||||
switch (keycode)
|
||||
{
|
||||
case SDLK_TAB: return ImGuiKey_Tab;
|
||||
|
@ -169,23 +220,6 @@ static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode)
|
|||
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
|
||||
case SDLK_PRINTSCREEN: return ImGuiKey_PrintScreen;
|
||||
case SDLK_PAUSE: return ImGuiKey_Pause;
|
||||
case SDLK_KP_0: return ImGuiKey_Keypad0;
|
||||
case SDLK_KP_1: return ImGuiKey_Keypad1;
|
||||
case SDLK_KP_2: return ImGuiKey_Keypad2;
|
||||
case SDLK_KP_3: return ImGuiKey_Keypad3;
|
||||
case SDLK_KP_4: return ImGuiKey_Keypad4;
|
||||
case SDLK_KP_5: return ImGuiKey_Keypad5;
|
||||
case SDLK_KP_6: return ImGuiKey_Keypad6;
|
||||
case SDLK_KP_7: return ImGuiKey_Keypad7;
|
||||
case SDLK_KP_8: return ImGuiKey_Keypad8;
|
||||
case SDLK_KP_9: return ImGuiKey_Keypad9;
|
||||
case SDLK_KP_PERIOD: return ImGuiKey_KeypadDecimal;
|
||||
case SDLK_KP_DIVIDE: return ImGuiKey_KeypadDivide;
|
||||
case SDLK_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||
case SDLK_KP_MINUS: return ImGuiKey_KeypadSubtract;
|
||||
case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd;
|
||||
case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual;
|
||||
case SDLK_LCTRL: return ImGuiKey_LeftCtrl;
|
||||
case SDLK_LSHIFT: return ImGuiKey_LeftShift;
|
||||
case SDLK_LALT: return ImGuiKey_LeftAlt;
|
||||
|
@ -205,32 +239,32 @@ static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode)
|
|||
case SDLK_7: return ImGuiKey_7;
|
||||
case SDLK_8: return ImGuiKey_8;
|
||||
case SDLK_9: return ImGuiKey_9;
|
||||
case SDLK_a: return ImGuiKey_A;
|
||||
case SDLK_b: return ImGuiKey_B;
|
||||
case SDLK_c: return ImGuiKey_C;
|
||||
case SDLK_d: return ImGuiKey_D;
|
||||
case SDLK_e: return ImGuiKey_E;
|
||||
case SDLK_f: return ImGuiKey_F;
|
||||
case SDLK_g: return ImGuiKey_G;
|
||||
case SDLK_h: return ImGuiKey_H;
|
||||
case SDLK_i: return ImGuiKey_I;
|
||||
case SDLK_j: return ImGuiKey_J;
|
||||
case SDLK_k: return ImGuiKey_K;
|
||||
case SDLK_l: return ImGuiKey_L;
|
||||
case SDLK_m: return ImGuiKey_M;
|
||||
case SDLK_n: return ImGuiKey_N;
|
||||
case SDLK_o: return ImGuiKey_O;
|
||||
case SDLK_p: return ImGuiKey_P;
|
||||
case SDLK_q: return ImGuiKey_Q;
|
||||
case SDLK_r: return ImGuiKey_R;
|
||||
case SDLK_s: return ImGuiKey_S;
|
||||
case SDLK_t: return ImGuiKey_T;
|
||||
case SDLK_u: return ImGuiKey_U;
|
||||
case SDLK_v: return ImGuiKey_V;
|
||||
case SDLK_w: return ImGuiKey_W;
|
||||
case SDLK_x: return ImGuiKey_X;
|
||||
case SDLK_y: return ImGuiKey_Y;
|
||||
case SDLK_z: return ImGuiKey_Z;
|
||||
case SDLK_A: return ImGuiKey_A;
|
||||
case SDLK_B: return ImGuiKey_B;
|
||||
case SDLK_C: return ImGuiKey_C;
|
||||
case SDLK_D: return ImGuiKey_D;
|
||||
case SDLK_E: return ImGuiKey_E;
|
||||
case SDLK_F: return ImGuiKey_F;
|
||||
case SDLK_G: return ImGuiKey_G;
|
||||
case SDLK_H: return ImGuiKey_H;
|
||||
case SDLK_I: return ImGuiKey_I;
|
||||
case SDLK_J: return ImGuiKey_J;
|
||||
case SDLK_K: return ImGuiKey_K;
|
||||
case SDLK_L: return ImGuiKey_L;
|
||||
case SDLK_M: return ImGuiKey_M;
|
||||
case SDLK_N: return ImGuiKey_N;
|
||||
case SDLK_O: return ImGuiKey_O;
|
||||
case SDLK_P: return ImGuiKey_P;
|
||||
case SDLK_Q: return ImGuiKey_Q;
|
||||
case SDLK_R: return ImGuiKey_R;
|
||||
case SDLK_S: return ImGuiKey_S;
|
||||
case SDLK_T: return ImGuiKey_T;
|
||||
case SDLK_U: return ImGuiKey_U;
|
||||
case SDLK_V: return ImGuiKey_V;
|
||||
case SDLK_W: return ImGuiKey_W;
|
||||
case SDLK_X: return ImGuiKey_X;
|
||||
case SDLK_Y: return ImGuiKey_Y;
|
||||
case SDLK_Z: return ImGuiKey_Z;
|
||||
case SDLK_F1: return ImGuiKey_F1;
|
||||
case SDLK_F2: return ImGuiKey_F2;
|
||||
case SDLK_F3: return ImGuiKey_F3;
|
||||
|
@ -257,6 +291,7 @@ static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode)
|
|||
case SDLK_F24: return ImGuiKey_F24;
|
||||
case SDLK_AC_BACK: return ImGuiKey_AppBack;
|
||||
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
|
||||
default: break;
|
||||
}
|
||||
return ImGuiKey_None;
|
||||
}
|
||||
|
@ -270,6 +305,13 @@ static void ImGui_ImplSDL3_UpdateKeyModifiers(SDL_Keymod sdl_key_mods)
|
|||
io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & SDL_KMOD_GUI) != 0);
|
||||
}
|
||||
|
||||
|
||||
static ImGuiViewport* ImGui_ImplSDL3_GetViewportForWindowID(SDL_WindowID window_id)
|
||||
{
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
return (window_id == bd->WindowID) ? ImGui::GetMainViewport() : nullptr;
|
||||
}
|
||||
|
||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
|
@ -285,6 +327,8 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||
{
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
{
|
||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->motion.windowID) == nullptr)
|
||||
return false;
|
||||
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
||||
io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
||||
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
||||
|
@ -292,12 +336,11 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||
}
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
{
|
||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->wheel.windowID) == nullptr)
|
||||
return false;
|
||||
//IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
|
||||
float wheel_x = -event->wheel.x;
|
||||
float wheel_y = event->wheel.y;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
wheel_x /= 100.0f;
|
||||
#endif
|
||||
io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
||||
io.AddMouseWheelEvent(wheel_x, wheel_y);
|
||||
return true;
|
||||
|
@ -305,6 +348,8 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
{
|
||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->button.windowID) == nullptr)
|
||||
return false;
|
||||
int mouse_button = -1;
|
||||
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
|
||||
if (event->button.button == SDL_BUTTON_RIGHT) { mouse_button = 1; }
|
||||
|
@ -320,20 +365,28 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||
}
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
{
|
||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->text.windowID) == nullptr)
|
||||
return false;
|
||||
io.AddInputCharactersUTF8(event->text.text);
|
||||
return true;
|
||||
}
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
case SDL_EVENT_KEY_UP:
|
||||
{
|
||||
ImGui_ImplSDL3_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod);
|
||||
ImGuiKey key = ImGui_ImplSDL3_KeycodeToImGuiKey(event->key.keysym.sym);
|
||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->key.windowID) == nullptr)
|
||||
return false;
|
||||
ImGui_ImplSDL3_UpdateKeyModifiers((SDL_Keymod)event->key.mod);
|
||||
//IMGUI_DEBUG_LOG("SDL_EVENT_KEY_%s : key=%d ('%s'), scancode=%d ('%s'), mod=%X\n",
|
||||
// (event->type == SDL_EVENT_KEY_DOWN) ? "DOWN" : "UP ", event->key.key, SDL_GetKeyName(event->key.key), event->key.scancode, SDL_GetScancodeName(event->key.scancode), event->key.mod);
|
||||
ImGuiKey key = ImGui_ImplSDL3_KeyEventToImGuiKey(event->key.key, event->key.scancode);
|
||||
io.AddKeyEvent(key, (event->type == SDL_EVENT_KEY_DOWN));
|
||||
io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
||||
io.SetKeyEventNativeData(key, event->key.key, event->key.scancode, event->key.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
||||
return true;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
{
|
||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == nullptr)
|
||||
return false;
|
||||
bd->MouseWindowID = event->window.windowID;
|
||||
bd->MousePendingLeaveFrame = 0;
|
||||
return true;
|
||||
|
@ -344,15 +397,19 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||
// FIXME: Unconfirmed whether this is still needed with SDL3.
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
{
|
||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == nullptr)
|
||||
return false;
|
||||
bd->MousePendingLeaveFrame = ImGui::GetFrameCount() + 1;
|
||||
return true;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
io.AddFocusEvent(true);
|
||||
return true;
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||
io.AddFocusEvent(false);
|
||||
{
|
||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == nullptr)
|
||||
return false;
|
||||
io.AddFocusEvent(event->type == SDL_EVENT_WINDOW_FOCUS_GAINED);
|
||||
return true;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
{
|
||||
|
@ -365,12 +422,12 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||
|
||||
static void ImGui_ImplSDL3_SetupPlatformHandles(ImGuiViewport* viewport, SDL_Window* window)
|
||||
{
|
||||
IM_UNUSED(window);
|
||||
viewport->PlatformHandle = (void*)(intptr_t)SDL_GetWindowID(window);
|
||||
viewport->PlatformHandleRaw = nullptr;
|
||||
#if defined(__WIN32__) && !defined(__WINRT__)
|
||||
viewport->PlatformHandleRaw = (HWND)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.win32.hwnd", nullptr);
|
||||
#if defined(_WIN32) && !defined(__WINRT__)
|
||||
viewport->PlatformHandleRaw = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr);
|
||||
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
|
||||
viewport->PlatformHandleRaw = (void*)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.cocoa.window", nullptr);
|
||||
viewport->PlatformHandleRaw = SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -400,13 +457,14 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
|
||||
bd->Window = window;
|
||||
bd->WindowID = SDL_GetWindowID(window);
|
||||
bd->Renderer = renderer;
|
||||
bd->MouseCanUseGlobalState = mouse_can_use_global_state;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
|
||||
io.ClipboardUserData = nullptr;
|
||||
io.SetPlatformImeDataFn = ImGui_ImplSDL3_SetPlatformImeData;
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
||||
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
|
||||
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL3_PlatformSetImeData;
|
||||
|
||||
// Gamepad handling
|
||||
bd->GamepadMode = ImGui_ImplSDL3_GamepadMode_AutoFirst;
|
||||
|
@ -474,6 +532,11 @@ bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* rendere
|
|||
return ImGui_ImplSDL3_Init(window, renderer, nullptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL3_InitForSDLGPU(SDL_Window* window)
|
||||
{
|
||||
return ImGui_ImplSDL3_Init(window, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL3_InitForOther(SDL_Window* window)
|
||||
{
|
||||
return ImGui_ImplSDL3_Init(window, nullptr, nullptr);
|
||||
|
@ -507,7 +570,7 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
|||
// We forward mouse input when hovered or captured (via SDL_EVENT_MOUSE_MOTION) or when focused (below)
|
||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
|
||||
SDL_CaptureMouse((bd->MouseButtonsDown != 0) ? SDL_TRUE : SDL_FALSE);
|
||||
SDL_CaptureMouse(bd->MouseButtonsDown != 0);
|
||||
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
||||
const bool is_app_focused = (bd->Window == focused_window);
|
||||
#else
|
||||
|
@ -516,7 +579,7 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
|||
#endif
|
||||
if (is_app_focused)
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
SDL_WarpMouseInWindow(bd->Window, io.MousePos.x, io.MousePos.y);
|
||||
|
||||
|
@ -625,8 +688,8 @@ static void ImGui_ImplSDL3_UpdateGamepads()
|
|||
if (bd->GamepadMode == ImGui_ImplSDL3_GamepadMode_AutoFirst)
|
||||
break;
|
||||
}
|
||||
SDL_free(sdl_gamepads);
|
||||
bd->WantUpdateGamepadsList = false;
|
||||
SDL_free(sdl_gamepads);
|
||||
}
|
||||
|
||||
// FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
// dear imgui: Platform Backend for SDL3 (*EXPERIMENTAL*)
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
// (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||
// (IMPORTANT: SDL 3.0.0 is NOT YET RELEASED. IT IS POSSIBLE THAT ITS SPECS/API WILL CHANGE BEFORE RELEASE)
|
||||
|
||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Missing features:
|
||||
// [ ] Platform: IME SUPPORT IS BROKEN IN SDL3 BECAUSE INPUTS GETS SENT TO BOTH APP AND IME + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: IME support.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -29,11 +29,13 @@ struct SDL_Renderer;
|
|||
struct SDL_Gamepad;
|
||||
typedef union SDL_Event SDL_Event;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForVulkan(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForMetal(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLGPU(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOther(SDL_Window* window);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame();
|
||||
|
@ -42,6 +44,6 @@ IMGUI_IMPL_API bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event);
|
|||
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||
enum ImGui_ImplSDL3_GamepadMode { ImGui_ImplSDL3_GamepadMode_AutoFirst, ImGui_ImplSDL3_GamepadMode_AutoAll, ImGui_ImplSDL3_GamepadMode_Manual };
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array = NULL, int manual_gamepads_count = -1);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
|
617
neo/libs/imgui/backends/imgui_impl_sdlgpu3.cpp
Normal file
|
@ -0,0 +1,617 @@
|
|||
// dear imgui: Renderer Backend for SDL_GPU
|
||||
// This needs to be used along with the SDL3 Platform Backend
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// Important note to the reader who wish to integrate imgui_impl_sdlgpu3.cpp/.h in their own engine/app.
|
||||
// - Unlike other backends, the user must call the function Imgui_ImplSDLGPU3_PrepareDrawData() BEFORE issuing a SDL_GPURenderPass containing ImGui_ImplSDLGPU3_RenderDrawData.
|
||||
// Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info.
|
||||
|
||||
// CHANGELOG
|
||||
// 2025-01-09: SDL_Gpu: Added the SDL_GPU3 backend.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_sdlgpu3.h"
|
||||
#include "imgui_impl_sdlgpu3_shaders.h"
|
||||
|
||||
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplSDLGPU3_RenderDrawData()
|
||||
struct ImGui_ImplSDLGPU3_FrameData
|
||||
{
|
||||
SDL_GPUBuffer* VertexBuffer = nullptr;
|
||||
SDL_GPUBuffer* IndexBuffer = nullptr;
|
||||
uint32_t VertexBufferSize = 0;
|
||||
uint32_t IndexBufferSize = 0;
|
||||
};
|
||||
|
||||
// SDL_GPU Data
|
||||
struct ImGui_ImplSDLGPU3_Data
|
||||
{
|
||||
ImGui_ImplSDLGPU3_InitInfo GPUInitInfo;
|
||||
|
||||
// Graphics pipeline & shaders
|
||||
SDL_GPUShader* VertexShader = nullptr;
|
||||
SDL_GPUShader* FragmentShader = nullptr;
|
||||
SDL_GPUGraphicsPipeline* Pipeline = nullptr;
|
||||
|
||||
// Font data
|
||||
SDL_GPUSampler* FontSampler = nullptr;
|
||||
SDL_GPUTexture* FontTexture = nullptr;
|
||||
SDL_GPUTextureSamplerBinding FontBinding = { nullptr, nullptr };
|
||||
|
||||
// Frame data for main window
|
||||
ImGui_ImplSDLGPU3_FrameData MainWindowFrameData;
|
||||
};
|
||||
|
||||
// Forward Declarations
|
||||
static bool ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
||||
static void ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||
static void ImGui_ImplSDLGPU3_DestroyFrameData();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FUNCTIONS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
// FIXME: multi-context support has never been tested.
|
||||
static ImGui_ImplSDLGPU3_Data* ImGui_ImplSDLGPU3_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass * render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height)
|
||||
{
|
||||
//ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
|
||||
// Bind graphics pipeline
|
||||
SDL_BindGPUGraphicsPipeline(render_pass,pipeline);
|
||||
|
||||
// Bind Vertex And Index Buffers
|
||||
if (draw_data->TotalVtxCount > 0)
|
||||
{
|
||||
SDL_GPUBufferBinding vertex_buffer_binding = {};
|
||||
vertex_buffer_binding.buffer = fd->VertexBuffer;
|
||||
vertex_buffer_binding.offset = 0;
|
||||
SDL_GPUBufferBinding index_buffer_binding = {};
|
||||
index_buffer_binding.buffer = fd->IndexBuffer;
|
||||
index_buffer_binding.offset = 0;
|
||||
SDL_BindGPUVertexBuffers(render_pass,0,&vertex_buffer_binding,1);
|
||||
SDL_BindGPUIndexBuffer(render_pass,&index_buffer_binding,sizeof(ImDrawIdx) == 2 ? SDL_GPU_INDEXELEMENTSIZE_16BIT : SDL_GPU_INDEXELEMENTSIZE_32BIT);
|
||||
}
|
||||
|
||||
// Setup viewport
|
||||
SDL_GPUViewport viewport = {};
|
||||
viewport.x = 0;
|
||||
viewport.y = 0;
|
||||
viewport.w = (float)fb_width;
|
||||
viewport.h = (float)fb_height;
|
||||
viewport.min_depth = 0.0f;
|
||||
viewport.max_depth = 1.0f;
|
||||
SDL_SetGPUViewport(render_pass,&viewport);
|
||||
|
||||
// Setup scale and translation
|
||||
// Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
struct UBO { float scale[2]; float translation[2]; } ubo;
|
||||
ubo.scale[0] = 2.0f / draw_data->DisplaySize.x;
|
||||
ubo.scale[1] = 2.0f / draw_data->DisplaySize.y;
|
||||
ubo.translation[0] = -1.0f - draw_data->DisplayPos.x * ubo.scale[0];
|
||||
ubo.translation[1] = -1.0f - draw_data->DisplayPos.y * ubo.scale[1];
|
||||
SDL_PushGPUVertexUniformData(command_buffer, 0, &ubo, sizeof(UBO));
|
||||
}
|
||||
|
||||
static void CreateOrResizeBuffer(SDL_GPUBuffer** buffer, uint32_t* old_size, uint32_t new_size, SDL_GPUBufferUsageFlags usage)
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
|
||||
SDL_WaitForGPUIdle(v->GpuDevice);
|
||||
SDL_ReleaseGPUBuffer(v->GpuDevice, *buffer);
|
||||
|
||||
SDL_GPUBufferCreateInfo buffer_info = {};
|
||||
buffer_info.usage = usage;
|
||||
buffer_info.size = new_size;
|
||||
buffer_info.props = 0;
|
||||
*buffer = SDL_CreateGPUBuffer(v->GpuDevice, &buffer_info);
|
||||
*old_size = new_size;
|
||||
IM_ASSERT(*buffer != nullptr && "Failed to create GPU Buffer, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
// SDL_GPU doesn't allow copy passes to occur while a render or compute pass is bound!
|
||||
// The only way to allow a user to supply their own RenderPass (to render to a texture instead of the window for example),
|
||||
// is to split the upload part of ImGui_ImplSDLGPU3_RenderDrawData() to another function that needs to be called by the user before rendering.
|
||||
void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount <= 0)
|
||||
return;
|
||||
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
ImGui_ImplSDLGPU3_FrameData* fd = &bd->MainWindowFrameData;
|
||||
|
||||
uint32_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
|
||||
uint32_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
|
||||
if (fd->VertexBuffer == nullptr || fd->VertexBufferSize < vertex_size)
|
||||
CreateOrResizeBuffer(&fd->VertexBuffer, &fd->VertexBufferSize, vertex_size, SDL_GPU_BUFFERUSAGE_VERTEX);
|
||||
if (fd->IndexBuffer == nullptr || fd->IndexBufferSize < index_size)
|
||||
CreateOrResizeBuffer(&fd->IndexBuffer, &fd->IndexBufferSize, index_size, SDL_GPU_BUFFERUSAGE_INDEX);
|
||||
|
||||
// FIXME: It feels like more code could be shared there.
|
||||
SDL_GPUTransferBufferCreateInfo vertex_transferbuffer_info = {};
|
||||
vertex_transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
vertex_transferbuffer_info.size = vertex_size;
|
||||
SDL_GPUTransferBufferCreateInfo index_transferbuffer_info = {};
|
||||
index_transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
index_transferbuffer_info.size = index_size;
|
||||
|
||||
SDL_GPUTransferBuffer* vertex_transferbuffer = SDL_CreateGPUTransferBuffer(v->GpuDevice, &vertex_transferbuffer_info);
|
||||
IM_ASSERT(vertex_transferbuffer != nullptr && "Failed to create the vertex transfer buffer, call SDL_GetError() for more information");
|
||||
SDL_GPUTransferBuffer* index_transferbuffer = SDL_CreateGPUTransferBuffer(v->GpuDevice, &index_transferbuffer_info);
|
||||
IM_ASSERT(index_transferbuffer != nullptr && "Failed to create the index transfer buffer, call SDL_GetError() for more information");
|
||||
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)SDL_MapGPUTransferBuffer(v->GpuDevice, vertex_transferbuffer, true);
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)SDL_MapGPUTransferBuffer(v->GpuDevice, index_transferbuffer, true);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
SDL_UnmapGPUTransferBuffer(v->GpuDevice, vertex_transferbuffer);
|
||||
SDL_UnmapGPUTransferBuffer(v->GpuDevice, index_transferbuffer);
|
||||
|
||||
SDL_GPUTransferBufferLocation vertex_buffer_location = {};
|
||||
vertex_buffer_location.offset = 0;
|
||||
vertex_buffer_location.transfer_buffer = vertex_transferbuffer;
|
||||
SDL_GPUTransferBufferLocation index_buffer_location = {};
|
||||
index_buffer_location.offset = 0;
|
||||
index_buffer_location.transfer_buffer = index_transferbuffer;
|
||||
|
||||
SDL_GPUBufferRegion vertex_buffer_region = {};
|
||||
vertex_buffer_region.buffer = fd->VertexBuffer;
|
||||
vertex_buffer_region.offset = 0;
|
||||
vertex_buffer_region.size = vertex_size;
|
||||
|
||||
SDL_GPUBufferRegion index_buffer_region = {};
|
||||
index_buffer_region.buffer = fd->IndexBuffer;
|
||||
index_buffer_region.offset = 0;
|
||||
index_buffer_region.size = index_size;
|
||||
|
||||
SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(command_buffer);
|
||||
SDL_UploadToGPUBuffer(copy_pass, &vertex_buffer_location, &vertex_buffer_region,true);
|
||||
SDL_UploadToGPUBuffer(copy_pass, &index_buffer_location, &index_buffer_region,true);
|
||||
SDL_EndGPUCopyPass(copy_pass);
|
||||
SDL_ReleaseGPUTransferBuffer(v->GpuDevice, index_transferbuffer);
|
||||
SDL_ReleaseGPUTransferBuffer(v->GpuDevice, vertex_transferbuffer);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0)
|
||||
return;
|
||||
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_FrameData* fd = &bd->MainWindowFrameData;
|
||||
|
||||
if (pipeline == nullptr)
|
||||
pipeline = bd->Pipeline;
|
||||
|
||||
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
|
||||
// Clamp to viewport as SDL_SetGPUScissor() won't accept values that are off bounds
|
||||
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
|
||||
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
|
||||
if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; }
|
||||
if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; }
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle
|
||||
SDL_Rect scissor_rect = {};
|
||||
scissor_rect.x = (int)clip_min.x;
|
||||
scissor_rect.y = (int)clip_min.y;
|
||||
scissor_rect.w = (int)(clip_max.x - clip_min.x);
|
||||
scissor_rect.h = (int)(clip_max.y - clip_min.y);
|
||||
SDL_SetGPUScissor(render_pass,&scissor_rect);
|
||||
|
||||
// Bind DescriptorSet with font or user texture
|
||||
SDL_BindGPUFragmentSamplers(render_pass, 0, (SDL_GPUTextureSamplerBinding*)pcmd->GetTexID(), 1);
|
||||
|
||||
// Draw
|
||||
SDL_DrawGPUIndexedPrimitives(render_pass, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
// Note: at this point both SDL_SetGPUViewport() and SDL_SetGPUScissor() have been called.
|
||||
// Our last values will leak into user/application rendering if you forgot to call SDL_SetGPUViewport() and SDL_SetGPUScissor() yourself to explicitly set that state
|
||||
// In theory we should aim to backup/restore those values but I am not sure this is possible.
|
||||
// We perform a call to SDL_SetGPUScissor() to set back a full viewport which is likely to fix things for 99% users but technically this is not perfect. (See github #4644)
|
||||
SDL_Rect scissor_rect { 0, 0, fb_width, fb_height };
|
||||
SDL_SetGPUScissor(render_pass, &scissor_rect);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLGPU3_CreateFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
|
||||
// Destroy existing texture (if any)
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
SDL_WaitForGPUIdle(v->GpuDevice);
|
||||
ImGui_ImplSDLGPU3_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
uint32_t upload_size = width * height * 4 * sizeof(char);
|
||||
|
||||
// Create the Image:
|
||||
{
|
||||
SDL_GPUTextureCreateInfo texture_info = {};
|
||||
texture_info.type = SDL_GPU_TEXTURETYPE_2D;
|
||||
texture_info.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
|
||||
texture_info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER;
|
||||
texture_info.width = width;
|
||||
texture_info.height = height;
|
||||
texture_info.layer_count_or_depth = 1;
|
||||
texture_info.num_levels = 1;
|
||||
texture_info.sample_count = SDL_GPU_SAMPLECOUNT_1;
|
||||
|
||||
bd->FontTexture = SDL_CreateGPUTexture(v->GpuDevice, &texture_info);
|
||||
IM_ASSERT(bd->FontTexture && "Failed to create font texture, call SDL_GetError() for more info");
|
||||
}
|
||||
|
||||
// Assign the texture to the TextureSamplerBinding
|
||||
bd->FontBinding.texture = bd->FontTexture;
|
||||
|
||||
// Create all the upload structures and upload:
|
||||
{
|
||||
SDL_GPUTransferBufferCreateInfo font_transferbuffer_info = {};
|
||||
font_transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
font_transferbuffer_info.size = upload_size;
|
||||
|
||||
SDL_GPUTransferBuffer* font_transferbuffer = SDL_CreateGPUTransferBuffer(v->GpuDevice, &font_transferbuffer_info);
|
||||
IM_ASSERT(font_transferbuffer != nullptr && "Failed to create font transfer buffer, call SDL_GetError() for more information");
|
||||
|
||||
void* texture_ptr = SDL_MapGPUTransferBuffer(v->GpuDevice, font_transferbuffer, false);
|
||||
memcpy(texture_ptr, pixels, upload_size);
|
||||
SDL_UnmapGPUTransferBuffer(v->GpuDevice, font_transferbuffer);
|
||||
|
||||
SDL_GPUTextureTransferInfo font_transfer_info = {};
|
||||
font_transfer_info.offset = 0;
|
||||
font_transfer_info.transfer_buffer = font_transferbuffer;
|
||||
|
||||
SDL_GPUTextureRegion font_texture_region = {};
|
||||
font_texture_region.texture = bd->FontTexture;
|
||||
font_texture_region.w = width;
|
||||
font_texture_region.h = height;
|
||||
font_texture_region.d = 1;
|
||||
|
||||
SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(v->GpuDevice);
|
||||
SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(cmd);
|
||||
SDL_UploadToGPUTexture(copy_pass, &font_transfer_info, &font_texture_region, false);
|
||||
SDL_EndGPUCopyPass(copy_pass);
|
||||
SDL_SubmitGPUCommandBuffer(cmd);
|
||||
SDL_ReleaseGPUTransferBuffer(v->GpuDevice, font_transferbuffer);
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)&bd->FontBinding);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// You probably never need to call this, as it is called by ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_Shutdown().
|
||||
void ImGui_ImplSDLGPU3_DestroyFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
SDL_ReleaseGPUTexture(v->GpuDevice, bd->FontTexture);
|
||||
bd->FontBinding.texture = nullptr;
|
||||
bd->FontTexture = nullptr;
|
||||
}
|
||||
io.Fonts->SetTexID(0);
|
||||
}
|
||||
|
||||
static void Imgui_ImplSDLGPU3_CreateShaders()
|
||||
{
|
||||
// Create the shader modules
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
|
||||
const char* driver = SDL_GetGPUDeviceDriver(v->GpuDevice);
|
||||
|
||||
SDL_GPUShaderCreateInfo vertex_shader_info = {};
|
||||
vertex_shader_info.entrypoint = "main";
|
||||
vertex_shader_info.stage = SDL_GPU_SHADERSTAGE_VERTEX;
|
||||
vertex_shader_info.num_uniform_buffers = 1;
|
||||
vertex_shader_info.num_storage_buffers = 0;
|
||||
vertex_shader_info.num_storage_textures = 0;
|
||||
vertex_shader_info.num_samplers = 0;
|
||||
|
||||
SDL_GPUShaderCreateInfo fragment_shader_info = {};
|
||||
fragment_shader_info.entrypoint = "main";
|
||||
fragment_shader_info.stage = SDL_GPU_SHADERSTAGE_FRAGMENT;
|
||||
fragment_shader_info.num_samplers = 1;
|
||||
fragment_shader_info.num_storage_buffers = 0;
|
||||
fragment_shader_info.num_storage_textures = 0;
|
||||
fragment_shader_info.num_uniform_buffers = 0;
|
||||
|
||||
if (strcmp(driver, "vulkan") == 0)
|
||||
{
|
||||
vertex_shader_info.format = SDL_GPU_SHADERFORMAT_SPIRV;
|
||||
vertex_shader_info.code = spirv_vertex;
|
||||
vertex_shader_info.code_size = sizeof(spirv_vertex);
|
||||
fragment_shader_info.format = SDL_GPU_SHADERFORMAT_SPIRV;
|
||||
fragment_shader_info.code = spirv_fragment;
|
||||
fragment_shader_info.code_size = sizeof(spirv_fragment);
|
||||
}
|
||||
else if (strcmp(driver, "direct3d12") == 0)
|
||||
{
|
||||
vertex_shader_info.format = SDL_GPU_SHADERFORMAT_DXBC;
|
||||
vertex_shader_info.code = dxbc_vertex;
|
||||
vertex_shader_info.code_size = sizeof(dxbc_vertex);
|
||||
fragment_shader_info.format = SDL_GPU_SHADERFORMAT_DXBC;
|
||||
fragment_shader_info.code = dxbc_fragment;
|
||||
fragment_shader_info.code_size = sizeof(dxbc_fragment);
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
else
|
||||
{
|
||||
vertex_shader_info.entrypoint = "main0";
|
||||
vertex_shader_info.format = SDL_GPU_SHADERFORMAT_METALLIB;
|
||||
vertex_shader_info.code = metallib_vertex;
|
||||
vertex_shader_info.code_size = sizeof(metallib_vertex);
|
||||
fragment_shader_info.entrypoint = "main0";
|
||||
fragment_shader_info.format = SDL_GPU_SHADERFORMAT_METALLIB;
|
||||
fragment_shader_info.code = metallib_fragment;
|
||||
fragment_shader_info.code_size = sizeof(metallib_fragment);
|
||||
}
|
||||
#endif
|
||||
bd->VertexShader = SDL_CreateGPUShader(v->GpuDevice, &vertex_shader_info);
|
||||
bd->FragmentShader = SDL_CreateGPUShader(v->GpuDevice, &fragment_shader_info);
|
||||
IM_ASSERT(bd->VertexShader != nullptr && "Failed to create vertex shader, call SDL_GetError() for more information");
|
||||
IM_ASSERT(bd->FragmentShader != nullptr && "Failed to create fragment shader, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLGPU3_CreateGraphicsPipeline()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
Imgui_ImplSDLGPU3_CreateShaders();
|
||||
|
||||
SDL_GPUVertexBufferDescription vertex_buffer_desc[1];
|
||||
vertex_buffer_desc[0].slot = 0;
|
||||
vertex_buffer_desc[0].input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX;
|
||||
vertex_buffer_desc[0].instance_step_rate = 0;
|
||||
vertex_buffer_desc[0].pitch = sizeof(ImDrawVert);
|
||||
|
||||
SDL_GPUVertexAttribute vertex_attributes[3];
|
||||
vertex_attributes[0].buffer_slot = 0;
|
||||
vertex_attributes[0].format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2;
|
||||
vertex_attributes[0].location = 0;
|
||||
vertex_attributes[0].offset = offsetof(ImDrawVert,pos);
|
||||
|
||||
vertex_attributes[1].buffer_slot = 0;
|
||||
vertex_attributes[1].format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2;
|
||||
vertex_attributes[1].location = 1;
|
||||
vertex_attributes[1].offset = offsetof(ImDrawVert, uv);
|
||||
|
||||
vertex_attributes[2].buffer_slot = 0;
|
||||
vertex_attributes[2].format = SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM;
|
||||
vertex_attributes[2].location = 2;
|
||||
vertex_attributes[2].offset = offsetof(ImDrawVert, col);
|
||||
|
||||
SDL_GPUVertexInputState vertex_input_state = {};
|
||||
vertex_input_state.num_vertex_attributes = 3;
|
||||
vertex_input_state.vertex_attributes = vertex_attributes;
|
||||
vertex_input_state.num_vertex_buffers = 1;
|
||||
vertex_input_state.vertex_buffer_descriptions = vertex_buffer_desc;
|
||||
|
||||
SDL_GPURasterizerState rasterizer_state = {};
|
||||
rasterizer_state.fill_mode = SDL_GPU_FILLMODE_FILL;
|
||||
rasterizer_state.cull_mode = SDL_GPU_CULLMODE_NONE;
|
||||
rasterizer_state.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE;
|
||||
rasterizer_state.enable_depth_bias = false;
|
||||
rasterizer_state.enable_depth_clip = false;
|
||||
|
||||
SDL_GPUMultisampleState multisample_state = {};
|
||||
multisample_state.sample_count = v->MSAASamples;
|
||||
multisample_state.enable_mask = false;
|
||||
|
||||
SDL_GPUDepthStencilState depth_stencil_state = {};
|
||||
depth_stencil_state.enable_depth_test = false;
|
||||
depth_stencil_state.enable_depth_write = false;
|
||||
depth_stencil_state.enable_stencil_test = false;
|
||||
|
||||
SDL_GPUColorTargetBlendState blend_state = {};
|
||||
blend_state.enable_blend = true;
|
||||
blend_state.src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA;
|
||||
blend_state.dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blend_state.color_blend_op = SDL_GPU_BLENDOP_ADD;
|
||||
blend_state.src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE;
|
||||
blend_state.dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blend_state.alpha_blend_op = SDL_GPU_BLENDOP_ADD;
|
||||
blend_state.color_write_mask = SDL_GPU_COLORCOMPONENT_R | SDL_GPU_COLORCOMPONENT_G | SDL_GPU_COLORCOMPONENT_B | SDL_GPU_COLORCOMPONENT_A;
|
||||
|
||||
SDL_GPUColorTargetDescription color_target_desc[1];
|
||||
color_target_desc[0].format = v->ColorTargetFormat;
|
||||
color_target_desc[0].blend_state = blend_state;
|
||||
|
||||
SDL_GPUGraphicsPipelineTargetInfo target_info = {};
|
||||
target_info.num_color_targets = 1;
|
||||
target_info.color_target_descriptions = color_target_desc;
|
||||
target_info.has_depth_stencil_target = false;
|
||||
|
||||
SDL_GPUGraphicsPipelineCreateInfo pipeline_info = {};
|
||||
pipeline_info.vertex_shader = bd->VertexShader;
|
||||
pipeline_info.fragment_shader = bd->FragmentShader;
|
||||
pipeline_info.vertex_input_state = vertex_input_state;
|
||||
pipeline_info.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST;
|
||||
pipeline_info.rasterizer_state = rasterizer_state;
|
||||
pipeline_info.multisample_state = multisample_state;
|
||||
pipeline_info.depth_stencil_state = depth_stencil_state;
|
||||
pipeline_info.target_info = target_info;
|
||||
|
||||
bd->Pipeline = SDL_CreateGPUGraphicsPipeline(v->GpuDevice, &pipeline_info);
|
||||
IM_ASSERT(bd->Pipeline != nullptr && "Failed to create graphics pipeline, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLGPU3_CreateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
|
||||
if (!bd->FontSampler)
|
||||
{
|
||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||
SDL_GPUSamplerCreateInfo sampler_info = {};
|
||||
sampler_info.min_filter = SDL_GPU_FILTER_LINEAR;
|
||||
sampler_info.mag_filter = SDL_GPU_FILTER_LINEAR;
|
||||
sampler_info.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR;
|
||||
sampler_info.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||
sampler_info.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||
sampler_info.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||
sampler_info.mip_lod_bias = 0.0f;
|
||||
sampler_info.min_lod = -1000.0f;
|
||||
sampler_info.max_lod = 1000.0f;
|
||||
sampler_info.enable_anisotropy = true;
|
||||
sampler_info.max_anisotropy = 1.0f;
|
||||
sampler_info.enable_compare = false;
|
||||
|
||||
bd->FontSampler = SDL_CreateGPUSampler(v->GpuDevice, &sampler_info);
|
||||
bd->FontBinding.sampler = bd->FontSampler;
|
||||
IM_ASSERT(bd->FontSampler != nullptr && "Failed to create font sampler, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
ImGui_ImplSDLGPU3_CreateGraphicsPipeline();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_DestroyFrameData()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
|
||||
SDL_ReleaseGPUBuffer(v->GpuDevice, bd->MainWindowFrameData.VertexBuffer);
|
||||
SDL_ReleaseGPUBuffer(v->GpuDevice, bd->MainWindowFrameData.IndexBuffer);
|
||||
bd->MainWindowFrameData.VertexBuffer = nullptr;
|
||||
bd->MainWindowFrameData.IndexBuffer = nullptr;
|
||||
bd->MainWindowFrameData.VertexBufferSize = 0;
|
||||
bd->MainWindowFrameData.IndexBufferSize = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo;
|
||||
|
||||
ImGui_ImplSDLGPU3_DestroyFrameData();
|
||||
ImGui_ImplSDLGPU3_DestroyFontsTexture();
|
||||
|
||||
if (bd->VertexShader) { SDL_ReleaseGPUShader(v->GpuDevice, bd->VertexShader); bd->VertexShader = nullptr;}
|
||||
if (bd->FragmentShader) { SDL_ReleaseGPUShader(v->GpuDevice, bd->FragmentShader); bd->FragmentShader = nullptr;}
|
||||
if (bd->FontSampler) { SDL_ReleaseGPUSampler(v->GpuDevice, bd->FontSampler); bd->FontSampler = nullptr;}
|
||||
if (bd->Pipeline) { SDL_ReleaseGPUGraphicsPipeline(v->GpuDevice, bd->Pipeline); bd->Pipeline = nullptr;}
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplSDLGPU3_Data* bd = IM_NEW(ImGui_ImplSDLGPU3_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_sdlgpu3";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
IM_ASSERT(info->GpuDevice != nullptr);
|
||||
IM_ASSERT(info->ColorTargetFormat != SDL_GPU_TEXTUREFORMAT_INVALID);
|
||||
|
||||
bd->GPUInitInfo = *info;
|
||||
|
||||
ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_Shutdown()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_NewFrame()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLGPU3_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplSDLGPU3_CreateFontsTexture();
|
||||
}
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
46
neo/libs/imgui/backends/imgui_impl_sdlgpu3.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
// dear imgui: Renderer Backend for SDL_GPU
|
||||
// This needs to be used along with the SDL3 Platform Backend
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// Important note to the reader who wish to integrate imgui_impl_sdlgpu3.cpp/.h in their own engine/app.
|
||||
// - Unline other backends, the user must call the function Imgui_ImplSDLGPU_PrepareDrawData BEFORE issuing a SDL_GPURenderPass containing ImGui_ImplSDLGPU_RenderDrawData.
|
||||
// Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info.
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include <SDL3/SDL_gpu.h>
|
||||
|
||||
// Initialization data, for ImGui_ImplSDLGPU_Init()
|
||||
// - Remember to set ColorTargetFormat to the correct format. If you're rendering to the swapchain, call SDL_GetGPUSwapchainTextureFormat to query the right value
|
||||
struct ImGui_ImplSDLGPU3_InitInfo
|
||||
{
|
||||
SDL_GPUDevice* GpuDevice = nullptr;
|
||||
SDL_GPUTextureFormat ColorTargetFormat = SDL_GPU_TEXTUREFORMAT_INVALID;
|
||||
SDL_GPUSampleCount MSAASamples = SDL_GPU_SAMPLECOUNT_1;
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_NewFrame();
|
||||
IMGUI_IMPL_API void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline = nullptr);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyFontsTexture();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
372
neo/libs/imgui/backends/imgui_impl_sdlgpu3_shaders.h
Normal file
|
@ -0,0 +1,372 @@
|
|||
#pragma once
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include <stdint.h>
|
||||
|
||||
// Data exported using
|
||||
// misc/fonts/binary_to_compressed_c.exe -u8 -nocompress filename symbolname >filename.h
|
||||
// With some manual pasting.
|
||||
|
||||
// Check sdlgpu3/ folder for the shaders' source code and instruction on how to build them
|
||||
const uint8_t spirv_vertex[1732] = {
|
||||
3,2,35,7,0,0,1,0,11,0,13,0,55,0,0,0,0,0,0,0,17,0,2,0,1,0,0,0,11,0,6,0,1,0,0,0,71,76,83,76,46,115,116,100,46,52,53,48,0,0,0,0,14,0,3,0,0,0,0,0,1,0,0,0,15,0,10,0,0,0,0,0,4,0,0,0,109,
|
||||
97,105,110,0,0,0,0,11,0,0,0,15,0,0,0,21,0,0,0,30,0,0,0,31,0,0,0,3,0,3,0,2,0,0,0,194,1,0,0,4,0,10,0,71,76,95,71,79,79,71,76,69,95,99,112,112,95,115,116,121,108,101,95,108,105,110,101,
|
||||
95,100,105,114,101,99,116,105,118,101,0,0,4,0,8,0,71,76,95,71,79,79,71,76,69,95,105,110,99,108,117,100,101,95,100,105,114,101,99,116,105,118,101,0,5,0,4,0,4,0,0,0,109,97,105,110,0,
|
||||
0,0,0,5,0,3,0,9,0,0,0,0,0,0,0,6,0,5,0,9,0,0,0,0,0,0,0,67,111,108,111,114,0,0,0,6,0,4,0,9,0,0,0,1,0,0,0,85,86,0,0,5,0,3,0,11,0,0,0,79,117,116,0,5,0,4,0,15,0,0,0,97,67,111,108,111,114,
|
||||
0,0,5,0,3,0,21,0,0,0,97,85,86,0,5,0,6,0,28,0,0,0,103,108,95,80,101,114,86,101,114,116,101,120,0,0,0,0,6,0,6,0,28,0,0,0,0,0,0,0,103,108,95,80,111,115,105,116,105,111,110,0,6,0,7,0,28,
|
||||
0,0,0,1,0,0,0,103,108,95,80,111,105,110,116,83,105,122,101,0,0,0,0,6,0,7,0,28,0,0,0,2,0,0,0,103,108,95,67,108,105,112,68,105,115,116,97,110,99,101,0,6,0,7,0,28,0,0,0,3,0,0,0,103,108,
|
||||
95,67,117,108,108,68,105,115,116,97,110,99,101,0,5,0,3,0,30,0,0,0,0,0,0,0,5,0,4,0,31,0,0,0,97,80,111,115,0,0,0,0,5,0,6,0,33,0,0,0,117,80,117,115,104,67,111,110,115,116,97,110,116,0,
|
||||
0,0,6,0,5,0,33,0,0,0,0,0,0,0,117,83,99,97,108,101,0,0,6,0,6,0,33,0,0,0,1,0,0,0,117,84,114,97,110,115,108,97,116,101,0,0,5,0,3,0,35,0,0,0,112,99,0,0,71,0,4,0,11,0,0,0,30,0,0,0,0,0,0,
|
||||
0,71,0,4,0,15,0,0,0,30,0,0,0,2,0,0,0,71,0,4,0,21,0,0,0,30,0,0,0,1,0,0,0,71,0,3,0,28,0,0,0,2,0,0,0,72,0,5,0,28,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,72,0,5,0,28,0,0,0,1,0,0,0,11,0,0,0,1,0,
|
||||
0,0,72,0,5,0,28,0,0,0,2,0,0,0,11,0,0,0,3,0,0,0,72,0,5,0,28,0,0,0,3,0,0,0,11,0,0,0,4,0,0,0,71,0,4,0,31,0,0,0,30,0,0,0,0,0,0,0,71,0,3,0,33,0,0,0,2,0,0,0,72,0,5,0,33,0,0,0,0,0,0,0,35,
|
||||
0,0,0,0,0,0,0,72,0,5,0,33,0,0,0,1,0,0,0,35,0,0,0,8,0,0,0,71,0,4,0,35,0,0,0,33,0,0,0,0,0,0,0,71,0,4,0,35,0,0,0,34,0,0,0,1,0,0,0,19,0,2,0,2,0,0,0,33,0,3,0,3,0,0,0,2,0,0,0,22,0,3,0,6,
|
||||
0,0,0,32,0,0,0,23,0,4,0,7,0,0,0,6,0,0,0,4,0,0,0,23,0,4,0,8,0,0,0,6,0,0,0,2,0,0,0,30,0,4,0,9,0,0,0,7,0,0,0,8,0,0,0,32,0,4,0,10,0,0,0,3,0,0,0,9,0,0,0,59,0,4,0,10,0,0,0,11,0,0,0,3,0,0,
|
||||
0,21,0,4,0,12,0,0,0,32,0,0,0,1,0,0,0,43,0,4,0,12,0,0,0,13,0,0,0,0,0,0,0,32,0,4,0,14,0,0,0,1,0,0,0,7,0,0,0,59,0,4,0,14,0,0,0,15,0,0,0,1,0,0,0,32,0,4,0,17,0,0,0,3,0,0,0,7,0,0,0,43,0,
|
||||
4,0,12,0,0,0,19,0,0,0,1,0,0,0,32,0,4,0,20,0,0,0,1,0,0,0,8,0,0,0,59,0,4,0,20,0,0,0,21,0,0,0,1,0,0,0,32,0,4,0,23,0,0,0,3,0,0,0,8,0,0,0,21,0,4,0,25,0,0,0,32,0,0,0,0,0,0,0,43,0,4,0,25,
|
||||
0,0,0,26,0,0,0,1,0,0,0,28,0,4,0,27,0,0,0,6,0,0,0,26,0,0,0,30,0,6,0,28,0,0,0,7,0,0,0,6,0,0,0,27,0,0,0,27,0,0,0,32,0,4,0,29,0,0,0,3,0,0,0,28,0,0,0,59,0,4,0,29,0,0,0,30,0,0,0,3,0,0,0,
|
||||
59,0,4,0,20,0,0,0,31,0,0,0,1,0,0,0,30,0,4,0,33,0,0,0,8,0,0,0,8,0,0,0,32,0,4,0,34,0,0,0,2,0,0,0,33,0,0,0,59,0,4,0,34,0,0,0,35,0,0,0,2,0,0,0,32,0,4,0,36,0,0,0,2,0,0,0,8,0,0,0,43,0,4,
|
||||
0,6,0,0,0,43,0,0,0,0,0,0,0,43,0,4,0,6,0,0,0,44,0,0,0,0,0,128,63,43,0,4,0,6,0,0,0,49,0,0,0,0,0,128,191,32,0,4,0,50,0,0,0,3,0,0,0,6,0,0,0,54,0,5,0,2,0,0,0,4,0,0,0,0,0,0,0,3,0,0,0,248,
|
||||
0,2,0,5,0,0,0,61,0,4,0,7,0,0,0,16,0,0,0,15,0,0,0,65,0,5,0,17,0,0,0,18,0,0,0,11,0,0,0,13,0,0,0,62,0,3,0,18,0,0,0,16,0,0,0,61,0,4,0,8,0,0,0,22,0,0,0,21,0,0,0,65,0,5,0,23,0,0,0,24,0,0,
|
||||
0,11,0,0,0,19,0,0,0,62,0,3,0,24,0,0,0,22,0,0,0,61,0,4,0,8,0,0,0,32,0,0,0,31,0,0,0,65,0,5,0,36,0,0,0,37,0,0,0,35,0,0,0,13,0,0,0,61,0,4,0,8,0,0,0,38,0,0,0,37,0,0,0,133,0,5,0,8,0,0,0,
|
||||
39,0,0,0,32,0,0,0,38,0,0,0,65,0,5,0,36,0,0,0,40,0,0,0,35,0,0,0,19,0,0,0,61,0,4,0,8,0,0,0,41,0,0,0,40,0,0,0,129,0,5,0,8,0,0,0,42,0,0,0,39,0,0,0,41,0,0,0,81,0,5,0,6,0,0,0,45,0,0,0,42,
|
||||
0,0,0,0,0,0,0,81,0,5,0,6,0,0,0,46,0,0,0,42,0,0,0,1,0,0,0,80,0,7,0,7,0,0,0,47,0,0,0,45,0,0,0,46,0,0,0,43,0,0,0,44,0,0,0,65,0,5,0,17,0,0,0,48,0,0,0,30,0,0,0,13,0,0,0,62,0,3,0,48,0,0,
|
||||
0,47,0,0,0,65,0,6,0,50,0,0,0,51,0,0,0,30,0,0,0,13,0,0,0,26,0,0,0,61,0,4,0,6,0,0,0,52,0,0,0,51,0,0,0,133,0,5,0,6,0,0,0,53,0,0,0,52,0,0,0,49,0,0,0,65,0,6,0,50,0,0,0,54,0,0,0,30,0,0,0,
|
||||
13,0,0,0,26,0,0,0,62,0,3,0,54,0,0,0,53,0,0,0,253,0,1,0,56,0,1,0,
|
||||
};
|
||||
const uint8_t spirv_fragment[844] = {
|
||||
3,2,35,7,0,0,1,0,11,0,13,0,30,0,0,0,0,0,0,0,17,0,2,0,1,0,0,0,11,0,6,0,1,0,0,0,71,76,83,76,46,115,116,100,46,52,53,48,0,0,0,0,14,0,3,0,0,0,0,0,1,0,0,0,15,0,7,0,4,0,0,0,4,0,0,0,109,97,
|
||||
105,110,0,0,0,0,9,0,0,0,13,0,0,0,16,0,3,0,4,0,0,0,7,0,0,0,3,0,3,0,2,0,0,0,194,1,0,0,4,0,10,0,71,76,95,71,79,79,71,76,69,95,99,112,112,95,115,116,121,108,101,95,108,105,110,101,95,100,
|
||||
105,114,101,99,116,105,118,101,0,0,4,0,8,0,71,76,95,71,79,79,71,76,69,95,105,110,99,108,117,100,101,95,100,105,114,101,99,116,105,118,101,0,5,0,4,0,4,0,0,0,109,97,105,110,0,0,0,0,5,
|
||||
0,4,0,9,0,0,0,102,67,111,108,111,114,0,0,5,0,3,0,11,0,0,0,0,0,0,0,6,0,5,0,11,0,0,0,0,0,0,0,67,111,108,111,114,0,0,0,6,0,4,0,11,0,0,0,1,0,0,0,85,86,0,0,5,0,3,0,13,0,0,0,73,110,0,0,5,
|
||||
0,5,0,22,0,0,0,115,84,101,120,116,117,114,101,0,0,0,0,71,0,4,0,9,0,0,0,30,0,0,0,0,0,0,0,71,0,4,0,13,0,0,0,30,0,0,0,0,0,0,0,71,0,4,0,22,0,0,0,33,0,0,0,0,0,0,0,71,0,4,0,22,0,0,0,34,0,
|
||||
0,0,2,0,0,0,19,0,2,0,2,0,0,0,33,0,3,0,3,0,0,0,2,0,0,0,22,0,3,0,6,0,0,0,32,0,0,0,23,0,4,0,7,0,0,0,6,0,0,0,4,0,0,0,32,0,4,0,8,0,0,0,3,0,0,0,7,0,0,0,59,0,4,0,8,0,0,0,9,0,0,0,3,0,0,0,23,
|
||||
0,4,0,10,0,0,0,6,0,0,0,2,0,0,0,30,0,4,0,11,0,0,0,7,0,0,0,10,0,0,0,32,0,4,0,12,0,0,0,1,0,0,0,11,0,0,0,59,0,4,0,12,0,0,0,13,0,0,0,1,0,0,0,21,0,4,0,14,0,0,0,32,0,0,0,1,0,0,0,43,0,4,0,
|
||||
14,0,0,0,15,0,0,0,0,0,0,0,32,0,4,0,16,0,0,0,1,0,0,0,7,0,0,0,25,0,9,0,19,0,0,0,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,27,0,3,0,20,0,0,0,19,0,0,0,32,0,4,0,21,0,0,0,0,
|
||||
0,0,0,20,0,0,0,59,0,4,0,21,0,0,0,22,0,0,0,0,0,0,0,43,0,4,0,14,0,0,0,24,0,0,0,1,0,0,0,32,0,4,0,25,0,0,0,1,0,0,0,10,0,0,0,54,0,5,0,2,0,0,0,4,0,0,0,0,0,0,0,3,0,0,0,248,0,2,0,5,0,0,0,65,
|
||||
0,5,0,16,0,0,0,17,0,0,0,13,0,0,0,15,0,0,0,61,0,4,0,7,0,0,0,18,0,0,0,17,0,0,0,61,0,4,0,20,0,0,0,23,0,0,0,22,0,0,0,65,0,5,0,25,0,0,0,26,0,0,0,13,0,0,0,24,0,0,0,61,0,4,0,10,0,0,0,27,0,
|
||||
0,0,26,0,0,0,87,0,5,0,7,0,0,0,28,0,0,0,23,0,0,0,27,0,0,0,133,0,5,0,7,0,0,0,29,0,0,0,18,0,0,0,28,0,0,0,62,0,3,0,9,0,0,0,29,0,0,0,253,0,1,0,56,0,1,0,
|
||||
};
|
||||
|
||||
const uint8_t dxbc_vertex[1064] = {
|
||||
68,88,66,67,32,50,127,204,241,196,165,104,216,114,216,116,220,164,29,45,1,0,0,0,40,4,0,0,5,0,0,0,52,0,0,0,136,1,0,0,236,1,0,0,92,2,0,0,140,3,0,0,82,68,69,70,76,1,0,0,1,0,0,0,116,0,
|
||||
0,0,1,0,0,0,60,0,0,0,1,5,254,255,0,5,0,0,34,1,0,0,19,19,68,37,60,0,0,0,24,0,0,0,40,0,0,0,40,0,0,0,36,0,0,0,12,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
|
||||
0,1,0,0,0,1,0,0,0,0,0,0,0,117,80,117,115,104,67,111,110,115,116,97,110,116,0,171,171,100,0,0,0,2,0,0,0,140,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,8,0,0,0,2,0,0,0,240,0,0,
|
||||
0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,20,1,0,0,8,0,0,0,8,0,0,0,2,0,0,0,240,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,112,99,95,117,83,99,97,
|
||||
108,101,0,102,108,111,97,116,50,0,171,171,171,1,0,3,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,112,99,95,117,84,114,97,110,115,108,97,116,101,0,77,105,99,114,
|
||||
111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,49,48,46,49,0,171,171,73,83,71,78,92,0,0,0,3,0,0,0,8,0,0,0,80,0,0,0,0,0,
|
||||
0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,3,0,0,80,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,3,0,0,80,0,0,0,2,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,15,15,0,0,84,69,88,67,79,79,82,68,0,171,171,171,79,83,
|
||||
71,78,104,0,0,0,3,0,0,0,8,0,0,0,80,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,80,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,12,0,0,89,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,2,0,0,0,15,0,0,
|
||||
0,84,69,88,67,79,79,82,68,0,83,86,95,80,111,115,105,116,105,111,110,0,171,171,171,83,72,69,88,40,1,0,0,81,0,1,0,74,0,0,0,106,8,0,1,89,0,0,7,70,142,48,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
|
||||
0,0,1,0,0,0,95,0,0,3,50,16,16,0,0,0,0,0,95,0,0,3,50,16,16,0,1,0,0,0,95,0,0,3,242,16,16,0,2,0,0,0,101,0,0,3,242,32,16,0,0,0,0,0,101,0,0,3,50,32,16,0,1,0,0,0,103,0,0,4,242,32,16,0,2,
|
||||
0,0,0,1,0,0,0,104,0,0,2,1,0,0,0,50,0,0,13,50,0,16,0,0,0,0,0,70,16,16,0,0,0,0,0,70,128,48,0,0,0,0,0,0,0,0,0,0,0,0,0,230,138,48,0,0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,6,34,32,16,0,2,0,0,0,
|
||||
26,0,16,128,65,0,0,0,0,0,0,0,54,0,0,5,242,32,16,0,0,0,0,0,70,30,16,0,2,0,0,0,54,0,0,5,18,32,16,0,2,0,0,0,10,0,16,0,0,0,0,0,54,0,0,8,194,32,16,0,2,0,0,0,2,64,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,128,63,54,0,0,5,50,32,16,0,1,0,0,0,70,16,16,0,1,0,0,0,62,0,0,1,83,84,65,84,148,0,0,0,7,0,0,0,1,0,0,0,0,0,0,0,6,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
const uint8_t dxbc_fragment[744] = {
|
||||
68,88,66,67,235,219,43,109,38,151,39,223,98,41,193,28,215,98,67,110,1,0,0,0,232,2,0,0,5,0,0,0,52,0,0,0,12,1,0,0,88,1,0,0,140,1,0,0,76,2,0,0,82,68,69,70,208,0,0,0,0,0,0,0,0,0,0,0,2,
|
||||
0,0,0,60,0,0,0,1,5,255,255,0,5,0,0,167,0,0,0,19,19,68,37,60,0,0,0,24,0,0,0,40,0,0,0,40,0,0,0,36,0,0,0,12,0,0,0,0,0,0,0,140,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
|
||||
0,0,2,0,0,0,0,0,0,0,158,0,0,0,2,0,0,0,5,0,0,0,4,0,0,0,255,255,255,255,0,0,0,0,1,0,0,0,12,0,0,0,2,0,0,0,0,0,0,0,95,115,84,101,120,116,117,114,101,95,115,97,109,112,108,101,114,0,115,
|
||||
84,101,120,116,117,114,101,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,49,48,46,49,0,171,73,83,71,78,
|
||||
68,0,0,0,2,0,0,0,8,0,0,0,56,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,15,0,0,56,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,3,0,0,84,69,88,67,79,79,82,68,0,171,171,171,79,83,71,78,44,0,
|
||||
0,0,1,0,0,0,8,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,83,86,95,84,97,114,103,101,116,0,171,171,83,72,69,88,184,0,0,0,81,0,0,0,46,0,0,0,106,8,0,1,90,0,0,6,70,110,48,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,88,24,0,7,70,126,48,0,0,0,0,0,0,0,0,0,0,0,0,0,85,85,0,0,2,0,0,0,98,16,0,3,242,16,16,0,0,0,0,0,98,16,0,3,50,16,16,0,1,0,0,0,101,0,0,3,242,32,16,0,0,
|
||||
0,0,0,104,0,0,2,1,0,0,0,69,0,0,11,242,0,16,0,0,0,0,0,70,16,16,0,1,0,0,0,70,126,32,0,0,0,0,0,0,0,0,0,0,96,32,0,0,0,0,0,0,0,0,0,56,0,0,7,242,32,16,0,0,0,0,0,70,14,16,0,0,0,0,0,70,30,
|
||||
16,0,0,0,0,0,62,0,0,1,83,84,65,84,148,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_MAC
|
||||
const uint8_t metallib_vertex[3892] = {
|
||||
77,84,76,66,1,128,2,0,7,0,0,129,14,0,0,0,52,15,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,12,1,0,0,0,0,0,0,8,0,0,0,0,0,0,0,20,1,0,0,0,0,0,0,32,
|
||||
14,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,0,72,65,83,72,32,0,62,81,190,157,8,240,236,158,164,213,65,62,170,226,96,136,231,243,238,160,100,
|
||||
26,13,254,254,64,19,129,180,3,149,75,77,68,83,90,8,0,32,14,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,6,0,3,0,1,0,69,78,68,84,
|
||||
69,78,68,84,45,0,0,0,86,65,84,84,24,0,3,0,97,80,111,115,0,0,128,97,85,86,0,1,128,97,67,111,108,111,114,0,2,128,86,65,84,89,5,0,3,0,4,4,6,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,
|
||||
11,0,0,0,0,20,0,0,0,8,14,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,0,0,74,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,
|
||||
6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,16,69,2,66,146,11,66,132,16,50,20,56,8,24,75,10,50,66,136,72,112,196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,
|
||||
32,201,1,50,66,132,24,42,40,42,144,49,124,176,92,145,32,196,200,0,0,0,137,32,0,0,24,0,0,0,50,34,8,9,32,98,70,0,33,43,36,152,16,33,37,36,152,16,25,39,12,133,164,144,96,66,100,92,32,
|
||||
36,100,130,224,153,1,24,70,32,128,97,4,1,184,67,72,32,37,77,17,37,76,62,149,82,210,193,57,141,52,1,205,148,4,145,65,4,66,48,197,136,68,145,13,4,204,17,128,129,10,228,28,1,40,12,34,
|
||||
8,194,48,2,145,140,0,0,0,0,0,81,24,0,0,100,0,0,0,27,246,35,248,255,255,255,255,1,48,5,192,15,0,56,0,254,0,144,0,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,
|
||||
192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,
|
||||
202,225,28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,
|
||||
119,104,131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,
|
||||
7,121,168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,
|
||||
13,232,65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,
|
||||
3,113,168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,195,24,8,
|
||||
4,176,0,164,0,84,65,128,4,105,0,13,225,144,14,242,208,6,226,80,15,230,96,14,229,32,15,109,224,14,239,208,6,225,192,14,233,16,14,243,0,0,0,73,24,0,0,1,0,0,0,19,132,64,0,19,176,112,72,
|
||||
7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,118,8,135,113,120,135,121,192,135,56,160,3,55,128,3,55,128,131,13,183,81,14,109,0,15,122,96,7,116,160,7,118,64,7,122,96,7,116,
|
||||
208,6,233,16,7,122,128,7,122,128,7,109,144,14,120,160,7,120,160,7,120,208,6,233,16,7,118,160,7,113,96,7,122,16,7,118,208,6,233,48,7,114,160,7,115,32,7,122,48,7,114,208,6,233,96,7,116,
|
||||
160,7,118,64,7,122,96,7,116,208,6,230,48,7,114,160,7,115,32,7,122,48,7,114,208,6,230,96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,16,7,118,160,7,113,96,7,122,16,7,118,208,6,246,32,
|
||||
7,116,160,7,115,32,7,122,48,7,114,208,6,246,48,7,114,160,7,115,32,7,122,48,7,114,208,6,246,64,7,120,160,7,118,64,7,122,96,7,116,208,6,246,96,7,116,160,7,118,64,7,122,96,7,116,208,6,
|
||||
246,144,7,118,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,114,128,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,144,7,114,160,7,114,80,7,118,160,7,114,80,7,118,208,
|
||||
6,246,32,7,117,96,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,117,16,7,114,160,7,117,16,7,114,160,7,117,16,7,114,208,6,246,16,7,112,32,7,116,160,7,113,0,7,114,64,7,122,16,7,112,
|
||||
32,7,116,208,6,238,128,7,122,16,7,118,160,7,115,32,7,26,33,12,89,48,0,210,208,67,42,160,48,0,0,8,0,0,0,4,0,0,0,0,0,10,64,98,131,64,81,166,1,0,128,44,16,0,11,0,0,0,50,30,152,16,25,17,
|
||||
76,144,140,9,38,71,198,4,67,202,34,40,129,66,40,135,242,41,64,129,130,40,144,98,24,1,40,3,218,17,0,210,177,132,39,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,
|
||||
67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,
|
||||
120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,
|
||||
97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,
|
||||
135,119,128,135,95,8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,
|
||||
29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,
|
||||
7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,
|
||||
29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,
|
||||
30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,
|
||||
129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,
|
||||
212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,
|
||||
14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,
|
||||
7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,
|
||||
248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,32,0,0,26,1,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,152,
|
||||
6,100,208,82,0,0,0,139,210,88,216,6,109,80,28,20,27,71,6,209,18,25,76,178,24,6,179,64,18,49,24,202,131,68,148,161,68,87,35,0,0,0,0,83,68,75,32,86,101,114,115,105,111,110,119,99,104,
|
||||
97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,
|
||||
95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,
|
||||
97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,
|
||||
112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,
|
||||
56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,
|
||||
116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,
|
||||
97,105,114,46,118,101,114,116,101,120,95,111,117,116,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,
|
||||
116,52,97,105,114,46,97,114,103,95,110,97,109,101,79,117,116,95,67,111,108,111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,79,117,116,95,85,86,97,105,114,46,112,
|
||||
111,115,105,116,105,111,110,103,108,95,80,111,115,105,116,105,111,110,97,105,114,46,118,101,114,116,101,120,95,105,110,112,117,116,97,105,114,46,108,111,99,97,116,105,111,110,95,105,
|
||||
110,100,101,120,97,80,111,115,97,85,86,97,67,111,108,111,114,97,105,114,46,98,117,102,102,101,114,97,105,114,46,98,117,102,102,101,114,95,115,105,122,101,97,105,114,46,114,101,97,100,
|
||||
97,105,114,46,97,100,100,114,101,115,115,95,115,112,97,99,101,97,105,114,46,115,116,114,117,99,116,95,116,121,112,101,95,105,110,102,111,117,83,99,97,108,101,117,84,114,97,110,115,
|
||||
108,97,116,101,97,105,114,46,97,114,103,95,116,121,112,101,95,115,105,122,101,97,105,114,46,97,114,103,95,116,121,112,101,95,97,108,105,103,110,95,115,105,122,101,117,80,117,115,104,
|
||||
67,111,110,115,116,97,110,116,112,99,0,0,0,166,119,0,0,0,0,0,0,48,130,144,4,35,8,74,51,130,144,8,35,8,201,48,130,144,16,35,8,73,49,130,144,24,35,8,201,49,130,144,32,35,8,73,50,130,
|
||||
144,40,35,8,201,50,130,112,0,51,12,106,16,172,193,12,3,27,8,109,48,195,224,6,131,26,204,48,184,1,241,6,51,12,110,80,188,193,12,131,27,24,111,48,195,224,6,7,28,204,48,184,1,18,7,51,
|
||||
12,110,144,200,193,12,129,50,195,160,6,115,64,7,51,16,75,29,176,1,29,204,16,48,51,4,205,12,129,51,131,241,64,145,52,81,51,24,79,21,89,211,53,67,129,69,210,148,205,48,152,194,41,160,
|
||||
194,12,9,29,104,27,29,176,65,100,77,220,12,9,27,104,27,27,176,65,100,77,221,12,137,26,104,155,26,176,65,36,77,222,12,10,29,196,1,29,88,100,16,7,113,64,7,86,25,204,64,213,193,7,6,114,
|
||||
176,209,1,27,132,129,24,168,193,24,180,130,25,200,193,25,196,65,132,6,83,26,204,64,168,194,42,176,130,43,204,48,216,65,42,188,194,157,1,192,113,28,199,113,28,199,113,28,199,185,129,
|
||||
27,184,129,27,184,129,27,184,129,27,184,129,69,7,122,96,89,22,29,208,129,27,208,1,46,224,2,46,240,3,122,128,130,140,4,38,40,35,54,54,187,54,151,182,55,178,58,182,50,23,51,182,176,179,
|
||||
185,81,18,59,184,3,60,200,3,61,216,3,62,232,3,63,72,133,141,205,174,205,37,141,172,204,141,110,148,224,15,114,9,75,147,115,177,43,147,155,75,123,115,27,37,0,133,164,194,210,228,92,
|
||||
216,194,220,206,234,194,206,202,190,236,202,228,230,210,222,220,70,9,66,33,167,176,52,57,151,177,183,54,184,52,182,178,175,55,56,186,180,55,183,185,81,6,81,24,5,82,72,37,44,77,206,
|
||||
197,174,76,142,174,12,111,148,224,21,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,
|
||||
29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,
|
||||
195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,
|
||||
15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,68,0,0,0,19,4,65,44,16,0,0,0,11,0,0,0,148,51,0,180,37,
|
||||
64,61,7,161,72,146,52,7,161,72,9,65,48,26,48,2,48,70,0,130,32,136,127,20,115,16,150,117,97,36,163,1,52,51,0,0,0,0,0,241,48,0,0,32,0,0,0,34,71,200,144,81,18,196,43,0,0,0,0,207,115,89,
|
||||
0,111,109,110,105,112,111,116,101,110,116,32,99,104,97,114,83,105,109,112,108,101,32,67,43,43,32,84,66,65,65,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,
|
||||
110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,97,114,103,40,51,41,0,19,132,133,89,33,216,194,44,172,24,110,193,22,104,97,67,32,11,27,134,88,192,133,90,216,48,228,
|
||||
66,46,212,194,134,224,22,0,0,157,134,5,146,40,16,130,1,36,254,157,6,103,234,40,16,130,67,0,254,131,12,1,226,12,50,4,138,51,134,48,68,22,128,255,28,195,16,76,179,13,204,5,204,54,4,89,
|
||||
48,219,16,12,194,6,1,49,0,4,0,0,0,91,138,32,200,133,67,23,182,20,68,144,11,135,46,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,134,6,0,0,0,0,0,0,0,0,101,12,0,0,31,0,0,0,18,3,148,
|
||||
240,0,0,0,0,3,0,0,0,5,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,1,0,0,0,112,0,0,0,0,0,0,0,14,0,0,0,24,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,0,0,0,0,93,12,0,0,13,0,0,0,18,3,148,102,0,0,0,0,109,97,105,110,48,51,50,48,50,51,46,51,54,56,97,105,114,54,
|
||||
52,45,97,112,112,108,101,45,109,97,99,111,115,120,49,52,46,48,46,48,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
const uint8_t metallib_fragment[3787] = {
|
||||
77,84,76,66,1,128,2,0,7,0,0,129,14,0,0,0,203,14,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,227,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,235,0,0,0,0,0,0,0,
|
||||
224,13,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,1,72,65,83,72,32,0,201,103,233,140,10,95,185,107,79,93,85,82,78,218,248,8,95,184,8,139,191,
|
||||
155,174,56,51,95,203,135,255,117,44,62,77,68,83,90,8,0,224,13,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,6,0,3,0,1,0,69,78,68,
|
||||
84,69,78,68,84,4,0,0,0,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,11,0,0,0,0,20,0,0,0,196,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,
|
||||
12,0,0,44,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,20,69,2,66,146,11,66,164,16,50,20,56,8,24,75,10,50,82,136,72,112,
|
||||
196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,32,201,1,50,82,132,24,42,40,42,144,49,124,176,92,145,32,197,200,0,0,0,137,32,0,0,31,0,0,0,50,34,72,9,32,98,70,0,33,
|
||||
43,36,152,20,33,37,36,152,20,25,39,12,133,164,144,96,82,100,92,32,36,101,130,128,154,1,24,70,32,128,27,132,97,4,1,64,74,154,34,74,152,252,127,34,174,137,138,136,223,30,254,105,140,
|
||||
0,24,68,32,2,140,164,41,162,132,201,255,37,128,121,22,34,250,167,49,2,96,16,193,16,76,33,194,40,135,208,28,1,114,132,160,230,8,130,57,2,48,24,70,16,26,163,172,114,6,115,12,128,70,111,
|
||||
32,64,5,218,8,0,0,81,24,0,0,105,0,0,0,27,246,35,248,255,255,255,255,1,104,3,96,13,0,83,0,252,0,144,128,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,192,28,
|
||||
224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,202,225,
|
||||
28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,119,104,
|
||||
131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,7,121,
|
||||
168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,13,232,
|
||||
65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,3,113,
|
||||
168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,131,33,12,192,
|
||||
2,84,27,140,129,0,22,160,218,0,17,255,255,255,255,63,0,109,0,172,1,96,10,128,31,0,18,80,1,125,176,193,40,2,96,1,170,13,134,33,0,11,80,109,96,142,255,255,255,255,31,128,54,0,214,0,144,
|
||||
128,10,232,3,0,73,24,0,0,4,0,0,0,19,134,64,24,38,12,68,97,76,24,142,194,0,0,0,0,19,176,112,72,7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,118,8,135,113,120,135,121,192,
|
||||
135,56,160,3,55,128,3,55,128,131,13,183,81,14,109,0,15,122,96,7,116,160,7,118,64,7,122,96,7,116,208,6,233,16,7,122,128,7,122,128,7,109,144,14,120,160,7,120,160,7,120,208,6,233,16,7,
|
||||
118,160,7,113,96,7,122,16,7,118,208,6,233,48,7,114,160,7,115,32,7,122,48,7,114,208,6,233,96,7,116,160,7,118,64,7,122,96,7,116,208,6,230,48,7,114,160,7,115,32,7,122,48,7,114,208,6,230,
|
||||
96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,16,7,118,160,7,113,96,7,122,16,7,118,208,6,246,32,7,116,160,7,115,32,7,122,48,7,114,208,6,246,48,7,114,160,7,115,32,7,122,48,7,114,208,
|
||||
6,246,64,7,120,160,7,118,64,7,122,96,7,116,208,6,246,96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,144,7,118,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,114,128,7,122,16,
|
||||
7,114,128,7,122,16,7,114,128,7,109,96,15,113,144,7,114,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,32,7,117,96,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,117,16,7,114,160,
|
||||
7,117,16,7,114,160,7,117,16,7,114,208,6,246,16,7,112,32,7,116,160,7,113,0,7,114,64,7,122,16,7,112,32,7,116,208,6,238,128,7,122,16,7,118,160,7,115,32,7,26,33,12,89,48,0,210,208,67,42,
|
||||
160,64,0,0,8,0,0,0,4,0,0,0,0,0,10,96,72,85,108,15,16,0,2,0,0,128,0,0,0,0,0,64,1,72,108,16,40,234,50,0,0,144,5,2,0,0,0,10,0,0,0,50,30,152,16,25,17,76,144,140,9,38,71,198,4,67,106,69,
|
||||
80,2,133,80,14,229,83,128,2,5,81,32,197,48,2,80,6,36,199,18,158,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,
|
||||
230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,
|
||||
112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,
|
||||
188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,8,135,113,24,135,114,152,135,121,
|
||||
152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,
|
||||
57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,
|
||||
0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,
|
||||
36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,
|
||||
59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,
|
||||
65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,
|
||||
135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,
|
||||
23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,
|
||||
14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,
|
||||
32,0,0,252,0,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,56,6,220,41,1,0,0,0,139,210,88,216,6,109,80,28,20,27,71,
|
||||
6,81,100,48,134,180,40,15,178,24,197,34,41,24,178,28,13,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,
|
||||
97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,
|
||||
46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,
|
||||
101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,
|
||||
114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,
|
||||
101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,
|
||||
112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,114,101,110,100,101,114,95,116,97,114,103,101,116,97,105,114,
|
||||
46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,97,114,103,95,110,97,109,101,102,67,111,108,111,114,97,105,114,46,102,114,97,103,109,101,110,
|
||||
116,95,105,110,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,99,101,110,116,101,114,97,105,114,46,112,101,114,115,112,101,99,116,105,118,101,73,110,95,67,111,108,
|
||||
111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,73,110,95,85,86,97,105,114,46,116,101,120,116,117,114,101,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,
|
||||
100,101,120,97,105,114,46,115,97,109,112,108,101,116,101,120,116,117,114,101,50,100,60,102,108,111,97,116,44,32,115,97,109,112,108,101,62,115,84,101,120,116,117,114,101,97,105,114,
|
||||
46,115,97,109,112,108,101,114,115,97,109,112,108,101,114,115,84,101,120,116,117,114,101,83,109,112,108,114,0,198,96,0,0,0,0,0,0,48,130,208,8,35,8,82,51,130,208,12,35,8,13,49,130,208,
|
||||
20,35,8,141,49,130,208,28,35,8,13,50,130,208,36,35,8,141,50,130,208,44,35,8,13,51,130,144,0,51,12,100,16,148,193,12,131,25,8,103,48,195,128,6,3,25,204,48,160,1,145,6,51,12,104,80,164,
|
||||
193,12,3,26,24,105,48,195,128,6,135,26,204,48,160,1,178,6,51,12,104,144,176,193,12,129,50,195,64,6,109,224,6,51,16,203,27,152,129,27,204,16,48,51,4,205,12,129,51,195,241,184,129,27,
|
||||
64,145,52,205,16,128,194,12,137,27,80,149,117,65,145,132,205,144,152,1,149,89,23,164,73,219,12,10,25,112,157,27,152,129,7,125,18,24,204,144,188,65,24,116,110,96,6,144,24,72,99,48,3,
|
||||
33,10,163,64,10,165,48,195,0,7,161,96,10,71,6,0,199,113,28,199,113,28,199,113,28,231,6,110,224,6,110,224,6,110,224,6,110,224,6,22,29,232,129,101,89,166,192,177,2,43,144,131,58,128,
|
||||
130,140,4,38,40,35,54,54,187,54,151,182,55,178,58,182,50,23,51,182,176,179,185,81,18,56,136,3,57,152,3,58,168,3,59,184,3,60,72,133,141,205,174,205,37,141,172,204,141,110,148,32,15,
|
||||
114,9,75,147,115,177,43,147,155,75,123,115,27,37,208,131,164,194,210,228,92,216,194,220,206,234,194,206,202,190,236,202,228,230,210,222,220,70,9,246,32,167,176,52,57,151,177,183,54,
|
||||
184,52,182,178,175,55,56,186,180,55,183,185,81,6,62,232,3,63,72,38,44,77,206,197,76,46,236,172,173,204,141,110,148,192,20,0,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,
|
||||
88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,
|
||||
80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,
|
||||
28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,
|
||||
67,56,144,195,1,0,0,0,97,32,0,0,49,0,0,0,19,4,65,44,16,0,0,0,4,0,0,0,196,106,96,4,128,220,8,0,129,17,0,18,51,0,0,0,241,48,0,0,28,0,0,0,34,71,200,144,81,14,196,42,0,0,0,0,23,134,1,0,
|
||||
97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,115,97,109,112,108,101,114,115,97,105,114,
|
||||
45,97,108,105,97,115,45,115,99,111,112,101,45,116,101,120,116,117,114,101,115,0,43,132,85,64,133,21,3,43,172,66,42,172,24,90,97,21,84,97,131,208,10,172,0,0,35,6,205,16,130,96,240,88,
|
||||
135,129,20,3,33,8,204,104,66,0,96,176,136,255,108,3,17,0,27,4,196,0,0,0,2,0,0,0,91,6,224,104,5,0,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,251,5,0,0,0,0,0,0,0,0,101,12,0,0,37,
|
||||
0,0,0,18,3,148,40,1,0,0,0,3,0,0,0,32,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,2,0,0,0,136,0,0,0,0,0,0,0,41,0,0,0,24,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,136,0,0,0,
|
||||
0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,5,0,0,0,27,0,0,0,5,0,0,0,27,0,0,0,255,255,255,255,8,36,0,0,0,0,0,0,93,12,0,0,20,0,0,0,18,3,
|
||||
148,161,0,0,0,0,109,97,105,110,48,97,105,114,46,115,97,109,112,108,101,95,116,101,120,116,117,114,101,95,50,100,46,118,52,102,51,50,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,
|
||||
112,112,108,101,45,109,97,99,111,115,120,49,52,46,48,46,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
#elif TARGET_OS_IPHONE
|
||||
const uint8_t metallib_vertex[3876] = {
|
||||
77,84,76,66,1,0,2,0,7,0,0,130,18,0,1,0,36,15,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,12,1,0,0,0,0,0,0,8,0,0,0,0,0,0,0,20,1,0,0,0,0,0,0,16,
|
||||
14,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,0,72,65,83,72,32,0,240,54,230,217,232,66,102,78,35,5,77,235,101,252,229,192,148,96,126,162,111,
|
||||
77,253,247,211,52,17,198,182,137,68,244,77,68,83,90,8,0,16,14,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,7,0,3,0,2,0,69,78,68,
|
||||
84,69,78,68,84,45,0,0,0,86,65,84,84,24,0,3,0,97,80,111,115,0,0,128,97,85,86,0,1,128,97,67,111,108,111,114,0,2,128,86,65,84,89,5,0,3,0,4,4,6,69,78,68,84,4,0,0,0,69,78,68,84,222,192,
|
||||
23,11,0,0,0,0,20,0,0,0,252,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,0,0,72,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,
|
||||
4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,16,69,2,66,146,11,66,132,16,50,20,56,8,24,75,10,50,66,136,72,112,196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,
|
||||
136,32,201,1,50,66,132,24,42,40,42,144,49,124,176,92,145,32,196,200,0,0,0,137,32,0,0,24,0,0,0,50,34,8,9,32,98,70,0,33,43,36,152,16,33,37,36,152,16,25,39,12,133,164,144,96,66,100,92,
|
||||
32,36,100,130,224,153,1,24,70,32,128,97,4,1,184,67,72,32,37,77,17,37,76,62,149,82,210,193,57,141,52,1,205,148,4,145,65,4,66,48,197,136,68,145,13,4,204,17,128,129,10,228,28,1,40,12,
|
||||
34,8,194,48,2,145,140,0,0,0,0,0,81,24,0,0,100,0,0,0,27,246,35,248,255,255,255,255,1,48,5,192,15,0,56,0,254,0,144,0,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,
|
||||
218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,
|
||||
29,202,225,28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,
|
||||
119,104,131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,
|
||||
7,121,168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,
|
||||
13,232,65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,
|
||||
3,113,168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,195,24,8,
|
||||
4,176,0,164,0,84,65,128,4,105,0,13,225,144,14,242,208,6,226,80,15,230,96,14,229,32,15,109,224,14,239,208,6,225,192,14,233,16,14,243,0,0,0,73,24,0,0,1,0,0,0,19,132,64,0,19,170,112,72,
|
||||
7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,116,120,135,121,136,3,60,112,131,56,112,3,56,216,112,27,229,208,6,240,160,7,118,64,7,122,96,7,116,160,7,118,64,7,109,144,14,
|
||||
113,160,7,120,160,7,120,208,6,233,128,7,122,128,7,122,128,7,109,144,14,113,96,7,122,16,7,118,160,7,113,96,7,109,144,14,115,32,7,122,48,7,114,160,7,115,32,7,109,144,14,118,64,7,122,
|
||||
96,7,116,160,7,118,64,7,109,96,14,115,32,7,122,48,7,114,160,7,115,32,7,109,96,14,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,113,96,7,122,16,7,118,160,7,113,96,7,109,96,15,114,64,
|
||||
7,122,48,7,114,160,7,115,32,7,109,96,15,115,32,7,122,48,7,114,160,7,115,32,7,109,96,15,116,128,7,122,96,7,116,160,7,118,64,7,109,96,15,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,
|
||||
121,96,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,32,7,120,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,121,32,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,114,
|
||||
80,7,118,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,80,7,113,32,7,122,80,7,113,32,7,122,80,7,113,32,7,109,96,15,113,0,7,114,64,7,122,16,7,112,32,7,116,160,7,113,0,7,114,64,7,109,
|
||||
224,14,120,160,7,113,96,7,122,48,7,114,160,17,194,144,5,3,32,13,61,164,2,10,3,0,128,0,0,0,64,0,0,0,0,0,160,0,36,54,8,20,85,26,0,0,200,2,1,0,11,0,0,0,50,30,152,16,25,17,76,144,140,9,
|
||||
38,71,198,4,67,202,34,40,129,66,40,135,242,41,64,129,130,40,144,17,128,50,160,29,1,32,29,75,144,2,0,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,
|
||||
140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,
|
||||
7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,
|
||||
59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,
|
||||
8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,
|
||||
67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,
|
||||
135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,
|
||||
81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,
|
||||
29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,
|
||||
192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,
|
||||
113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,
|
||||
35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,
|
||||
119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,
|
||||
119,168,7,120,152,7,0,0,0,0,121,32,0,0,25,1,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,152,6,100,208,82,0,0,0,139,
|
||||
210,88,216,6,109,80,28,20,27,71,6,209,18,25,76,178,24,6,179,64,18,49,24,202,131,68,148,161,68,87,35,0,0,0,0,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,
|
||||
101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,
|
||||
97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,
|
||||
116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,
|
||||
65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,
|
||||
108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,
|
||||
95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,118,101,
|
||||
114,116,101,120,95,111,117,116,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,
|
||||
97,114,103,95,110,97,109,101,79,117,116,95,67,111,108,111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,79,117,116,95,85,86,97,105,114,46,112,111,115,105,116,105,
|
||||
111,110,103,108,95,80,111,115,105,116,105,111,110,97,105,114,46,118,101,114,116,101,120,95,105,110,112,117,116,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,100,101,120,97,
|
||||
80,111,115,97,85,86,97,67,111,108,111,114,97,105,114,46,98,117,102,102,101,114,97,105,114,46,98,117,102,102,101,114,95,115,105,122,101,97,105,114,46,114,101,97,100,97,105,114,46,97,
|
||||
100,100,114,101,115,115,95,115,112,97,99,101,97,105,114,46,115,116,114,117,99,116,95,116,121,112,101,95,105,110,102,111,117,83,99,97,108,101,117,84,114,97,110,115,108,97,116,101,97,
|
||||
105,114,46,97,114,103,95,116,121,112,101,95,115,105,122,101,97,105,114,46,97,114,103,95,116,121,112,101,95,97,108,105,103,110,95,115,105,122,101,117,80,117,115,104,67,111,110,115,116,
|
||||
97,110,116,112,99,0,0,0,230,117,0,0,0,0,0,0,48,130,144,4,35,8,10,51,130,144,8,35,8,201,48,130,144,16,35,8,73,49,130,144,24,35,8,201,49,130,144,32,35,8,73,50,130,144,40,35,8,7,48,195,
|
||||
160,6,193,26,204,48,176,129,208,6,51,12,110,48,168,193,12,131,27,16,111,48,195,224,6,197,27,204,48,184,129,241,6,51,12,110,112,192,193,12,131,27,32,113,48,195,224,6,137,28,204,16,40,
|
||||
51,12,106,224,6,115,48,3,177,208,129,26,204,193,12,1,51,67,208,204,16,56,51,24,15,20,73,19,53,131,241,84,145,53,93,51,20,88,36,77,217,12,67,41,152,194,41,204,144,204,129,182,205,1,
|
||||
27,68,214,196,205,144,176,129,182,177,1,27,68,214,212,205,144,168,129,182,169,1,27,68,210,228,205,160,204,65,28,204,129,69,6,113,16,7,115,96,149,193,12,20,29,124,96,32,7,219,28,176,
|
||||
65,24,136,129,26,140,1,43,152,129,28,156,65,28,68,104,48,165,193,12,68,42,168,194,42,180,194,12,67,29,160,130,43,156,25,0,28,199,113,28,199,113,28,199,113,110,224,6,110,224,6,110,224,
|
||||
6,110,224,6,110,96,209,129,30,88,150,69,7,116,224,6,116,128,11,184,128,11,252,128,30,160,32,35,129,9,202,136,141,205,174,205,165,237,141,172,142,173,204,197,140,45,236,108,110,148,
|
||||
164,14,236,224,14,240,32,15,244,96,15,248,160,15,82,97,99,179,107,115,73,35,43,115,163,27,37,240,131,92,194,210,228,92,236,202,228,230,210,222,220,70,9,254,32,169,176,52,57,23,182,
|
||||
48,183,179,186,176,179,178,47,187,50,185,185,180,55,183,81,2,80,200,41,44,77,206,101,236,173,13,46,141,173,236,235,13,142,46,237,205,109,110,148,33,20,68,97,20,82,9,75,147,115,177,
|
||||
43,147,163,43,195,27,37,112,5,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,
|
||||
33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,
|
||||
180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,
|
||||
128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,68,0,0,0,19,4,65,44,16,0,0,0,11,0,0,0,148,51,0,197,64,91,2,212,
|
||||
115,16,73,20,69,115,16,73,36,17,4,163,1,35,0,99,4,32,8,130,248,71,49,7,97,89,23,70,50,26,64,51,3,0,0,0,241,48,0,0,32,0,0,0,34,71,200,144,81,18,196,43,0,0,0,0,207,115,89,0,111,109,110,
|
||||
105,112,111,116,101,110,116,32,99,104,97,114,83,105,109,112,108,101,32,67,43,43,32,84,66,65,65,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,
|
||||
105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,97,114,103,40,51,41,0,19,132,101,89,33,212,130,44,172,24,108,161,22,102,97,67,16,11,27,6,88,184,5,90,216,48,224,2,46,208,194,134,
|
||||
192,22,0,0,157,6,38,154,40,16,130,65,36,254,157,134,135,234,40,16,130,67,0,254,131,12,1,226,12,50,4,138,51,134,48,68,22,128,255,28,195,16,76,179,13,12,6,204,54,4,90,48,219,16,12,194,
|
||||
6,1,49,0,4,0,0,0,91,138,32,192,133,35,23,182,20,68,128,11,71,46,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,132,6,0,0,0,0,0,0,0,0,101,12,0,0,31,0,0,0,18,3,148,240,0,0,0,0,3,0,
|
||||
0,0,5,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,1,0,0,0,112,0,0,0,0,0,0,0,14,0,0,0,21,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
|
||||
0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,0,0,0,0,93,12,0,0,12,0,0,0,18,3,148,99,0,0,0,0,109,97,105,110,48,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,112,112,
|
||||
108,101,45,105,111,115,49,56,46,49,46,48,0,0,0,0,0,
|
||||
};
|
||||
const uint8_t metallib_fragment[3771] = {
|
||||
77,84,76,66,1,0,2,0,7,0,0,130,18,0,1,0,187,14,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,227,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,235,0,0,0,0,0,0,0,208,
|
||||
13,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,1,72,65,83,72,32,0,167,26,51,31,140,153,203,226,66,149,243,47,185,58,96,202,28,176,71,121,86,159,
|
||||
244,234,235,69,155,58,121,67,241,212,77,68,83,90,8,0,208,13,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,7,0,3,0,2,0,69,78,68,84,
|
||||
69,78,68,84,4,0,0,0,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,11,0,0,0,0,20,0,0,0,180,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,
|
||||
0,0,41,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,20,69,2,66,146,11,66,164,16,50,20,56,8,24,75,10,50,82,136,72,112,
|
||||
196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,32,201,1,50,82,132,24,42,40,42,144,49,124,176,92,145,32,197,200,0,0,0,137,32,0,0,31,0,0,0,50,34,72,9,32,98,70,0,33,
|
||||
43,36,152,20,33,37,36,152,20,25,39,12,133,164,144,96,82,100,92,32,36,101,130,128,154,1,24,70,32,128,27,132,97,4,1,64,74,154,34,74,152,252,127,34,174,137,138,136,223,30,254,105,140,
|
||||
0,24,68,32,2,140,164,41,162,132,201,255,37,128,121,22,34,250,167,49,2,96,16,193,16,76,33,194,40,135,208,28,1,114,132,160,230,8,130,57,2,48,24,70,16,26,163,172,114,6,115,12,128,70,111,
|
||||
32,64,5,218,8,0,0,81,24,0,0,105,0,0,0,27,246,35,248,255,255,255,255,1,104,3,96,13,0,83,0,252,0,144,128,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,192,28,
|
||||
224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,202,225,
|
||||
28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,119,104,
|
||||
131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,7,121,
|
||||
168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,13,232,
|
||||
65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,3,113,
|
||||
168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,131,33,12,192,
|
||||
2,84,27,140,129,0,22,160,218,0,17,255,255,255,255,63,0,109,0,172,1,96,10,128,31,0,18,80,1,125,176,193,40,2,96,1,170,13,134,33,0,11,80,109,96,142,255,255,255,255,31,128,54,0,214,0,144,
|
||||
128,10,232,3,0,73,24,0,0,4,0,0,0,19,134,64,24,38,12,68,97,76,24,142,194,0,0,0,0,19,170,112,72,7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,116,120,135,121,136,3,60,112,131,
|
||||
56,112,3,56,216,112,27,229,208,6,240,160,7,118,64,7,122,96,7,116,160,7,118,64,7,109,144,14,113,160,7,120,160,7,120,208,6,233,128,7,122,128,7,122,128,7,109,144,14,113,96,7,122,16,7,
|
||||
118,160,7,113,96,7,109,144,14,115,32,7,122,48,7,114,160,7,115,32,7,109,144,14,118,64,7,122,96,7,116,160,7,118,64,7,109,96,14,115,32,7,122,48,7,114,160,7,115,32,7,109,96,14,118,64,7,
|
||||
122,96,7,116,160,7,118,64,7,109,96,15,113,96,7,122,16,7,118,160,7,113,96,7,109,96,15,114,64,7,122,48,7,114,160,7,115,32,7,109,96,15,115,32,7,122,48,7,114,160,7,115,32,7,109,96,15,116,
|
||||
128,7,122,96,7,116,160,7,118,64,7,109,96,15,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,121,96,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,32,7,120,160,7,113,32,7,120,
|
||||
160,7,113,32,7,120,208,6,246,16,7,121,32,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,114,80,7,118,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,80,7,113,32,7,122,80,7,113,32,
|
||||
7,122,80,7,113,32,7,109,96,15,113,0,7,114,64,7,122,16,7,112,32,7,116,160,7,113,0,7,114,64,7,109,224,14,120,160,7,113,96,7,122,48,7,114,160,17,194,144,5,3,32,13,61,164,2,10,4,0,128,
|
||||
0,0,0,64,0,0,0,0,0,160,0,134,84,197,246,0,1,32,0,0,0,8,0,0,0,0,0,20,128,196,6,129,162,43,3,0,0,89,32,10,0,0,0,50,30,152,16,25,17,76,144,140,9,38,71,198,4,67,106,69,80,2,133,80,14,229,
|
||||
83,128,2,5,81,32,35,0,101,64,114,44,65,10,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,
|
||||
128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,
|
||||
135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,
|
||||
240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,
|
||||
238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,
|
||||
56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,
|
||||
144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,
|
||||
7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,
|
||||
57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,
|
||||
225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,
|
||||
96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,
|
||||
29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,
|
||||
14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,32,0,0,251,0,0,0,114,
|
||||
30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,56,6,220,41,1,0,0,0,139,210,88,216,6,109,80,28,20,27,71,6,81,100,48,134,180,
|
||||
40,15,178,24,197,34,41,24,178,28,13,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,
|
||||
97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,
|
||||
104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,
|
||||
105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,
|
||||
51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,
|
||||
95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,
|
||||
97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,114,101,110,100,101,114,95,116,97,114,103,101,116,97,105,114,46,97,114,103,95,116,121,
|
||||
112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,97,114,103,95,110,97,109,101,102,67,111,108,111,114,97,105,114,46,102,114,97,103,109,101,110,116,95,105,110,112,117,116,
|
||||
117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,99,101,110,116,101,114,97,105,114,46,112,101,114,115,112,101,99,116,105,118,101,73,110,95,67,111,108,111,114,117,115,101,114,40,
|
||||
108,111,99,110,49,41,102,108,111,97,116,50,73,110,95,85,86,97,105,114,46,116,101,120,116,117,114,101,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,100,101,120,97,105,114,46,
|
||||
115,97,109,112,108,101,116,101,120,116,117,114,101,50,100,60,102,108,111,97,116,44,32,115,97,109,112,108,101,62,115,84,101,120,116,117,114,101,97,105,114,46,115,97,109,112,108,101,
|
||||
114,115,97,109,112,108,101,114,115,84,101,120,116,117,114,101,83,109,112,108,114,0,6,95,0,0,0,0,0,0,48,130,208,8,35,8,18,51,130,208,12,35,8,13,49,130,208,20,35,8,141,49,130,208,28,
|
||||
35,8,13,50,130,208,36,35,8,141,50,130,208,44,35,8,9,48,195,64,6,65,25,204,48,152,129,112,6,51,12,104,48,144,193,12,3,26,16,105,48,195,128,6,69,26,204,48,160,129,145,6,51,12,104,112,
|
||||
168,193,12,3,26,32,107,48,195,128,6,9,27,204,16,40,51,12,100,128,6,109,48,3,177,184,1,25,180,193,12,1,51,67,208,204,16,56,51,28,79,27,180,1,20,73,211,12,193,31,204,144,180,1,85,89,
|
||||
23,20,73,216,12,137,25,80,153,117,65,154,180,205,160,144,1,215,181,129,25,120,208,39,129,193,12,137,27,132,65,215,6,102,0,137,129,52,6,51,16,161,32,10,163,64,10,51,12,111,0,10,165,
|
||||
112,99,0,112,28,199,113,28,199,113,28,199,185,129,27,184,129,27,184,129,27,184,129,27,184,129,69,7,122,96,89,150,41,112,172,192,10,228,160,14,160,32,35,129,9,202,136,141,205,174,205,
|
||||
165,237,141,172,142,173,204,197,140,45,236,108,110,148,228,13,224,32,14,228,96,14,232,160,14,236,224,14,82,97,99,179,107,115,73,35,43,115,163,27,37,192,131,92,194,210,228,92,236,202,
|
||||
228,230,210,222,220,70,9,242,32,169,176,52,57,23,182,48,183,179,186,176,179,178,47,187,50,185,185,180,55,183,81,2,61,200,41,44,77,206,101,236,173,13,46,141,173,236,235,13,142,46,237,
|
||||
205,109,110,148,97,15,248,160,15,146,9,75,147,115,49,147,11,59,107,43,115,163,27,37,40,5,0,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,
|
||||
67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,
|
||||
112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,
|
||||
200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,
|
||||
49,0,0,0,19,4,65,44,16,0,0,0,4,0,0,0,196,106,96,4,128,220,8,0,129,17,0,18,51,0,0,0,241,48,0,0,28,0,0,0,34,71,200,144,81,14,196,42,0,0,0,0,23,134,1,0,97,105,114,45,97,108,105,97,115,
|
||||
45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,115,97,109,112,108,101,114,115,97,105,114,45,97,108,105,97,115,45,115,99,
|
||||
111,112,101,45,116,101,120,116,117,114,101,115,0,43,4,85,56,133,21,195,42,168,2,42,172,24,88,65,21,82,97,131,192,10,171,0,0,35,6,205,16,130,96,240,84,135,129,20,3,33,8,204,104,66,0,
|
||||
96,176,136,255,108,3,17,0,27,4,196,0,0,0,2,0,0,0,91,6,224,96,5,0,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,248,5,0,0,0,0,0,0,0,0,101,12,0,0,37,0,0,0,18,3,148,40,1,0,0,0,3,0,
|
||||
0,0,32,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,2,0,0,0,136,0,0,0,0,0,0,0,41,0,0,0,21,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,
|
||||
0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,5,0,0,0,27,0,0,0,5,0,0,0,27,0,0,0,255,255,255,255,8,36,0,0,0,0,0,0,93,12,0,0,19,0,0,0,18,3,148,126,0,0,0,0,109,97,105,110,
|
||||
48,97,105,114,46,115,97,109,112,108,101,95,116,101,120,116,117,114,101,95,50,100,46,118,52,102,51,50,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,112,112,108,101,45,105,111,115,
|
||||
49,56,46,49,46,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
#elif TARGET_IPHONE_SIMULATOR
|
||||
#error "SDL_GPU does not support the iphone simulator"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -20,6 +21,7 @@
|
|||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer2_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
|
||||
// 2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
|
@ -140,21 +142,29 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||
SDL_RenderGetViewport(renderer, &old.Viewport);
|
||||
SDL_RenderGetClipRect(renderer, &old.ClipRect);
|
||||
|
||||
// Setup desired state
|
||||
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplSDLRenderer2_RenderState render_state;
|
||||
render_state.Renderer = renderer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = render_scale;
|
||||
|
||||
// Render command lists
|
||||
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
|
@ -162,7 +172,7 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -193,11 +203,12 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||
xy, (int)sizeof(ImDrawVert),
|
||||
color, (int)sizeof(ImDrawVert),
|
||||
uv, (int)sizeof(ImDrawVert),
|
||||
cmd_list->VtxBuffer.Size - pcmd->VtxOffset,
|
||||
draw_list->VtxBuffer.Size - pcmd->VtxOffset,
|
||||
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
|
||||
}
|
||||
}
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
|
||||
// Restore modified SDL_Renderer state
|
||||
SDL_RenderSetViewport(renderer, &old.Viewport);
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -25,6 +26,7 @@
|
|||
|
||||
struct SDL_Renderer;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_NewFrame();
|
||||
|
@ -36,4 +38,12 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyFontsTexture();
|
|||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLRenderer2_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplSDLRenderer2_RenderState
|
||||
{
|
||||
SDL_Renderer* Renderer;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// dear imgui: Renderer Backend for SDL_Renderer for SDL3
|
||||
// (Requires: SDL 3.0.0+)
|
||||
|
||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
||||
|
||||
// Note how SDL_Renderer is an _optional_ component of SDL3.
|
||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
||||
|
@ -9,7 +11,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -20,6 +23,8 @@
|
|||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer3_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-07-01: Update for SDL3 api changes: SDL_RenderGeometryRaw() uint32 version was removed (SDL#9009).
|
||||
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
|
||||
// 2024-02-12: Amend to query SDL_RenderViewportSet() and restore viewport accordingly.
|
||||
// 2023-05-30: Initial version.
|
||||
|
@ -44,8 +49,10 @@
|
|||
// SDL_Renderer data
|
||||
struct ImGui_ImplSDLRenderer3_Data
|
||||
{
|
||||
SDL_Renderer* Renderer; // Main viewport's renderer
|
||||
SDL_Texture* FontTexture;
|
||||
SDL_Renderer* Renderer; // Main viewport's renderer
|
||||
SDL_Texture* FontTexture;
|
||||
ImVector<SDL_FColor> ColorBuffer;
|
||||
|
||||
ImGui_ImplSDLRenderer3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
|
@ -106,8 +113,28 @@ void ImGui_ImplSDLRenderer3_NewFrame()
|
|||
ImGui_ImplSDLRenderer3_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
// https://github.com/libsdl-org/SDL/issues/9009
|
||||
static int SDL_RenderGeometryRaw8BitColor(SDL_Renderer* renderer, ImVector<SDL_FColor>& colors_out, SDL_Texture* texture, const float* xy, int xy_stride, const SDL_Color* color, int color_stride, const float* uv, int uv_stride, int num_vertices, const void* indices, int num_indices, int size_indices)
|
||||
{
|
||||
const Uint8* color2 = (const Uint8*)color;
|
||||
colors_out.resize(num_vertices);
|
||||
SDL_FColor* color3 = colors_out.Data;
|
||||
for (int i = 0; i < num_vertices; i++)
|
||||
{
|
||||
color3[i].r = color->r / 255.0f;
|
||||
color3[i].g = color->g / 255.0f;
|
||||
color3[i].b = color->b / 255.0f;
|
||||
color3[i].a = color->a / 255.0f;
|
||||
color2 += color_stride;
|
||||
color = (const SDL_Color*)color2;
|
||||
}
|
||||
return SDL_RenderGeometryRaw(renderer, texture, xy, xy_stride, color3, sizeof(*color3), uv, uv_stride, num_vertices, indices, num_indices, size_indices);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer)
|
||||
{
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
|
||||
// If there's a scale factor set by the user, use that instead
|
||||
// If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass
|
||||
// to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
|
||||
|
@ -133,26 +160,34 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||
SDL_Rect ClipRect;
|
||||
};
|
||||
BackupSDLRendererState old = {};
|
||||
old.ViewportEnabled = SDL_RenderViewportSet(renderer) == SDL_TRUE;
|
||||
old.ClipEnabled = SDL_RenderClipEnabled(renderer) == SDL_TRUE;
|
||||
old.ViewportEnabled = SDL_RenderViewportSet(renderer);
|
||||
old.ClipEnabled = SDL_RenderClipEnabled(renderer);
|
||||
SDL_GetRenderViewport(renderer, &old.Viewport);
|
||||
SDL_GetRenderClipRect(renderer, &old.ClipRect);
|
||||
|
||||
// Setup desired state
|
||||
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplSDLRenderer3_RenderState render_state;
|
||||
render_state.Renderer = renderer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = render_scale;
|
||||
|
||||
// Render command lists
|
||||
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
|
@ -160,7 +195,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -183,15 +218,16 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||
|
||||
// Bind texture, Draw
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
SDL_RenderGeometryRaw(renderer, tex,
|
||||
SDL_RenderGeometryRaw8BitColor(renderer, bd->ColorBuffer, tex,
|
||||
xy, (int)sizeof(ImDrawVert),
|
||||
color, (int)sizeof(ImDrawVert),
|
||||
uv, (int)sizeof(ImDrawVert),
|
||||
cmd_list->VtxBuffer.Size - pcmd->VtxOffset,
|
||||
draw_list->VtxBuffer.Size - pcmd->VtxOffset,
|
||||
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
|
||||
}
|
||||
}
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
|
||||
// Restore modified SDL_Renderer state
|
||||
SDL_SetRenderViewport(renderer, old.ViewportEnabled ? &old.Viewport : nullptr);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// dear imgui: Renderer Backend for SDL_Renderer for SDL3
|
||||
// (Requires: SDL 3.0.0+)
|
||||
|
||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
||||
|
||||
// Note how SDL_Renderer is an _optional_ component of SDL3.
|
||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
||||
|
@ -9,7 +11,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -25,6 +28,7 @@
|
|||
|
||||
struct SDL_Renderer;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_NewFrame();
|
||||
|
@ -36,4 +40,12 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyFontsTexture();
|
|||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLRenderer3_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplSDLRenderer3_RenderState
|
||||
{
|
||||
SDL_Renderer* Renderer;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
|
|
@ -2,16 +2,9 @@
|
|||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
||||
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||
// To build this on 32-bit systems and support texture changes:
|
||||
// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in our .vcxproj files)
|
||||
// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
|
||||
// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
|
||||
// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in our batch files)
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Call ImGui_ImplVulkan_AddTexture() to register one. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
@ -33,6 +26,13 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-01-09: Vulkan: Added IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE to clarify how many image sampler descriptors are expected to be available in descriptor pool. (#6642)
|
||||
// 2025-01-06: Vulkan: Added more ImGui_ImplVulkanH_XXXX helper functions to simplify our examples.
|
||||
// 2024-12-11: Vulkan: Fixed setting VkSwapchainCreateInfoKHR::preTransform for platforms not supporting VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR. (#8222)
|
||||
// 2024-11-27: Vulkan: Make user-provided descriptor pool optional. As a convenience, when setting init_info->DescriptorPoolSize the backend will create one itself. (#8172, #4867)
|
||||
// 2024-10-07: Vulkan: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-10-07: Vulkan: Expose selected render state in ImGui_ImplVulkan_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-10-07: Vulkan: Compiling with '#define ImTextureID=ImU64' is unnecessary now that dear imgui defaults ImTextureID to u64 instead of void*.
|
||||
// 2024-04-19: Vulkan: Added convenience support for Volk via IMGUI_IMPL_VULKAN_USE_VOLK define (you can also use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().)
|
||||
// 2024-02-14: *BREAKING CHANGE*: Moved RenderPass parameter from ImGui_ImplVulkan_Init() function to ImGui_ImplVulkan_InitInfo structure. Not required when using dynamic rendering.
|
||||
// 2024-02-12: *BREAKING CHANGE*: Dynamic rendering now require filling PipelineRenderingCreateInfo structure.
|
||||
|
@ -135,6 +135,7 @@ static bool g_FunctionsLoaded = true;
|
|||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdSetViewport) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateBuffer) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateCommandPool) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateDescriptorPool) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateDescriptorSetLayout) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateFence) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateFramebuffer) \
|
||||
|
@ -149,6 +150,7 @@ static bool g_FunctionsLoaded = true;
|
|||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateSwapchainKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyBuffer) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyCommandPool) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyDescriptorPool) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyDescriptorSetLayout) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyFence) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyFramebuffer) \
|
||||
|
@ -163,6 +165,7 @@ static bool g_FunctionsLoaded = true;
|
|||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySurfaceKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySwapchainKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDeviceWaitIdle) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkEnumeratePhysicalDevices) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkEndCommandBuffer) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFlushMappedMemoryRanges) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeCommandBuffers) \
|
||||
|
@ -170,7 +173,9 @@ static bool g_FunctionsLoaded = true;
|
|||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeMemory) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetBufferMemoryRequirements) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetImageMemoryRequirements) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceProperties) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceMemoryProperties) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceQueueFamilyProperties) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceFormatsKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfacePresentModesKHR) \
|
||||
|
@ -214,6 +219,16 @@ struct ImGui_ImplVulkan_WindowRenderBuffers
|
|||
ImGui_ImplVulkan_FrameRenderBuffers* FrameRenderBuffers;
|
||||
};
|
||||
|
||||
struct ImGui_ImplVulkan_Texture
|
||||
{
|
||||
VkDeviceMemory Memory;
|
||||
VkImage Image;
|
||||
VkImageView ImageView;
|
||||
VkDescriptorSet DescriptorSet;
|
||||
|
||||
ImGui_ImplVulkan_Texture() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Vulkan data
|
||||
struct ImGui_ImplVulkan_Data
|
||||
{
|
||||
|
@ -225,15 +240,13 @@ struct ImGui_ImplVulkan_Data
|
|||
VkPipeline Pipeline;
|
||||
VkShaderModule ShaderModuleVert;
|
||||
VkShaderModule ShaderModuleFrag;
|
||||
VkDescriptorPool DescriptorPool;
|
||||
|
||||
// Font data
|
||||
VkSampler FontSampler;
|
||||
VkDeviceMemory FontMemory;
|
||||
VkImage FontImage;
|
||||
VkImageView FontView;
|
||||
VkDescriptorSet FontDescriptorSet;
|
||||
VkCommandPool FontCommandPool;
|
||||
VkCommandBuffer FontCommandBuffer;
|
||||
// Texture management
|
||||
ImGui_ImplVulkan_Texture FontTexture;
|
||||
VkSampler TexSampler;
|
||||
VkCommandPool TexCommandPool;
|
||||
VkCommandBuffer TexCommandBuffer;
|
||||
|
||||
// Render buffers for main window
|
||||
ImGui_ImplVulkan_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
|
@ -394,7 +407,7 @@ static inline VkDeviceSize AlignBufferSize(VkDeviceSize size, VkDeviceSize align
|
|||
return (size + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& buffer_size, size_t new_size, VkBufferUsageFlagBits usage)
|
||||
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& buffer_size, VkDeviceSize new_size, VkBufferUsageFlagBits usage)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
|
@ -493,7 +506,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
wrb->Index = 0;
|
||||
wrb->Count = v->ImageCount;
|
||||
wrb->FrameRenderBuffers = (ImGui_ImplVulkan_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
|
||||
memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
|
||||
memset((void*)wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
|
||||
}
|
||||
IM_ASSERT(wrb->Count == v->ImageCount);
|
||||
wrb->Index = (wrb->Index + 1) % wrb->Count;
|
||||
|
@ -502,8 +515,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
if (draw_data->TotalVtxCount > 0)
|
||||
{
|
||||
// Create or resize the vertex/index buffers
|
||||
size_t vertex_size = AlignBufferSize(draw_data->TotalVtxCount * sizeof(ImDrawVert), bd->BufferMemoryAlignment);
|
||||
size_t index_size = AlignBufferSize(draw_data->TotalIdxCount * sizeof(ImDrawIdx), bd->BufferMemoryAlignment);
|
||||
VkDeviceSize vertex_size = AlignBufferSize(draw_data->TotalVtxCount * sizeof(ImDrawVert), bd->BufferMemoryAlignment);
|
||||
VkDeviceSize index_size = AlignBufferSize(draw_data->TotalIdxCount * sizeof(ImDrawIdx), bd->BufferMemoryAlignment);
|
||||
if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size)
|
||||
CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size)
|
||||
|
@ -518,11 +531,11 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
check_vk_result(err);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
VkMappedMemoryRange range[2] = {};
|
||||
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||
|
@ -540,6 +553,14 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
// Setup desired Vulkan state
|
||||
ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplVulkan_RenderState render_state;
|
||||
render_state.CommandBuffer = command_buffer;
|
||||
render_state.Pipeline = pipeline;
|
||||
render_state.PipelineLayout = bd->PipelineLayout;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
@ -550,10 +571,10 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
int global_idx_offset = 0;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
|
@ -561,7 +582,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -586,22 +607,17 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||
|
||||
// Bind DescriptorSet with font or user texture
|
||||
VkDescriptorSet desc_set[1] = { (VkDescriptorSet)pcmd->TextureId };
|
||||
if (sizeof(ImTextureID) < sizeof(ImU64))
|
||||
{
|
||||
// We don't support texture switches if ImTextureID hasn't been redefined to be 64-bit. Do a flaky check that other textures haven't been used.
|
||||
IM_ASSERT(pcmd->TextureId == (ImTextureID)bd->FontDescriptorSet);
|
||||
desc_set[0] = bd->FontDescriptorSet;
|
||||
}
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, desc_set, 0, nullptr);
|
||||
VkDescriptorSet desc_set = (VkDescriptorSet)pcmd->GetTexID();
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, &desc_set, 0, nullptr);
|
||||
|
||||
// Draw
|
||||
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
|
||||
// Note: at this point both vkCmdSetViewport() and vkCmdSetScissor() have been called.
|
||||
// Our last values will leak into user/application rendering IF:
|
||||
|
@ -622,39 +638,39 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
|||
VkResult err;
|
||||
|
||||
// Destroy existing texture (if any)
|
||||
if (bd->FontView || bd->FontImage || bd->FontMemory || bd->FontDescriptorSet)
|
||||
if (bd->FontTexture.DescriptorSet)
|
||||
{
|
||||
vkQueueWaitIdle(v->Queue);
|
||||
ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
// Create command pool/buffer
|
||||
if (bd->FontCommandPool == VK_NULL_HANDLE)
|
||||
if (bd->TexCommandPool == VK_NULL_HANDLE)
|
||||
{
|
||||
VkCommandPoolCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
info.flags = 0;
|
||||
info.queueFamilyIndex = v->QueueFamily;
|
||||
vkCreateCommandPool(v->Device, &info, v->Allocator, &bd->FontCommandPool);
|
||||
vkCreateCommandPool(v->Device, &info, v->Allocator, &bd->TexCommandPool);
|
||||
}
|
||||
if (bd->FontCommandBuffer == VK_NULL_HANDLE)
|
||||
if (bd->TexCommandBuffer == VK_NULL_HANDLE)
|
||||
{
|
||||
VkCommandBufferAllocateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
info.commandPool = bd->FontCommandPool;
|
||||
info.commandPool = bd->TexCommandPool;
|
||||
info.commandBufferCount = 1;
|
||||
err = vkAllocateCommandBuffers(v->Device, &info, &bd->FontCommandBuffer);
|
||||
err = vkAllocateCommandBuffers(v->Device, &info, &bd->TexCommandBuffer);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
// Start command buffer
|
||||
{
|
||||
err = vkResetCommandPool(v->Device, bd->FontCommandPool, 0);
|
||||
err = vkResetCommandPool(v->Device, bd->TexCommandPool, 0);
|
||||
check_vk_result(err);
|
||||
VkCommandBufferBeginInfo begin_info = {};
|
||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
err = vkBeginCommandBuffer(bd->FontCommandBuffer, &begin_info);
|
||||
err = vkBeginCommandBuffer(bd->TexCommandBuffer, &begin_info);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
|
@ -664,6 +680,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
|||
size_t upload_size = width * height * 4 * sizeof(char);
|
||||
|
||||
// Create the Image:
|
||||
ImGui_ImplVulkan_Texture* backend_tex = &bd->FontTexture;
|
||||
{
|
||||
VkImageCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
|
@ -679,17 +696,17 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
|||
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
err = vkCreateImage(v->Device, &info, v->Allocator, &bd->FontImage);
|
||||
err = vkCreateImage(v->Device, &info, v->Allocator, &backend_tex->Image);
|
||||
check_vk_result(err);
|
||||
VkMemoryRequirements req;
|
||||
vkGetImageMemoryRequirements(v->Device, bd->FontImage, &req);
|
||||
vkGetImageMemoryRequirements(v->Device, backend_tex->Image, &req);
|
||||
VkMemoryAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.allocationSize = IM_MAX(v->MinAllocationSize, req.size);
|
||||
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits);
|
||||
err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &bd->FontMemory);
|
||||
err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &backend_tex->Memory);
|
||||
check_vk_result(err);
|
||||
err = vkBindImageMemory(v->Device, bd->FontImage, bd->FontMemory, 0);
|
||||
err = vkBindImageMemory(v->Device, backend_tex->Image, backend_tex->Memory, 0);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
|
@ -697,18 +714,18 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
|||
{
|
||||
VkImageViewCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
info.image = bd->FontImage;
|
||||
info.image = backend_tex->Image;
|
||||
info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
info.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
info.subresourceRange.levelCount = 1;
|
||||
info.subresourceRange.layerCount = 1;
|
||||
err = vkCreateImageView(v->Device, &info, v->Allocator, &bd->FontView);
|
||||
err = vkCreateImageView(v->Device, &info, v->Allocator, &backend_tex->ImageView);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
// Create the Descriptor Set:
|
||||
bd->FontDescriptorSet = (VkDescriptorSet)ImGui_ImplVulkan_AddTexture(bd->FontSampler, bd->FontView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
backend_tex->DescriptorSet = ImGui_ImplVulkan_AddTexture(bd->TexSampler, backend_tex->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
// Create the Upload Buffer:
|
||||
VkDeviceMemory upload_buffer_memory;
|
||||
|
@ -758,11 +775,11 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
|||
copy_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
copy_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
copy_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
copy_barrier[0].image = bd->FontImage;
|
||||
copy_barrier[0].image = backend_tex->Image;
|
||||
copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copy_barrier[0].subresourceRange.levelCount = 1;
|
||||
copy_barrier[0].subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(bd->FontCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, copy_barrier);
|
||||
vkCmdPipelineBarrier(bd->TexCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, copy_barrier);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
@ -770,7 +787,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
|||
region.imageExtent.width = width;
|
||||
region.imageExtent.height = height;
|
||||
region.imageExtent.depth = 1;
|
||||
vkCmdCopyBufferToImage(bd->FontCommandBuffer, upload_buffer, bd->FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
vkCmdCopyBufferToImage(bd->TexCommandBuffer, upload_buffer, backend_tex->Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
VkImageMemoryBarrier use_barrier[1] = {};
|
||||
use_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
|
@ -780,22 +797,22 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
|||
use_barrier[0].newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
use_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
use_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
use_barrier[0].image = bd->FontImage;
|
||||
use_barrier[0].image = backend_tex->Image;
|
||||
use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
use_barrier[0].subresourceRange.levelCount = 1;
|
||||
use_barrier[0].subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(bd->FontCommandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, use_barrier);
|
||||
vkCmdPipelineBarrier(bd->TexCommandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, use_barrier);
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)bd->FontDescriptorSet);
|
||||
io.Fonts->SetTexID((ImTextureID)backend_tex->DescriptorSet);
|
||||
|
||||
// End command buffer
|
||||
VkSubmitInfo end_info = {};
|
||||
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
end_info.commandBufferCount = 1;
|
||||
end_info.pCommandBuffers = &bd->FontCommandBuffer;
|
||||
err = vkEndCommandBuffer(bd->FontCommandBuffer);
|
||||
end_info.pCommandBuffers = &bd->TexCommandBuffer;
|
||||
err = vkEndCommandBuffer(bd->TexCommandBuffer);
|
||||
check_vk_result(err);
|
||||
err = vkQueueSubmit(v->Queue, 1, &end_info, VK_NULL_HANDLE);
|
||||
check_vk_result(err);
|
||||
|
@ -816,16 +833,17 @@ void ImGui_ImplVulkan_DestroyFontsTexture()
|
|||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
|
||||
if (bd->FontDescriptorSet)
|
||||
ImGui_ImplVulkan_Texture* backend_tex = &bd->FontTexture;
|
||||
|
||||
if (backend_tex->DescriptorSet)
|
||||
{
|
||||
ImGui_ImplVulkan_RemoveTexture(bd->FontDescriptorSet);
|
||||
bd->FontDescriptorSet = VK_NULL_HANDLE;
|
||||
ImGui_ImplVulkan_RemoveTexture(backend_tex->DescriptorSet);
|
||||
backend_tex->DescriptorSet = VK_NULL_HANDLE;
|
||||
io.Fonts->SetTexID(0);
|
||||
}
|
||||
|
||||
if (bd->FontView) { vkDestroyImageView(v->Device, bd->FontView, v->Allocator); bd->FontView = VK_NULL_HANDLE; }
|
||||
if (bd->FontImage) { vkDestroyImage(v->Device, bd->FontImage, v->Allocator); bd->FontImage = VK_NULL_HANDLE; }
|
||||
if (bd->FontMemory) { vkFreeMemory(v->Device, bd->FontMemory, v->Allocator); bd->FontMemory = VK_NULL_HANDLE; }
|
||||
if (backend_tex->ImageView) { vkDestroyImageView(v->Device, backend_tex->ImageView, v->Allocator); backend_tex->ImageView = VK_NULL_HANDLE; }
|
||||
if (backend_tex->Image) { vkDestroyImage(v->Device, backend_tex->Image, v->Allocator); backend_tex->Image = VK_NULL_HANDLE; }
|
||||
if (backend_tex->Memory) { vkFreeMemory(v->Device, backend_tex->Memory, v->Allocator); backend_tex->Memory = VK_NULL_HANDLE; }
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAllocationCallbacks* allocator)
|
||||
|
@ -957,7 +975,7 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
|
|||
if (bd->VulkanInitInfo.UseDynamicRendering)
|
||||
{
|
||||
IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR");
|
||||
IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.pNext == nullptr && "PipelineRenderingCreateInfo pNext must be NULL");
|
||||
IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.pNext == nullptr && "PipelineRenderingCreateInfo pNext must be nullptr");
|
||||
info.pNext = &bd->VulkanInitInfo.PipelineRenderingCreateInfo;
|
||||
info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr.
|
||||
}
|
||||
|
@ -973,7 +991,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
|||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
VkResult err;
|
||||
|
||||
if (!bd->FontSampler)
|
||||
if (!bd->TexSampler)
|
||||
{
|
||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||
VkSamplerCreateInfo info = {};
|
||||
|
@ -981,13 +999,13 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
|||
info.magFilter = VK_FILTER_LINEAR;
|
||||
info.minFilter = VK_FILTER_LINEAR;
|
||||
info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
info.minLod = -1000;
|
||||
info.maxLod = 1000;
|
||||
info.maxAnisotropy = 1.0f;
|
||||
err = vkCreateSampler(v->Device, &info, v->Allocator, &bd->FontSampler);
|
||||
err = vkCreateSampler(v->Device, &info, v->Allocator, &bd->TexSampler);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
|
@ -1005,6 +1023,21 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
|||
check_vk_result(err);
|
||||
}
|
||||
|
||||
if (v->DescriptorPoolSize != 0)
|
||||
{
|
||||
IM_ASSERT(v->DescriptorPoolSize > IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE);
|
||||
VkDescriptorPoolSize pool_size = { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, v->DescriptorPoolSize };
|
||||
VkDescriptorPoolCreateInfo pool_info = {};
|
||||
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||
pool_info.maxSets = v->DescriptorPoolSize;
|
||||
pool_info.poolSizeCount = 1;
|
||||
pool_info.pPoolSizes = &pool_size;
|
||||
|
||||
err = vkCreateDescriptorPool(v->Device, &pool_info, v->Allocator, &bd->DescriptorPool);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
if (!bd->PipelineLayout)
|
||||
{
|
||||
// Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix
|
||||
|
@ -1035,14 +1068,15 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
|
|||
ImGui_ImplVulkan_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||
ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
|
||||
if (bd->FontCommandBuffer) { vkFreeCommandBuffers(v->Device, bd->FontCommandPool, 1, &bd->FontCommandBuffer); bd->FontCommandBuffer = VK_NULL_HANDLE; }
|
||||
if (bd->FontCommandPool) { vkDestroyCommandPool(v->Device, bd->FontCommandPool, v->Allocator); bd->FontCommandPool = VK_NULL_HANDLE; }
|
||||
if (bd->TexCommandBuffer) { vkFreeCommandBuffers(v->Device, bd->TexCommandPool, 1, &bd->TexCommandBuffer); bd->TexCommandBuffer = VK_NULL_HANDLE; }
|
||||
if (bd->TexCommandPool) { vkDestroyCommandPool(v->Device, bd->TexCommandPool, v->Allocator); bd->TexCommandPool = VK_NULL_HANDLE; }
|
||||
if (bd->TexSampler) { vkDestroySampler(v->Device, bd->TexSampler, v->Allocator); bd->TexSampler = VK_NULL_HANDLE; }
|
||||
if (bd->ShaderModuleVert) { vkDestroyShaderModule(v->Device, bd->ShaderModuleVert, v->Allocator); bd->ShaderModuleVert = VK_NULL_HANDLE; }
|
||||
if (bd->ShaderModuleFrag) { vkDestroyShaderModule(v->Device, bd->ShaderModuleFrag, v->Allocator); bd->ShaderModuleFrag = VK_NULL_HANDLE; }
|
||||
if (bd->FontSampler) { vkDestroySampler(v->Device, bd->FontSampler, v->Allocator); bd->FontSampler = VK_NULL_HANDLE; }
|
||||
if (bd->DescriptorSetLayout) { vkDestroyDescriptorSetLayout(v->Device, bd->DescriptorSetLayout, v->Allocator); bd->DescriptorSetLayout = VK_NULL_HANDLE; }
|
||||
if (bd->PipelineLayout) { vkDestroyPipelineLayout(v->Device, bd->PipelineLayout, v->Allocator); bd->PipelineLayout = VK_NULL_HANDLE; }
|
||||
if (bd->Pipeline) { vkDestroyPipeline(v->Device, bd->Pipeline, v->Allocator); bd->Pipeline = VK_NULL_HANDLE; }
|
||||
if (bd->DescriptorPool) { vkDestroyDescriptorPool(v->Device, bd->DescriptorPool, v->Allocator); bd->DescriptorPool = VK_NULL_HANDLE; }
|
||||
}
|
||||
|
||||
bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data)
|
||||
|
@ -1105,7 +1139,10 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
|
|||
IM_ASSERT(info->PhysicalDevice != VK_NULL_HANDLE);
|
||||
IM_ASSERT(info->Device != VK_NULL_HANDLE);
|
||||
IM_ASSERT(info->Queue != VK_NULL_HANDLE);
|
||||
IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE);
|
||||
if (info->DescriptorPool != VK_NULL_HANDLE) // Either DescriptorPool or DescriptorPoolSize must be set, not both!
|
||||
IM_ASSERT(info->DescriptorPoolSize == 0);
|
||||
else
|
||||
IM_ASSERT(info->DescriptorPoolSize > 0);
|
||||
IM_ASSERT(info->MinImageCount >= 2);
|
||||
IM_ASSERT(info->ImageCount >= info->MinImageCount);
|
||||
if (info->UseDynamicRendering == false)
|
||||
|
@ -1136,7 +1173,7 @@ void ImGui_ImplVulkan_NewFrame()
|
|||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplVulkan_Init()?");
|
||||
|
||||
if (!bd->FontDescriptorSet)
|
||||
if (!bd->FontTexture.DescriptorSet)
|
||||
ImGui_ImplVulkan_CreateFontsTexture();
|
||||
}
|
||||
|
||||
|
@ -1154,19 +1191,20 @@ void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count)
|
|||
bd->VulkanInitInfo.MinImageCount = min_image_count;
|
||||
}
|
||||
|
||||
// Register a texture
|
||||
// Register a texture by creating a descriptor
|
||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem, please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||
VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
VkDescriptorPool pool = bd->DescriptorPool ? bd->DescriptorPool : v->DescriptorPool;
|
||||
|
||||
// Create Descriptor Set:
|
||||
VkDescriptorSet descriptor_set;
|
||||
{
|
||||
VkDescriptorSetAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
alloc_info.descriptorPool = v->DescriptorPool;
|
||||
alloc_info.descriptorPool = pool;
|
||||
alloc_info.descriptorSetCount = 1;
|
||||
alloc_info.pSetLayouts = &bd->DescriptorSetLayout;
|
||||
VkResult err = vkAllocateDescriptorSets(v->Device, &alloc_info, &descriptor_set);
|
||||
|
@ -1194,7 +1232,8 @@ void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set)
|
|||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
vkFreeDescriptorSets(v->Device, v->DescriptorPool, 1, &descriptor_set);
|
||||
VkDescriptorPool pool = bd->DescriptorPool ? bd->DescriptorPool : v->DescriptorPool;
|
||||
vkFreeDescriptorSets(v->Device, pool, 1, &descriptor_set);
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
|
||||
|
@ -1301,6 +1340,49 @@ VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_d
|
|||
return VK_PRESENT_MODE_FIFO_KHR; // Always available
|
||||
}
|
||||
|
||||
VkPhysicalDevice ImGui_ImplVulkanH_SelectPhysicalDevice(VkInstance instance)
|
||||
{
|
||||
uint32_t gpu_count;
|
||||
VkResult err = vkEnumeratePhysicalDevices(instance, &gpu_count, nullptr);
|
||||
check_vk_result(err);
|
||||
IM_ASSERT(gpu_count > 0);
|
||||
|
||||
ImVector<VkPhysicalDevice> gpus;
|
||||
gpus.resize(gpu_count);
|
||||
err = vkEnumeratePhysicalDevices(instance, &gpu_count, gpus.Data);
|
||||
check_vk_result(err);
|
||||
|
||||
// If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers
|
||||
// most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple
|
||||
// dedicated GPUs) is out of scope of this sample.
|
||||
for (VkPhysicalDevice& device : gpus)
|
||||
{
|
||||
VkPhysicalDeviceProperties properties;
|
||||
vkGetPhysicalDeviceProperties(device, &properties);
|
||||
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||
return device;
|
||||
}
|
||||
|
||||
// Use first GPU (Integrated) is a Discrete one is not available.
|
||||
if (gpu_count > 0)
|
||||
return gpus[0];
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ImGui_ImplVulkanH_SelectQueueFamilyIndex(VkPhysicalDevice physical_device)
|
||||
{
|
||||
uint32_t count;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, nullptr);
|
||||
ImVector<VkQueueFamilyProperties> queues_properties;
|
||||
queues_properties.resize((int)count);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, queues_properties.Data);
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
if (queues_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||
return i;
|
||||
return (uint32_t)-1;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
IM_ASSERT(physical_device != VK_NULL_HANDLE && device != VK_NULL_HANDLE);
|
||||
|
@ -1394,6 +1476,10 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
|||
|
||||
// Create Swapchain
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR cap;
|
||||
err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, wd->Surface, &cap);
|
||||
check_vk_result(err);
|
||||
|
||||
VkSwapchainCreateInfoKHR info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||
info.surface = wd->Surface;
|
||||
|
@ -1403,19 +1489,15 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
|||
info.imageArrayLayers = 1;
|
||||
info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; // Assume that graphics family == present family
|
||||
info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
||||
info.preTransform = (cap.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : cap.currentTransform;
|
||||
info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
info.presentMode = wd->PresentMode;
|
||||
info.clipped = VK_TRUE;
|
||||
info.oldSwapchain = old_swapchain;
|
||||
VkSurfaceCapabilitiesKHR cap;
|
||||
err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, wd->Surface, &cap);
|
||||
check_vk_result(err);
|
||||
if (info.minImageCount < cap.minImageCount)
|
||||
info.minImageCount = cap.minImageCount;
|
||||
else if (cap.maxImageCount != 0 && info.minImageCount > cap.maxImageCount)
|
||||
info.minImageCount = cap.maxImageCount;
|
||||
|
||||
if (cap.currentExtent.width == 0xffffffff)
|
||||
{
|
||||
info.imageExtent.width = wd->Width = w;
|
||||
|
@ -1440,8 +1522,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
|||
wd->SemaphoreCount = wd->ImageCount + 1;
|
||||
wd->Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * wd->ImageCount);
|
||||
wd->FrameSemaphores = (ImGui_ImplVulkanH_FrameSemaphores*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameSemaphores) * wd->SemaphoreCount);
|
||||
memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount);
|
||||
memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->SemaphoreCount);
|
||||
memset((void*)wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount);
|
||||
memset((void*)wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->SemaphoreCount);
|
||||
for (uint32_t i = 0; i < wd->ImageCount; i++)
|
||||
wd->Frames[i].Backbuffer = backbuffers[i];
|
||||
}
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
||||
// See imgui_impl_vulkan.cpp file for details.
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Call ImGui_ImplVulkan_AddTexture() to register one. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
@ -55,7 +53,7 @@
|
|||
|
||||
// Vulkan includes
|
||||
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
|
||||
#include <Volk/volk.h>
|
||||
#include <volk.h>
|
||||
#else
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
|
@ -63,11 +61,18 @@
|
|||
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
#endif
|
||||
|
||||
// Current version of the backend use 1 descriptor for the font atlas + as many as additional calls done to ImGui_ImplVulkan_AddTexture().
|
||||
// It is expected that as early as Q1 2025 the backend will use a few more descriptors. Use this value + number of desired calls to ImGui_ImplVulkan_AddTexture().
|
||||
#define IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE (1) // Minimum per atlas
|
||||
|
||||
// Initialization data, for ImGui_ImplVulkan_Init()
|
||||
// - VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
// and must contain a pool size large enough to hold an ImGui VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor.
|
||||
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
||||
// [Please zero-clear before use!]
|
||||
// - About descriptor pool:
|
||||
// - A VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
// and must contain a pool size large enough to hold a small number of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptors.
|
||||
// - As an convenience, by setting DescriptorPoolSize > 0 the backend will create one for you.
|
||||
// - About dynamic rendering:
|
||||
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
||||
struct ImGui_ImplVulkan_InitInfo
|
||||
{
|
||||
VkInstance Instance;
|
||||
|
@ -75,7 +80,7 @@ struct ImGui_ImplVulkan_InitInfo
|
|||
VkDevice Device;
|
||||
uint32_t QueueFamily;
|
||||
VkQueue Queue;
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above; ignored if using DescriptorPoolSize > 0
|
||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
|
@ -85,6 +90,9 @@ struct ImGui_ImplVulkan_InitInfo
|
|||
VkPipelineCache PipelineCache;
|
||||
uint32_t Subpass;
|
||||
|
||||
// (Optional) Set to create internal descriptor pool instead of using DescriptorPool
|
||||
uint32_t DescriptorPoolSize;
|
||||
|
||||
// (Optional) Dynamic Rendering
|
||||
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
||||
bool UseDynamicRendering;
|
||||
|
@ -98,39 +106,55 @@ struct ImGui_ImplVulkan_InitInfo
|
|||
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||
};
|
||||
|
||||
// Called by user code
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
|
||||
// Register a texture (VkDescriptorSet == ImTextureID)
|
||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem
|
||||
// Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
||||
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
||||
|
||||
// Optional: load Vulkan functions with a custom function loader
|
||||
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplVulkan_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplVulkan_RenderState
|
||||
{
|
||||
VkCommandBuffer CommandBuffer;
|
||||
VkPipeline Pipeline;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.)
|
||||
//-------------------------------------------------------------------------
|
||||
// Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.
|
||||
//
|
||||
// You probably do NOT need to use or care about those functions.
|
||||
// Those functions only exist because:
|
||||
// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
|
||||
// 2) the multi-viewport / platform window implementation needs them internally.
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the backends,
|
||||
// but it is too much code to duplicate everywhere so we exceptionally expose them.
|
||||
//
|
||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
|
||||
// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
|
||||
// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
|
||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain,
|
||||
// render pass, frame buffers, etc.). You may read this code if you are curious, but
|
||||
// it is recommended you use you own custom tailored code to do equivalent work.
|
||||
//
|
||||
// We don't provide a strong guarantee that we won't change those functions API.
|
||||
//
|
||||
// The ImGui_ImplVulkanH_XXX functions should NOT interact with any of the state used
|
||||
// by the regular ImGui_ImplVulkan_XXX functions).
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct ImGui_ImplVulkanH_Frame;
|
||||
|
@ -141,6 +165,8 @@ IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkIns
|
|||
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wnd, const VkAllocationCallbacks* allocator);
|
||||
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
|
||||
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);
|
||||
IMGUI_IMPL_API VkPhysicalDevice ImGui_ImplVulkanH_SelectPhysicalDevice(VkInstance instance);
|
||||
IMGUI_IMPL_API uint32_t ImGui_ImplVulkanH_SelectQueueFamilyIndex(VkPhysicalDevice physical_device);
|
||||
IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);
|
||||
|
||||
// Helper structure to hold the data needed by one rendering frame
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -16,6 +17,10 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-10-14: Update Dawn support for change of string usages. (#8082, #8083)
|
||||
// 2024-10-07: Expose selected render state in ImGui_ImplWGPU_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-10-07: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-09-16: Added support for optional IMGUI_IMPL_WEBGPU_BACKEND_DAWN / IMGUI_IMPL_WEBGPU_BACKEND_WGPU define to handle ever-changing native implementations. (#7977)
|
||||
// 2024-01-22: Added configurable PipelineMultisampleState struct. (#7240)
|
||||
// 2024-01-22: (Breaking) ImGui_ImplWGPU_Init() now takes a ImGui_ImplWGPU_InitInfo structure instead of variety of parameters, allowing for easier further changes.
|
||||
// 2024-01-22: Fixed pipeline layout leak. (#7245)
|
||||
|
@ -35,6 +40,18 @@
|
|||
// 2021-02-18: Change blending equation to preserve alpha in output buffer.
|
||||
// 2021-01-28: Initial version.
|
||||
|
||||
// When targeting native platforms (i.e. NOT emscripten), one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
// or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. See imgui_impl_wgpu.h for more details.
|
||||
#ifndef __EMSCRIPTEN__
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) == defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#error exactly one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be defined!
|
||||
#endif
|
||||
#else
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#error neither IMGUI_IMPL_WEBGPU_BACKEND_DAWN nor IMGUI_IMPL_WEBGPU_BACKEND_WGPU may be defined if targeting emscripten!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_wgpu.h"
|
||||
|
@ -244,16 +261,26 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
|
|||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
|
||||
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
WGPUShaderSourceWGSL wgsl_desc = {};
|
||||
wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL;
|
||||
wgsl_desc.code = { wgsl_source, WGPU_STRLEN };
|
||||
#else
|
||||
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
|
||||
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
|
||||
wgsl_desc.code = wgsl_source;
|
||||
wgsl_desc.code = wgsl_source;
|
||||
#endif
|
||||
|
||||
WGPUShaderModuleDescriptor desc = {};
|
||||
desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&wgsl_desc);
|
||||
|
||||
WGPUProgrammableStageDescriptor stage_desc = {};
|
||||
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
stage_desc.entryPoint = { "main", WGPU_STRLEN };
|
||||
#else
|
||||
stage_desc.entryPoint = "main";
|
||||
#endif
|
||||
return stage_desc;
|
||||
}
|
||||
|
||||
|
@ -366,6 +393,9 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||
{
|
||||
nullptr,
|
||||
"Dear ImGui Vertex buffer",
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
WGPU_STRLEN,
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||
MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4),
|
||||
false
|
||||
|
@ -390,6 +420,9 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||
{
|
||||
nullptr,
|
||||
"Dear ImGui Index buffer",
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
WGPU_STRLEN,
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
|
||||
MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4),
|
||||
false
|
||||
|
@ -406,11 +439,11 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||
ImDrawIdx* idx_dst = (ImDrawIdx*)fr->IndexBufferHost;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
int64_t vb_write_size = MEMALIGN((char*)vtx_dst - (char*)fr->VertexBufferHost, 4);
|
||||
int64_t ib_write_size = MEMALIGN((char*)idx_dst - (char*)fr->IndexBufferHost, 4);
|
||||
|
@ -420,6 +453,13 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||
// Setup desired render state
|
||||
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplWGPU_RenderState render_state;
|
||||
render_state.Device = bd->wgpuDevice;
|
||||
render_state.RenderPassEncoder = pass_encoder;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
int global_vtx_offset = 0;
|
||||
|
@ -428,10 +468,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
|
@ -439,7 +479,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -475,9 +515,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||
wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWGPU_CreateFontsTexture()
|
||||
|
@ -492,7 +533,11 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
|
|||
// Upload texture to graphics system
|
||||
{
|
||||
WGPUTextureDescriptor tex_desc = {};
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
tex_desc.label = { "Dear ImGui Font Texture", WGPU_STRLEN };
|
||||
#else
|
||||
tex_desc.label = "Dear ImGui Font Texture";
|
||||
#endif
|
||||
tex_desc.dimension = WGPUTextureDimension_2D;
|
||||
tex_desc.size.width = width;
|
||||
tex_desc.size.height = height;
|
||||
|
@ -536,9 +581,9 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
|
|||
sampler_desc.minFilter = WGPUFilterMode_Linear;
|
||||
sampler_desc.magFilter = WGPUFilterMode_Linear;
|
||||
sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Linear;
|
||||
sampler_desc.addressModeU = WGPUAddressMode_Repeat;
|
||||
sampler_desc.addressModeV = WGPUAddressMode_Repeat;
|
||||
sampler_desc.addressModeW = WGPUAddressMode_Repeat;
|
||||
sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
|
||||
sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
|
||||
sampler_desc.addressModeW = WGPUAddressMode_ClampToEdge;
|
||||
sampler_desc.maxAnisotropy = 1;
|
||||
bd->renderResources.Sampler = wgpuDeviceCreateSampler(bd->wgpuDevice, &sampler_desc);
|
||||
}
|
||||
|
@ -555,6 +600,9 @@ static void ImGui_ImplWGPU_CreateUniformBuffer()
|
|||
{
|
||||
nullptr,
|
||||
"Dear ImGui Uniform buffer",
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
WGPU_STRLEN,
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform,
|
||||
MEMALIGN(sizeof(Uniforms), 16),
|
||||
false
|
||||
|
@ -660,7 +708,11 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
|||
// Create depth-stencil State
|
||||
WGPUDepthStencilState depth_stencil_state = {};
|
||||
depth_stencil_state.format = bd->depthStencilFormat;
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
depth_stencil_state.depthWriteEnabled = WGPUOptionalBool_False;
|
||||
#else
|
||||
depth_stencil_state.depthWriteEnabled = false;
|
||||
#endif
|
||||
depth_stencil_state.depthCompare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilFront.compare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilFront.failOp = WGPUStencilOperation_Keep;
|
||||
|
@ -730,7 +782,15 @@ bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
|
|||
// Setup backend capabilities flags
|
||||
ImGui_ImplWGPU_Data* bd = IM_NEW(ImGui_ImplWGPU_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
io.BackendRendererName = "imgui_impl_webgpu_emscripten";
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||
io.BackendRendererName = "imgui_impl_webgpu_dawn";
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
io.BackendRendererName = "imgui_impl_webgpu_wgpu";
|
||||
#else
|
||||
io.BackendRendererName = "imgui_impl_webgpu";
|
||||
#endif
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
bd->initInfo = *init_info;
|
||||
|
|
|
@ -2,9 +2,17 @@
|
|||
// This needs to be used along with a Platform Binding (e.g. GLFW)
|
||||
// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.)
|
||||
|
||||
// Important note to dawn and/or wgpu users: when targeting native platforms (i.e. NOT emscripten),
|
||||
// one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided.
|
||||
// Add #define to your imconfig.h file, or as a compilation flag in your build system.
|
||||
// This requirement will be removed once WebGPU stabilizes and backends converge on a unified interface.
|
||||
//#define IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
//#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -37,13 +45,23 @@ struct ImGui_ImplWGPU_InitInfo
|
|||
}
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info);
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder);
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplWGPU_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplWGPU_RenderState
|
||||
{
|
||||
WGPUDevice Device;
|
||||
WGPURenderPassEncoder RenderPassEncoder;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
// Implemented features:
|
||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -21,6 +21,7 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-07-08: Inputs: Fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN. (#7768)
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||
// 2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
|
||||
// 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window.
|
||||
|
@ -98,6 +99,7 @@ typedef DWORD(WINAPI* PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
|||
#endif
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
|
||||
#endif
|
||||
|
||||
|
@ -105,7 +107,7 @@ struct ImGui_ImplWin32_Data
|
|||
{
|
||||
HWND hWnd;
|
||||
HWND MouseHwnd;
|
||||
int MouseTrackedArea; // 0: not tracked, 1: client are, 2: non-client area
|
||||
int MouseTrackedArea; // 0: not tracked, 1: client area, 2: non-client area
|
||||
int MouseButtonsDown;
|
||||
INT64 Time;
|
||||
INT64 TicksPerSecond;
|
||||
|
@ -131,12 +133,16 @@ static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
|
|||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||
}
|
||||
static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData(ImGuiIO& io)
|
||||
{
|
||||
return (ImGui_ImplWin32_Data*)io.BackendPlatformUserData;
|
||||
}
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplWin32_UpdateKeyboardCodePage()
|
||||
static void ImGui_ImplWin32_UpdateKeyboardCodePage(ImGuiIO& io)
|
||||
{
|
||||
// Retrieve keyboard code page, required for handling of non-Unicode Windows.
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||
HKL keyboard_layout = ::GetKeyboardLayout(0);
|
||||
LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT);
|
||||
if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0)
|
||||
|
@ -166,10 +172,11 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
|
|||
bd->TicksPerSecond = perf_frequency;
|
||||
bd->Time = perf_counter;
|
||||
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||
ImGui_ImplWin32_UpdateKeyboardCodePage();
|
||||
ImGui_ImplWin32_UpdateKeyboardCodePage(io);
|
||||
|
||||
// Set platform dependent data in viewport
|
||||
ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd;
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd;
|
||||
IM_UNUSED(platform_has_own_dc); // Used in 'docking' branch
|
||||
|
||||
// Dynamically load XInput library
|
||||
|
@ -225,13 +232,11 @@ void ImGui_ImplWin32_Shutdown()
|
|||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplWin32_UpdateMouseCursor()
|
||||
static bool ImGui_ImplWin32_UpdateMouseCursor(ImGuiIO& io, ImGuiMouseCursor imgui_cursor)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
||||
return false;
|
||||
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
||||
{
|
||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||
|
@ -263,49 +268,46 @@ static bool IsVkDown(int vk)
|
|||
return (::GetKeyState(vk) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_AddKeyEvent(ImGuiKey key, bool down, int native_keycode, int native_scancode = -1)
|
||||
static void ImGui_ImplWin32_AddKeyEvent(ImGuiIO& io, ImGuiKey key, bool down, int native_keycode, int native_scancode = -1)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddKeyEvent(key, down);
|
||||
io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To support legacy indexing (<1.87 user code)
|
||||
IM_UNUSED(native_scancode);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
||||
static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds(ImGuiIO& io)
|
||||
{
|
||||
// Left & right Shift keys: when both are pressed together, Windows tend to not generate the WM_KEYUP event for the first released one.
|
||||
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && !IsVkDown(VK_LSHIFT))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, false, VK_LSHIFT);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftShift, false, VK_LSHIFT);
|
||||
if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, false, VK_RSHIFT);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightShift, false, VK_RSHIFT);
|
||||
|
||||
// Sometimes WM_KEYUP for Win key is not passed down to the app (e.g. for Win+V on some setups, according to GLFW).
|
||||
if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftSuper, false, VK_LWIN);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftSuper, false, VK_LWIN);
|
||||
if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightSuper, false, VK_RWIN);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightSuper, false, VK_RWIN);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateKeyModifiers()
|
||||
static void ImGui_ImplWin32_UpdateKeyModifiers(ImGuiIO& io)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddKeyEvent(ImGuiMod_Ctrl, IsVkDown(VK_CONTROL));
|
||||
io.AddKeyEvent(ImGuiMod_Shift, IsVkDown(VK_SHIFT));
|
||||
io.AddKeyEvent(ImGuiMod_Alt, IsVkDown(VK_MENU));
|
||||
io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_APPS));
|
||||
io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_LWIN) || IsVkDown(VK_RWIN));
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateMouseData()
|
||||
static void ImGui_ImplWin32_UpdateMouseData(ImGuiIO& io)
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||
IM_ASSERT(bd->hWnd != 0);
|
||||
|
||||
HWND focused_window = ::GetForegroundWindow();
|
||||
const bool is_app_focused = (focused_window == bd->hWnd);
|
||||
if (is_app_focused)
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
{
|
||||
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
|
||||
|
@ -325,11 +327,10 @@ static void ImGui_ImplWin32_UpdateMouseData()
|
|||
}
|
||||
|
||||
// Gamepad navigation mapping
|
||||
static void ImGui_ImplWin32_UpdateGamepads()
|
||||
static void ImGui_ImplWin32_UpdateGamepads(ImGuiIO& io)
|
||||
{
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||
//if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||
// return;
|
||||
|
||||
|
@ -378,7 +379,9 @@ static void ImGui_ImplWin32_UpdateGamepads()
|
|||
MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
#else // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
IM_UNUSED(io);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImGui_ImplWin32_NewFrame()
|
||||
|
@ -399,29 +402,32 @@ void ImGui_ImplWin32_NewFrame()
|
|||
bd->Time = current_time;
|
||||
|
||||
// Update OS mouse position
|
||||
ImGui_ImplWin32_UpdateMouseData();
|
||||
ImGui_ImplWin32_UpdateMouseData(io);
|
||||
|
||||
// Process workarounds for known Windows key handling issues
|
||||
ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
|
||||
ImGui_ImplWin32_ProcessKeyEventsWorkarounds(io);
|
||||
|
||||
// Update OS mouse cursor with the cursor requested by imgui
|
||||
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
||||
if (bd->LastMouseCursor != mouse_cursor)
|
||||
{
|
||||
bd->LastMouseCursor = mouse_cursor;
|
||||
ImGui_ImplWin32_UpdateMouseCursor();
|
||||
ImGui_ImplWin32_UpdateMouseCursor(io, mouse_cursor);
|
||||
}
|
||||
|
||||
// Update game controllers (if enabled and available)
|
||||
ImGui_ImplWin32_UpdateGamepads();
|
||||
ImGui_ImplWin32_UpdateGamepads(io);
|
||||
}
|
||||
|
||||
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED, we assign it an arbitrary value to make code more readable (VK_ codes go up to 255)
|
||||
#define IM_VK_KEYPAD_ENTER (VK_RETURN + 256)
|
||||
|
||||
// Map VK_xxx to ImGuiKey_xxx.
|
||||
static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam);
|
||||
ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED.
|
||||
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
||||
return ImGuiKey_KeypadEnter;
|
||||
|
||||
switch (wParam)
|
||||
{
|
||||
case VK_TAB: return ImGuiKey_Tab;
|
||||
|
@ -470,7 +476,6 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
|||
case VK_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||
case VK_SUBTRACT: return ImGuiKey_KeypadSubtract;
|
||||
case VK_ADD: return ImGuiKey_KeypadAdd;
|
||||
case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case VK_LSHIFT: return ImGuiKey_LeftShift;
|
||||
case VK_LCONTROL: return ImGuiKey_LeftCtrl;
|
||||
case VK_LMENU: return ImGuiKey_LeftAlt;
|
||||
|
@ -554,22 +559,10 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
|||
#define DBT_DEVNODES_CHANGED 0x0007
|
||||
#endif
|
||||
|
||||
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
|
||||
// Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
||||
// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
|
||||
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
|
||||
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
|
||||
#if 0
|
||||
// Copy this line into your .cpp file to forward declare the function.
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
// Helper to obtain the source of mouse messages.
|
||||
// See https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages
|
||||
// Prefer to call this at the top of the message handler to avoid the possibility of other Win32 calls interfering with this.
|
||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||
static ImGuiMouseSource ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo()
|
||||
{
|
||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||
|
@ -579,22 +572,40 @@ static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
|||
return ImGuiMouseSource_Mouse;
|
||||
}
|
||||
|
||||
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
|
||||
// Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
||||
// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
|
||||
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
|
||||
|
||||
// Copy either line into your .cpp file to forward declare the function:
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Use ImGui::GetCurrentContext()
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ImGuiIO& io); // Doesn't use ImGui::GetCurrentContext()
|
||||
|
||||
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// Most backends don't have silent checks like this one, but we need it because WndProc are called early in CreateWindow().
|
||||
// We silently allow both context or just only backend data to be nullptr.
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
if (ImGui::GetCurrentContext() == nullptr)
|
||||
return 0;
|
||||
return ImGui_ImplWin32_WndProcHandlerEx(hwnd, msg, wParam, lParam, ImGui::GetIO());
|
||||
}
|
||||
|
||||
// This version is in theory thread-safe in the sense that no path should access ImGui::GetCurrentContext().
|
||||
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, ImGuiIO& io)
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||
if (bd == nullptr)
|
||||
return 0;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_NCMOUSEMOVE:
|
||||
{
|
||||
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
||||
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||
ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
|
||||
const int area = (msg == WM_MOUSEMOVE) ? 1 : 2;
|
||||
bd->MouseHwnd = hwnd;
|
||||
if (bd->MouseTrackedArea != area)
|
||||
|
@ -626,19 +637,29 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
case WM_DESTROY:
|
||||
if (bd->MouseHwnd == hwnd && bd->MouseTrackedArea != 0)
|
||||
{
|
||||
TRACKMOUSEEVENT tme_cancel = { sizeof(tme_cancel), TME_CANCEL, hwnd, 0 };
|
||||
::TrackMouseEvent(&tme_cancel);
|
||||
bd->MouseHwnd = nullptr;
|
||||
bd->MouseTrackedArea = 0;
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
}
|
||||
return 0;
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
|
||||
{
|
||||
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||
ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
|
||||
int button = 0;
|
||||
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
|
||||
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
||||
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
|
||||
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||
if (bd->MouseButtonsDown == 0 && ::GetCapture() == nullptr)
|
||||
::SetCapture(hwnd);
|
||||
::SetCapture(hwnd); // Allow us to read mouse coordinates when dragging mouse outside of our window bounds.
|
||||
bd->MouseButtonsDown |= 1 << button;
|
||||
io.AddMouseSourceEvent(mouse_source);
|
||||
io.AddMouseButtonEvent(button, true);
|
||||
|
@ -649,7 +670,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||
case WM_MBUTTONUP:
|
||||
case WM_XBUTTONUP:
|
||||
{
|
||||
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||
ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
|
||||
int button = 0;
|
||||
if (msg == WM_LBUTTONUP) { button = 0; }
|
||||
if (msg == WM_RBUTTONUP) { button = 1; }
|
||||
|
@ -677,40 +698,37 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||
if (wParam < 256)
|
||||
{
|
||||
// Submit modifiers
|
||||
ImGui_ImplWin32_UpdateKeyModifiers();
|
||||
ImGui_ImplWin32_UpdateKeyModifiers(io);
|
||||
|
||||
// Obtain virtual key code
|
||||
// (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.)
|
||||
int vk = (int)wParam;
|
||||
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
||||
vk = IM_VK_KEYPAD_ENTER;
|
||||
const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
|
||||
// Obtain virtual key code and convert to ImGuiKey
|
||||
const ImGuiKey key = ImGui_ImplWin32_KeyEventToImGuiKey(wParam, lParam);
|
||||
const int vk = (int)wParam;
|
||||
const int scancode = (int)LOBYTE(HIWORD(lParam));
|
||||
|
||||
// Special behavior for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit the key down event.
|
||||
if (key == ImGuiKey_PrintScreen && !is_key_down)
|
||||
ImGui_ImplWin32_AddKeyEvent(key, true, vk, scancode);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, key, true, vk, scancode);
|
||||
|
||||
// Submit key event
|
||||
if (key != ImGuiKey_None)
|
||||
ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, key, is_key_down, vk, scancode);
|
||||
|
||||
// Submit individual left/right modifier events
|
||||
if (vk == VK_SHIFT)
|
||||
{
|
||||
// Important: Shift keys tend to get stuck when pressed together, missing key-up events are corrected in ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
||||
if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); }
|
||||
if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
|
||||
if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); }
|
||||
if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
|
||||
}
|
||||
else if (vk == VK_CONTROL)
|
||||
{
|
||||
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
|
||||
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
|
||||
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
|
||||
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
|
||||
}
|
||||
else if (vk == VK_MENU)
|
||||
{
|
||||
if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); }
|
||||
if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
|
||||
if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); }
|
||||
if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -720,7 +738,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||
io.AddFocusEvent(msg == WM_SETFOCUS);
|
||||
return 0;
|
||||
case WM_INPUTLANGCHANGE:
|
||||
ImGui_ImplWin32_UpdateKeyboardCodePage();
|
||||
ImGui_ImplWin32_UpdateKeyboardCodePage(io);
|
||||
return 0;
|
||||
case WM_CHAR:
|
||||
if (::IsWindowUnicode(hwnd))
|
||||
|
@ -738,7 +756,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||
return 0;
|
||||
case WM_SETCURSOR:
|
||||
// This is required to restore cursor when transitioning from e.g resize borders to client area.
|
||||
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
|
||||
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor(io, bd->LastMouseCursor))
|
||||
return 1;
|
||||
return 0;
|
||||
case WM_DEVICECHANGE:
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
// Implemented features:
|
||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -20,6 +20,7 @@
|
|||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
|
||||
IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd);
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
|
||||
|
|