Compare commits

..

1 Commits

Author SHA1 Message Date
889c4d0b97
tmp patch to enlargen the ngc lossy custom pkg size 2023-12-13 14:03:06 +01:00
2671 changed files with 761497 additions and 53460 deletions

View File

@ -7,231 +7,37 @@ on:
branches: [ master ] branches: [ master ]
env: env:
BUILD_TYPE: RelWithDebInfo BUILD_TYPE: Release
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
jobs: jobs:
linux-ubuntu:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Dependencies
run: sudo apt update && sudo apt -y install libsodium-dev cmake
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
- name: Determine tag name
id: tag
shell: bash
# taken from llama.cpp
run: |
SHORT_HASH="$(git rev-parse --short=7 HEAD)"
if [[ "${{ env.BRANCH_NAME }}" == "master" ]]; then
echo "name=dev-${SHORT_HASH}" >> $GITHUB_OUTPUT
else
SAFE_NAME=$(echo "${{ env.BRANCH_NAME }}" | tr '/' '-')
echo "name=dev-${SAFE_NAME}-${SHORT_HASH}" >> $GITHUB_OUTPUT
fi
- name: Compress artifacts
shell: bash
run: |
tar -czvf ${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-ubuntu20.04-x86_64.tar.gz -C ${{github.workspace}}/build/bin/ .
- uses: actions/upload-artifact@v4
with:
# TODO: simpler name?
name: ${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-ubuntu20.04-x86_64
# TODO: do propper packing
path: |
${{github.workspace}}/${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-ubuntu20.04-x86_64.tar.gz
windows: windows:
timeout-minutes: 15 timeout-minutes: 15
runs-on: windows-2019 runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
submodules: recursive submodules: recursive
- name: update vcpkg
shell: bash
run: |
cd C:/vcpkg
git pull
- name: Install Dependencies - name: Install Dependencies
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static
# setup vs env # setup vs env
- uses: ilammy/msvc-dev-cmd@v1 - uses: ilammy/msvc-dev-cmd@v1
with: with:
arch: amd64 arch: amd64
## sdl_image vendored needs nasm for dav1d
#- uses: ilammy/setup-nasm@v1
- name: Configure CMake - name: Configure CMake
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -t tomato run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
- name: Determine tag name - uses: actions/upload-artifact@v3
id: tag
shell: bash
# taken from llama.cpp
run: |
SHORT_HASH="$(git rev-parse --short=7 HEAD)"
if [[ "${{ env.BRANCH_NAME }}" == "master" ]]; then
echo "name=dev-${SHORT_HASH}" >> $GITHUB_OUTPUT
else
SAFE_NAME=$(echo "${{ env.BRANCH_NAME }}" | tr '/' '-')
echo "name=dev-${SAFE_NAME}-${SHORT_HASH}" >> $GITHUB_OUTPUT
fi
- name: Compress artifacts
shell: powershell
run: |
Compress-Archive -Path ${{github.workspace}}/build/bin/* -Destination ${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-msvc-x86_64.zip
- uses: actions/upload-artifact@v4
with: with:
# TODO: simpler name? name: ${{ github.event.repository.name }}-windows-msvc-x86_64
name: ${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-msvc-x86_64
# TODO: do propper packing # TODO: do propper packing
path: | path: |
${{github.workspace}}/${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-msvc-x86_64.zip ${{github.workspace}}/build/bin/
windows-asan:
timeout-minutes: 15
runs-on: windows-2019
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: update vcpkg
shell: bash
run: |
cd C:/vcpkg
git pull
- name: Install Dependencies
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows
# setup vs env
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: amd64
## sdl_image vendored needs nasm for dav1d
#- uses: ilammy/setup-nasm@v1
- name: Configure CMake
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DTOMATO_ASAN=ON -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
- name: Determine tag name
id: tag
shell: bash
# taken from llama.cpp
run: |
SHORT_HASH="$(git rev-parse --short=7 HEAD)"
if [[ "${{ env.BRANCH_NAME }}" == "master" ]]; then
echo "name=dev-${SHORT_HASH}" >> $GITHUB_OUTPUT
else
SAFE_NAME=$(echo "${{ env.BRANCH_NAME }}" | tr '/' '-')
echo "name=dev-${SAFE_NAME}-${SHORT_HASH}" >> $GITHUB_OUTPUT
fi
- name: Compress artifacts
shell: powershell
run: |
Compress-Archive -Path ${{github.workspace}}/build/bin/* -Destination ${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-msvc-asan-x86_64.zip
- uses: actions/upload-artifact@v4
with:
# TODO: simpler name?
name: ${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-msvc-asan-x86_64
# TODO: do propper packing
path: |
${{github.workspace}}/${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-msvc-asan-x86_64.zip
release:
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) }}
runs-on: ubuntu-latest
needs:
- linux-ubuntu
- windows
- windows-asan
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Determine tag name
id: tag
shell: bash
# taken from llama.cpp
run: |
SHORT_HASH="$(git rev-parse --short=7 HEAD)"
if [[ "${{ env.BRANCH_NAME }}" == "master" ]]; then
echo "name=dev-${SHORT_HASH}" >> $GITHUB_OUTPUT
else
SAFE_NAME=$(echo "${{ env.BRANCH_NAME }}" | tr '/' '-')
echo "name=dev-${SAFE_NAME}-${SHORT_HASH}" >> $GITHUB_OUTPUT
fi
- name: Download artifacts
id: download-artifact
uses: actions/download-artifact@v4
with:
path: ./artifacts/
- name: Create release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ steps.tag.outputs.name }}
shell: bash
run: |
gh release create "$tag" \
--repo="$GITHUB_REPOSITORY" \
--title="${tag#v}" \
--notes="preview build of the latest commit" \
--prerelease
- name: Upload artifacts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ steps.tag.outputs.name }}
shell: bash
run: |
ls -laR ./artifacts
gh release upload "$tag" ./artifacts/*/* \
--repo="$GITHUB_REPOSITORY"

View File

@ -16,18 +16,18 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
submodules: recursive submodules: recursive
- name: Install Dependencies - name: Install Dependencies
run: sudo apt update && sudo apt -y install libsodium-dev cmake run: sudo apt update && sudo apt -y install libsodium-dev
- name: Configure CMake - name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
macos: macos:
timeout-minutes: 10 timeout-minutes: 10
@ -35,7 +35,7 @@ jobs:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
submodules: recursive submodules: recursive
@ -46,39 +46,29 @@ jobs:
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
windows: windows:
timeout-minutes: 15 timeout-minutes: 10
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
submodules: recursive submodules: recursive
- name: update vcpkg
shell: bash
run: |
cd C:/vcpkg
git pull
- name: Install Dependencies - name: Install Dependencies
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static
# setup vs env # setup vs env
- uses: ilammy/msvc-dev-cmd@v1 - uses: ilammy/msvc-dev-cmd@v1
with: with:
arch: amd64 arch: amd64
## sdl_image vendored needs nasm for dav1d
#- uses: ilammy/setup-nasm@v1
- name: Configure CMake - name: Configure CMake
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4

6
.gitmodules vendored
View File

@ -20,9 +20,3 @@
[submodule "external/solanaceae_plugin"] [submodule "external/solanaceae_plugin"]
path = external/solanaceae_plugin path = external/solanaceae_plugin
url = https://github.com/Green-Sky/solanaceae_plugin.git url = https://github.com/Green-Sky/solanaceae_plugin.git
[submodule "external/solanaceae_object_store"]
path = external/solanaceae_object_store
url = https://github.com/Green-Sky/solanaceae_object_store.git
[submodule "external/solanaceae_message_serializer"]
path = external/solanaceae_message_serializer
url = https://github.com/Green-Sky/solanaceae_message_serializer.git

View File

@ -1,6 +1,4 @@
cmake_minimum_required(VERSION 3.14...3.24 FATAL_ERROR) cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
#pingpong
# cmake setup begin # cmake setup begin
project(tomato) project(tomato)
@ -8,7 +6,7 @@ project(tomato)
set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# defaulting to debug mode, if not specified # defaulting to debug mode, if not specified
if (NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug") set(CMAKE_BUILD_TYPE "Debug")
endif() endif()
@ -20,30 +18,6 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
option(TOMATO_ASAN "Build tomato with asan (gcc/clang/msvc)" OFF)
if (TOMATO_ASAN)
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
if (NOT WIN32) # exclude mingw
#link_libraries(-fsanitize=address)
link_libraries(-fsanitize=address,undefined)
#link_libraries(-fsanitize=undefined)
message("II enabled ASAN")
else()
message("!! can not enable ASAN on this platform (gcc/clang + win)")
endif()
elseif (MSVC)
add_compile_options("/fsanitize=address")
message("II enabled ASAN")
else()
message("!! can not enable ASAN on this platform")
endif()
endif()
# uggly, but it needs to be defined for all of tomato.
# but this also means that we can not compile tomato in the same cmake as plugins
add_compile_definitions(ENTT_API_EXPORT)
# external libs # external libs
add_subdirectory(./external) # before increasing warn levels, sad :( add_subdirectory(./external) # before increasing warn levels, sad :(
@ -59,8 +33,13 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL
#-Wsign-conversion # Warn on sign conversions #-Wsign-conversion # Warn on sign conversions
-Wshadow # Warn if a variable declaration shadows one from a parent context -Wshadow # Warn if a variable declaration shadows one from a parent context
) )
if (NOT WIN32)
#link_libraries(-fsanitize=address,undefined)
#link_libraries(-fsanitize=undefined)
endif()
elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
if (MSVC) if (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else() else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")

View File

@ -2,7 +2,3 @@
![tomato](res/icon/tomato_v1_256.png) ![tomato](res/icon/tomato_v1_256.png)
## Highly experimental solanaceae client with Tox built-in
![group chat](res/tomato_screenshot_group_bot_text_23-02-2024.png)

View File

@ -1,11 +1,10 @@
cmake_minimum_required(VERSION 3.14...3.24 FATAL_ERROR) cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
add_subdirectory(./entt) add_subdirectory(./entt)
add_subdirectory(./solanaceae_util) add_subdirectory(./solanaceae_util)
add_subdirectory(./solanaceae_contact) add_subdirectory(./solanaceae_contact)
add_subdirectory(./solanaceae_message3) add_subdirectory(./solanaceae_message3)
add_subdirectory(./solanaceae_message_serializer)
add_subdirectory(./solanaceae_plugin) add_subdirectory(./solanaceae_plugin)
@ -13,13 +12,9 @@ add_subdirectory(./toxcore)
add_subdirectory(./solanaceae_toxcore) add_subdirectory(./solanaceae_toxcore)
add_subdirectory(./solanaceae_tox) add_subdirectory(./solanaceae_tox)
add_subdirectory(./solanaceae_object_store)
add_subdirectory(./sdl) add_subdirectory(./sdl)
add_subdirectory(./imgui) add_subdirectory(./imgui)
add_subdirectory(./stb) add_subdirectory(./stb)
add_subdirectory(./libwebp) add_subdirectory(./libwebp)
add_subdirectory(./qoi)
add_subdirectory(./sdl_image)

View File

@ -1 +0,0 @@
blank_issues_enabled: false

View File

@ -1,90 +0,0 @@
name: "Ask a question, report a bug, request a feature, etc."
description: "Ask any question, discuss best practices, report a bug, request a feature."
body:
- type: markdown
attributes:
value: |
FOR FIRST-TIME USERS ISSUES COMPILING/LINKING/RUNNING or LOADING FONTS, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions)
For anything else: we are happy to use 'GitHub Issues' for many types of open-ended questions. We are encouraging 'Issues' becoming a large, centralized and cross-referenced database of Dear ImGui contents.
Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users.
- type: markdown
attributes:
value: |
**Prerequisites:**
- I have read [Frequently Asked Questions](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md).
- I have read [Contributing Guidelines -> General Advices](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#getting-started--general-advice).
- I have read [Contributing Guidelines -> How to open an Issue](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#how-to-open-an-issue).
- I have searched [Github Issues and PR](https://github.com/ocornut/imgui/issues?q=) for discussion of similar topics.
----
- type: input
id: specs_version
attributes:
label: "Version/Branch of Dear ImGui:"
description: "(please specify if you have made substantial modifications to your copy)"
value: "Version 1.XX, Branch: XXX (master/docking/etc.)"
placeholder: "Version 1.XX, Branch: XXX (master/docking/etc.)"
validations:
required: true
- type: input
id: specs_backend
attributes:
label: "Back-ends:"
description: (or specify when using custom engine/back-ends)
value: "imgui_impl_XXX.cpp + imgui_impl_XXX.cpp"
placeholder: "imgui_impl_XXX.cpp + imgui_impl_XXX.cpp or n/a"
validations:
required: true
- type: input
id: specs_compiler_os
attributes:
label: "Compiler, OS:"
placeholder: "e.g. Windows 11 + MSVC 2022, macOS + Clang 12, Linux + GCC etc."
validations:
required: true
- type: textarea
id: specs_full
attributes:
label: "Full config/build information:"
placeholder: |
(If you can run, you may go to 'Demo->Tools->About Dear ImGui->Config/Build Info' to obtain detailed information that you can paste here)
validations:
required: false
- type: textarea
id: issue_description
attributes:
label: "Details:"
description: "Try to be explicit with your goals, your expectations and what you have tried. Be mindful of [The XY Problem](https://xyproblem.info). What you have in mind or in your code is not obvious to other people. People frequently discuss problems and suggest incorrect solutions without first clarifying their goals. When requesting a new feature, please describe the usage context (how you intend to use it, why you need it, etc.). If you tried something and it failed, show us what you tried. If you are reporting a bug, explain what's the bug, how does it occur, etc. If you are reporting a crash, please include a debugger callstack."
value: |
**My Issue/Question:**
XXX _(please provide as much context as possible)_
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: "Screenshots/Video:"
description: "Attach screenshots or gif/videos to clarify the context. They often convey useful information that is omitted by the description."
placeholder: "(You can drag files here)"
validations:
required: false
- type: textarea
id: repro_code
attributes:
label: "Minimal, Complete and Verifiable Example code:"
description: "Provide an [MCVE](https://stackoverflow.com/help/mcve) to demonstrate your problem. An ideal submission includes a small piece of code that anyone can paste into one of the examples applications (examples/*/main.cpp) or the demo (imgui_demo.cpp) to understand and reproduce it. Narrowing your problem to its shortest and purest form is the easiest way to understand it, explain it and fix it. Please test your shortened code to ensure it exhibits the problem. Often while creating the MCVE you will solve the problem! Many questions that are missing a standalone verifiable example are missing the actual cause of their issue in the description, which ends up wasting everyone's time."
value: |
```cpp
// Here's some code anyone can copy and paste to reproduce your issue
ImGui::Begin("Example Bug");
MoreCodeToExplainMyIssue();
ImGui::End();
```
validations:
required: false
- type: markdown
attributes:
value: |
Thank you for taking the time to read prerequisites, filling this template and double-checking your message and your code!

View File

@ -0,0 +1,46 @@
(Click "Preview" above ^ to turn URL into clickable links)
1. FOR FIRST-TIME USERS ISSUES COMPILING/LINKING/RUNNING or LOADING FONTS, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions).
2. PLEASE CAREFULLY READ: [FAQ](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md)
3. PLEASE CAREFULLY READ: [Contributing Guidelines](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md)
4. PLEASE MAKE SURE that you have: read the FAQ; explored the contents of `ShowDemoWindow()` including the Examples menu; searched among Issues; used your IDE to search for keywords in all sources and text files; and read the links above.
5. Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users.
6. Delete points 1-6 and PLEASE FILL THE TEMPLATE BELOW before submitting your issue.
Thank you!
----
_(you may also go to Demo>About Window, and click "Config/Build Information" to obtain a bunch of detailed information that you can paste here)_
**Version/Branch of Dear ImGui:**
Version: XXX
Branch: XXX _(master/viewport/docking/etc.)_
**Back-end/Renderer/Compiler/OS**
Back-ends: imgui_impl_XXX.cpp + imgui_impl_XXX.cpp _(or specify if using a custom engine/back-end)_
Compiler: XXX _(if the question is related to building or platform specific features)_
Operating System: XXX
**My Issue/Question:**
XXX _(please provide as much context as possible)_
**Screenshots/Video**
XXX _(you can drag files here)_
**Standalone, minimal, complete and verifiable example:** _(see https://github.com/ocornut/imgui/issues/2261)_
```
// Here's some code anyone can copy and paste to reproduce your issue
ImGui::Begin("Example Bug");
MoreCodeToExplainMyIssue();
ImGui::End();
```

View File

@ -21,7 +21,7 @@ jobs:
VS_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\ VS_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\
MSBUILD_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\ MSBUILD_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install Dependencies - name: Install Dependencies
shell: powershell shell: powershell
@ -209,7 +209,7 @@ jobs:
Linux: Linux:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install Dependencies - name: Install Dependencies
run: | run: |
@ -402,7 +402,7 @@ jobs:
MacOS: MacOS:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install Dependencies - name: Install Dependencies
run: | run: |
@ -462,7 +462,7 @@ jobs:
iOS: iOS:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Build example_apple_metal - name: Build example_apple_metal
run: | run: |
@ -472,15 +472,15 @@ jobs:
Emscripten: Emscripten:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install Dependencies - name: Install Dependencies
run: | run: |
wget -q https://github.com/emscripten-core/emsdk/archive/master.tar.gz wget -q https://github.com/emscripten-core/emsdk/archive/master.tar.gz
tar -xvf master.tar.gz tar -xvf master.tar.gz
emsdk-master/emsdk update emsdk-master/emsdk update
emsdk-master/emsdk install latest emsdk-master/emsdk install 3.1.37
emsdk-master/emsdk activate latest emsdk-master/emsdk activate 3.1.37
- name: Build example_sdl2_opengl3 with Emscripten - name: Build example_sdl2_opengl3 with Emscripten
run: | run: |
@ -489,17 +489,17 @@ jobs:
popd popd
make -C examples/example_sdl2_opengl3 -f Makefile.emscripten make -C examples/example_sdl2_opengl3 -f Makefile.emscripten
- name: Build example_glfw_wgpu - name: Build example_emscripten_wgpu
run: | run: |
pushd emsdk-master pushd emsdk-master
source ./emsdk_env.sh source ./emsdk_env.sh
popd popd
make -C examples/example_glfw_wgpu -f Makefile.emscripten make -C examples/example_emscripten_wgpu
Android: Android:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Build example_android_opengl3 - name: Build example_android_opengl3
run: | run: |

View File

@ -12,7 +12,7 @@ jobs:
PVS-Studio: PVS-Studio:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
fetch-depth: 1 fetch-depth: 1

View File

@ -8,6 +8,7 @@ imgui.ini
*.o *.o
*.obj *.obj
*.exe *.exe
examples/build/*
examples/*/Debug/* examples/*/Debug/*
examples/*/Release/* examples/*/Release/*
examples/*/x64/* examples/*/x64/*
@ -29,7 +30,7 @@ ipch
JSON/ JSON/
## Commonly used CMake directories ## Commonly used CMake directories
build*/ /build*/
## Xcode artifacts ## Xcode artifacts
project.xcworkspace project.xcworkspace
@ -40,9 +41,8 @@ examples/*.o.tmp
examples/*.out.js examples/*.out.js
examples/*.out.wasm examples/*.out.wasm
examples/example_glfw_opengl3/web/* examples/example_glfw_opengl3/web/*
examples/example_glfw_wgpu/web/*
examples/example_glfw_wgpu/external/*
examples/example_sdl2_opengl3/web/* examples/example_sdl2_opengl3/web/*
examples/example_emscripten_wgpu/web/*
## JetBrains IDE artifacts ## JetBrains IDE artifacts
.idea .idea

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2024 Omar Cornut Copyright (c) 2014-2023 Omar Cornut
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -12,11 +12,8 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
@ -27,7 +24,7 @@
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). // 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates. // 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-12-08: Renderer: 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-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
// 2021-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events. // 2021-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events.
// 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-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: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
@ -50,11 +47,10 @@
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_allegro5.h"
#include <stdint.h> // uint64_t #include <stdint.h> // uint64_t
#include <cstring> // memcpy #include <cstring> // memcpy
#include "imgui.h"
#include "imgui_impl_allegro5.h"
// Allegro // Allegro
#include <allegro5/allegro.h> #include <allegro5/allegro.h>
@ -423,7 +419,6 @@ static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display) bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
// Setup backend capabilities flags // Setup backend capabilities flags
@ -439,9 +434,9 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion. // We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
ALLEGRO_VERTEX_ELEMENT elems[] = ALLEGRO_VERTEX_ELEMENT elems[] =
{ {
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, pos) }, { ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, IM_OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, uv) }, { ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, IM_OFFSETOF(ImDrawVertAllegro, uv) },
{ ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ImDrawVertAllegro, col) }, { ALLEGRO_PRIM_COLOR_ATTR, 0, IM_OFFSETOF(ImDrawVertAllegro, col) },
{ 0, 0, 0 } { 0, 0, 0 }
}; };
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro)); bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
@ -491,9 +486,8 @@ static void ImGui_ImplAllegro5_UpdateKeyModifiers()
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev) bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev)
{ {
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplAllegro5_Init()?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
switch (ev->type) switch (ev->type)
{ {
@ -588,7 +582,7 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
void ImGui_ImplAllegro5_NewFrame() void ImGui_ImplAllegro5_NewFrame()
{ {
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplAllegro5_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplAllegro5_Init()?");
if (!bd->Texture) if (!bd->Texture)
ImGui_ImplAllegro5_CreateDeviceObjects(); ImGui_ImplAllegro5_CreateDeviceObjects();
@ -609,7 +603,3 @@ void ImGui_ImplAllegro5_NewFrame()
// Setup mouse cursor shape // Setup mouse cursor shape
ImGui_ImplAllegro5_UpdateMouseCursor(); ImGui_ImplAllegro5_UpdateMouseCursor();
} }
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -12,15 +12,11 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ALLEGRO_DISPLAY; struct ALLEGRO_DISPLAY;
union ALLEGRO_EVENT; union ALLEGRO_EVENT;
@ -34,5 +30,3 @@ IMGUI_IMPL_API bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* event);
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplAllegro5_InvalidateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplAllegro5_InvalidateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -15,11 +15,8 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
@ -30,7 +27,6 @@
// 2021-03-04: Initial version. // 2021-03-04: Initial version.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_android.h" #include "imgui_impl_android.h"
#include <time.h> #include <time.h>
#include <android/native_window.h> #include <android/native_window.h>
@ -156,7 +152,7 @@ static ImGuiKey ImGui_ImplAndroid_KeyCodeToImGuiKey(int32_t key_code)
} }
} }
int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event) int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
int32_t event_type = AInputEvent_getType(input_event); int32_t event_type = AInputEvent_getType(input_event);
@ -183,7 +179,7 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event)
case AKEY_EVENT_ACTION_UP: case AKEY_EVENT_ACTION_UP:
{ {
ImGuiKey key = ImGui_ImplAndroid_KeyCodeToImGuiKey(event_key_code); ImGuiKey key = ImGui_ImplAndroid_KeyCodeToImGuiKey(event_key_code);
if (key != ImGuiKey_None) if (key != ImGuiKey_None && (event_action == AKEY_EVENT_ACTION_DOWN || event_action == AKEY_EVENT_ACTION_UP))
{ {
io.AddKeyEvent(key, event_action == AKEY_EVENT_ACTION_DOWN); io.AddKeyEvent(key, event_action == AKEY_EVENT_ACTION_DOWN);
io.SetKeyEventNativeData(key, event_key_code, event_scan_code); io.SetKeyEventNativeData(key, event_key_code, event_scan_code);
@ -221,27 +217,25 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event)
{ {
case AMOTION_EVENT_ACTION_DOWN: case AMOTION_EVENT_ACTION_DOWN:
case AMOTION_EVENT_ACTION_UP: case AMOTION_EVENT_ACTION_UP:
{
// Physical mouse buttons (and probably other physical devices) also invoke the actions AMOTION_EVENT_ACTION_DOWN/_UP, // Physical mouse buttons (and probably other physical devices) also invoke the actions AMOTION_EVENT_ACTION_DOWN/_UP,
// but we have to process them separately to identify the actual button pressed. This is done below via // but we have to process them separately to identify the actual button pressed. This is done below via
// AMOTION_EVENT_ACTION_BUTTON_PRESS/_RELEASE. Here, we only process "FINGER" input (and "UNKNOWN", as a fallback). // AMOTION_EVENT_ACTION_BUTTON_PRESS/_RELEASE. Here, we only process "FINGER" input (and "UNKNOWN", as a fallback).
int tool_type = AMotionEvent_getToolType(input_event, event_pointer_index); if((AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_FINGER)
if (tool_type == AMOTION_EVENT_TOOL_TYPE_FINGER || tool_type == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) || (AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_UNKNOWN))
{ {
io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
io.AddMouseButtonEvent(0, event_action == AMOTION_EVENT_ACTION_DOWN); io.AddMouseButtonEvent(0, event_action == AMOTION_EVENT_ACTION_DOWN);
} }
break; break;
}
case AMOTION_EVENT_ACTION_BUTTON_PRESS: case AMOTION_EVENT_ACTION_BUTTON_PRESS:
case AMOTION_EVENT_ACTION_BUTTON_RELEASE: case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
{ {
int32_t button_state = AMotionEvent_getButtonState(input_event); int32_t button_state = AMotionEvent_getButtonState(input_event);
io.AddMouseButtonEvent(0, (button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0); io.AddMouseButtonEvent(0, (button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0);
io.AddMouseButtonEvent(1, (button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0); io.AddMouseButtonEvent(1, (button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0);
io.AddMouseButtonEvent(2, (button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0); io.AddMouseButtonEvent(2, (button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0);
}
break; break;
}
case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse) case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse)
case AMOTION_EVENT_ACTION_MOVE: // Touch pointer moves while DOWN case AMOTION_EVENT_ACTION_MOVE: // Touch pointer moves while DOWN
io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
@ -263,8 +257,6 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event)
bool ImGui_ImplAndroid_Init(ANativeWindow* window) bool ImGui_ImplAndroid_Init(ANativeWindow* window)
{ {
IMGUI_CHECKVERSION();
g_Window = window; g_Window = window;
g_Time = 0.0; g_Time = 0.0;
@ -302,7 +294,3 @@ void ImGui_ImplAndroid_NewFrame()
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f);
g_Time = current_time; g_Time = current_time;
} }
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -15,22 +15,15 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ANativeWindow; struct ANativeWindow;
struct AInputEvent; struct AInputEvent;
IMGUI_IMPL_API bool ImGui_ImplAndroid_Init(ANativeWindow* window); IMGUI_IMPL_API bool ImGui_ImplAndroid_Init(ANativeWindow* window);
IMGUI_IMPL_API int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event); IMGUI_IMPL_API int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event);
IMGUI_IMPL_API void ImGui_ImplAndroid_Shutdown(); IMGUI_IMPL_API void ImGui_ImplAndroid_Shutdown();
IMGUI_IMPL_API void ImGui_ImplAndroid_NewFrame(); IMGUI_IMPL_API void ImGui_ImplAndroid_NewFrame();
#endif // #ifndef IMGUI_DISABLE

View File

@ -7,11 +7,8 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
@ -33,7 +30,6 @@
// 2016-05-07: DirectX10: Disabling depth-write. // 2016-05-07: DirectX10: Disabling depth-write.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx10.h" #include "imgui_impl_dx10.h"
// DirectX // DirectX
@ -414,9 +410,9 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
// Create the input layout // Create the input layout
D3D10_INPUT_ELEMENT_DESC local_layout[] = D3D10_INPUT_ELEMENT_DESC local_layout[] =
{ {
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D10_INPUT_PER_VERTEX_DATA, 0 },
}; };
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK) if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
{ {
@ -534,7 +530,6 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
bool ImGui_ImplDX10_Init(ID3D10Device* device) bool ImGui_ImplDX10_Init(ID3D10Device* device)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags
@ -579,12 +574,8 @@ void ImGui_ImplDX10_Shutdown()
void ImGui_ImplDX10_NewFrame() void ImGui_ImplDX10_NewFrame()
{ {
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX10_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX10_Init()?");
if (!bd->pFontSampler) if (!bd->pFontSampler)
ImGui_ImplDX10_CreateDeviceObjects(); ImGui_ImplDX10_CreateDeviceObjects();
} }
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -5,17 +5,13 @@
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! // [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) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ID3D10Device; struct ID3D10Device;
@ -27,5 +23,3 @@ IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -7,11 +7,8 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
@ -34,7 +31,6 @@
// 2016-05-07: DirectX11: Disabling depth-write. // 2016-05-07: DirectX11: Disabling depth-write.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx11.h" #include "imgui_impl_dx11.h"
// DirectX // DirectX
@ -426,9 +422,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
// Create the input layout // Create the input layout
D3D11_INPUT_ELEMENT_DESC local_layout[] = D3D11_INPUT_ELEMENT_DESC local_layout[] =
{ {
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
}; };
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK) if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
{ {
@ -546,7 +542,6 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context) bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags
@ -595,12 +590,8 @@ void ImGui_ImplDX11_Shutdown()
void ImGui_ImplDX11_NewFrame() void ImGui_ImplDX11_NewFrame()
{ {
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX11_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX11_Init()?");
if (!bd->pFontSampler) if (!bd->pFontSampler)
ImGui_ImplDX11_CreateDeviceObjects(); ImGui_ImplDX11_CreateDeviceObjects();
} }
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -5,17 +5,13 @@
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! // [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) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ID3D11Device; struct ID3D11Device;
struct ID3D11DeviceContext; struct ID3D11DeviceContext;
@ -28,5 +24,3 @@ IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -15,11 +15,8 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
@ -42,7 +39,6 @@
// 2018-02-22: Merged into master with all Win32 code synchronized to other examples. // 2018-02-22: Merged into master with all Win32 code synchronized to other examples.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx12.h" #include "imgui_impl_dx12.h"
// DirectX // DirectX
@ -592,9 +588,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
// Create the input layout // Create the input layout
static D3D12_INPUT_ELEMENT_DESC local_layout[] = static D3D12_INPUT_ELEMENT_DESC local_layout[] =
{ {
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
}; };
psoDesc.InputLayout = { local_layout, 3 }; psoDesc.InputLayout = { local_layout, 3 };
} }
@ -702,7 +698,6 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags
@ -751,12 +746,8 @@ void ImGui_ImplDX12_Shutdown()
void ImGui_ImplDX12_NewFrame() void ImGui_ImplDX12_NewFrame()
{ {
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX12_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX12_Init()?");
if (!bd->pPipelineState) if (!bd->pPipelineState)
ImGui_ImplDX12_CreateDeviceObjects(); ImGui_ImplDX12_CreateDeviceObjects();
} }
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -10,15 +10,11 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
#include <dxgiformat.h> // DXGI_FORMAT #include <dxgiformat.h> // DXGI_FORMAT
struct ID3D12Device; struct ID3D12Device;
@ -40,5 +36,3 @@ IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -7,15 +7,11 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 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. // 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-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-06-25: DirectX9: Explicitly disable texture state stages after >= 1. // 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1.
@ -36,7 +32,6 @@
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx9.h" #include "imgui_impl_dx9.h"
// DirectX // DirectX
@ -285,7 +280,6 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags
@ -314,24 +308,6 @@ void ImGui_ImplDX9_Shutdown()
IM_DELETE(bd); IM_DELETE(bd);
} }
static bool ImGui_ImplDX9_CheckFormatSupport(IDirect3DDevice9* pDevice, D3DFORMAT format)
{
IDirect3D9* pd3d = nullptr;
if (pDevice->GetDirect3D(&pd3d) != D3D_OK)
return false;
D3DDEVICE_CREATION_PARAMETERS param = {};
D3DDISPLAYMODE mode = {};
if (pDevice->GetCreationParameters(&param) != 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;
}
static bool ImGui_ImplDX9_CreateFontsTexture() static bool ImGui_ImplDX9_CreateFontsTexture()
{ {
// Build texture atlas // Build texture atlas
@ -343,21 +319,18 @@ static bool ImGui_ImplDX9_CreateFontsTexture()
// Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices) // Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
#ifndef IMGUI_USE_BGRA_PACKED_COLOR #ifndef IMGUI_USE_BGRA_PACKED_COLOR
const bool rgba_support = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8); if (io.Fonts->TexPixelsUseColors)
if (!rgba_support && io.Fonts->TexPixelsUseColors)
{ {
ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel); 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++) 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); *dst = IMGUI_COL_TO_DX9_ARGB(*src);
pixels = (unsigned char*)dst_start; pixels = (unsigned char*)dst_start;
} }
#else
const bool rgba_support = false;
#endif #endif
// Upload texture to graphics system // Upload texture to graphics system
bd->FontTexture = nullptr; 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, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0)
return false; return false;
D3DLOCKED_RECT tex_locked_rect; D3DLOCKED_RECT tex_locked_rect;
if (bd->FontTexture->LockRect(0, &tex_locked_rect, nullptr, 0) != D3D_OK) if (bd->FontTexture->LockRect(0, &tex_locked_rect, nullptr, 0) != D3D_OK)
@ -370,7 +343,7 @@ static bool ImGui_ImplDX9_CreateFontsTexture()
io.Fonts->SetTexID((ImTextureID)bd->FontTexture); io.Fonts->SetTexID((ImTextureID)bd->FontTexture);
#ifndef IMGUI_USE_BGRA_PACKED_COLOR #ifndef IMGUI_USE_BGRA_PACKED_COLOR
if (!rgba_support && io.Fonts->TexPixelsUseColors) if (io.Fonts->TexPixelsUseColors)
ImGui::MemFree(pixels); ImGui::MemFree(pixels);
#endif #endif
@ -400,12 +373,8 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
void ImGui_ImplDX9_NewFrame() void ImGui_ImplDX9_NewFrame()
{ {
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX9_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX9_Init()?");
if (!bd->FontTexture) if (!bd->FontTexture)
ImGui_ImplDX9_CreateDeviceObjects(); ImGui_ImplDX9_CreateDeviceObjects();
} }
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -5,17 +5,13 @@
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID! // [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) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct IDirect3DDevice9; struct IDirect3DDevice9;
@ -27,5 +23,3 @@ IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -12,17 +12,11 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 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)
// 2023-06-12: Accept glfwGetTime() not returning a monotonically increasing value. This seems to happens on some Windows setup when peripherals disconnect, and is likely to also happen on browser + Emscripten. (#6491) // 2023-06-12: Accept glfwGetTime() not returning a monotonically increasing value. This seems to happens on some Windows setup when peripherals disconnect, and is likely to also happen on browser + Emscripten. (#6491)
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen on Windows ONLY, using a custom WndProc hook. (#2702) // 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen on Windows ONLY, using a custom WndProc hook. (#2702)
// 2023-03-16: Inputs: Fixed key modifiers handling on secondary viewports (docking branch). Broken on 2023/01/04. (#6248, #6034) // 2023-03-16: Inputs: Fixed key modifiers handling on secondary viewports (docking branch). Broken on 2023/01/04. (#6248, #6034)
@ -33,7 +27,7 @@
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785) // 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 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). // 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
// 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position *EDIT* Reverted 2023-07-18. // 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position.
// 2022-04-30: Inputs: Fixed ImGui_ImplGlfw_TranslateUntranslatedKey() for lower case letters on OSX. // 2022-04-30: Inputs: Fixed ImGui_ImplGlfw_TranslateUntranslatedKey() for lower case letters on OSX.
// 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11. // 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11.
// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend. // 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend.
@ -70,7 +64,6 @@
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. // 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_glfw.h" #include "imgui_impl_glfw.h"
// Clang warnings with -Weverything // Clang warnings with -Weverything
@ -85,15 +78,11 @@
#ifdef _WIN32 #ifdef _WIN32
#undef APIENTRY #undef APIENTRY
#ifndef GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WIN32 #define GLFW_EXPOSE_NATIVE_WIN32
#endif
#include <GLFW/glfw3native.h> // for glfwGetWin32Window() #include <GLFW/glfw3native.h> // for glfwGetWin32Window()
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
#ifndef GLFW_EXPOSE_NATIVE_COCOA
#define GLFW_EXPOSE_NATIVE_COCOA #define GLFW_EXPOSE_NATIVE_COCOA
#endif
#include <GLFW/glfw3native.h> // for glfwGetCocoaWindow() #include <GLFW/glfw3native.h> // for glfwGetCocoaWindow()
#endif #endif
@ -118,7 +107,7 @@ enum GlfwClientApi
{ {
GlfwClientApi_Unknown, GlfwClientApi_Unknown,
GlfwClientApi_OpenGL, GlfwClientApi_OpenGL,
GlfwClientApi_Vulkan, GlfwClientApi_Vulkan
}; };
struct ImGui_ImplGlfw_Data struct ImGui_ImplGlfw_Data
@ -131,9 +120,6 @@ struct ImGui_ImplGlfw_Data
ImVec2 LastValidMousePos; ImVec2 LastValidMousePos;
bool InstalledCallbacks; bool InstalledCallbacks;
bool CallbacksChainForAllWindows; bool CallbacksChainForAllWindows;
#ifdef __EMSCRIPTEN__
const char* CanvasSelector;
#endif
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any. // Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
GLFWwindowfocusfun PrevUserCallbackWindowFocus; GLFWwindowfocusfun PrevUserCallbackWindowFocus;
@ -283,18 +269,6 @@ static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
case GLFW_KEY_F10: return ImGuiKey_F10; case GLFW_KEY_F10: return ImGuiKey_F10;
case GLFW_KEY_F11: return ImGuiKey_F11; case GLFW_KEY_F11: return ImGuiKey_F11;
case GLFW_KEY_F12: return ImGuiKey_F12; case GLFW_KEY_F12: return ImGuiKey_F12;
case GLFW_KEY_F13: return ImGuiKey_F13;
case GLFW_KEY_F14: return ImGuiKey_F14;
case GLFW_KEY_F15: return ImGuiKey_F15;
case GLFW_KEY_F16: return ImGuiKey_F16;
case GLFW_KEY_F17: return ImGuiKey_F17;
case GLFW_KEY_F18: return ImGuiKey_F18;
case GLFW_KEY_F19: return ImGuiKey_F19;
case GLFW_KEY_F20: return ImGuiKey_F20;
case GLFW_KEY_F21: return ImGuiKey_F21;
case GLFW_KEY_F22: return ImGuiKey_F22;
case GLFW_KEY_F23: return ImGuiKey_F23;
case GLFW_KEY_F24: return ImGuiKey_F24;
default: return ImGuiKey_None; default: return ImGuiKey_None;
} }
} }
@ -411,6 +385,8 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window)) if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
bd->PrevUserCallbackCursorPos(window, x, y); bd->PrevUserCallbackCursorPos(window, x, y);
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
return;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.AddMousePosEvent((float)x, (float)y); io.AddMousePosEvent((float)x, (float)y);
@ -424,6 +400,8 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
if (bd->PrevUserCallbackCursorEnter != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window)) if (bd->PrevUserCallbackCursorEnter != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
bd->PrevUserCallbackCursorEnter(window, entered); bd->PrevUserCallbackCursorEnter(window, entered);
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
return;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if (entered) if (entered)
@ -497,7 +475,7 @@ static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wPara
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo()); ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
break; break;
} }
return ::CallWindowProcW(bd->GlfwWndProc, hWnd, msg, wParam, lParam); return ::CallWindowProc(bd->GlfwWndProc, hWnd, msg, wParam, lParam);
} }
#endif #endif
@ -556,7 +534,6 @@ void ImGui_ImplGlfw_SetCallbacksChainForAllWindows(bool chain_for_all_windows)
static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api) static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
//printf("GLFW_VERSION: %d.%d.%d (%d)", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION, GLFW_VERSION_COMBINED); //printf("GLFW_VERSION: %d.%d.%d (%d)", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION, GLFW_VERSION_COMBINED);
@ -622,9 +599,9 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
// Windows: register a WndProc hook so we can intercept some messages. // Windows: register a WndProc hook so we can intercept some messages.
#ifdef _WIN32 #ifdef _WIN32
bd->GlfwWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC); bd->GlfwWndProc = (WNDPROC)::GetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
IM_ASSERT(bd->GlfwWndProc != nullptr); IM_ASSERT(bd->GlfwWndProc != nullptr);
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc); ::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
#endif #endif
bd->ClientApi = client_api; bd->ClientApi = client_api;
@ -654,9 +631,6 @@ void ImGui_ImplGlfw_Shutdown()
if (bd->InstalledCallbacks) if (bd->InstalledCallbacks)
ImGui_ImplGlfw_RestoreCallbacks(bd->Window); ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
#ifdef __EMSCRIPTEN__
emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, false, nullptr);
#endif
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
glfwDestroyCursor(bd->MouseCursors[cursor_n]); glfwDestroyCursor(bd->MouseCursors[cursor_n]);
@ -664,7 +638,7 @@ void ImGui_ImplGlfw_Shutdown()
// Windows: register a WndProc hook so we can intercept some messages. // Windows: register a WndProc hook so we can intercept some messages.
#ifdef _WIN32 #ifdef _WIN32
ImGuiViewport* main_viewport = ImGui::GetMainViewport(); ImGuiViewport* main_viewport = ImGui::GetMainViewport();
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->GlfwWndProc); ::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->GlfwWndProc);
bd->GlfwWndProc = nullptr; bd->GlfwWndProc = nullptr;
#endif #endif
@ -679,9 +653,16 @@ static void ImGui_ImplGlfw_UpdateMouseData()
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if (glfwGetInputMode(bd->Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
{
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
return;
}
// (those braces are here to reduce diff with multi-viewports support in 'docking' branch) // (those braces are here to reduce diff with multi-viewports support in 'docking' branch)
{ {
GLFWwindow* window = bd->Window; GLFWwindow* window = bd->Window;
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
const bool is_window_focused = true; const bool is_window_focused = true;
#else #else
@ -788,7 +769,7 @@ void ImGui_ImplGlfw_NewFrame()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplGlfw_InitForXXX()?");
// Setup display size (every frame to accommodate for window resizing) // Setup display size (every frame to accommodate for window resizing)
int w, h; int w, h;
@ -814,46 +795,6 @@ void ImGui_ImplGlfw_NewFrame()
ImGui_ImplGlfw_UpdateGamepads(); ImGui_ImplGlfw_UpdateGamepads();
} }
#ifdef __EMSCRIPTEN__
static EM_BOOL ImGui_ImplGlfw_OnCanvasSizeChange(int event_type, const EmscriptenUiEvent* event, void* user_data)
{
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
double canvas_width, canvas_height;
emscripten_get_element_css_size(bd->CanvasSelector, &canvas_width, &canvas_height);
glfwSetWindowSize(bd->Window, (int)canvas_width, (int)canvas_height);
return true;
}
static EM_BOOL ImGui_ImplEmscripten_FullscreenChangeCallback(int event_type, const EmscriptenFullscreenChangeEvent* event, void* user_data)
{
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
double canvas_width, canvas_height;
emscripten_get_element_css_size(bd->CanvasSelector, &canvas_width, &canvas_height);
glfwSetWindowSize(bd->Window, (int)canvas_width, (int)canvas_height);
return true;
}
// '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)
{
IM_ASSERT(canvas_selector != nullptr);
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?");
bd->CanvasSelector = canvas_selector;
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, bd, false, ImGui_ImplGlfw_OnCanvasSizeChange);
emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, bd, false, ImGui_ImplEmscripten_FullscreenChangeCallback);
// Change the size of the GLFW window according to the size of the canvas
ImGui_ImplGlfw_OnCanvasSizeChange(EMSCRIPTEN_EVENT_RESIZE, {}, bd);
}
#endif
//-----------------------------------------------------------------------------
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -11,15 +11,11 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct GLFWwindow; struct GLFWwindow;
struct GLFWmonitor; struct GLFWmonitor;
@ -30,11 +26,6 @@ IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool ins
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown(); IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame(); IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();
// Emscripten related initialization phase methods
#ifdef __EMSCRIPTEN__
IMGUI_IMPL_API void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector);
#endif
// GLFW callbacks install // GLFW callbacks install
// - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any. // - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any.
// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks. // - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks.
@ -54,5 +45,3 @@ IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double
IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c);
IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event); IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event);
#endif // #ifndef IMGUI_DISABLE

View File

@ -16,11 +16,8 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
@ -35,7 +32,6 @@
// 2018-03-22: Added GLUT Platform binding. // 2018-03-22: Added GLUT Platform binding.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_glut.h" #include "imgui_impl_glut.h"
#define GL_SILENCE_DEPRECATION #define GL_SILENCE_DEPRECATION
#ifdef __APPLE__ #ifdef __APPLE__
@ -167,7 +163,6 @@ static ImGuiKey ImGui_ImplGLUT_KeyToImGuiKey(int key)
bool ImGui_ImplGLUT_Init() bool ImGui_ImplGLUT_Init()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
#ifdef FREEGLUT #ifdef FREEGLUT
io.BackendPlatformName = "imgui_impl_glut (freeglut)"; io.BackendPlatformName = "imgui_impl_glut (freeglut)";
@ -303,7 +298,3 @@ void ImGui_ImplGLUT_MotionFunc(int x, int y)
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.AddMousePosEvent((float)x, (float)y); io.AddMousePosEvent((float)x, (float)y);
} }
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -16,14 +16,10 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#ifndef IMGUI_DISABLE
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
IMGUI_IMPL_API bool ImGui_ImplGLUT_Init(); IMGUI_IMPL_API bool ImGui_ImplGLUT_Init();
@ -33,7 +29,7 @@ IMGUI_IMPL_API void ImGui_ImplGLUT_NewFrame();
// You can call ImGui_ImplGLUT_InstallFuncs() to get all those functions installed automatically, // You can call ImGui_ImplGLUT_InstallFuncs() to get all those functions installed automatically,
// or call them yourself from your own GLUT handlers. We are using the same weird names as GLUT for consistency.. // or call them yourself from your own GLUT handlers. We are using the same weird names as GLUT for consistency..
//------------------------------------ GLUT name ---------------------------------------------- Decent Name --------- //---------------------------------------- GLUT name --------------------------------------------- Decent Name ---------
IMGUI_IMPL_API void ImGui_ImplGLUT_ReshapeFunc(int w, int h); // ~ ResizeFunc IMGUI_IMPL_API void ImGui_ImplGLUT_ReshapeFunc(int w, int h); // ~ ResizeFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_MotionFunc(int x, int y); // ~ MouseMoveFunc IMGUI_IMPL_API void ImGui_ImplGLUT_MotionFunc(int x, int y); // ~ MouseMoveFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_MouseFunc(int button, int state, int x, int y); // ~ MouseButtonFunc IMGUI_IMPL_API void ImGui_ImplGLUT_MouseFunc(int button, int state, int x, int y); // ~ MouseButtonFunc
@ -42,5 +38,3 @@ IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int
IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y); // ~ CharReleasedFunc IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y); // ~ CharReleasedFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y); // ~ KeyPressedFunc IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y); // ~ KeyPressedFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y); // ~ KeyReleasedFunc IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y); // ~ KeyReleasedFunc
#endif // #ifndef IMGUI_DISABLE

View File

@ -5,16 +5,12 @@
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID! // [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) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// ObjC API // ObjC API
@ -66,7 +62,3 @@ IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects();
#endif #endif
#endif #endif
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -7,11 +7,8 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
@ -33,7 +30,6 @@
// 2018-07-05: Metal: Added new Metal backend implementation. // 2018-07-05: Metal: Added new Metal backend implementation.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_metal.h" #include "imgui_impl_metal.h"
#import <time.h> #import <time.h>
#import <Metal/Metal.h> #import <Metal/Metal.h>
@ -79,6 +75,7 @@ struct ImGui_ImplMetal_Data
ImGui_ImplMetal_Data() { memset(this, 0, sizeof(*this)); } ImGui_ImplMetal_Data() { memset(this, 0, sizeof(*this)); }
}; };
static ImGui_ImplMetal_Data* ImGui_ImplMetal_CreateBackendData() { return IM_NEW(ImGui_ImplMetal_Data)(); }
static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; } static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; }
static void ImGui_ImplMetal_DestroyBackendData(){ IM_DELETE(ImGui_ImplMetal_GetBackendData()); } static void ImGui_ImplMetal_DestroyBackendData(){ IM_DELETE(ImGui_ImplMetal_GetBackendData()); }
@ -124,11 +121,8 @@ bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device)
bool ImGui_ImplMetal_Init(id<MTLDevice> device) bool ImGui_ImplMetal_Init(id<MTLDevice> device)
{ {
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_CreateBackendData();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
ImGui_ImplMetal_Data* bd = IM_NEW(ImGui_ImplMetal_Data)();
io.BackendRendererUserData = (void*)bd; io.BackendRendererUserData = (void*)bd;
io.BackendRendererName = "imgui_impl_metal"; io.BackendRendererName = "imgui_impl_metal";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
@ -155,7 +149,7 @@ void ImGui_ImplMetal_Shutdown()
void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor) void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor)
{ {
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData(); ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
IM_ASSERT(bd != nil && "Context or backend not initialized! Did you call ImGui_ImplMetal_Init()?"); IM_ASSERT(bd->SharedMetalContext != nil && "No Metal context. Did you call ImGui_ImplMetal_Init() ?");
bd->SharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor]; bd->SharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor];
if (bd->SharedMetalContext.depthStencilState == nil) if (bd->SharedMetalContext.depthStencilState == nil)
@ -549,13 +543,13 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
} }
MTLVertexDescriptor* vertexDescriptor = [MTLVertexDescriptor vertexDescriptor]; MTLVertexDescriptor* vertexDescriptor = [MTLVertexDescriptor vertexDescriptor];
vertexDescriptor.attributes[0].offset = offsetof(ImDrawVert, pos); vertexDescriptor.attributes[0].offset = IM_OFFSETOF(ImDrawVert, pos);
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; // position vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; // position
vertexDescriptor.attributes[0].bufferIndex = 0; vertexDescriptor.attributes[0].bufferIndex = 0;
vertexDescriptor.attributes[1].offset = offsetof(ImDrawVert, uv); vertexDescriptor.attributes[1].offset = IM_OFFSETOF(ImDrawVert, uv);
vertexDescriptor.attributes[1].format = MTLVertexFormatFloat2; // texCoords vertexDescriptor.attributes[1].format = MTLVertexFormatFloat2; // texCoords
vertexDescriptor.attributes[1].bufferIndex = 0; vertexDescriptor.attributes[1].bufferIndex = 0;
vertexDescriptor.attributes[2].offset = offsetof(ImDrawVert, col); vertexDescriptor.attributes[2].offset = IM_OFFSETOF(ImDrawVert, col);
vertexDescriptor.attributes[2].format = MTLVertexFormatUChar4; // color vertexDescriptor.attributes[2].format = MTLVertexFormatUChar4; // color
vertexDescriptor.attributes[2].bufferIndex = 0; vertexDescriptor.attributes[2].bufferIndex = 0;
vertexDescriptor.layouts[0].stepRate = 1; vertexDescriptor.layouts[0].stepRate = 1;
@ -586,7 +580,3 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
} }
@end @end
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -6,11 +6,8 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** // **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
// **Prefer using the code in imgui_impl_opengl3.cpp** // **Prefer using the code in imgui_impl_opengl3.cpp**
@ -23,7 +20,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 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-12-08: OpenGL: Fixed mishandling of the 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). // 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: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications. // 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
@ -40,9 +37,12 @@
// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. // 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_opengl2.h" #include "imgui_impl_opengl2.h"
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t #include <stdint.h> // intptr_t
#endif
// Clang/GCC warnings with -Weverything // Clang/GCC warnings with -Weverything
#if defined(__clang__) #if defined(__clang__)
@ -83,7 +83,6 @@ static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
bool ImGui_ImplOpenGL2_Init() bool ImGui_ImplOpenGL2_Init()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags
@ -109,7 +108,7 @@ void ImGui_ImplOpenGL2_Shutdown()
void ImGui_ImplOpenGL2_NewFrame() void ImGui_ImplOpenGL2_NewFrame()
{ {
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL2_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplOpenGL2_Init()?");
if (!bd->FontTexture) if (!bd->FontTexture)
ImGui_ImplOpenGL2_CreateDeviceObjects(); ImGui_ImplOpenGL2_CreateDeviceObjects();
@ -192,9 +191,9 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* cmd_list = draw_data->CmdLists[n];
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos))); glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos)));
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv))); glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv)));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col))); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col)));
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{ {
@ -294,10 +293,6 @@ void ImGui_ImplOpenGL2_DestroyDeviceObjects()
ImGui_ImplOpenGL2_DestroyFontsTexture(); ImGui_ImplOpenGL2_DestroyFontsTexture();
} }
//-----------------------------------------------------------------------------
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -4,13 +4,10 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** // **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
// **Prefer using the code in imgui_impl_opengl3.cpp** // **Prefer using the code in imgui_impl_opengl3.cpp**
@ -22,7 +19,6 @@
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init(); IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init();
IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown(); IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown();
@ -34,5 +30,3 @@ IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture(); IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -14,19 +14,11 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 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.
// 2023-11-08: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead of "libGL.so.1", accommodating for NetBSD systems having only "libGL.so.3" available. (#6983)
// 2023-10-05: OpenGL: Rename symbols in our internal loader so that LTO compilation with another copy of gl3w is possible. (#6875, #6668, #4445)
// 2023-06-20: OpenGL: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts lower than 3.2. (#6539, #6333) // 2023-06-20: OpenGL: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts lower than 3.2. (#6539, #6333)
// 2023-05-09: OpenGL: Support for glBindSampler() backup/restore on ES3. (#6375) // 2023-05-09: OpenGL: Support for glBindSampler() backup/restore on ES3. (#6375)
// 2023-04-18: OpenGL: Restore front and back polygon mode separately when supported by context. (#6333) // 2023-04-18: OpenGL: Restore front and back polygon mode separately when supported by context. (#6333)
@ -112,10 +104,13 @@
#endif #endif
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_opengl3.h" #include "imgui_impl_opengl3.h"
#include <stdio.h> #include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t #include <stdint.h> // intptr_t
#endif
#if defined(__APPLE__) #if defined(__APPLE__)
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
@ -178,21 +173,9 @@
#define GL_VERTEX_ARRAY_BINDING GL_VERTEX_ARRAY_BINDING_OES #define GL_VERTEX_ARRAY_BINDING GL_VERTEX_ARRAY_BINDING_OES
#endif #endif
// Desktop GL 2.0+ has extension and glPolygonMode() which GL ES and WebGL don't have.. // Desktop GL 2.0+ has glPolygonMode() which GL ES and WebGL don't have.
// A desktop ES context can technically compile fine with our loader, so we also perform a runtime checks #ifdef GL_POLYGON_MODE
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) #define IMGUI_IMPL_HAS_POLYGON_MODE
#define IMGUI_IMPL_OPENGL_HAS_EXTENSIONS // has glGetIntegerv(GL_NUM_EXTENSIONS)
#define IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE // may have glPolygonMode()
#endif
// Desktop GL 2.1+ and GL ES 3.0+ have glBindBuffer() with GL_PIXEL_UNPACK_BUFFER target.
#if !defined(IMGUI_IMPL_OPENGL_ES2)
#define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
#endif
// Desktop GL 3.1+ has GL_PRIMITIVE_RESTART state
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_1)
#define IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
#endif #endif
// Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have. // Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have.
@ -205,6 +188,16 @@
#define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER #define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
#endif #endif
// Desktop GL 3.1+ has GL_PRIMITIVE_RESTART state
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_1)
#define IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
#endif
// Desktop GL use extension detection
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
#define IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS
#endif
// [Debugging] // [Debugging]
//#define IMGUI_IMPL_OPENGL_DEBUG //#define IMGUI_IMPL_OPENGL_DEBUG
#ifdef IMGUI_IMPL_OPENGL_DEBUG #ifdef IMGUI_IMPL_OPENGL_DEBUG
@ -233,7 +226,6 @@ struct ImGui_ImplOpenGL3_Data
unsigned int VboHandle, ElementsHandle; unsigned int VboHandle, ElementsHandle;
GLsizeiptr VertexBufferSize; GLsizeiptr VertexBufferSize;
GLsizeiptr IndexBufferSize; GLsizeiptr IndexBufferSize;
bool HasPolygonMode;
bool HasClipOrigin; bool HasClipOrigin;
bool UseBufferSubData; bool UseBufferSubData;
@ -275,7 +267,6 @@ struct ImGui_ImplOpenGL3_VtxAttribState
bool ImGui_ImplOpenGL3_Init(const char* glsl_version) bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Initialize our loader // Initialize our loader
@ -299,13 +290,16 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
bd->GlProfileIsES2 = true; bd->GlProfileIsES2 = true;
#else #else
// Desktop or GLES 3 // Desktop or GLES 3
const char* gl_version_str = (const char*)glGetString(GL_VERSION);
GLint major = 0; GLint major = 0;
GLint minor = 0; GLint minor = 0;
glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MAJOR_VERSION, &major);
glGetIntegerv(GL_MINOR_VERSION, &minor); glGetIntegerv(GL_MINOR_VERSION, &minor);
if (major == 0 && minor == 0) if (major == 0 && minor == 0)
sscanf(gl_version_str, "%d.%d", &major, &minor); // Query GL_VERSION in desktop GL 2.x, the string will start with "<major>.<minor>" {
// Query GL_VERSION in desktop GL 2.x, the string will start with "<major>.<minor>"
const char* gl_version = (const char*)glGetString(GL_VERSION);
sscanf(gl_version, "%d.%d", &major, &minor);
}
bd->GlVersion = (GLuint)(major * 100 + minor * 10); bd->GlVersion = (GLuint)(major * 100 + minor * 10);
#if defined(GL_CONTEXT_PROFILE_MASK) #if defined(GL_CONTEXT_PROFILE_MASK)
if (bd->GlVersion >= 320) if (bd->GlVersion >= 320)
@ -315,9 +309,6 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
#if defined(IMGUI_IMPL_OPENGL_ES3) #if defined(IMGUI_IMPL_OPENGL_ES3)
bd->GlProfileIsES3 = true; bd->GlProfileIsES3 = true;
#else
if (strncmp(gl_version_str, "OpenGL ES 3", 11) == 0)
bd->GlProfileIsES3 = true;
#endif #endif
bd->UseBufferSubData = false; bd->UseBufferSubData = false;
@ -332,7 +323,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
#endif #endif
#ifdef IMGUI_IMPL_OPENGL_DEBUG #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\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2 = %d, GlProfileIsES3 = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
#endif #endif
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
@ -364,11 +355,8 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture); glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
// Detect extensions we support // Detect extensions we support
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
bd->HasPolygonMode = (!bd->GlProfileIsES2 && !bd->GlProfileIsES3);
#endif
bd->HasClipOrigin = (bd->GlVersion >= 450); bd->HasClipOrigin = (bd->GlVersion >= 450);
#ifdef IMGUI_IMPL_OPENGL_HAS_EXTENSIONS #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS
GLint num_extensions = 0; GLint num_extensions = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions); glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
for (GLint i = 0; i < num_extensions; i++) for (GLint i = 0; i < num_extensions; i++)
@ -398,7 +386,7 @@ void ImGui_ImplOpenGL3_Shutdown()
void ImGui_ImplOpenGL3_NewFrame() void ImGui_ImplOpenGL3_NewFrame()
{ {
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL3_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplOpenGL3_Init()?");
if (!bd->ShaderHandle) if (!bd->ShaderHandle)
ImGui_ImplOpenGL3_CreateDeviceObjects(); ImGui_ImplOpenGL3_CreateDeviceObjects();
@ -420,9 +408,8 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
if (bd->GlVersion >= 310) if (bd->GlVersion >= 310)
glDisable(GL_PRIMITIVE_RESTART); glDisable(GL_PRIMITIVE_RESTART);
#endif #endif
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE #ifdef IMGUI_IMPL_HAS_POLYGON_MODE
if (bd->HasPolygonMode) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif #endif
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
@ -473,9 +460,9 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxPos)); GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxPos));
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxUV)); GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxUV));
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxColor)); GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxColor));
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, pos))); GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)));
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, uv))); GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)));
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, col))); GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)));
} }
// OpenGL3 Render function. // OpenGL3 Render function.
@ -510,8 +497,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object); GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object);
#endif #endif
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE #ifdef IMGUI_IMPL_HAS_POLYGON_MODE
GLint last_polygon_mode[2]; if (bd->HasPolygonMode) { glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); } GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
#endif #endif
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
@ -649,10 +636,18 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
if (bd->GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); } if (bd->GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); }
#endif #endif
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE #ifdef IMGUI_IMPL_HAS_POLYGON_MODE
// Desktop OpenGL 3.0 and OpenGL 3.1 had separate polygon draw modes for front-facing and back-facing faces of polygons // Desktop OpenGL 3.0 and OpenGL 3.1 had separate polygon draw modes for front-facing and back-facing faces of polygons
if (bd->HasPolygonMode) { if (bd->GlVersion <= 310 || bd->GlProfileIsCompat) { glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); } else { glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); } } if (bd->GlVersion <= 310 || bd->GlProfileIsCompat)
#endif // IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE {
glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]);
glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
}
#endif // IMGUI_IMPL_HAS_POLYGON_MODE
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
@ -749,10 +744,6 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
GLint last_texture, last_array_buffer; GLint last_texture, last_array_buffer;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
GLint last_pixel_unpack_buffer = 0;
if (bd->GlVersion >= 210) { glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &last_pixel_unpack_buffer); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); }
#endif
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
GLint last_vertex_array; GLint last_vertex_array;
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@ -926,9 +917,6 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
// Restore modified GL state // Restore modified GL state
glBindTexture(GL_TEXTURE_2D, last_texture); glBindTexture(GL_TEXTURE_2D, last_texture);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
if (bd->GlVersion >= 210) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, last_pixel_unpack_buffer); }
#endif
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
glBindVertexArray(last_vertex_array); glBindVertexArray(last_vertex_array);
#endif #endif
@ -945,13 +933,9 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects()
ImGui_ImplOpenGL3_DestroyFontsTexture(); ImGui_ImplOpenGL3_DestroyFontsTexture();
} }
//-----------------------------------------------------------------------------
#if defined(__GNUC__) #if defined(__GNUC__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -14,11 +14,8 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// About GLSL version: // About GLSL version:
// The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string. // The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string.
@ -27,7 +24,6 @@
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
// Backend API // Backend API
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr); IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
@ -41,9 +37,9 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
// Configuration flags to add in your imconfig file: // Specific OpenGL ES versions
//#define IMGUI_IMPL_OPENGL_ES2 // Enable ES 2 (Auto-detected on Emscripten) //#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
//#define IMGUI_IMPL_OPENGL_ES3 // Enable ES 3 (Auto-detected on iOS/Android) //#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
// You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line. // You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
#if !defined(IMGUI_IMPL_OPENGL_ES2) \ #if !defined(IMGUI_IMPL_OPENGL_ES2) \
@ -62,5 +58,3 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
#endif #endif
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -10,7 +10,7 @@
// THE REST OF YOUR APP SHOULD USE A DIFFERENT GL LOADER: ANY GL LOADER OF YOUR CHOICE. // THE REST OF YOUR APP SHOULD USE A DIFFERENT GL LOADER: ANY GL LOADER OF YOUR CHOICE.
// //
// IF YOU GET BUILD ERRORS IN THIS FILE (commonly macro redefinitions or function redefinitions): // IF YOU GET BUILD ERRORS IN THIS FILE (commonly macro redefinitions or function redefinitions):
// IT LIKELY MEANS THAT YOU ARE BUILDING 'imgui_impl_opengl3.cpp' OR INCLUDING 'imgui_impl_opengl3_loader.h' // IT LIKELY MEANS THAT YOU ARE BUILDING 'imgui_impl_opengl3.cpp' OR INCUDING 'imgui_impl_opengl3_loader.h'
// IN THE SAME COMPILATION UNIT AS ONE OF YOUR FILE WHICH IS USING A THIRD-PARTY OPENGL LOADER. // IN THE SAME COMPILATION UNIT AS ONE OF YOUR FILE WHICH IS USING A THIRD-PARTY OPENGL LOADER.
// (e.g. COULD HAPPEN IF YOU ARE DOING A UNITY/JUMBO BUILD, OR INCLUDING .CPP FILES FROM OTHERS) // (e.g. COULD HAPPEN IF YOU ARE DOING A UNITY/JUMBO BUILD, OR INCLUDING .CPP FILES FROM OTHERS)
// YOU SHOULD NOT BUILD BOTH IN THE SAME COMPILATION UNIT. // YOU SHOULD NOT BUILD BOTH IN THE SAME COMPILATION UNIT.
@ -18,7 +18,7 @@
// WILL NOT BE USING OUR LOADER, AND INSTEAD EXPECT ANOTHER/YOUR LOADER TO BE AVAILABLE IN THE COMPILATION UNIT. // WILL NOT BE USING OUR LOADER, AND INSTEAD EXPECT ANOTHER/YOUR LOADER TO BE AVAILABLE IN THE COMPILATION UNIT.
// //
// Regenerate with: // Regenerate with:
// python3 gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt // python gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt
// //
// More info: // More info:
// https://github.com/dearimgui/gl3w_stripped // https://github.com/dearimgui/gl3w_stripped
@ -346,10 +346,6 @@ GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean
GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
#endif #endif
#endif /* GL_VERSION_2_0 */ #endif /* GL_VERSION_2_0 */
#ifndef GL_VERSION_2_1
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
#endif /* GL_VERSION_2_1 */
#ifndef GL_VERSION_3_0 #ifndef GL_VERSION_3_0
typedef khronos_uint16_t GLhalf; typedef khronos_uint16_t GLhalf;
#define GL_MAJOR_VERSION 0x821B #define GL_MAJOR_VERSION 0x821B
@ -471,7 +467,7 @@ GL3W_API int imgl3wIsSupported(int major, int minor);
GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc); GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
/* gl3w internal state */ /* gl3w internal state */
union ImGL3WProcs { union GL3WProcs {
GL3WglProc ptr[59]; GL3WglProc ptr[59];
struct { struct {
PFNGLACTIVETEXTUREPROC ActiveTexture; PFNGLACTIVETEXTUREPROC ActiveTexture;
@ -536,7 +532,7 @@ union ImGL3WProcs {
} gl; } gl;
}; };
GL3W_API extern union ImGL3WProcs imgl3wProcs; GL3W_API extern union GL3WProcs imgl3wProcs;
/* OpenGL functions */ /* OpenGL functions */
#define glActiveTexture imgl3wProcs.gl.ActiveTexture #define glActiveTexture imgl3wProcs.gl.ActiveTexture
@ -612,7 +608,7 @@ extern "C" {
#include <stdlib.h> #include <stdlib.h>
#define GL3W_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#if defined(_WIN32) #if defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
@ -665,123 +661,26 @@ static GL3WglProc get_proc(const char *proc)
#else #else
#include <dlfcn.h> #include <dlfcn.h>
static void* libgl; // OpenGL library static void *libgl;
static void* libglx; // GLX library static GL3WglProc (*glx_get_proc_address)(const GLubyte *);
static void* libegl; // EGL library
static GL3WGetProcAddressProc gl_get_proc_address;
static void close_libgl(void)
{
if (libgl) {
dlclose(libgl);
libgl = NULL;
}
if (libegl) {
dlclose(libegl);
libegl = NULL;
}
if (libglx) {
dlclose(libglx);
libglx = NULL;
}
}
static int is_library_loaded(const char* name, void** lib)
{
*lib = dlopen(name, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
return *lib != NULL;
}
static int open_libs(void)
{
// On Linux we have two APIs to get process addresses: EGL and GLX.
// EGL is supported under both X11 and Wayland, whereas GLX is X11-specific.
libgl = NULL;
libegl = NULL;
libglx = NULL;
// First check what's already loaded, the windowing library might have
// already loaded either EGL or GLX and we want to use the same one.
if (is_library_loaded("libEGL.so.1", &libegl) ||
is_library_loaded("libGLX.so.0", &libglx)) {
libgl = dlopen("libOpenGL.so.0", RTLD_LAZY | RTLD_LOCAL);
if (libgl)
return GL3W_OK;
else
close_libgl();
}
if (is_library_loaded("libGL.so", &libgl))
return GL3W_OK;
if (is_library_loaded("libGL.so.1", &libgl))
return GL3W_OK;
if (is_library_loaded("libGL.so.3", &libgl))
return GL3W_OK;
// Neither is already loaded, so we have to load one. Try EGL first
// because it is supported under both X11 and Wayland.
// Load OpenGL + EGL
libgl = dlopen("libOpenGL.so.0", RTLD_LAZY | RTLD_LOCAL);
libegl = dlopen("libEGL.so.1", RTLD_LAZY | RTLD_LOCAL);
if (libgl && libegl)
return GL3W_OK;
else
close_libgl();
// Fall back to legacy libGL, which includes GLX
// While most systems use libGL.so.1, NetBSD seems to use that libGL.so.3. See https://github.com/ocornut/imgui/issues/6983
libgl = dlopen("libGL.so", RTLD_LAZY | RTLD_LOCAL);
if (!libgl)
libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
if (!libgl)
libgl = dlopen("libGL.so.3", RTLD_LAZY | RTLD_LOCAL);
if (libgl)
return GL3W_OK;
return GL3W_ERROR_LIBRARY_OPEN;
}
static int open_libgl(void) static int open_libgl(void)
{ {
int res = open_libs(); libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
if (res) if (!libgl)
return res;
if (libegl)
*(void**)(&gl_get_proc_address) = dlsym(libegl, "eglGetProcAddress");
else if (libglx)
*(void**)(&gl_get_proc_address) = dlsym(libglx, "glXGetProcAddressARB");
else
*(void**)(&gl_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
if (!gl_get_proc_address) {
close_libgl();
return GL3W_ERROR_LIBRARY_OPEN; return GL3W_ERROR_LIBRARY_OPEN;
} *(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
return GL3W_OK; return GL3W_OK;
} }
static GL3WglProc get_proc(const char* proc) static void close_libgl(void) { dlclose(libgl); }
static GL3WglProc get_proc(const char *proc)
{ {
GL3WglProc res = NULL; GL3WglProc res;
res = glx_get_proc_address((const GLubyte *)proc);
// Before EGL version 1.5, eglGetProcAddress doesn't support querying core
// functions and may return a dummy function if we try, so try to load the
// function from the GL library directly first.
if (libegl)
*(void**)(&res) = dlsym(libgl, proc);
if (!res) if (!res)
res = gl_get_proc_address(proc); *(void **)(&res) = dlsym(libgl, proc);
if (!libegl && !res)
*(void**)(&res) = dlsym(libgl, proc);
return res; return res;
} }
#endif #endif
@ -895,12 +794,12 @@ static const char *proc_names[] = {
"glViewport", "glViewport",
}; };
GL3W_API union ImGL3WProcs imgl3wProcs; GL3W_API union GL3WProcs imgl3wProcs;
static void load_procs(GL3WGetProcAddressProc proc) static void load_procs(GL3WGetProcAddressProc proc)
{ {
size_t i; size_t i;
for (i = 0; i < GL3W_ARRAY_SIZE(proc_names); i++) for (i = 0; i < ARRAY_SIZE(proc_names); i++)
imgl3wProcs.ptr[i] = proc(proc_names[i]); imgl3wProcs.ptr[i] = proc(proc_names[i]);
} }

View File

@ -13,14 +13,10 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
#ifdef __OBJC__ #ifdef __OBJC__
@ -47,5 +43,3 @@ IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(void* _Nullable view);
#endif #endif
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -13,14 +13,10 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#import "imgui.h" #import "imgui.h"
#ifndef IMGUI_DISABLE
#import "imgui_impl_osx.h" #import "imgui_impl_osx.h"
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h> #import <Carbon/Carbon.h>
@ -29,7 +25,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 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-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). // 2023-02-01: Fixed scroll wheel scaling for devices emitting events with hasPreciseScrollingDeltas==false (e.g. non-Apple mices).
// 2022-11-02: Fixed mouse coordinates before clicking the host window. // 2022-11-02: Fixed mouse coordinates before clicking the host window.
@ -84,6 +79,7 @@ struct ImGui_ImplOSX_Data
ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); } ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); }
}; };
static ImGui_ImplOSX_Data* ImGui_ImplOSX_CreateBackendData() { return IM_NEW(ImGui_ImplOSX_Data)(); }
static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; } static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; }
static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(ImGui_ImplOSX_GetBackendData()); } static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(ImGui_ImplOSX_GetBackendData()); }
@ -337,36 +333,36 @@ static ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
case kVK_RightOption: return ImGuiKey_RightAlt; case kVK_RightOption: return ImGuiKey_RightAlt;
case kVK_RightCommand: return ImGuiKey_RightSuper; case kVK_RightCommand: return ImGuiKey_RightSuper;
// case kVK_Function: return ImGuiKey_; // case kVK_Function: return ImGuiKey_;
// case kVK_F17: return ImGuiKey_;
// case kVK_VolumeUp: return ImGuiKey_; // case kVK_VolumeUp: return ImGuiKey_;
// case kVK_VolumeDown: return ImGuiKey_; // case kVK_VolumeDown: return ImGuiKey_;
// case kVK_Mute: return ImGuiKey_; // case kVK_Mute: return ImGuiKey_;
case kVK_F1: return ImGuiKey_F1; // case kVK_F18: return ImGuiKey_;
case kVK_F2: return ImGuiKey_F2; // case kVK_F19: return ImGuiKey_;
case kVK_F3: return ImGuiKey_F3; // case kVK_F20: return ImGuiKey_;
case kVK_F4: return ImGuiKey_F4;
case kVK_F5: return ImGuiKey_F5; case kVK_F5: return ImGuiKey_F5;
case kVK_F6: return ImGuiKey_F6; case kVK_F6: return ImGuiKey_F6;
case kVK_F7: return ImGuiKey_F7; case kVK_F7: return ImGuiKey_F7;
case kVK_F3: return ImGuiKey_F3;
case kVK_F8: return ImGuiKey_F8; case kVK_F8: return ImGuiKey_F8;
case kVK_F9: return ImGuiKey_F9; case kVK_F9: return ImGuiKey_F9;
case kVK_F10: return ImGuiKey_F10;
case kVK_F11: return ImGuiKey_F11; case kVK_F11: return ImGuiKey_F11;
case kVK_F12: return ImGuiKey_F12; case kVK_F13: return ImGuiKey_PrintScreen;
case kVK_F13: return ImGuiKey_F13; // case kVK_F16: return ImGuiKey_;
case kVK_F14: return ImGuiKey_F14; // case kVK_F14: return ImGuiKey_;
case kVK_F15: return ImGuiKey_F15; case kVK_F10: return ImGuiKey_F10;
case kVK_F16: return ImGuiKey_F16;
case kVK_F17: return ImGuiKey_F17;
case kVK_F18: return ImGuiKey_F18;
case kVK_F19: return ImGuiKey_F19;
case kVK_F20: return ImGuiKey_F20;
case 0x6E: return ImGuiKey_Menu; case 0x6E: return ImGuiKey_Menu;
case kVK_F12: return ImGuiKey_F12;
// case kVK_F15: return ImGuiKey_;
case kVK_Help: return ImGuiKey_Insert; case kVK_Help: return ImGuiKey_Insert;
case kVK_Home: return ImGuiKey_Home; case kVK_Home: return ImGuiKey_Home;
case kVK_PageUp: return ImGuiKey_PageUp; case kVK_PageUp: return ImGuiKey_PageUp;
case kVK_ForwardDelete: return ImGuiKey_Delete; case kVK_ForwardDelete: return ImGuiKey_Delete;
case kVK_F4: return ImGuiKey_F4;
case kVK_End: return ImGuiKey_End; case kVK_End: return ImGuiKey_End;
case kVK_F2: return ImGuiKey_F2;
case kVK_PageDown: return ImGuiKey_PageDown; case kVK_PageDown: return ImGuiKey_PageDown;
case kVK_F1: return ImGuiKey_F1;
case kVK_LeftArrow: return ImGuiKey_LeftArrow; case kVK_LeftArrow: return ImGuiKey_LeftArrow;
case kVK_RightArrow: return ImGuiKey_RightArrow; case kVK_RightArrow: return ImGuiKey_RightArrow;
case kVK_DownArrow: return ImGuiKey_DownArrow; case kVK_DownArrow: return ImGuiKey_DownArrow;
@ -391,15 +387,13 @@ IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(void* _Nullable view) {
bool ImGui_ImplOSX_Init(NSView* view) bool ImGui_ImplOSX_Init(NSView* view)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION(); ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_CreateBackendData();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); io.BackendPlatformUserData = (void*)bd;
// Setup backend capabilities flags // Setup backend capabilities flags
ImGui_ImplOSX_Data* bd = IM_NEW(ImGui_ImplOSX_Data)();
io.BackendPlatformUserData = (void*)bd;
io.BackendPlatformName = "imgui_impl_osx";
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
//io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) //io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
io.BackendPlatformName = "imgui_impl_osx";
bd->Observer = [ImGuiObserver new]; bd->Observer = [ImGuiObserver new];
@ -535,6 +529,7 @@ static void ImGui_ImplOSX_UpdateMouseCursor()
static void ImGui_ImplOSX_UpdateGamepads() static void ImGui_ImplOSX_UpdateGamepads()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
memset(io.NavInputs, 0, sizeof(io.NavInputs));
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs. if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
return; return;
@ -601,7 +596,6 @@ static void ImGui_ImplOSX_UpdateImePosWithView(NSView* view)
void ImGui_ImplOSX_NewFrame(NSView* view) void ImGui_ImplOSX_NewFrame(NSView* view)
{ {
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData(); ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOSX_Init()?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Setup display size // Setup display size
@ -807,7 +801,3 @@ static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view)
return event; return event;
}]; }];
} }
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -13,16 +13,11 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 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) // 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)
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702) // 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702)
// 2023-02-23: Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. (#6189, #6114, #3644) // 2023-02-23: Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. (#6189, #6114, #3644)
@ -78,7 +73,6 @@
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. // 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_sdl2.h" #include "imgui_impl_sdl2.h"
// Clang warnings with -Weverything // Clang warnings with -Weverything
@ -104,23 +98,16 @@
// SDL Data // SDL Data
struct ImGui_ImplSDL2_Data struct ImGui_ImplSDL2_Data
{ {
SDL_Window* Window; SDL_Window* Window;
SDL_Renderer* Renderer; SDL_Renderer* Renderer;
Uint64 Time; Uint64 Time;
char* ClipboardTextData; Uint32 MouseWindowID;
int MouseButtonsDown;
// Mouse handling SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
Uint32 MouseWindowID; SDL_Cursor* LastMouseCursor;
int MouseButtonsDown; int PendingMouseLeaveFrame;
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT]; char* ClipboardTextData;
SDL_Cursor* MouseLastCursor; bool MouseCanUseGlobalState;
int MouseLastLeaveFrame;
bool MouseCanUseGlobalState;
// Gamepad handling
ImVector<SDL_GameController*> Gamepads;
ImGui_ImplSDL2_GamepadMode GamepadMode;
bool WantUpdateGamepadsList;
ImGui_ImplSDL2_Data() { memset((void*)this, 0, sizeof(*this)); } ImGui_ImplSDL2_Data() { memset((void*)this, 0, sizeof(*this)); }
}; };
@ -272,20 +259,6 @@ static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
case SDLK_F10: return ImGuiKey_F10; case SDLK_F10: return ImGuiKey_F10;
case SDLK_F11: return ImGuiKey_F11; case SDLK_F11: return ImGuiKey_F11;
case SDLK_F12: return ImGuiKey_F12; case SDLK_F12: return ImGuiKey_F12;
case SDLK_F13: return ImGuiKey_F13;
case SDLK_F14: return ImGuiKey_F14;
case SDLK_F15: return ImGuiKey_F15;
case SDLK_F16: return ImGuiKey_F16;
case SDLK_F17: return ImGuiKey_F17;
case SDLK_F18: return ImGuiKey_F18;
case SDLK_F19: return ImGuiKey_F19;
case SDLK_F20: return ImGuiKey_F20;
case SDLK_F21: return ImGuiKey_F21;
case SDLK_F22: return ImGuiKey_F22;
case SDLK_F23: return ImGuiKey_F23;
case SDLK_F24: return ImGuiKey_F24;
case SDLK_AC_BACK: return ImGuiKey_AppBack;
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
} }
return ImGuiKey_None; return ImGuiKey_None;
} }
@ -306,9 +279,8 @@ static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods)
// If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field. // If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field.
bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
{ {
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL2_Init()?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
switch (event->type) switch (event->type)
{ {
@ -377,22 +349,16 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
if (window_event == SDL_WINDOWEVENT_ENTER) if (window_event == SDL_WINDOWEVENT_ENTER)
{ {
bd->MouseWindowID = event->window.windowID; bd->MouseWindowID = event->window.windowID;
bd->MouseLastLeaveFrame = 0; bd->PendingMouseLeaveFrame = 0;
} }
if (window_event == SDL_WINDOWEVENT_LEAVE) if (window_event == SDL_WINDOWEVENT_LEAVE)
bd->MouseLastLeaveFrame = ImGui::GetFrameCount() + 1; bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
io.AddFocusEvent(true); io.AddFocusEvent(true);
else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST) else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
io.AddFocusEvent(false); io.AddFocusEvent(false);
return true; return true;
} }
case SDL_CONTROLLERDEVICEADDED:
case SDL_CONTROLLERDEVICEREMOVED:
{
bd->WantUpdateGamepadsList = true;
return true;
}
} }
return false; return false;
} }
@ -400,7 +366,6 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer) static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
// Check and store if we are on a SDL backend that supports global mouse position // Check and store if we are on a SDL backend that supports global mouse position
@ -430,10 +395,6 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
io.ClipboardUserData = nullptr; io.ClipboardUserData = nullptr;
io.SetPlatformImeDataFn = ImGui_ImplSDL2_SetPlatformImeData; io.SetPlatformImeDataFn = ImGui_ImplSDL2_SetPlatformImeData;
// Gamepad handling
bd->GamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst;
bd->WantUpdateGamepadsList = true;
// Load mouse cursors // Load mouse cursors
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
@ -516,13 +477,6 @@ bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* rendere
return ImGui_ImplSDL2_Init(window, renderer); return ImGui_ImplSDL2_Init(window, renderer);
} }
bool ImGui_ImplSDL2_InitForOther(SDL_Window* window)
{
return ImGui_ImplSDL2_Init(window, nullptr);
}
static void ImGui_ImplSDL2_CloseGamepads();
void ImGui_ImplSDL2_Shutdown() void ImGui_ImplSDL2_Shutdown()
{ {
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
@ -533,7 +487,7 @@ void ImGui_ImplSDL2_Shutdown()
SDL_free(bd->ClipboardTextData); SDL_free(bd->ClipboardTextData);
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
SDL_FreeCursor(bd->MouseCursors[cursor_n]); SDL_FreeCursor(bd->MouseCursors[cursor_n]);
ImGui_ImplSDL2_CloseGamepads(); bd->LastMouseCursor = nullptr;
io.BackendPlatformName = nullptr; io.BackendPlatformName = nullptr;
io.BackendPlatformUserData = nullptr; io.BackendPlatformUserData = nullptr;
@ -589,124 +543,65 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
{ {
// Show OS mouse cursor // Show OS mouse cursor
SDL_Cursor* expected_cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]; SDL_Cursor* expected_cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow];
if (bd->MouseLastCursor != expected_cursor) if (bd->LastMouseCursor != expected_cursor)
{ {
SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113) SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113)
bd->MouseLastCursor = expected_cursor; bd->LastMouseCursor = expected_cursor;
} }
SDL_ShowCursor(SDL_TRUE); SDL_ShowCursor(SDL_TRUE);
} }
} }
static void ImGui_ImplSDL2_CloseGamepads()
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
if (bd->GamepadMode != ImGui_ImplSDL2_GamepadMode_Manual)
for (SDL_GameController* gamepad : bd->Gamepads)
SDL_GameControllerClose(gamepad);
bd->Gamepads.resize(0);
}
void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array, int manual_gamepads_count)
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
ImGui_ImplSDL2_CloseGamepads();
if (mode == ImGui_ImplSDL2_GamepadMode_Manual)
{
IM_ASSERT(manual_gamepads_array != nullptr && manual_gamepads_count > 0);
for (int n = 0; n < manual_gamepads_count; n++)
bd->Gamepads.push_back(manual_gamepads_array[n]);
}
else
{
IM_ASSERT(manual_gamepads_array == nullptr && manual_gamepads_count <= 0);
bd->WantUpdateGamepadsList = true;
}
bd->GamepadMode = mode;
}
static void ImGui_ImplSDL2_UpdateGamepadButton(ImGui_ImplSDL2_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GameControllerButton button_no)
{
bool merged_value = false;
for (SDL_GameController* gamepad : bd->Gamepads)
merged_value |= SDL_GameControllerGetButton(gamepad, button_no) != 0;
io.AddKeyEvent(key, merged_value);
}
static inline float Saturate(float v) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v; }
static void ImGui_ImplSDL2_UpdateGamepadAnalog(ImGui_ImplSDL2_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GameControllerAxis axis_no, float v0, float v1)
{
float merged_value = 0.0f;
for (SDL_GameController* gamepad : bd->Gamepads)
{
float vn = Saturate((float)(SDL_GameControllerGetAxis(gamepad, axis_no) - v0) / (float)(v1 - v0));
if (merged_value < vn)
merged_value = vn;
}
io.AddKeyAnalogEvent(key, merged_value > 0.1f, merged_value);
}
static void ImGui_ImplSDL2_UpdateGamepads() static void ImGui_ImplSDL2_UpdateGamepads()
{ {
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
// Update list of controller(s) to use
if (bd->WantUpdateGamepadsList && bd->GamepadMode != ImGui_ImplSDL2_GamepadMode_Manual)
{
ImGui_ImplSDL2_CloseGamepads();
int joystick_count = SDL_NumJoysticks();
for (int n = 0; n < joystick_count; n++)
if (SDL_IsGameController(n))
if (SDL_GameController* gamepad = SDL_GameControllerOpen(n))
{
bd->Gamepads.push_back(gamepad);
if (bd->GamepadMode == ImGui_ImplSDL2_GamepadMode_AutoFirst)
break;
}
bd->WantUpdateGamepadsList = false;
}
// FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
return; return;
// Get gamepad
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
if (bd->Gamepads.Size == 0) SDL_GameController* game_controller = SDL_GameControllerOpen(0);
if (!game_controller)
return; return;
io.BackendFlags |= ImGuiBackendFlags_HasGamepad; io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
// Update gamepad inputs // Update gamepad inputs
const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value. #define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadStart, SDL_CONTROLLER_BUTTON_START); #define MAP_BUTTON(KEY_NO, BUTTON_NO) { io.AddKeyEvent(KEY_NO, SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0); }
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadBack, SDL_CONTROLLER_BUTTON_BACK); #define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); }
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X); // Xbox X, PS Square const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_B); // Xbox B, PS Circle MAP_BUTTON(ImGuiKey_GamepadStart, SDL_CONTROLLER_BUTTON_START);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y); // Xbox Y, PS Triangle MAP_BUTTON(ImGuiKey_GamepadBack, SDL_CONTROLLER_BUTTON_BACK);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_A); // Xbox A, PS Cross MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X); // Xbox X, PS Square
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT); MAP_BUTTON(ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_B); // Xbox B, PS Circle
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); MAP_BUTTON(ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y); // Xbox Y, PS Triangle
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP); MAP_BUTTON(ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_A); // Xbox A, PS Cross
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN); MAP_BUTTON(ImGuiKey_GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL1, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); MAP_BUTTON(ImGuiKey_GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR1, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); MAP_BUTTON(ImGuiKey_GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadL2, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0.0f, 32767); MAP_BUTTON(ImGuiKey_GamepadDpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadR2, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767); MAP_BUTTON(ImGuiKey_GamepadL1, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL3, SDL_CONTROLLER_BUTTON_LEFTSTICK); MAP_BUTTON(ImGuiKey_GamepadR1, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR3, SDL_CONTROLLER_BUTTON_RIGHTSTICK); MAP_ANALOG(ImGuiKey_GamepadL2, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0.0f, 32767);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768); MAP_ANALOG(ImGuiKey_GamepadR2, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767); MAP_BUTTON(ImGuiKey_GamepadL3, SDL_CONTROLLER_BUTTON_LEFTSTICK);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32768); MAP_BUTTON(ImGuiKey_GamepadR3, SDL_CONTROLLER_BUTTON_RIGHTSTICK);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767); MAP_ANALOG(ImGuiKey_GamepadLStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickLeft, SDL_CONTROLLER_AXIS_RIGHTX, -thumb_dead_zone, -32768); MAP_ANALOG(ImGuiKey_GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumb_dead_zone, +32767); MAP_ANALOG(ImGuiKey_GamepadLStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32768);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickUp, SDL_CONTROLLER_AXIS_RIGHTY, -thumb_dead_zone, -32768); MAP_ANALOG(ImGuiKey_GamepadLStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767); MAP_ANALOG(ImGuiKey_GamepadRStickLeft, SDL_CONTROLLER_AXIS_RIGHTX, -thumb_dead_zone, -32768);
MAP_ANALOG(ImGuiKey_GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumb_dead_zone, +32767);
MAP_ANALOG(ImGuiKey_GamepadRStickUp, SDL_CONTROLLER_AXIS_RIGHTY, -thumb_dead_zone, -32768);
MAP_ANALOG(ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767);
#undef MAP_BUTTON
#undef MAP_ANALOG
} }
void ImGui_ImplSDL2_NewFrame() void ImGui_ImplSDL2_NewFrame()
{ {
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL2_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplSDL2_Init()?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Setup display size (every frame to accommodate for window resizing) // Setup display size (every frame to accommodate for window resizing)
@ -732,10 +627,10 @@ void ImGui_ImplSDL2_NewFrame()
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f); io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
bd->Time = current_time; bd->Time = current_time;
if (bd->MouseLastLeaveFrame && bd->MouseLastLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0) if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0)
{ {
bd->MouseWindowID = 0; bd->MouseWindowID = 0;
bd->MouseLastLeaveFrame = 0; bd->PendingMouseLeaveFrame = 0;
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
} }
@ -746,10 +641,6 @@ void ImGui_ImplSDL2_NewFrame()
ImGui_ImplSDL2_UpdateGamepads(); ImGui_ImplSDL2_UpdateGamepads();
} }
//-----------------------------------------------------------------------------
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -12,19 +12,14 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct SDL_Window; struct SDL_Window;
struct SDL_Renderer; struct SDL_Renderer;
struct _SDL_GameController;
typedef union SDL_Event SDL_Event; typedef union SDL_Event SDL_Event;
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context); IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
@ -32,14 +27,10 @@ IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window);
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window); IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window);
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window); IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window);
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer); IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOther(SDL_Window* window);
IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown(); IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown();
IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame(); IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame();
IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event); 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. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// When using manual mode, caller is responsible for opening/closing gamepad. static inline void ImGui_ImplSDL2_NewFrame(SDL_Window*) { ImGui_ImplSDL2_NewFrame(); } // 1.84: removed unnecessary parameter
enum ImGui_ImplSDL2_GamepadMode { ImGui_ImplSDL2_GamepadMode_AutoFirst, ImGui_ImplSDL2_GamepadMode_AutoAll, ImGui_ImplSDL2_GamepadMode_Manual }; #endif
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = NULL, int manual_gamepads_count = -1);
#endif // #ifndef IMGUI_DISABLE

View File

@ -10,22 +10,15 @@
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [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. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Missing features: // 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: Basic IME support. Position somehow broken in SDL3 + 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. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 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.
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
// 2023-05-04: Fixed build on Emscripten/iOS/Android. (#6391) // 2023-05-04: Fixed build on Emscripten/iOS/Android. (#6391)
// 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) // 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)
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702) // 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702)
@ -33,7 +26,6 @@
// 2023-02-07: Forked "imgui_impl_sdl2" into "imgui_impl_sdl3". Removed version checks for old feature. Refer to imgui_impl_sdl2.cpp for older changelog. // 2023-02-07: Forked "imgui_impl_sdl2" into "imgui_impl_sdl3". Removed version checks for old feature. Refer to imgui_impl_sdl2.cpp for older changelog.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_sdl3.h" #include "imgui_impl_sdl3.h"
// Clang warnings with -Weverything // Clang warnings with -Weverything
@ -44,15 +36,10 @@
// SDL // SDL
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <SDL3/SDL_syswm.h>
#if defined(__APPLE__) #if defined(__APPLE__)
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#endif
#if !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__) #if !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__)
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1 #define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1
@ -60,34 +47,19 @@
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0 #define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
#endif #endif
// FIXME-LEGACY: remove when SDL 3.1.3 preview is released.
#ifndef SDLK_APOSTROPHE
#define SDLK_APOSTROPHE SDLK_QUOTE
#endif
#ifndef SDLK_GRAVE
#define SDLK_GRAVE SDLK_BACKQUOTE
#endif
// SDL Data // SDL Data
struct ImGui_ImplSDL3_Data struct ImGui_ImplSDL3_Data
{ {
SDL_Window* Window; SDL_Window* Window;
SDL_Renderer* Renderer; SDL_Renderer* Renderer;
Uint64 Time; Uint64 Time;
char* ClipboardTextData; Uint32 MouseWindowID;
int MouseButtonsDown;
// Mouse handling SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
Uint32 MouseWindowID; SDL_Cursor* LastMouseCursor;
int MouseButtonsDown; int PendingMouseLeaveFrame;
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT]; char* ClipboardTextData;
SDL_Cursor* MouseLastCursor; bool MouseCanUseGlobalState;
int MousePendingLeaveFrame;
bool MouseCanUseGlobalState;
// Gamepad handling
ImVector<SDL_Gamepad*> Gamepads;
ImGui_ImplSDL3_GamepadMode GamepadMode;
bool WantUpdateGamepadsList;
ImGui_ImplSDL3_Data() { memset((void*)this, 0, sizeof(*this)); } ImGui_ImplSDL3_Data() { memset((void*)this, 0, sizeof(*this)); }
}; };
@ -126,11 +98,6 @@ static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeDa
r.w = 1; r.w = 1;
r.h = (int)data->InputLineHeight; r.h = (int)data->InputLineHeight;
SDL_SetTextInputRect(&r); SDL_SetTextInputRect(&r);
SDL_StartTextInput();
}
else
{
SDL_StopTextInput();
} }
} }
@ -153,7 +120,7 @@ static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode)
case SDLK_SPACE: return ImGuiKey_Space; case SDLK_SPACE: return ImGuiKey_Space;
case SDLK_RETURN: return ImGuiKey_Enter; case SDLK_RETURN: return ImGuiKey_Enter;
case SDLK_ESCAPE: return ImGuiKey_Escape; case SDLK_ESCAPE: return ImGuiKey_Escape;
case SDLK_APOSTROPHE: return ImGuiKey_Apostrophe; case SDLK_QUOTE: return ImGuiKey_Apostrophe;
case SDLK_COMMA: return ImGuiKey_Comma; case SDLK_COMMA: return ImGuiKey_Comma;
case SDLK_MINUS: return ImGuiKey_Minus; case SDLK_MINUS: return ImGuiKey_Minus;
case SDLK_PERIOD: return ImGuiKey_Period; case SDLK_PERIOD: return ImGuiKey_Period;
@ -163,7 +130,7 @@ static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode)
case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket; case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
case SDLK_BACKSLASH: return ImGuiKey_Backslash; case SDLK_BACKSLASH: return ImGuiKey_Backslash;
case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket; case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
case SDLK_GRAVE: return ImGuiKey_GraveAccent; case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent;
case SDLK_CAPSLOCK: return ImGuiKey_CapsLock; case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock; case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock; case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
@ -243,20 +210,6 @@ static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode)
case SDLK_F10: return ImGuiKey_F10; case SDLK_F10: return ImGuiKey_F10;
case SDLK_F11: return ImGuiKey_F11; case SDLK_F11: return ImGuiKey_F11;
case SDLK_F12: return ImGuiKey_F12; case SDLK_F12: return ImGuiKey_F12;
case SDLK_F13: return ImGuiKey_F13;
case SDLK_F14: return ImGuiKey_F14;
case SDLK_F15: return ImGuiKey_F15;
case SDLK_F16: return ImGuiKey_F16;
case SDLK_F17: return ImGuiKey_F17;
case SDLK_F18: return ImGuiKey_F18;
case SDLK_F19: return ImGuiKey_F19;
case SDLK_F20: return ImGuiKey_F20;
case SDLK_F21: return ImGuiKey_F21;
case SDLK_F22: return ImGuiKey_F22;
case SDLK_F23: return ImGuiKey_F23;
case SDLK_F24: return ImGuiKey_F24;
case SDLK_AC_BACK: return ImGuiKey_AppBack;
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
} }
return ImGuiKey_None; return ImGuiKey_None;
} }
@ -277,9 +230,8 @@ static void ImGui_ImplSDL3_UpdateKeyModifiers(SDL_Keymod sdl_key_mods)
// If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field. // If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field.
bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event) bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
{ {
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL3_Init()?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
switch (event->type) switch (event->type)
{ {
@ -335,7 +287,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
case SDL_EVENT_WINDOW_MOUSE_ENTER: case SDL_EVENT_WINDOW_MOUSE_ENTER:
{ {
bd->MouseWindowID = event->window.windowID; bd->MouseWindowID = event->window.windowID;
bd->MousePendingLeaveFrame = 0; bd->PendingMouseLeaveFrame = 0;
return true; return true;
} }
// - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late, // - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
@ -344,7 +296,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
// FIXME: Unconfirmed whether this is still needed with SDL3. // FIXME: Unconfirmed whether this is still needed with SDL3.
case SDL_EVENT_WINDOW_MOUSE_LEAVE: case SDL_EVENT_WINDOW_MOUSE_LEAVE:
{ {
bd->MousePendingLeaveFrame = ImGui::GetFrameCount() + 1; bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
return true; return true;
} }
case SDL_EVENT_WINDOW_FOCUS_GAINED: case SDL_EVENT_WINDOW_FOCUS_GAINED:
@ -353,33 +305,14 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
case SDL_EVENT_WINDOW_FOCUS_LOST: case SDL_EVENT_WINDOW_FOCUS_LOST:
io.AddFocusEvent(false); io.AddFocusEvent(false);
return true; return true;
case SDL_EVENT_GAMEPAD_ADDED:
case SDL_EVENT_GAMEPAD_REMOVED:
{
bd->WantUpdateGamepadsList = true;
return true;
}
} }
return false; return false;
} }
static void ImGui_ImplSDL3_SetupPlatformHandles(ImGuiViewport* viewport, SDL_Window* window) static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer)
{
IM_UNUSED(window);
viewport->PlatformHandleRaw = nullptr;
#if defined(__WIN32__) && !defined(__WINRT__)
viewport->PlatformHandleRaw = (HWND)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.win32.hwnd", nullptr);
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
viewport->PlatformHandleRaw = (void*)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.cocoa.window", nullptr);
#endif
}
static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
IM_UNUSED(sdl_gl_context); // Unused in this branch
// Check and store if we are on a SDL backend that supports global mouse position // Check and store if we are on a SDL backend that supports global mouse position
// ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
@ -408,10 +341,6 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
io.ClipboardUserData = nullptr; io.ClipboardUserData = nullptr;
io.SetPlatformImeDataFn = ImGui_ImplSDL3_SetPlatformImeData; io.SetPlatformImeDataFn = ImGui_ImplSDL3_SetPlatformImeData;
// Gamepad handling
bd->GamepadMode = ImGui_ImplSDL3_GamepadMode_AutoFirst;
bd->WantUpdateGamepadsList = true;
// Load mouse cursors // Load mouse cursors
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
@ -426,7 +355,16 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
// Set platform dependent data in viewport // Set platform dependent data in viewport
// Our mouse update function expect PlatformHandle to be filled for the main viewport // Our mouse update function expect PlatformHandle to be filled for the main viewport
ImGuiViewport* main_viewport = ImGui::GetMainViewport(); ImGuiViewport* main_viewport = ImGui::GetMainViewport();
ImGui_ImplSDL3_SetupPlatformHandles(main_viewport, window); main_viewport->PlatformHandleRaw = nullptr;
SDL_SysWMinfo info;
if (SDL_GetWindowWMInfo(window, &info, SDL_SYSWM_CURRENT_VERSION) == 0)
{
#if defined(SDL_ENABLE_SYSWM_WINDOWS)
main_viewport->PlatformHandleRaw = (void*)info.info.win.window;
#elif defined(__APPLE__) && defined(SDL_ENABLE_SYSWM_COCOA)
main_viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
#endif
}
// From 2.0.5: Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event. // From 2.0.5: Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event.
// Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered. // Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
@ -448,12 +386,12 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context) bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
{ {
IM_UNUSED(sdl_gl_context); // Viewport branch will need this. IM_UNUSED(sdl_gl_context); // Viewport branch will need this.
return ImGui_ImplSDL3_Init(window, nullptr, sdl_gl_context); return ImGui_ImplSDL3_Init(window, nullptr);
} }
bool ImGui_ImplSDL3_InitForVulkan(SDL_Window* window) bool ImGui_ImplSDL3_InitForVulkan(SDL_Window* window)
{ {
return ImGui_ImplSDL3_Init(window, nullptr, nullptr); return ImGui_ImplSDL3_Init(window, nullptr);
} }
bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window) bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window)
@ -461,26 +399,19 @@ bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window)
#if !defined(_WIN32) #if !defined(_WIN32)
IM_ASSERT(0 && "Unsupported"); IM_ASSERT(0 && "Unsupported");
#endif #endif
return ImGui_ImplSDL3_Init(window, nullptr, nullptr); return ImGui_ImplSDL3_Init(window, nullptr);
} }
bool ImGui_ImplSDL3_InitForMetal(SDL_Window* window) bool ImGui_ImplSDL3_InitForMetal(SDL_Window* window)
{ {
return ImGui_ImplSDL3_Init(window, nullptr, nullptr); return ImGui_ImplSDL3_Init(window, nullptr);
} }
bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer) bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer)
{ {
return ImGui_ImplSDL3_Init(window, renderer, nullptr); return ImGui_ImplSDL3_Init(window, renderer);
} }
bool ImGui_ImplSDL3_InitForOther(SDL_Window* window)
{
return ImGui_ImplSDL3_Init(window, nullptr, nullptr);
}
static void ImGui_ImplSDL3_CloseGamepads();
void ImGui_ImplSDL3_Shutdown() void ImGui_ImplSDL3_Shutdown()
{ {
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData(); ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
@ -491,7 +422,7 @@ void ImGui_ImplSDL3_Shutdown()
SDL_free(bd->ClipboardTextData); SDL_free(bd->ClipboardTextData);
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
SDL_DestroyCursor(bd->MouseCursors[cursor_n]); SDL_DestroyCursor(bd->MouseCursors[cursor_n]);
ImGui_ImplSDL3_CloseGamepads(); bd->LastMouseCursor = nullptr;
io.BackendPlatformName = nullptr; io.BackendPlatformName = nullptr;
io.BackendPlatformUserData = nullptr; io.BackendPlatformUserData = nullptr;
@ -550,125 +481,65 @@ static void ImGui_ImplSDL3_UpdateMouseCursor()
{ {
// Show OS mouse cursor // Show OS mouse cursor
SDL_Cursor* expected_cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]; SDL_Cursor* expected_cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow];
if (bd->MouseLastCursor != expected_cursor) if (bd->LastMouseCursor != expected_cursor)
{ {
SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113) SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113)
bd->MouseLastCursor = expected_cursor; bd->LastMouseCursor = expected_cursor;
} }
SDL_ShowCursor(); SDL_ShowCursor();
} }
} }
static void ImGui_ImplSDL3_CloseGamepads()
{
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
if (bd->GamepadMode != ImGui_ImplSDL3_GamepadMode_Manual)
for (SDL_Gamepad* gamepad : bd->Gamepads)
SDL_CloseGamepad(gamepad);
bd->Gamepads.resize(0);
}
void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array, int manual_gamepads_count)
{
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
ImGui_ImplSDL3_CloseGamepads();
if (mode == ImGui_ImplSDL3_GamepadMode_Manual)
{
IM_ASSERT(manual_gamepads_array != nullptr && manual_gamepads_count > 0);
for (int n = 0; n < manual_gamepads_count; n++)
bd->Gamepads.push_back(manual_gamepads_array[n]);
}
else
{
IM_ASSERT(manual_gamepads_array == nullptr && manual_gamepads_count <= 0);
bd->WantUpdateGamepadsList = true;
}
bd->GamepadMode = mode;
}
static void ImGui_ImplSDL3_UpdateGamepadButton(ImGui_ImplSDL3_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GamepadButton button_no)
{
bool merged_value = false;
for (SDL_Gamepad* gamepad : bd->Gamepads)
merged_value |= SDL_GetGamepadButton(gamepad, button_no) != 0;
io.AddKeyEvent(key, merged_value);
}
static inline float Saturate(float v) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v; }
static void ImGui_ImplSDL3_UpdateGamepadAnalog(ImGui_ImplSDL3_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GamepadAxis axis_no, float v0, float v1)
{
float merged_value = 0.0f;
for (SDL_Gamepad* gamepad : bd->Gamepads)
{
float vn = Saturate((float)(SDL_GetGamepadAxis(gamepad, axis_no) - v0) / (float)(v1 - v0));
if (merged_value < vn)
merged_value = vn;
}
io.AddKeyAnalogEvent(key, merged_value > 0.1f, merged_value);
}
static void ImGui_ImplSDL3_UpdateGamepads() static void ImGui_ImplSDL3_UpdateGamepads()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData(); if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
// Update list of gamepads to use
if (bd->WantUpdateGamepadsList && bd->GamepadMode != ImGui_ImplSDL3_GamepadMode_Manual)
{
ImGui_ImplSDL3_CloseGamepads();
int sdl_gamepads_count = 0;
SDL_JoystickID* sdl_gamepads = SDL_GetGamepads(&sdl_gamepads_count);
for (int n = 0; n < sdl_gamepads_count; n++)
if (SDL_Gamepad* gamepad = SDL_OpenGamepad(sdl_gamepads[n]))
{
bd->Gamepads.push_back(gamepad);
if (bd->GamepadMode == ImGui_ImplSDL3_GamepadMode_AutoFirst)
break;
}
SDL_free(sdl_gamepads);
bd->WantUpdateGamepadsList = false;
}
// FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
return; return;
// Get gamepad
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
if (bd->Gamepads.Size == 0) SDL_Gamepad* gamepad = SDL_OpenGamepad(0);
if (!gamepad)
return; return;
io.BackendFlags |= ImGuiBackendFlags_HasGamepad; io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
// Update gamepad inputs // Update gamepad inputs
const int thumb_dead_zone = 8000; // SDL_gamepad.h suggests using this value. #define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadStart, SDL_GAMEPAD_BUTTON_START); #define MAP_BUTTON(KEY_NO, BUTTON_NO) { io.AddKeyEvent(KEY_NO, SDL_GetGamepadButton(gamepad, BUTTON_NO) != 0); }
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadBack, SDL_GAMEPAD_BUTTON_BACK); #define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GetGamepadAxis(gamepad, AXIS_NO) - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); }
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceLeft, SDL_GAMEPAD_BUTTON_WEST); // Xbox X, PS Square const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceRight, SDL_GAMEPAD_BUTTON_EAST); // Xbox B, PS Circle MAP_BUTTON(ImGuiKey_GamepadStart, SDL_GAMEPAD_BUTTON_START);
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceUp, SDL_GAMEPAD_BUTTON_NORTH); // Xbox Y, PS Triangle MAP_BUTTON(ImGuiKey_GamepadBack, SDL_GAMEPAD_BUTTON_BACK);
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceDown, SDL_GAMEPAD_BUTTON_SOUTH); // Xbox A, PS Cross MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SDL_GAMEPAD_BUTTON_X); // Xbox X, PS Square
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadLeft, SDL_GAMEPAD_BUTTON_DPAD_LEFT); MAP_BUTTON(ImGuiKey_GamepadFaceRight, SDL_GAMEPAD_BUTTON_B); // Xbox B, PS Circle
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadRight, SDL_GAMEPAD_BUTTON_DPAD_RIGHT); MAP_BUTTON(ImGuiKey_GamepadFaceUp, SDL_GAMEPAD_BUTTON_Y); // Xbox Y, PS Triangle
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadUp, SDL_GAMEPAD_BUTTON_DPAD_UP); MAP_BUTTON(ImGuiKey_GamepadFaceDown, SDL_GAMEPAD_BUTTON_A); // Xbox A, PS Cross
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadDown, SDL_GAMEPAD_BUTTON_DPAD_DOWN); MAP_BUTTON(ImGuiKey_GamepadDpadLeft, SDL_GAMEPAD_BUTTON_DPAD_LEFT);
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL1, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER); MAP_BUTTON(ImGuiKey_GamepadDpadRight, SDL_GAMEPAD_BUTTON_DPAD_RIGHT);
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR1, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER); MAP_BUTTON(ImGuiKey_GamepadDpadUp, SDL_GAMEPAD_BUTTON_DPAD_UP);
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadL2, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 0.0f, 32767); MAP_BUTTON(ImGuiKey_GamepadDpadDown, SDL_GAMEPAD_BUTTON_DPAD_DOWN);
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadR2, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 0.0f, 32767); MAP_BUTTON(ImGuiKey_GamepadL1, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER);
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL3, SDL_GAMEPAD_BUTTON_LEFT_STICK); MAP_BUTTON(ImGuiKey_GamepadR1, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER);
ImGui_ImplSDL3_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR3, SDL_GAMEPAD_BUTTON_RIGHT_STICK); MAP_ANALOG(ImGuiKey_GamepadL2, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 0.0f, 32767);
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickLeft, SDL_GAMEPAD_AXIS_LEFTX, -thumb_dead_zone, -32768); MAP_ANALOG(ImGuiKey_GamepadR2, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 0.0f, 32767);
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickRight, SDL_GAMEPAD_AXIS_LEFTX, +thumb_dead_zone, +32767); MAP_BUTTON(ImGuiKey_GamepadL3, SDL_GAMEPAD_BUTTON_LEFT_STICK);
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickUp, SDL_GAMEPAD_AXIS_LEFTY, -thumb_dead_zone, -32768); MAP_BUTTON(ImGuiKey_GamepadR3, SDL_GAMEPAD_BUTTON_RIGHT_STICK);
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickDown, SDL_GAMEPAD_AXIS_LEFTY, +thumb_dead_zone, +32767); MAP_ANALOG(ImGuiKey_GamepadLStickLeft, SDL_GAMEPAD_AXIS_LEFTX, -thumb_dead_zone, -32768);
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickLeft, SDL_GAMEPAD_AXIS_RIGHTX, -thumb_dead_zone, -32768); MAP_ANALOG(ImGuiKey_GamepadLStickRight, SDL_GAMEPAD_AXIS_LEFTX, +thumb_dead_zone, +32767);
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickRight, SDL_GAMEPAD_AXIS_RIGHTX, +thumb_dead_zone, +32767); MAP_ANALOG(ImGuiKey_GamepadLStickUp, SDL_GAMEPAD_AXIS_LEFTY, -thumb_dead_zone, -32768);
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickUp, SDL_GAMEPAD_AXIS_RIGHTY, -thumb_dead_zone, -32768); MAP_ANALOG(ImGuiKey_GamepadLStickDown, SDL_GAMEPAD_AXIS_LEFTY, +thumb_dead_zone, +32767);
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickDown, SDL_GAMEPAD_AXIS_RIGHTY, +thumb_dead_zone, +32767); MAP_ANALOG(ImGuiKey_GamepadRStickLeft, SDL_GAMEPAD_AXIS_RIGHTX, -thumb_dead_zone, -32768);
MAP_ANALOG(ImGuiKey_GamepadRStickRight, SDL_GAMEPAD_AXIS_RIGHTX, +thumb_dead_zone, +32767);
MAP_ANALOG(ImGuiKey_GamepadRStickUp, SDL_GAMEPAD_AXIS_RIGHTY, -thumb_dead_zone, -32768);
MAP_ANALOG(ImGuiKey_GamepadRStickDown, SDL_GAMEPAD_AXIS_RIGHTY, +thumb_dead_zone, +32767);
#undef MAP_BUTTON
#undef MAP_ANALOG
} }
void ImGui_ImplSDL3_NewFrame() void ImGui_ImplSDL3_NewFrame()
{ {
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData(); ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL3_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplSDL3_Init()?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Setup display size (every frame to accommodate for window resizing) // Setup display size (every frame to accommodate for window resizing)
@ -691,10 +562,10 @@ void ImGui_ImplSDL3_NewFrame()
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f); io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
bd->Time = current_time; bd->Time = current_time;
if (bd->MousePendingLeaveFrame && bd->MousePendingLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0) if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0)
{ {
bd->MouseWindowID = 0; bd->MouseWindowID = 0;
bd->MousePendingLeaveFrame = 0; bd->PendingMouseLeaveFrame = 0;
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
} }
@ -705,10 +576,7 @@ void ImGui_ImplSDL3_NewFrame()
ImGui_ImplSDL3_UpdateGamepads(); ImGui_ImplSDL3_UpdateGamepads();
} }
//-----------------------------------------------------------------------------
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -10,23 +10,18 @@
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [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. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Missing features: // 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: Basic IME support. Position somehow broken in SDL3 + 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. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct SDL_Window; struct SDL_Window;
struct SDL_Renderer; struct SDL_Renderer;
struct SDL_Gamepad;
typedef union SDL_Event SDL_Event; typedef union SDL_Event SDL_Event;
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context); IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
@ -34,14 +29,6 @@ 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_InitForD3D(SDL_Window* window);
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForMetal(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_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOther(SDL_Window* window);
IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown(); IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame(); IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame();
IMGUI_IMPL_API bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event); 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);
#endif // #ifndef IMGUI_DISABLE

View File

@ -12,15 +12,10 @@
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// 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. // 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. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2021-12-21: Update SDL_RenderGeometryRaw() format to work with SDL 2.0.19. // 2021-12-21: Update SDL_RenderGeometryRaw() format to work with SDL 2.0.19.
@ -29,9 +24,12 @@
// 2021-09-21: Initial version. // 2021-09-21: Initial version.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_sdlrenderer2.h" #include "imgui_impl_sdlrenderer2.h"
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t #include <stdint.h> // intptr_t
#endif
// Clang warnings with -Weverything // Clang warnings with -Weverything
#if defined(__clang__) #if defined(__clang__)
@ -48,9 +46,9 @@
// SDL_Renderer data // SDL_Renderer data
struct ImGui_ImplSDLRenderer2_Data struct ImGui_ImplSDLRenderer2_Data
{ {
SDL_Renderer* Renderer; // Main viewport's renderer SDL_Renderer* SDLRenderer;
SDL_Texture* FontTexture; SDL_Texture* FontTexture;
ImGui_ImplSDLRenderer2_Data() { memset((void*)this, 0, sizeof(*this)); } ImGui_ImplSDLRenderer2_Data() { memset((void*)this, 0, sizeof(*this)); }
}; };
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
@ -64,7 +62,6 @@ static ImGui_ImplSDLRenderer2_Data* ImGui_ImplSDLRenderer2_GetBackendData()
bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer) bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!"); IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!");
@ -74,7 +71,7 @@ bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer)
io.BackendRendererName = "imgui_impl_sdlrenderer2"; io.BackendRendererName = "imgui_impl_sdlrenderer2";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
bd->Renderer = renderer; bd->SDLRenderer = renderer;
return true; return true;
} }
@ -93,31 +90,35 @@ void ImGui_ImplSDLRenderer2_Shutdown()
IM_DELETE(bd); IM_DELETE(bd);
} }
static void ImGui_ImplSDLRenderer2_SetupRenderState(SDL_Renderer* renderer) static void ImGui_ImplSDLRenderer2_SetupRenderState()
{ {
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
// Clear out any viewports and cliprect set by the user // Clear out any viewports and cliprect set by the user
// FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process. // FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.
SDL_RenderSetViewport(renderer, nullptr); SDL_RenderSetViewport(bd->SDLRenderer, nullptr);
SDL_RenderSetClipRect(renderer, nullptr); SDL_RenderSetClipRect(bd->SDLRenderer, nullptr);
} }
void ImGui_ImplSDLRenderer2_NewFrame() void ImGui_ImplSDLRenderer2_NewFrame()
{ {
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData(); ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLRenderer2_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplSDLRenderer2_Init()?");
if (!bd->FontTexture) if (!bd->FontTexture)
ImGui_ImplSDLRenderer2_CreateDeviceObjects(); ImGui_ImplSDLRenderer2_CreateDeviceObjects();
} }
void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer) void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data)
{ {
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
// If there's a scale factor set by the user, use that instead // 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 // 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. // to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
float rsx = 1.0f; float rsx = 1.0f;
float rsy = 1.0f; float rsy = 1.0f;
SDL_RenderGetScale(renderer, &rsx, &rsy); SDL_RenderGetScale(bd->SDLRenderer, &rsx, &rsy);
ImVec2 render_scale; ImVec2 render_scale;
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f; render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f; render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
@ -136,16 +137,16 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
SDL_Rect ClipRect; SDL_Rect ClipRect;
}; };
BackupSDLRendererState old = {}; BackupSDLRendererState old = {};
old.ClipEnabled = SDL_RenderIsClipEnabled(renderer) == SDL_TRUE; old.ClipEnabled = SDL_RenderIsClipEnabled(bd->SDLRenderer) == SDL_TRUE;
SDL_RenderGetViewport(renderer, &old.Viewport); SDL_RenderGetViewport(bd->SDLRenderer, &old.Viewport);
SDL_RenderGetClipRect(renderer, &old.ClipRect); SDL_RenderGetClipRect(bd->SDLRenderer, &old.ClipRect);
// Will project scissor/clipping rectangles into framebuffer space // Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = render_scale; ImVec2 clip_scale = render_scale;
// Render command lists // Render command lists
ImGui_ImplSDLRenderer2_SetupRenderState(renderer); ImGui_ImplSDLRenderer2_SetupRenderState();
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* cmd_list = draw_data->CmdLists[n];
@ -160,7 +161,7 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
// User callback, registered via ImDrawList::AddCallback() // 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.) // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplSDLRenderer2_SetupRenderState(renderer); ImGui_ImplSDLRenderer2_SetupRenderState();
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
@ -177,19 +178,19 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
continue; continue;
SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) }; SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };
SDL_RenderSetClipRect(renderer, &r); SDL_RenderSetClipRect(bd->SDLRenderer, &r);
const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos)); const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, pos));
const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv)); const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, uv));
#if SDL_VERSION_ATLEAST(2,0,19) #if SDL_VERSION_ATLEAST(2,0,19)
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+ const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.19+
#else #else
const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18 const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18
#endif #endif
// Bind texture, Draw // Bind texture, Draw
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID(); SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
SDL_RenderGeometryRaw(renderer, tex, SDL_RenderGeometryRaw(bd->SDLRenderer, tex,
xy, (int)sizeof(ImDrawVert), xy, (int)sizeof(ImDrawVert),
color, (int)sizeof(ImDrawVert), color, (int)sizeof(ImDrawVert),
uv, (int)sizeof(ImDrawVert), uv, (int)sizeof(ImDrawVert),
@ -200,8 +201,8 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
} }
// Restore modified SDL_Renderer state // Restore modified SDL_Renderer state
SDL_RenderSetViewport(renderer, &old.Viewport); SDL_RenderSetViewport(bd->SDLRenderer, &old.Viewport);
SDL_RenderSetClipRect(renderer, old.ClipEnabled ? &old.ClipRect : nullptr); SDL_RenderSetClipRect(bd->SDLRenderer, old.ClipEnabled ? &old.ClipRect : nullptr);
} }
// Called by Init/NewFrame/Shutdown // Called by Init/NewFrame/Shutdown
@ -217,7 +218,7 @@ bool ImGui_ImplSDLRenderer2_CreateFontsTexture()
// Upload texture to graphics system // Upload texture to graphics system
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling) // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height); bd->FontTexture = SDL_CreateTexture(bd->SDLRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height);
if (bd->FontTexture == nullptr) if (bd->FontTexture == nullptr)
{ {
SDL_Log("error creating texture"); SDL_Log("error creating texture");
@ -255,10 +256,6 @@ void ImGui_ImplSDLRenderer2_DestroyDeviceObjects()
ImGui_ImplSDLRenderer2_DestroyFontsTexture(); ImGui_ImplSDLRenderer2_DestroyFontsTexture();
} }
//-----------------------------------------------------------------------------
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -11,16 +11,7 @@
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! // [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) with 16-bit indices.
// 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
#pragma once #pragma once
#ifndef IMGUI_DISABLE
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
struct SDL_Renderer; struct SDL_Renderer;
@ -28,12 +19,10 @@ struct SDL_Renderer;
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer); IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer);
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_Shutdown(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_Shutdown();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_NewFrame(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_NewFrame();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer); IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data);
// Called by Init/NewFrame/Shutdown // Called by Init/NewFrame/Shutdown
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateFontsTexture(); IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyFontsTexture(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -12,22 +12,19 @@
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// 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. // 2023-05-30: Initial version.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_sdlrenderer3.h" #include "imgui_impl_sdlrenderer3.h"
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t #include <stdint.h> // intptr_t
#endif
// Clang warnings with -Weverything // Clang warnings with -Weverything
#if defined(__clang__) #if defined(__clang__)
@ -44,9 +41,9 @@
// SDL_Renderer data // SDL_Renderer data
struct ImGui_ImplSDLRenderer3_Data struct ImGui_ImplSDLRenderer3_Data
{ {
SDL_Renderer* Renderer; // Main viewport's renderer SDL_Renderer* SDLRenderer;
SDL_Texture* FontTexture; SDL_Texture* FontTexture;
ImGui_ImplSDLRenderer3_Data() { memset((void*)this, 0, sizeof(*this)); } ImGui_ImplSDLRenderer3_Data() { memset((void*)this, 0, sizeof(*this)); }
}; };
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
@ -60,7 +57,6 @@ static ImGui_ImplSDLRenderer3_Data* ImGui_ImplSDLRenderer3_GetBackendData()
bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer) bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!"); IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!");
@ -70,7 +66,7 @@ bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer)
io.BackendRendererName = "imgui_impl_sdlrenderer3"; io.BackendRendererName = "imgui_impl_sdlrenderer3";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
bd->Renderer = renderer; bd->SDLRenderer = renderer;
return true; return true;
} }
@ -89,31 +85,35 @@ void ImGui_ImplSDLRenderer3_Shutdown()
IM_DELETE(bd); IM_DELETE(bd);
} }
static void ImGui_ImplSDLRenderer3_SetupRenderState(SDL_Renderer* renderer) static void ImGui_ImplSDLRenderer3_SetupRenderState()
{ {
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
// Clear out any viewports and cliprect set by the user // Clear out any viewports and cliprect set by the user
// FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process. // FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.
SDL_SetRenderViewport(renderer, nullptr); SDL_SetRenderViewport(bd->SDLRenderer, nullptr);
SDL_SetRenderClipRect(renderer, nullptr); SDL_SetRenderClipRect(bd->SDLRenderer, nullptr);
} }
void ImGui_ImplSDLRenderer3_NewFrame() void ImGui_ImplSDLRenderer3_NewFrame()
{ {
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData(); ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLRenderer3_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplSDLRenderer3_Init()?");
if (!bd->FontTexture) if (!bd->FontTexture)
ImGui_ImplSDLRenderer3_CreateDeviceObjects(); ImGui_ImplSDLRenderer3_CreateDeviceObjects();
} }
void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer) void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data)
{ {
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
// If there's a scale factor set by the user, use that instead // 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 // 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. // to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
float rsx = 1.0f; float rsx = 1.0f;
float rsy = 1.0f; float rsy = 1.0f;
SDL_GetRenderScale(renderer, &rsx, &rsy); SDL_GetRenderScale(bd->SDLRenderer, &rsx, &rsy);
ImVec2 render_scale; ImVec2 render_scale;
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f; render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f; render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
@ -128,22 +128,20 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
struct BackupSDLRendererState struct BackupSDLRendererState
{ {
SDL_Rect Viewport; SDL_Rect Viewport;
bool ViewportEnabled;
bool ClipEnabled; bool ClipEnabled;
SDL_Rect ClipRect; SDL_Rect ClipRect;
}; };
BackupSDLRendererState old = {}; BackupSDLRendererState old = {};
old.ViewportEnabled = SDL_RenderViewportSet(renderer) == SDL_TRUE; old.ClipEnabled = SDL_RenderClipEnabled(bd->SDLRenderer) == SDL_TRUE;
old.ClipEnabled = SDL_RenderClipEnabled(renderer) == SDL_TRUE; SDL_GetRenderViewport(bd->SDLRenderer, &old.Viewport);
SDL_GetRenderViewport(renderer, &old.Viewport); SDL_GetRenderClipRect(bd->SDLRenderer, &old.ClipRect);
SDL_GetRenderClipRect(renderer, &old.ClipRect);
// Will project scissor/clipping rectangles into framebuffer space // Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = render_scale; ImVec2 clip_scale = render_scale;
// Render command lists // Render command lists
ImGui_ImplSDLRenderer3_SetupRenderState(renderer); ImGui_ImplSDLRenderer3_SetupRenderState();
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* cmd_list = draw_data->CmdLists[n];
@ -158,7 +156,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
// User callback, registered via ImDrawList::AddCallback() // 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.) // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplSDLRenderer3_SetupRenderState(renderer); ImGui_ImplSDLRenderer3_SetupRenderState();
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
@ -175,15 +173,19 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
continue; continue;
SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) }; SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };
SDL_SetRenderClipRect(renderer, &r); SDL_SetRenderClipRect(bd->SDLRenderer, &r);
const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos)); const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, pos));
const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv)); const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, uv));
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+ #if SDL_VERSION_ATLEAST(2,0,19)
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.19+
#else
const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18
#endif
// Bind texture, Draw // Bind texture, Draw
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID(); SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
SDL_RenderGeometryRaw(renderer, tex, SDL_RenderGeometryRaw(bd->SDLRenderer, tex,
xy, (int)sizeof(ImDrawVert), xy, (int)sizeof(ImDrawVert),
color, (int)sizeof(ImDrawVert), color, (int)sizeof(ImDrawVert),
uv, (int)sizeof(ImDrawVert), uv, (int)sizeof(ImDrawVert),
@ -194,8 +196,8 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
} }
// Restore modified SDL_Renderer state // Restore modified SDL_Renderer state
SDL_SetRenderViewport(renderer, old.ViewportEnabled ? &old.Viewport : nullptr); SDL_SetRenderViewport(bd->SDLRenderer, &old.Viewport);
SDL_SetRenderClipRect(renderer, old.ClipEnabled ? &old.ClipRect : nullptr); SDL_SetRenderClipRect(bd->SDLRenderer, old.ClipEnabled ? &old.ClipRect : nullptr);
} }
// Called by Init/NewFrame/Shutdown // Called by Init/NewFrame/Shutdown
@ -211,7 +213,7 @@ bool ImGui_ImplSDLRenderer3_CreateFontsTexture()
// Upload texture to graphics system // Upload texture to graphics system
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling) // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height); bd->FontTexture = SDL_CreateTexture(bd->SDLRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height);
if (bd->FontTexture == nullptr) if (bd->FontTexture == nullptr)
{ {
SDL_Log("error creating texture"); SDL_Log("error creating texture");
@ -249,10 +251,6 @@ void ImGui_ImplSDLRenderer3_DestroyDeviceObjects()
ImGui_ImplSDLRenderer3_DestroyFontsTexture(); ImGui_ImplSDLRenderer3_DestroyFontsTexture();
} }
//-----------------------------------------------------------------------------
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -11,29 +11,18 @@
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! // [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) with 16-bit indices.
// 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.
// 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct SDL_Renderer; struct SDL_Renderer;
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer); IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer);
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_Shutdown(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_NewFrame(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_NewFrame();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer); IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data);
// Called by Init/NewFrame/Shutdown // Called by Init/NewFrame/Shutdown
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateFontsTexture(); IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyFontsTexture(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -13,16 +13,13 @@
// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!) // - [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) // - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in our batch files)
// 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/
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder). // The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
// - Introduction, links and more at the top of imgui.cpp // IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app. // Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. // - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
@ -33,23 +30,10 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 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.
// 2024-01-19: Vulkan: Fixed vkAcquireNextImageKHR() validation errors in VulkanSDK 1.3.275 by allocating one extra semaphore than in-flight frames. (#7236)
// 2024-01-11: Vulkan: Fixed vkMapMemory() calls unnecessarily using full buffer size (#3957). Fixed MinAllocationSize handing (#7189).
// 2024-01-03: Vulkan: Added MinAllocationSize field in ImGui_ImplVulkan_InitInfo to workaround zealous "best practice" validation layer. (#7189, #4238)
// 2024-01-03: Vulkan: Stopped creating command pools with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT as we don't reset them.
// 2023-11-29: Vulkan: Fixed mismatching allocator passed to vkCreateCommandPool() vs vkDestroyCommandPool(). (#7075)
// 2023-11-10: *BREAKING CHANGE*: Removed parameter from ImGui_ImplVulkan_CreateFontsTexture(): backend now creates its own command-buffer to upload fonts.
// *BREAKING CHANGE*: Removed ImGui_ImplVulkan_DestroyFontUploadObjects() which is now unnecessary as we create and destroy those objects in the backend.
// ImGui_ImplVulkan_CreateFontsTexture() is automatically called by NewFrame() the first time.
// You can call ImGui_ImplVulkan_CreateFontsTexture() again to recreate the font atlas texture.
// Added ImGui_ImplVulkan_DestroyFontsTexture() but you probably never need to call this.
// 2023-07-04: Vulkan: Added optional support for VK_KHR_dynamic_rendering. User needs to set init_info->UseDynamicRendering = true and init_info->ColorAttachmentFormat. // 2023-07-04: Vulkan: Added optional support for VK_KHR_dynamic_rendering. User needs to set init_info->UseDynamicRendering = true and init_info->ColorAttachmentFormat.
// 2023-01-02: Vulkan: Fixed sampler passed to ImGui_ImplVulkan_AddTexture() not being honored + removed a bunch of duplicate code. // 2023-01-02: Vulkan: Fixed sampler passed to ImGui_ImplVulkan_AddTexture() not being honored + removed a bunch of duplicate code.
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2022-10-04: Vulkan: Added experimental ImGui_ImplVulkan_RemoveTexture() for api symmetry. (#914, #5738). // 2022-10-04: Vulkan: Added experimental ImGui_ImplVulkan_RemoveTexture() for api symetry. (#914, #5738).
// 2022-01-20: Vulkan: Added support for ImTextureID as VkDescriptorSet. User need to call ImGui_ImplVulkan_AddTexture(). Building for 32-bit targets requires '#define ImTextureID ImU64'. (#914). // 2022-01-20: Vulkan: Added support for ImTextureID as VkDescriptorSet. User need to call ImGui_ImplVulkan_AddTexture(). Building for 32-bit targets requires '#define ImTextureID ImU64'. (#914).
// 2021-10-15: Vulkan: Call vkCmdSetScissor() at the end of render a full-viewport to reduce likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame. // 2021-10-15: Vulkan: Call vkCmdSetScissor() at the end of render a full-viewport to reduce likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame.
// 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-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).
@ -82,45 +66,90 @@
// 2016-10-18: Vulkan: Add location decorators & change to use structs as in/out in glsl, update embedded spv (produced with glslangValidator -x). Null the released resources. // 2016-10-18: Vulkan: Add location decorators & change to use structs as in/out in glsl, update embedded spv (produced with glslangValidator -x). Null the released resources.
// 2016-08-27: Vulkan: Fix Vulkan example for use when a depth buffer is active. // 2016-08-27: Vulkan: Fix Vulkan example for use when a depth buffer is active.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_vulkan.h" #include "imgui_impl_vulkan.h"
#include <stdio.h> #include <stdio.h>
#ifndef IM_MAX
#define IM_MAX(A, B) (((A) >= (B)) ? (A) : (B))
#endif
// Visual Studio warnings // Visual Studio warnings
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable: 4127) // condition expression is constant #pragma warning (disable: 4127) // condition expression is constant
#endif #endif
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
// [Please zero-clear before use!]
struct ImGui_ImplVulkanH_FrameRenderBuffers
{
VkDeviceMemory VertexBufferMemory;
VkDeviceMemory IndexBufferMemory;
VkDeviceSize VertexBufferSize;
VkDeviceSize IndexBufferSize;
VkBuffer VertexBuffer;
VkBuffer IndexBuffer;
};
// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
// [Please zero-clear before use!]
struct ImGui_ImplVulkanH_WindowRenderBuffers
{
uint32_t Index;
uint32_t Count;
ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers;
};
// Vulkan data
struct ImGui_ImplVulkan_Data
{
ImGui_ImplVulkan_InitInfo VulkanInitInfo;
VkRenderPass RenderPass;
VkDeviceSize BufferMemoryAlignment;
VkPipelineCreateFlags PipelineCreateFlags;
VkDescriptorSetLayout DescriptorSetLayout;
VkPipelineLayout PipelineLayout;
VkPipeline Pipeline;
uint32_t Subpass;
VkShaderModule ShaderModuleVert;
VkShaderModule ShaderModuleFrag;
// Font data
VkSampler FontSampler;
VkDeviceMemory FontMemory;
VkImage FontImage;
VkImageView FontView;
VkDescriptorSet FontDescriptorSet;
VkDeviceMemory UploadBufferMemory;
VkBuffer UploadBuffer;
// Render buffers for main window
ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers;
ImGui_ImplVulkan_Data()
{
memset((void*)this, 0, sizeof(*this));
BufferMemoryAlignment = 256;
}
};
// Forward Declarations // Forward Declarations
struct ImGui_ImplVulkan_FrameRenderBuffers;
struct ImGui_ImplVulkan_WindowRenderBuffers;
bool ImGui_ImplVulkan_CreateDeviceObjects(); bool ImGui_ImplVulkan_CreateDeviceObjects();
void ImGui_ImplVulkan_DestroyDeviceObjects(); void ImGui_ImplVulkan_DestroyDeviceObjects();
void ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkan_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator); void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator);
void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator); void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator);
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator); void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
// Vulkan prototypes for use with custom loaders // Vulkan prototypes for use with custom loaders
// (see description of IMGUI_IMPL_VULKAN_NO_PROTOTYPES in imgui_impl_vulkan.h // (see description of IMGUI_IMPL_VULKAN_NO_PROTOTYPES in imgui_impl_vulkan.h
#if defined(VK_NO_PROTOTYPES) && !defined(VOLK_H_) #ifdef VK_NO_PROTOTYPES
#define IMGUI_IMPL_VULKAN_USE_LOADER
static bool g_FunctionsLoaded = false; static bool g_FunctionsLoaded = false;
#else #else
static bool g_FunctionsLoaded = true; static bool g_FunctionsLoaded = true;
#endif #endif
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER #ifdef VK_NO_PROTOTYPES
#define IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_MAP_MACRO) \ #define IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_MAP_MACRO) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateCommandBuffers) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateCommandBuffers) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateDescriptorSets) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateDescriptorSets) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateMemory) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBeginCommandBuffer) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindBufferMemory) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindBufferMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindImageMemory) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindImageMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindDescriptorSets) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindDescriptorSets) \
@ -163,7 +192,6 @@ static bool g_FunctionsLoaded = true;
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySurfaceKHR) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySurfaceKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySwapchainKHR) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySwapchainKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDeviceWaitIdle) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkDeviceWaitIdle) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkEndCommandBuffer) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFlushMappedMemoryRanges) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkFlushMappedMemoryRanges) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeCommandBuffers) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeCommandBuffers) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeDescriptorSets) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeDescriptorSets) \
@ -176,9 +204,6 @@ static bool g_FunctionsLoaded = true;
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfacePresentModesKHR) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfacePresentModesKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetSwapchainImagesKHR) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetSwapchainImagesKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkMapMemory) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkMapMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueueSubmit) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueueWaitIdle) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkResetCommandPool) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUnmapMemory) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkUnmapMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets) IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets)
@ -186,70 +211,19 @@ static bool g_FunctionsLoaded = true;
#define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func; #define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func;
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF) IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
#undef IMGUI_VULKAN_FUNC_DEF #undef IMGUI_VULKAN_FUNC_DEF
#endif // IMGUI_IMPL_VULKAN_USE_LOADER #endif // VK_NO_PROTOTYPES
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING #if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
static PFN_vkCmdBeginRenderingKHR ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR; static PFN_vkCmdBeginRenderingKHR ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR;
static PFN_vkCmdEndRenderingKHR ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR; static PFN_vkCmdEndRenderingKHR ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR;
#endif #endif
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
// [Please zero-clear before use!]
struct ImGui_ImplVulkan_FrameRenderBuffers
{
VkDeviceMemory VertexBufferMemory;
VkDeviceMemory IndexBufferMemory;
VkDeviceSize VertexBufferSize;
VkDeviceSize IndexBufferSize;
VkBuffer VertexBuffer;
VkBuffer IndexBuffer;
};
// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
// [Please zero-clear before use!]
struct ImGui_ImplVulkan_WindowRenderBuffers
{
uint32_t Index;
uint32_t Count;
ImGui_ImplVulkan_FrameRenderBuffers* FrameRenderBuffers;
};
// Vulkan data
struct ImGui_ImplVulkan_Data
{
ImGui_ImplVulkan_InitInfo VulkanInitInfo;
VkDeviceSize BufferMemoryAlignment;
VkPipelineCreateFlags PipelineCreateFlags;
VkDescriptorSetLayout DescriptorSetLayout;
VkPipelineLayout PipelineLayout;
VkPipeline Pipeline;
VkShaderModule ShaderModuleVert;
VkShaderModule ShaderModuleFrag;
// Font data
VkSampler FontSampler;
VkDeviceMemory FontMemory;
VkImage FontImage;
VkImageView FontView;
VkDescriptorSet FontDescriptorSet;
VkCommandPool FontCommandPool;
VkCommandBuffer FontCommandBuffer;
// Render buffers for main window
ImGui_ImplVulkan_WindowRenderBuffers MainWindowRenderBuffers;
ImGui_ImplVulkan_Data()
{
memset((void*)this, 0, sizeof(*this));
BufferMemoryAlignment = 256;
}
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// SHADERS // SHADERS
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// backends/vulkan/glsl_shader.vert, compiled with: // glsl_shader.vert, compiled with:
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert // # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
/* /*
#version 450 core #version 450 core
@ -313,7 +287,7 @@ static uint32_t __glsl_shader_vert_spv[] =
0x0000002d,0x0000002c,0x000100fd,0x00010038 0x0000002d,0x0000002c,0x000100fd,0x00010038
}; };
// backends/vulkan/glsl_shader.frag, compiled with: // glsl_shader.frag, compiled with:
// # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag // # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag
/* /*
#version 450 core #version 450 core
@ -388,13 +362,7 @@ static void check_vk_result(VkResult err)
v->CheckVkResultFn(err); v->CheckVkResultFn(err);
} }
// Same as IM_MEMALIGN(). 'alignment' must be a power of two. static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& p_buffer_size, size_t new_size, VkBufferUsageFlagBits usage)
static inline VkDeviceSize AlignBufferSize(VkDeviceSize size, VkDeviceSize alignment)
{
return (size + alignment - 1) & ~(alignment - 1);
}
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& buffer_size, size_t new_size, VkBufferUsageFlagBits usage)
{ {
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
@ -404,10 +372,10 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
if (buffer_memory != VK_NULL_HANDLE) if (buffer_memory != VK_NULL_HANDLE)
vkFreeMemory(v->Device, buffer_memory, v->Allocator); vkFreeMemory(v->Device, buffer_memory, v->Allocator);
VkDeviceSize buffer_size_aligned = AlignBufferSize(IM_MAX(v->MinAllocationSize, new_size), bd->BufferMemoryAlignment); VkDeviceSize vertex_buffer_size_aligned = ((new_size - 1) / bd->BufferMemoryAlignment + 1) * bd->BufferMemoryAlignment;
VkBufferCreateInfo buffer_info = {}; VkBufferCreateInfo buffer_info = {};
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_info.size = buffer_size_aligned; buffer_info.size = vertex_buffer_size_aligned;
buffer_info.usage = usage; buffer_info.usage = usage;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &buffer); err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &buffer);
@ -425,10 +393,10 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0); err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0);
check_vk_result(err); check_vk_result(err);
buffer_size = buffer_size_aligned; p_buffer_size = req.size;
} }
static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkan_FrameRenderBuffers* rb, int fb_width, int fb_height) static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height)
{ {
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
@ -487,23 +455,23 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
pipeline = bd->Pipeline; pipeline = bd->Pipeline;
// Allocate array to store enough vertex/index buffers // Allocate array to store enough vertex/index buffers
ImGui_ImplVulkan_WindowRenderBuffers* wrb = &bd->MainWindowRenderBuffers; ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &bd->MainWindowRenderBuffers;
if (wrb->FrameRenderBuffers == nullptr) if (wrb->FrameRenderBuffers == nullptr)
{ {
wrb->Index = 0; wrb->Index = 0;
wrb->Count = v->ImageCount; wrb->Count = v->ImageCount;
wrb->FrameRenderBuffers = (ImGui_ImplVulkan_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count); wrb->FrameRenderBuffers = (ImGui_ImplVulkanH_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count);
memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count); memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count);
} }
IM_ASSERT(wrb->Count == v->ImageCount); IM_ASSERT(wrb->Count == v->ImageCount);
wrb->Index = (wrb->Index + 1) % wrb->Count; wrb->Index = (wrb->Index + 1) % wrb->Count;
ImGui_ImplVulkan_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index]; ImGui_ImplVulkanH_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index];
if (draw_data->TotalVtxCount > 0) if (draw_data->TotalVtxCount > 0)
{ {
// Create or resize the vertex/index buffers // Create or resize the vertex/index buffers
size_t vertex_size = AlignBufferSize(draw_data->TotalVtxCount * sizeof(ImDrawVert), bd->BufferMemoryAlignment); size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
size_t index_size = AlignBufferSize(draw_data->TotalIdxCount * sizeof(ImDrawIdx), bd->BufferMemoryAlignment); size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size) 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); 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) if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size)
@ -512,9 +480,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
// Upload vertex/index data into a single contiguous GPU buffer // Upload vertex/index data into a single contiguous GPU buffer
ImDrawVert* vtx_dst = nullptr; ImDrawVert* vtx_dst = nullptr;
ImDrawIdx* idx_dst = nullptr; ImDrawIdx* idx_dst = nullptr;
VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)&vtx_dst); VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)(&vtx_dst));
check_vk_result(err); check_vk_result(err);
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)&idx_dst); err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)(&idx_dst));
check_vk_result(err); check_vk_result(err);
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
@ -614,55 +582,19 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
vkCmdSetScissor(command_buffer, 0, 1, &scissor); vkCmdSetScissor(command_buffer, 0, 1, &scissor);
} }
bool ImGui_ImplVulkan_CreateFontsTexture() bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
VkResult err;
// Destroy existing texture (if any)
if (bd->FontView || bd->FontImage || bd->FontMemory || bd->FontDescriptorSet)
{
vkQueueWaitIdle(v->Queue);
ImGui_ImplVulkan_DestroyFontsTexture();
}
// Create command pool/buffer
if (bd->FontCommandPool == 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);
}
if (bd->FontCommandBuffer == VK_NULL_HANDLE)
{
VkCommandBufferAllocateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
info.commandPool = bd->FontCommandPool;
info.commandBufferCount = 1;
err = vkAllocateCommandBuffers(v->Device, &info, &bd->FontCommandBuffer);
check_vk_result(err);
}
// Start command buffer
{
err = vkResetCommandPool(v->Device, bd->FontCommandPool, 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);
check_vk_result(err);
}
unsigned char* pixels; unsigned char* pixels;
int width, height; int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
size_t upload_size = width * height * 4 * sizeof(char); size_t upload_size = width * height * 4 * sizeof(char);
VkResult err;
// Create the Image: // Create the Image:
{ {
VkImageCreateInfo info = {}; VkImageCreateInfo info = {};
@ -685,7 +617,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
vkGetImageMemoryRequirements(v->Device, bd->FontImage, &req); vkGetImageMemoryRequirements(v->Device, bd->FontImage, &req);
VkMemoryAllocateInfo alloc_info = {}; VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = IM_MAX(v->MinAllocationSize, req.size); alloc_info.allocationSize = req.size;
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits); 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, &bd->FontMemory);
check_vk_result(err); check_vk_result(err);
@ -711,42 +643,40 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
bd->FontDescriptorSet = (VkDescriptorSet)ImGui_ImplVulkan_AddTexture(bd->FontSampler, bd->FontView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); bd->FontDescriptorSet = (VkDescriptorSet)ImGui_ImplVulkan_AddTexture(bd->FontSampler, bd->FontView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
// Create the Upload Buffer: // Create the Upload Buffer:
VkDeviceMemory upload_buffer_memory;
VkBuffer upload_buffer;
{ {
VkBufferCreateInfo buffer_info = {}; VkBufferCreateInfo buffer_info = {};
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_info.size = upload_size; buffer_info.size = upload_size;
buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &upload_buffer); err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &bd->UploadBuffer);
check_vk_result(err); check_vk_result(err);
VkMemoryRequirements req; VkMemoryRequirements req;
vkGetBufferMemoryRequirements(v->Device, upload_buffer, &req); vkGetBufferMemoryRequirements(v->Device, bd->UploadBuffer, &req);
bd->BufferMemoryAlignment = (bd->BufferMemoryAlignment > req.alignment) ? bd->BufferMemoryAlignment : req.alignment; bd->BufferMemoryAlignment = (bd->BufferMemoryAlignment > req.alignment) ? bd->BufferMemoryAlignment : req.alignment;
VkMemoryAllocateInfo alloc_info = {}; VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = IM_MAX(v->MinAllocationSize, req.size); alloc_info.allocationSize = req.size;
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &upload_buffer_memory); err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &bd->UploadBufferMemory);
check_vk_result(err); check_vk_result(err);
err = vkBindBufferMemory(v->Device, upload_buffer, upload_buffer_memory, 0); err = vkBindBufferMemory(v->Device, bd->UploadBuffer, bd->UploadBufferMemory, 0);
check_vk_result(err); check_vk_result(err);
} }
// Upload to Buffer: // Upload to Buffer:
{ {
char* map = nullptr; char* map = nullptr;
err = vkMapMemory(v->Device, upload_buffer_memory, 0, upload_size, 0, (void**)(&map)); err = vkMapMemory(v->Device, bd->UploadBufferMemory, 0, upload_size, 0, (void**)(&map));
check_vk_result(err); check_vk_result(err);
memcpy(map, pixels, upload_size); memcpy(map, pixels, upload_size);
VkMappedMemoryRange range[1] = {}; VkMappedMemoryRange range[1] = {};
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range[0].memory = upload_buffer_memory; range[0].memory = bd->UploadBufferMemory;
range[0].size = upload_size; range[0].size = upload_size;
err = vkFlushMappedMemoryRanges(v->Device, 1, range); err = vkFlushMappedMemoryRanges(v->Device, 1, range);
check_vk_result(err); check_vk_result(err);
vkUnmapMemory(v->Device, upload_buffer_memory); vkUnmapMemory(v->Device, bd->UploadBufferMemory);
} }
// Copy to Image: // Copy to Image:
@ -762,7 +692,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_barrier[0].subresourceRange.levelCount = 1; copy_barrier[0].subresourceRange.levelCount = 1;
copy_barrier[0].subresourceRange.layerCount = 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(command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, copy_barrier);
VkBufferImageCopy region = {}; VkBufferImageCopy region = {};
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -770,7 +700,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
region.imageExtent.width = width; region.imageExtent.width = width;
region.imageExtent.height = height; region.imageExtent.height = height;
region.imageExtent.depth = 1; region.imageExtent.depth = 1;
vkCmdCopyBufferToImage(bd->FontCommandBuffer, upload_buffer, bd->FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region); vkCmdCopyBufferToImage(command_buffer, bd->UploadBuffer, bd->FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
VkImageMemoryBarrier use_barrier[1] = {}; VkImageMemoryBarrier use_barrier[1] = {};
use_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; use_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@ -784,50 +714,15 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
use_barrier[0].subresourceRange.levelCount = 1; use_barrier[0].subresourceRange.levelCount = 1;
use_barrier[0].subresourceRange.layerCount = 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(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, use_barrier);
} }
// Store our identifier // Store our identifier
io.Fonts->SetTexID((ImTextureID)bd->FontDescriptorSet); io.Fonts->SetTexID((ImTextureID)bd->FontDescriptorSet);
// 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);
check_vk_result(err);
err = vkQueueSubmit(v->Queue, 1, &end_info, VK_NULL_HANDLE);
check_vk_result(err);
err = vkQueueWaitIdle(v->Queue);
check_vk_result(err);
vkDestroyBuffer(v->Device, upload_buffer, v->Allocator);
vkFreeMemory(v->Device, upload_buffer_memory, v->Allocator);
return true; return true;
} }
// You probably never need to call this, as it is called by ImGui_ImplVulkan_CreateFontsTexture() and ImGui_ImplVulkan_Shutdown().
void ImGui_ImplVulkan_DestroyFontsTexture()
{
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
if (bd->FontDescriptorSet)
{
ImGui_ImplVulkan_RemoveTexture(bd->FontDescriptorSet);
bd->FontDescriptorSet = 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; }
}
static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAllocationCallbacks* allocator) static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAllocationCallbacks* allocator)
{ {
// Create the shader modules // Create the shader modules
@ -875,15 +770,15 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
attribute_desc[0].location = 0; attribute_desc[0].location = 0;
attribute_desc[0].binding = binding_desc[0].binding; attribute_desc[0].binding = binding_desc[0].binding;
attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT; attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT;
attribute_desc[0].offset = offsetof(ImDrawVert, pos); attribute_desc[0].offset = IM_OFFSETOF(ImDrawVert, pos);
attribute_desc[1].location = 1; attribute_desc[1].location = 1;
attribute_desc[1].binding = binding_desc[0].binding; attribute_desc[1].binding = binding_desc[0].binding;
attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT; attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT;
attribute_desc[1].offset = offsetof(ImDrawVert, uv); attribute_desc[1].offset = IM_OFFSETOF(ImDrawVert, uv);
attribute_desc[2].location = 2; attribute_desc[2].location = 2;
attribute_desc[2].binding = binding_desc[0].binding; attribute_desc[2].binding = binding_desc[0].binding;
attribute_desc[2].format = VK_FORMAT_R8G8B8A8_UNORM; attribute_desc[2].format = VK_FORMAT_R8G8B8A8_UNORM;
attribute_desc[2].offset = offsetof(ImDrawVert, col); attribute_desc[2].offset = IM_OFFSETOF(ImDrawVert, col);
VkPipelineVertexInputStateCreateInfo vertex_info = {}; VkPipelineVertexInputStateCreateInfo vertex_info = {};
vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
@ -954,11 +849,13 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
info.subpass = subpass; info.subpass = subpass;
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
VkPipelineRenderingCreateInfoKHR pipelineRenderingCreateInfo = {};
pipelineRenderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
pipelineRenderingCreateInfo.colorAttachmentCount = 1;
pipelineRenderingCreateInfo.pColorAttachmentFormats = &bd->VulkanInitInfo.ColorAttachmentFormat;
if (bd->VulkanInitInfo.UseDynamicRendering) 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"); info.pNext = &pipelineRenderingCreateInfo;
IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.pNext == nullptr && "PipelineRenderingCreateInfo pNext must be NULL");
info.pNext = &bd->VulkanInitInfo.PipelineRenderingCreateInfo;
info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr. info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr.
} }
#endif #endif
@ -1023,22 +920,39 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
check_vk_result(err); check_vk_result(err);
} }
ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, v->RenderPass, v->MSAASamples, &bd->Pipeline, v->Subpass); ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, bd->RenderPass, v->MSAASamples, &bd->Pipeline, bd->Subpass);
return true; return true;
} }
void ImGui_ImplVulkan_DestroyFontUploadObjects()
{
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
if (bd->UploadBuffer)
{
vkDestroyBuffer(v->Device, bd->UploadBuffer, v->Allocator);
bd->UploadBuffer = VK_NULL_HANDLE;
}
if (bd->UploadBufferMemory)
{
vkFreeMemory(v->Device, bd->UploadBufferMemory, v->Allocator);
bd->UploadBufferMemory = VK_NULL_HANDLE;
}
}
void ImGui_ImplVulkan_DestroyDeviceObjects() void ImGui_ImplVulkan_DestroyDeviceObjects()
{ {
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
ImGui_ImplVulkan_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator); ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
ImGui_ImplVulkan_DestroyFontsTexture(); ImGui_ImplVulkan_DestroyFontUploadObjects();
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->ShaderModuleVert) { vkDestroyShaderModule(v->Device, bd->ShaderModuleVert, v->Allocator); bd->ShaderModuleVert = 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->ShaderModuleFrag) { vkDestroyShaderModule(v->Device, bd->ShaderModuleFrag, v->Allocator); bd->ShaderModuleFrag = VK_NULL_HANDLE; }
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 (bd->FontSampler) { vkDestroySampler(v->Device, bd->FontSampler, v->Allocator); bd->FontSampler = 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->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->PipelineLayout) { vkDestroyPipelineLayout(v->Device, bd->PipelineLayout, v->Allocator); bd->PipelineLayout = VK_NULL_HANDLE; }
@ -1050,8 +964,8 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch
// Load function pointers // Load function pointers
// You can use the default Vulkan loader using: // You can use the default Vulkan loader using:
// ImGui_ImplVulkan_LoadFunctions([](const char* function_name, void*) { return vkGetInstanceProcAddr(your_vk_isntance, function_name); }); // ImGui_ImplVulkan_LoadFunctions([](const char* function_name, void*) { return vkGetInstanceProcAddr(your_vk_isntance, function_name); });
// But this would be roughly equivalent to not setting VK_NO_PROTOTYPES. // But this would be equivalent to not setting VK_NO_PROTOTYPES.
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER #ifdef VK_NO_PROTOTYPES
#define IMGUI_VULKAN_FUNC_LOAD(func) \ #define IMGUI_VULKAN_FUNC_LOAD(func) \
func = reinterpret_cast<decltype(func)>(loader_func(#func, user_data)); \ func = reinterpret_cast<decltype(func)>(loader_func(#func, user_data)); \
if (func == nullptr) \ if (func == nullptr) \
@ -1073,14 +987,14 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch
return true; return true;
} }
bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info) bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass)
{ {
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!"); IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
if (info->UseDynamicRendering) if (info->UseDynamicRendering)
{ {
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
#ifndef IMGUI_IMPL_VULKAN_USE_LOADER #ifndef VK_NO_PROTOTYPES
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR")); ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR"));
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR")); ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR"));
#endif #endif
@ -1092,7 +1006,6 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
} }
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags
@ -1109,9 +1022,11 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
IM_ASSERT(info->MinImageCount >= 2); IM_ASSERT(info->MinImageCount >= 2);
IM_ASSERT(info->ImageCount >= info->MinImageCount); IM_ASSERT(info->ImageCount >= info->MinImageCount);
if (info->UseDynamicRendering == false) if (info->UseDynamicRendering == false)
IM_ASSERT(info->RenderPass != VK_NULL_HANDLE); IM_ASSERT(render_pass != VK_NULL_HANDLE);
bd->VulkanInitInfo = *info; bd->VulkanInitInfo = *info;
bd->RenderPass = render_pass;
bd->Subpass = info->Subpass;
ImGui_ImplVulkan_CreateDeviceObjects(); ImGui_ImplVulkan_CreateDeviceObjects();
@ -1134,10 +1049,8 @@ void ImGui_ImplVulkan_Shutdown()
void ImGui_ImplVulkan_NewFrame() void ImGui_ImplVulkan_NewFrame()
{ {
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplVulkan_Init()?"); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplVulkan_Init()?");
IM_UNUSED(bd);
if (!bd->FontDescriptorSet)
ImGui_ImplVulkan_CreateFontsTexture();
} }
void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count) void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count)
@ -1150,7 +1063,7 @@ void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count)
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
VkResult err = vkDeviceWaitIdle(v->Device); VkResult err = vkDeviceWaitIdle(v->Device);
check_vk_result(err); check_vk_result(err);
ImGui_ImplVulkan_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator); ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
bd->VulkanInitInfo.MinImageCount = min_image_count; bd->VulkanInitInfo.MinImageCount = min_image_count;
} }
@ -1197,26 +1110,6 @@ void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set)
vkFreeDescriptorSets(v->Device, v->DescriptorPool, 1, &descriptor_set); vkFreeDescriptorSets(v->Device, v->DescriptorPool, 1, &descriptor_set);
} }
void ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
{
if (buffers->VertexBuffer) { vkDestroyBuffer(device, buffers->VertexBuffer, allocator); buffers->VertexBuffer = VK_NULL_HANDLE; }
if (buffers->VertexBufferMemory) { vkFreeMemory(device, buffers->VertexBufferMemory, allocator); buffers->VertexBufferMemory = VK_NULL_HANDLE; }
if (buffers->IndexBuffer) { vkDestroyBuffer(device, buffers->IndexBuffer, allocator); buffers->IndexBuffer = VK_NULL_HANDLE; }
if (buffers->IndexBufferMemory) { vkFreeMemory(device, buffers->IndexBufferMemory, allocator); buffers->IndexBufferMemory = VK_NULL_HANDLE; }
buffers->VertexBufferSize = 0;
buffers->IndexBufferSize = 0;
}
void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkan_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
{
for (uint32_t n = 0; n < buffers->Count; n++)
ImGui_ImplVulkan_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator);
IM_FREE(buffers->FrameRenderBuffers);
buffers->FrameRenderBuffers = nullptr;
buffers->Index = 0;
buffers->Count = 0;
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Internal / Miscellaneous Vulkan Helpers // Internal / Miscellaneous Vulkan Helpers
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.) // (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.)
@ -1304,17 +1197,19 @@ VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_d
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator) 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); IM_ASSERT(physical_device != VK_NULL_HANDLE && device != VK_NULL_HANDLE);
IM_UNUSED(physical_device); (void)physical_device;
(void)allocator;
// Create Command Buffers // Create Command Buffers
VkResult err; VkResult err;
for (uint32_t i = 0; i < wd->ImageCount; i++) for (uint32_t i = 0; i < wd->ImageCount; i++)
{ {
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i]; ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i];
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i];
{ {
VkCommandPoolCreateInfo info = {}; VkCommandPoolCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
info.flags = 0; info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
info.queueFamilyIndex = queue_family; info.queueFamilyIndex = queue_family;
err = vkCreateCommandPool(device, &info, allocator, &fd->CommandPool); err = vkCreateCommandPool(device, &info, allocator, &fd->CommandPool);
check_vk_result(err); check_vk_result(err);
@ -1335,11 +1230,6 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_devi
err = vkCreateFence(device, &info, allocator, &fd->Fence); err = vkCreateFence(device, &info, allocator, &fd->Fence);
check_vk_result(err); check_vk_result(err);
} }
}
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
{
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i];
{ {
VkSemaphoreCreateInfo info = {}; VkSemaphoreCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
@ -1375,9 +1265,10 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
// We don't use ImGui_ImplVulkanH_DestroyWindow() because we want to preserve the old swapchain to create the new one. // We don't use ImGui_ImplVulkanH_DestroyWindow() because we want to preserve the old swapchain to create the new one.
// Destroy old Framebuffer // Destroy old Framebuffer
for (uint32_t i = 0; i < wd->ImageCount; i++) for (uint32_t i = 0; i < wd->ImageCount; i++)
{
ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator); ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator);
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator); ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
}
IM_FREE(wd->Frames); IM_FREE(wd->Frames);
IM_FREE(wd->FrameSemaphores); IM_FREE(wd->FrameSemaphores);
wd->Frames = nullptr; wd->Frames = nullptr;
@ -1436,12 +1327,11 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, backbuffers); err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, backbuffers);
check_vk_result(err); check_vk_result(err);
IM_ASSERT(wd->Frames == nullptr && wd->FrameSemaphores == nullptr); IM_ASSERT(wd->Frames == nullptr);
wd->SemaphoreCount = wd->ImageCount + 1;
wd->Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * wd->ImageCount); 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); wd->FrameSemaphores = (ImGui_ImplVulkanH_FrameSemaphores*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameSemaphores) * wd->ImageCount);
memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount); memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount);
memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->SemaphoreCount); memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->ImageCount);
for (uint32_t i = 0; i < wd->ImageCount; i++) for (uint32_t i = 0; i < wd->ImageCount; i++)
wd->Frames[i].Backbuffer = backbuffers[i]; wd->Frames[i].Backbuffer = backbuffers[i];
} }
@ -1487,7 +1377,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
// We do not create a pipeline by default as this is also used by examples' main.cpp, // We do not create a pipeline by default as this is also used by examples' main.cpp,
// but secondary viewport in multi-viewport mode may want to create one with: // but secondary viewport in multi-viewport mode may want to create one with:
//ImGui_ImplVulkan_CreatePipeline(device, allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &wd->Pipeline, v->Subpass); //ImGui_ImplVulkan_CreatePipeline(device, allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &wd->Pipeline, bd->Subpass);
} }
// Create The Image Views // Create The Image Views
@ -1548,9 +1438,10 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui
//vkQueueWaitIdle(bd->Queue); //vkQueueWaitIdle(bd->Queue);
for (uint32_t i = 0; i < wd->ImageCount; i++) for (uint32_t i = 0; i < wd->ImageCount; i++)
{
ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator); ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator);
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator); ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
}
IM_FREE(wd->Frames); IM_FREE(wd->Frames);
IM_FREE(wd->FrameSemaphores); IM_FREE(wd->FrameSemaphores);
wd->Frames = nullptr; wd->Frames = nullptr;
@ -1583,6 +1474,22 @@ void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH
fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE; fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE;
} }
//----------------------------------------------------------------------------- void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
{
if (buffers->VertexBuffer) { vkDestroyBuffer(device, buffers->VertexBuffer, allocator); buffers->VertexBuffer = VK_NULL_HANDLE; }
if (buffers->VertexBufferMemory) { vkFreeMemory(device, buffers->VertexBufferMemory, allocator); buffers->VertexBufferMemory = VK_NULL_HANDLE; }
if (buffers->IndexBuffer) { vkDestroyBuffer(device, buffers->IndexBuffer, allocator); buffers->IndexBuffer = VK_NULL_HANDLE; }
if (buffers->IndexBufferMemory) { vkFreeMemory(device, buffers->IndexBufferMemory, allocator); buffers->IndexBufferMemory = VK_NULL_HANDLE; }
buffers->VertexBufferSize = 0;
buffers->IndexBufferSize = 0;
}
#endif // #ifndef IMGUI_DISABLE void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
{
for (uint32_t n = 0; n < buffers->Count; n++)
ImGui_ImplVulkanH_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator);
IM_FREE(buffers->FrameRenderBuffers);
buffers->FrameRenderBuffers = nullptr;
buffers->Index = 0;
buffers->Count = 0;
}

View File

@ -8,16 +8,13 @@
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'. // 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. // See imgui_impl_vulkan.cpp file for details.
// 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/
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder). // The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
// - Introduction, links and more at the top of imgui.cpp // IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app. // Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. // - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
@ -27,7 +24,6 @@
// Read comments in imgui_impl_vulkan.h. // Read comments in imgui_impl_vulkan.h.
#pragma once #pragma once
#ifndef IMGUI_DISABLE
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
// [Configuration] in order to use a custom Vulkan function loader: // [Configuration] in order to use a custom Vulkan function loader:
@ -42,31 +38,13 @@
// If you have no idea what this is, leave it alone! // If you have no idea what this is, leave it alone!
//#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES //#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES
// Convenience support for Volk // Vulkan includes
// (you can also technically use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().)
//#define IMGUI_IMPL_VULKAN_USE_VOLK
#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES) #if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES)
#define VK_NO_PROTOTYPES #define VK_NO_PROTOTYPES
#endif #endif
#if defined(VK_USE_PLATFORM_WIN32_KHR) && !defined(NOMINMAX)
#define NOMINMAX
#endif
// Vulkan includes
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
#include <Volk/volk.h>
#else
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#endif
#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
#endif
// Initialization data, for ImGui_ImplVulkan_Init() // 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!] // [Please zero-clear before use!]
struct ImGui_ImplVulkan_InitInfo struct ImGui_ImplVulkan_InitInfo
{ {
@ -75,36 +53,29 @@ struct ImGui_ImplVulkan_InitInfo
VkDevice Device; VkDevice Device;
uint32_t QueueFamily; uint32_t QueueFamily;
VkQueue Queue; VkQueue Queue;
VkDescriptorPool DescriptorPool; // See requirements in note above
VkRenderPass RenderPass; // Ignored if using dynamic rendering
uint32_t MinImageCount; // >= 2
uint32_t ImageCount; // >= MinImageCount
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
// (Optional)
VkPipelineCache PipelineCache; VkPipelineCache PipelineCache;
VkDescriptorPool DescriptorPool;
uint32_t Subpass; uint32_t Subpass;
uint32_t MinImageCount; // >= 2
uint32_t ImageCount; // >= MinImageCount
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
// (Optional) Dynamic Rendering // Dynamic Rendering (Optional)
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3. bool UseDynamicRendering; // Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
bool UseDynamicRendering; VkFormat ColorAttachmentFormat; // Required for dynamic rendering
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo;
#endif
// (Optional) Allocation, Debugging // Allocation, Debugging
const VkAllocationCallbacks* Allocator; const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err); void (*CheckVkResultFn)(VkResult err);
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 // Called by user code
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info); IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass);
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown(); IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame(); 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 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 bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture(); IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects();
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated) 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) // Register a texture (VkDescriptorSet == ImTextureID)
@ -179,7 +150,6 @@ struct ImGui_ImplVulkanH_Window
VkClearValue ClearValue; VkClearValue ClearValue;
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount) uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count) uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data) uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
ImGui_ImplVulkanH_Frame* Frames; ImGui_ImplVulkanH_Frame* Frames;
ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores; ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
@ -192,4 +162,3 @@ struct ImGui_ImplVulkanH_Window
} }
}; };
#endif // #ifndef IMGUI_DISABLE

View File

@ -8,19 +8,11 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 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)
// 2024-01-17: Explicitly fill all of WGPUDepthStencilState since standard removed defaults.
// 2023-07-13: Use WGPUShaderModuleWGSLDescriptor's code instead of source. use WGPUMipmapFilterMode_Linear instead of WGPUFilterMode_Linear. (#6602)
// 2023-04-11: Align buffer sizes. Use WGSL shaders instead of precompiled SPIR-V. // 2023-04-11: Align buffer sizes. Use WGSL shaders instead of precompiled SPIR-V.
// 2023-04-11: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2023-04-11: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2023-01-25: Revert automatic pipeline layout generation (see https://github.com/gpuweb/gpuweb/issues/2470) // 2023-01-25: Revert automatic pipeline layout generation (see https://github.com/gpuweb/gpuweb/issues/2470)
@ -36,7 +28,6 @@
// 2021-01-28: Initial version. // 2021-01-28: Initial version.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_wgpu.h" #include "imgui_impl_wgpu.h"
#include <limits.h> #include <limits.h>
#include <webgpu/webgpu.h> #include <webgpu/webgpu.h>
@ -76,17 +67,16 @@ struct Uniforms
struct ImGui_ImplWGPU_Data struct ImGui_ImplWGPU_Data
{ {
ImGui_ImplWGPU_InitInfo initInfo; WGPUDevice wgpuDevice = nullptr;
WGPUDevice wgpuDevice = nullptr; WGPUQueue defaultQueue = nullptr;
WGPUQueue defaultQueue = nullptr; WGPUTextureFormat renderTargetFormat = WGPUTextureFormat_Undefined;
WGPUTextureFormat renderTargetFormat = WGPUTextureFormat_Undefined; WGPUTextureFormat depthStencilFormat = WGPUTextureFormat_Undefined;
WGPUTextureFormat depthStencilFormat = WGPUTextureFormat_Undefined; WGPURenderPipeline pipelineState = nullptr;
WGPURenderPipeline pipelineState = nullptr;
RenderResources renderResources; RenderResources renderResources;
FrameResources* pFrameResources = nullptr; FrameResources* pFrameResources = nullptr;
unsigned int numFramesInFlight = 0; unsigned int numFramesInFlight = 0;
unsigned int frameIndex = UINT_MAX; unsigned int frameIndex = UINT_MAX;
}; };
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
@ -184,12 +174,6 @@ static void SafeRelease(WGPUBuffer& res)
wgpuBufferRelease(res); wgpuBufferRelease(res);
res = nullptr; res = nullptr;
} }
static void SafeRelease(WGPUPipelineLayout& res)
{
if (res)
wgpuPipelineLayoutRelease(res);
res = nullptr;
}
static void SafeRelease(WGPURenderPipeline& res) static void SafeRelease(WGPURenderPipeline& res)
{ {
if (res) if (res)
@ -246,7 +230,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
WGPUShaderModuleWGSLDescriptor wgsl_desc = {}; WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
wgsl_desc.code = wgsl_source; wgsl_desc.source = wgsl_source;
WGPUShaderModuleDescriptor desc = {}; WGPUShaderModuleDescriptor desc = {};
desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&wgsl_desc); desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&wgsl_desc);
@ -340,9 +324,7 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder) void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder)
{ {
// Avoid rendering when minimized // Avoid rendering when minimized
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdListsCount == 0)
return; return;
// FIXME: Assuming that this only gets called once per frame! // FIXME: Assuming that this only gets called once per frame!
@ -461,12 +443,6 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
// Project scissor/clipping rectangles into framebuffer space // 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_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); 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 wgpuRenderPassEncoderSetScissorRect() 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) if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue; continue;
@ -535,7 +511,7 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
WGPUSamplerDescriptor sampler_desc = {}; WGPUSamplerDescriptor sampler_desc = {};
sampler_desc.minFilter = WGPUFilterMode_Linear; sampler_desc.minFilter = WGPUFilterMode_Linear;
sampler_desc.magFilter = WGPUFilterMode_Linear; sampler_desc.magFilter = WGPUFilterMode_Linear;
sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Linear; sampler_desc.mipmapFilter = WGPUFilterMode_Linear;
sampler_desc.addressModeU = WGPUAddressMode_Repeat; sampler_desc.addressModeU = WGPUAddressMode_Repeat;
sampler_desc.addressModeV = WGPUAddressMode_Repeat; sampler_desc.addressModeV = WGPUAddressMode_Repeat;
sampler_desc.addressModeW = WGPUAddressMode_Repeat; sampler_desc.addressModeW = WGPUAddressMode_Repeat;
@ -576,7 +552,9 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined; graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined;
graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW; graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW;
graphics_pipeline_desc.primitive.cullMode = WGPUCullMode_None; graphics_pipeline_desc.primitive.cullMode = WGPUCullMode_None;
graphics_pipeline_desc.multisample = bd->initInfo.PipelineMultisampleState; graphics_pipeline_desc.multisample.count = 1;
graphics_pipeline_desc.multisample.mask = UINT_MAX;
graphics_pipeline_desc.multisample.alphaToCoverageEnabled = false;
// Bind group layouts // Bind group layouts
WGPUBindGroupLayoutEntry common_bg_layout_entries[2] = {}; WGPUBindGroupLayoutEntry common_bg_layout_entries[2] = {};
@ -618,9 +596,9 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
// Vertex input configuration // Vertex input configuration
WGPUVertexAttribute attribute_desc[] = WGPUVertexAttribute attribute_desc[] =
{ {
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 }, { WGPUVertexFormat_Float32x2, (uint64_t)IM_OFFSETOF(ImDrawVert, pos), 0 },
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 }, { WGPUVertexFormat_Float32x2, (uint64_t)IM_OFFSETOF(ImDrawVert, uv), 1 },
{ WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 }, { WGPUVertexFormat_Unorm8x4, (uint64_t)IM_OFFSETOF(ImDrawVert, col), 2 },
}; };
WGPUVertexBufferLayout buffer_layouts[1]; WGPUVertexBufferLayout buffer_layouts[1];
@ -663,13 +641,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
depth_stencil_state.depthWriteEnabled = false; depth_stencil_state.depthWriteEnabled = false;
depth_stencil_state.depthCompare = WGPUCompareFunction_Always; depth_stencil_state.depthCompare = WGPUCompareFunction_Always;
depth_stencil_state.stencilFront.compare = WGPUCompareFunction_Always; depth_stencil_state.stencilFront.compare = WGPUCompareFunction_Always;
depth_stencil_state.stencilFront.failOp = WGPUStencilOperation_Keep;
depth_stencil_state.stencilFront.depthFailOp = WGPUStencilOperation_Keep;
depth_stencil_state.stencilFront.passOp = WGPUStencilOperation_Keep;
depth_stencil_state.stencilBack.compare = WGPUCompareFunction_Always; depth_stencil_state.stencilBack.compare = WGPUCompareFunction_Always;
depth_stencil_state.stencilBack.failOp = WGPUStencilOperation_Keep;
depth_stencil_state.stencilBack.depthFailOp = WGPUStencilOperation_Keep;
depth_stencil_state.stencilBack.passOp = WGPUStencilOperation_Keep;
// Configure disabled depth-stencil state // Configure disabled depth-stencil state
graphics_pipeline_desc.depthStencil = (bd->depthStencilFormat == WGPUTextureFormat_Undefined) ? nullptr : &depth_stencil_state; graphics_pipeline_desc.depthStencil = (bd->depthStencilFormat == WGPUTextureFormat_Undefined) ? nullptr : &depth_stencil_state;
@ -699,7 +671,6 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
SafeRelease(vertex_shader_desc.module); SafeRelease(vertex_shader_desc.module);
SafeRelease(pixel_shader_desc.module); SafeRelease(pixel_shader_desc.module);
SafeRelease(graphics_pipeline_desc.layout);
SafeRelease(bg_layouts[0]); SafeRelease(bg_layouts[0]);
return true; return true;
@ -721,10 +692,9 @@ void ImGui_ImplWGPU_InvalidateDeviceObjects()
SafeRelease(bd->pFrameResources[i]); SafeRelease(bd->pFrameResources[i]);
} }
bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info) bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags
@ -733,12 +703,11 @@ bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
io.BackendRendererName = "imgui_impl_webgpu"; io.BackendRendererName = "imgui_impl_webgpu";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
bd->initInfo = *init_info; bd->wgpuDevice = device;
bd->wgpuDevice = init_info->Device;
bd->defaultQueue = wgpuDeviceGetQueue(bd->wgpuDevice); bd->defaultQueue = wgpuDeviceGetQueue(bd->wgpuDevice);
bd->renderTargetFormat = init_info->RenderTargetFormat; bd->renderTargetFormat = rt_format;
bd->depthStencilFormat = init_info->DepthStencilFormat; bd->depthStencilFormat = depth_format;
bd->numFramesInFlight = init_info->NumFramesInFlight; bd->numFramesInFlight = num_frames_in_flight;
bd->frameIndex = UINT_MAX; bd->frameIndex = UINT_MAX;
bd->renderResources.FontTexture = nullptr; bd->renderResources.FontTexture = nullptr;
@ -751,8 +720,8 @@ bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
bd->renderResources.ImageBindGroupLayout = nullptr; bd->renderResources.ImageBindGroupLayout = nullptr;
// Create buffers with a default size (they will later be grown as needed) // Create buffers with a default size (they will later be grown as needed)
bd->pFrameResources = new FrameResources[bd->numFramesInFlight]; bd->pFrameResources = new FrameResources[num_frames_in_flight];
for (unsigned int i = 0; i < bd->numFramesInFlight; i++) for (int i = 0; i < num_frames_in_flight; i++)
{ {
FrameResources* fr = &bd->pFrameResources[i]; FrameResources* fr = &bd->pFrameResources[i];
fr->IndexBuffer = nullptr; fr->IndexBuffer = nullptr;
@ -792,7 +761,3 @@ void ImGui_ImplWGPU_NewFrame()
if (!bd->pipelineState) if (!bd->pipelineState)
ImGui_ImplWGPU_CreateDeviceObjects(); ImGui_ImplWGPU_CreateDeviceObjects();
} }
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View File

@ -8,36 +8,14 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
#include <webgpu/webgpu.h> #include <webgpu/webgpu.h>
// Initialization data, for ImGui_ImplWGPU_Init() IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format = WGPUTextureFormat_Undefined);
struct ImGui_ImplWGPU_InitInfo
{
WGPUDevice Device;
int NumFramesInFlight = 3;
WGPUTextureFormat RenderTargetFormat = WGPUTextureFormat_Undefined;
WGPUTextureFormat DepthStencilFormat = WGPUTextureFormat_Undefined;
WGPUMultisampleState PipelineMultisampleState = {};
ImGui_ImplWGPU_InitInfo()
{
PipelineMultisampleState.count = 1;
PipelineMultisampleState.mask = UINT32_MAX;
PipelineMultisampleState.alphaToCoverageEnabled = false;
}
};
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_Shutdown();
IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame(); IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame();
IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder); IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder);
@ -45,5 +23,3 @@ IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURen
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View File

@ -10,20 +10,31 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// Configuration flags to add in your imconfig file: #include "imgui.h"
#include "imgui_impl_win32.h"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <windowsx.h> // GET_X_LPARAM(), GET_Y_LPARAM()
#include <tchar.h>
#include <dwmapi.h>
// Configuration flags to add in your imconfig.h file:
//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant. //#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant.
// Using XInput for gamepad (will load DLL dynamically)
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
#include <xinput.h>
typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
#endif
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 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.
// 2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218) // 2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218)
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702) // 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702)
// 2023-02-15: Inputs: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse position over non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162) // 2023-02-15: Inputs: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse position over non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162)
@ -73,34 +84,6 @@
// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(nullptr) when io.MouseDrawCursor is set. // 2016-11-12: Inputs: Only call Win32 ::SetCursor(nullptr) when io.MouseDrawCursor is set.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_win32.h"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <windowsx.h> // GET_X_LPARAM(), GET_Y_LPARAM()
#include <tchar.h>
#include <dwmapi.h>
// Using XInput for gamepad (will load DLL dynamically)
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
#include <xinput.h>
typedef DWORD(WINAPI* PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
typedef DWORD(WINAPI* PFN_XInputGetState)(DWORD, XINPUT_STATE*);
#endif
// Clang/GCC warnings with -Weverything
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
#endif
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
#endif
struct ImGui_ImplWin32_Data struct ImGui_ImplWin32_Data
{ {
HWND hWnd; HWND hWnd;
@ -110,7 +93,6 @@ struct ImGui_ImplWin32_Data
INT64 Time; INT64 Time;
INT64 TicksPerSecond; INT64 TicksPerSecond;
ImGuiMouseCursor LastMouseCursor; ImGuiMouseCursor LastMouseCursor;
UINT32 KeyboardCodePage;
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
bool HasGamepad; bool HasGamepad;
@ -133,20 +115,9 @@ static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
} }
// Functions // Functions
static void ImGui_ImplWin32_UpdateKeyboardCodePage()
{
// Retrieve keyboard code page, required for handling of non-Unicode Windows.
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
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)
bd->KeyboardCodePage = CP_ACP; // Fallback to default ANSI code page when fails.
}
static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc) static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
INT64 perf_frequency, perf_counter; INT64 perf_frequency, perf_counter;
@ -166,7 +137,6 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
bd->TicksPerSecond = perf_frequency; bd->TicksPerSecond = perf_frequency;
bd->Time = perf_counter; bd->Time = perf_counter;
bd->LastMouseCursor = ImGuiMouseCursor_COUNT; bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
ImGui_ImplWin32_UpdateKeyboardCodePage();
// Set platform dependent data in viewport // Set platform dependent data in viewport
ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd; ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd;
@ -383,9 +353,9 @@ static void ImGui_ImplWin32_UpdateGamepads()
void ImGui_ImplWin32_NewFrame() void ImGui_ImplWin32_NewFrame()
{ {
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized? Did you call ImGui_ImplWin32_Init()?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplWin32_Init()?");
// Setup display size (every frame to accommodate for window resizing) // Setup display size (every frame to accommodate for window resizing)
RECT rect = { 0, 0, 0, 0 }; RECT rect = { 0, 0, 0, 0 };
@ -528,20 +498,6 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
case VK_F10: return ImGuiKey_F10; case VK_F10: return ImGuiKey_F10;
case VK_F11: return ImGuiKey_F11; case VK_F11: return ImGuiKey_F11;
case VK_F12: return ImGuiKey_F12; case VK_F12: return ImGuiKey_F12;
case VK_F13: return ImGuiKey_F13;
case VK_F14: return ImGuiKey_F14;
case VK_F15: return ImGuiKey_F15;
case VK_F16: return ImGuiKey_F16;
case VK_F17: return ImGuiKey_F17;
case VK_F18: return ImGuiKey_F18;
case VK_F19: return ImGuiKey_F19;
case VK_F20: return ImGuiKey_F20;
case VK_F21: return ImGuiKey_F21;
case VK_F22: return ImGuiKey_F22;
case VK_F23: return ImGuiKey_F23;
case VK_F24: return ImGuiKey_F24;
case VK_BROWSER_BACK: return ImGuiKey_AppBack;
case VK_BROWSER_FORWARD: return ImGuiKey_AppForward;
default: return ImGuiKey_None; default: return ImGuiKey_None;
} }
} }
@ -581,12 +537,11 @@ static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 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(). if (ImGui::GetCurrentContext() == nullptr)
// We silently allow both context or just only backend data to be nullptr.
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
if (bd == nullptr)
return 0; return 0;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
switch (msg) switch (msg)
{ {
@ -608,10 +563,10 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
} }
POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) }; POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
if (msg == WM_NCMOUSEMOVE && ::ScreenToClient(hwnd, &mouse_pos) == FALSE) // WM_NCMOUSEMOVE are provided in absolute coordinates. if (msg == WM_NCMOUSEMOVE && ::ScreenToClient(hwnd, &mouse_pos) == FALSE) // WM_NCMOUSEMOVE are provided in absolute coordinates.
return 0; break;
io.AddMouseSourceEvent(mouse_source); io.AddMouseSourceEvent(mouse_source);
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y); io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
return 0; break;
} }
case WM_MOUSELEAVE: case WM_MOUSELEAVE:
case WM_NCMOUSELEAVE: case WM_NCMOUSELEAVE:
@ -624,7 +579,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
bd->MouseTrackedArea = 0; bd->MouseTrackedArea = 0;
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
} }
return 0; break;
} }
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
@ -684,14 +639,10 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
int vk = (int)wParam; int vk = (int)wParam;
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED)) if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
vk = IM_VK_KEYPAD_ENTER; vk = IM_VK_KEYPAD_ENTER;
const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
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);
// Submit key event // Submit key event
const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
const int scancode = (int)LOBYTE(HIWORD(lParam));
if (key != ImGuiKey_None) if (key != ImGuiKey_None)
ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode); ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);
@ -719,9 +670,6 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
case WM_KILLFOCUS: case WM_KILLFOCUS:
io.AddFocusEvent(msg == WM_SETFOCUS); io.AddFocusEvent(msg == WM_SETFOCUS);
return 0; return 0;
case WM_INPUTLANGCHANGE:
ImGui_ImplWin32_UpdateKeyboardCodePage();
return 0;
case WM_CHAR: case WM_CHAR:
if (::IsWindowUnicode(hwnd)) if (::IsWindowUnicode(hwnd))
{ {
@ -732,7 +680,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
else else
{ {
wchar_t wch = 0; wchar_t wch = 0;
::MultiByteToWideChar(bd->KeyboardCodePage, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1); ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1);
io.AddInputCharacter(wch); io.AddInputCharacter(wch);
} }
return 0; return 0;
@ -911,12 +859,3 @@ void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
} }
//--------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -10,15 +10,11 @@
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // 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. // 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: // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// - FAQ https://dearimgui.com/faq // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd); IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd);
@ -48,5 +44,3 @@ IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); //
// - Use to enable alpha compositing transparency with the desktop. // - Use to enable alpha compositing transparency with the desktop.
// - Use together with e.g. clearing your framebuffer with zero-alpha. // - Use together with e.g. clearing your framebuffer with zero-alpha.
IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
#endif // #ifndef IMGUI_DISABLE

View File

@ -63,7 +63,7 @@ List of Platforms Backends:
imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/ imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/
imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends) imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends)
imgui_impl_sdl2.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org imgui_impl_sdl2.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org
imgui_impl_sdl3.cpp ; SDL3 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org (*EXPERIMENTAL UNTIL SDL3 IS RELEASED*) imgui_impl_sdl3.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org (*EXPERIMENTAL*)
imgui_impl_win32.cpp ; Win32 native API (Windows) imgui_impl_win32.cpp ; Win32 native API (Windows)
imgui_impl_glut.cpp ; GLUT/FreeGLUT (this is prehistoric software and absolutely not recommended today!) imgui_impl_glut.cpp ; GLUT/FreeGLUT (this is prehistoric software and absolutely not recommended today!)
@ -79,14 +79,14 @@ List of Renderer Backends:
imgui_impl_sdlrenderer2.cpp ; SDL_Renderer (optional component of SDL2 available from SDL 2.0.18+) imgui_impl_sdlrenderer2.cpp ; SDL_Renderer (optional component of SDL2 available from SDL 2.0.18+)
imgui_impl_sdlrenderer3.cpp ; SDL_Renderer (optional component of SDL3 available from SDL 3.0.0+) imgui_impl_sdlrenderer3.cpp ; SDL_Renderer (optional component of SDL3 available from SDL 3.0.0+)
imgui_impl_vulkan.cpp ; Vulkan imgui_impl_vulkan.cpp ; Vulkan
imgui_impl_wgpu.cpp ; WebGPU (web and desktop) imgui_impl_wgpu.cpp ; WebGPU
List of high-level Frameworks Backends (combining Platform + Renderer): List of high-level Frameworks Backends (combining Platform + Renderer):
imgui_impl_allegro5.cpp imgui_impl_allegro5.cpp
Emscripten is also supported! Emscripten is also supported!
The SDL+GL, GLFW+GL and GLFW+WebGPU examples are all ready to build and run with Emscripten. The SDL+GL, GLFW+GL and SDL+WebGPU examples are all ready to build and run with Emscripten.
### Backends for third-party frameworks, graphics API or other languages ### Backends for third-party frameworks, graphics API or other languages

View File

@ -5,815 +5,31 @@ This document holds the user-facing changelog that we also use in release notes.
We generally fold multiple commits pertaining to the same topic as a single entry. We generally fold multiple commits pertaining to the same topic as a single entry.
Changes to backends are also included within the individual .cpp files of each backend. Changes to backends are also included within the individual .cpp files of each backend.
FAQ https://www.dearimgui.com/faq/
RELEASE NOTES: https://github.com/ocornut/imgui/releases RELEASE NOTES: https://github.com/ocornut/imgui/releases
REPORT ISSUES: https://github.com/ocornut/imgui/issues
DISCUSS, ASK QUESTIONS: https://github.com/ocornut/imgui/discussions
WIKI https://github.com/ocornut/imgui/wiki WIKI https://github.com/ocornut/imgui/wiki
GETTING STARTED https://github.com/ocornut/imgui/wiki/Getting-Started FAQ https://www.dearimgui.com/faq/
GLOSSARY https://github.com/ocornut/imgui/wiki/Glossary
ISSUES & SUPPORT https://github.com/ocornut/imgui/issues
WHEN TO UPDATE? WHEN TO UPDATE?
- Keeping your copy of Dear ImGui updated regularly is recommended. - Keeping your copy of Dear ImGui updated regularly is recommended.
- It is generally safe and recommended to sync to the latest commit in 'master' or 'docking' - It is generally safe to sync to the latest commit in master or docking branches
branches. The library is fairly stable and regressions tends to be fixed fast when reported. The library is fairly stable and regressions tends to be fixed fast when reported.
HOW TO UPDATE? HOW TO UPDATE?
- Update submodule or copy/overwrite every file. - Overwrite every file except imconfig.h (if you have modified it).
- About imconfig.h: - You may also locally branch to modify imconfig.h and merge latest into your branch.
- You may modify your copy of imconfig.h, in this case don't overwrite it.
- or you may locally branch to modify imconfig.h and merge/rebase latest.
- or you may '#define IMGUI_USER_CONFIG "my_config_file.h"' globally from your build system to
specify a custom path for your imconfig.h file and instead not have to modify the default one.
- Read the `Breaking Changes` section (in imgui.cpp or here in the Changelog). - Read the `Breaking Changes` section (in imgui.cpp or here in the Changelog).
- If you have a problem with a missing function/symbols, search for its name in the code, there will likely be a comment about it. - If you have a problem with a missing function/symbols, search for its name in the code, there will likely be a comment about it.
- If you are copying this repository in your codebase, please leave the demo and documentations files in there, they will be useful. - If you are dropping this repository in your codebase, please leave the demo and text files in there, they will be useful.
- You may diff your previous Changelog with the one you just copied and read that diff. - You may diff your previous Changelog with the one you just copied and read that diff.
- You may enable `IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in imconfig.h to forcefully disable legacy names and symbols. - You may enable `IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in imconfig.h to forcefully disable legacy names and symbols.
Doing it every once in a while is a good way to make sure you are not using obsolete symbols. Dear ImGui is in active development, Doing it every once in a while is a good way to make sure you are not using obsolete symbols. Dear ImGui is in active development,
and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users. and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users.
- Please report any issue! - Please report any issue!
-----------------------------------------------------------------------
VERSION 1.90.7 (Released 2024-05-27)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.7
Breaking changes:
- Inputs: on macOS X, Cmd and Ctrl keys are now automatically swapped by io.AddKeyEvent(),
as this naturally align with how macOS X uses those keys. (#2343, #4084, #5923, #456)
- Effectively it means that e.g. ImGuiMod_Ctrl | ImGuiKey_C is a valid idiomatic shortcut
for both Windows and Mac style users.
- It shouldn't really affect your code unless you had explicit/custom shortcut swapping in
place for macOS X apps in your input logic.
- Removed ImGuiMod_Shortcut which was previously dynamically remapping to Ctrl or Cmd/Super.
It is now unnecessary to specific cross-platform idiomatic shortcuts.
Kept symbols redirecting ImGuiMod_Shortcut to ImGuiMod_Ctrl (will obsolete).
- Commented out obsolete symbols renamed in 1.88 (May 2022):
CaptureKeyboardFromApp() -> SetNextFrameWantCaptureKeyboard()
CaptureMouseFromApp() -> SetNextFrameWantCaptureMouse()
- Backends: SDL_Renderer2/SDL_Renderer3: ImGui_ImplSDLRenderer2_RenderDrawData() and
ImGui_ImplSDLRenderer3_RenderDrawData() now takes a SDL_Renderer* parameter. This was previously
overlooked from the API but it will allow eventual support for multi-viewports.
Other changes:
- Windows: BeginChild(): fixed visibility of fully clipped child windows and tables to Test Engine.
- Windows: BeginChild(): fixed auto-fit calculation when using either (not both) ResizeX/ResizeY
and double-clicking on a border. Calculation incorrectly didn't always account for scrollbar as
it assumed the other axis would also be auto-fit. (#1710)
- Inputs: added shortcut and routing system in public API. (#456, #2637) [BETA]
- The general idea is that several callers may register interest in a shortcut, and only one owner gets it.
- in Parent: call Shortcut(Ctrl+S) // When Parent is focused, Parent gets the shortcut.
- in Child1: call Shortcut(Ctrl+S) // When Child1 is focused, Child1 gets the shortcut (Child1 overrides Parent shortcuts)
- in Child2: no call // When Child2 is focused, Parent gets the shortcut.
The whole system is order independent, so if Child1 makes its calls before Parent, results will be identical.
This is an important property as it facilitate working with foreign code or larger codebase.
- Added Shortcut() function:
e.g. Using ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_C); with default policy:
- checks that CTRL+C is pressed,
- and that current window is in focus stack,
- and that no other requests for CTRL+C have been made from higher priority locations
(e.g. deeper in the window/item stack).
- Added SetNextItemShortcut() to set a shortcut to locally or remotely press or activate
an item (depending on specified routing policy: using ImGuiInputFlags_RouteGlobal the item
shortcut may be executed even if its window is not in focus stack).
Items like buttons are not fully activated, in the sense that they get pressed but another
active item, e.g. InputText() won't be deactivated.
- Added routing policies for Shortcut(), SetNextItemShortcut(): (#456, #2637)
- ImGuiInputFlags_RouteFocused: focus stack route (default)
- ImGuiInputFlags_RouteActive: only route to active item
- ImGuiInputFlags_RouteGlobal: route globally, unless a focus route claim shame shortcut.
- ImGuiInputFlags_RouteAlways: no routing submission, no routing check.
- Added other shortcut/routing options: (#456, #2637)
- ImGuiInputFlags_Repeat: for use by Shortcut() and by upcoming rework of various
input functions (which are still internal for now).
- ImGuiInputFlags_Tooltip: for SetNextItemShortcut() to show a tooltip when hovering item.
- ImGuiInputFlags_RouteOverFocused: global route takes priority over focus route.
- ImGuiInputFlags_RouteOverActive: global route takes priority over active item.
- ImGuiInputFlags_RouteUnlessBgFocused: global route disabled if no imgui window focused.
- ImGuiInputFlags_RouteFromRootWindow: route evaluated from the point of view of root window rather than current window.
- Inputs: (OSX) Fixes variety of code which inconsistently required using Ctrl instead of Cmd.
- e.g. Drags/Sliders now use Cmd+Click to input a value. (#4084)
- Some shortcuts still uses Ctrl on Mac: e.g. Ctrl+Tab to switch windows. (#4828)
- Inputs: (OSX) Ctrl+Left Click alias as a Right click. (#2343) [@haldean, @ocornut]
- Inputs: Fixed ImGui::GetKeyName(ImGuiKey_None) from returning "N/A" or "None" depending
on value of IMGUI_DISABLE_OBSOLETE_KEYIO. It always returns "None".
- Nav: fixed holding Ctrl or gamepad L1 from not slowing down keyboard/gamepad tweak speed.
Broken during a refactor refactor for 1.89. Holding Shift/R1 to speed up wasn't broken.
- Tables: fixed cell background of fully clipped row overlapping with header. (#7575, #7041) [@prabuinet]
- Demo: Added "Inputs & Focus -> Shortcuts" section. (#456, #2637)
- Demo: Documents: Added shortcuts and renaming tabs/documents. (#7233)
- Examples: Win32+DX9,DX10,DX11,DX12: rework main loop to handle minimization and screen
locking without burning resources by running unthrottled code. (#2496, #3907, #6308, #7615)
- Backends: all backends + demo now call IMGUI_CHECKVERSION() to verify ABI compatibility between caller
code and compiled version of Dear ImGui. If you get an assert it most likely mean you have a build issue,
read comments near the assert. (#7568)
- Backends: Win32: undo an assert introduced in 1.90.6 which didn't allow WndProc
handler to be called before backend initialization. Because of how ::CreateWindow()
calls in WndProc this is facilitating. (#6275) [@MennoVink]
- Backends, Examples: SDL3: updates for latest SDL3 API changes. (#7580) [@kuvaus, @ocornut]
Breaking changes IF you were using imgui_internal.h versions of Shortcut() or owner-aware
versions of IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked() prior to this version:
- Inputs (Internals): Renamed ImGuiKeyOwner_None to ImGuiKeyOwner_NoOwner, to make use more
explicit and reduce confusion with the fact it is a non-zero value and cannot be a default.
- Inputs (Internals): Renamed symbols global routes:
Renamed ImGuiInputFlags_RouteGlobalLow -> ImGuiInputFlags_RouteGlobal (this is the suggested global route)
Renamed ImGuiInputFlags_RouteGlobal -> ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused
Renamed ImGuiInputFlags_RouteGlobalHigh -> ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive
- Inputs (Internals): Shortcut(), SetShortcutRouting(): swapped last two parameters order
in function signatures:
Before: Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
After: Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0, ImGuiID owner_id = 0);
- Inputs (Internals): owner-aware versions of IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked():
swapped last two parameters order in function signatures:
Before: IsKeyPressed(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0);
After: IsKeyPressed(ImGuiKey key, ImGuiInputFlags flags, ImGuiID owner_id = 0);
Before: IsMouseClicked(ImGuiMouseButton button, ImGuiID owner_id, ImGuiInputFlags flags = 0);
After: IsMouseClicked(ImGuiMouseButton button, ImGuiInputFlags flags, ImGuiID owner_id = 0);
- For several reasons those changes makes sense. They were all made before making some of
those API public. Only past users of imgui_internal.h with the extra parameters will be affected.
Added asserts for valid flags in various functions to detect _some_ misuses, BUT NOT ALL.
-----------------------------------------------------------------------
VERSION 1.90.6 (Released 2024-05-08)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.6
Breaking changes:
- TreeNode: Fixed a layout inconsistency when using a empty/hidden label followed
by a SameLine() call. (#7505, #282)
Before: TreeNode("##Hidden"); SameLine(); Text("Hello");
// This was actually incorrect! BUT appeared to look ok with the default style
// where ItemSpacing.x == FramePadding.x * 2 (it didn't look aligned otherwise).
After: TreeNode("##Hidden"); SameLine(0, 0); Text("Hello");
// This is correct for all values in style.
With the fix, IF you were successfully using TreeNode("")+SameLine(); you will now
have extra spacing between your TreeNode and the following item. You'll need to change
the SameLine() call to SameLine(0,0) to remove this extraneous spacing.
This seemed like the more sensible fix that's not making things less consistent.
(Note: when using this idiom you are likely to also use ImGuiTreeNodeFlags_SpanAvailWidth).
Other changes:
- Windows: Changed default ClipRect to extend to windows' left and right borders,
instead of adding arbitrary WindowPadding.x * 0.5f space on left and right.
That ClipRect half-padding was arbitrary/confusing and inconsistent with Y axis.
It also made it harder to draw items covering whole window without pushing an
extended ClipRect. Some items near windows left and right edge that used to be clipped
may be partly more visible. (#3312, #7540, #3756, #6170, #6365)
- Windows: Fixed subsequent Begin() append calls from setting last item information
for title bar, making it impossible to use IsItemHovered() on a Begin()-to-append,
and causing issue bypassing hover detection on collapsed windows. (#7506, #823)
- Fonts: Fixed font ascent and descent calculation when a font hits exact integer values.
It is possible that some prior manual use of ImFontConfig::GlyphOffset may become
duplicate with this fix. (#7399, #7404) [@GamingMinds-DanielC]
- TreeNode: Added ImGuiTreeNodeFlags_SpanTextWidth to make hitbox and highlight only
cover the label. (#6937) [@dimateos]
- Tables: Angled headers: fixed multi-line label display when angle is flipped. (#6917)
- Tables: Angled headers: added style.TableAngledHeadersTextAlign and corresponding
ImGuiStyleVar_TableAngledHeadersTextAlign variable. Default to horizontal center. (#6917)
[@thedmd, @ocornut]
- ProgressBar: Added support for indeterminate progress bar by passing an animated
negative fraction, e.g. ProgressBar(-1.0f * GetTime()). (#5316, #5370, #1901)[@gan74]
- Text, DrawList: Improved handling of long single-line wrapped text. Faster and
mitigate issues with reading vertex indexing limits with 16-bit indices. (#7496, #5720)
- Backends: OpenGL3: Detect ES3 contexts on desktop based on version string,
to e.g. avoid calling glPolygonMode() on them. (#7447) [@afraidofdark, @ocornut]
- Backends: OpenGL3: Update loader for Linux to support EGL/GLVND. (#7562) [@ShadowNinja, @vanfanel]
- Backends: Vulkan: Added convenience support for Volk via IMGUI_IMPL_VULKAN_USE_VOLK define.
(you could always use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + ImGui_ImplVulkan_LoadFunctions() as well).
(#6582, #4854) [@adalsteinnh, @kennyalive, @ocornut]
- Backends: SDL3: Fixed text inputs. Re-enable calling SDL_StartTextInput()/SDL_StopTextInput()
as SDL3 no longer enables it by default. (#7452, #6306, #6071, #1953) [@Green-Sky]
- Examples: GLFW+Vulkan, SDL+Vulkan: Added optional support for Volk. (#6582, #4854)
- Examples: GLFW+WebGPU: Added support for WebGPU-native/Dawn (#7435, #7132) [@eliasdaler, @Zelif]
- Examples: GLFW+WebGPU: Renamed example_emscripten_wgpu/ to example_glfw_wgpu/. (#7435, #7132)
-----------------------------------------------------------------------
VERSION 1.90.5 (Released 2024-04-11)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.5
Breaking changes:
- More formally obsoleted GetKeyIndex() when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is set.
It has been unnecessary and a no-op since 1.87 (it returns the same value as passed
when used with a 1.87+ backend using io.AddKeyEvent() function). (#4921)
- IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) --> IsKeyPressed(ImGuiKey_XXX)
- ImDrawList: Merged the radius_x/radius_y parameters in AddEllipse(), AddEllipseFilled()
and PathEllipticalArcTo() into a single ImVec2 parameter. Exceptionally, because those
functions were added recently in 1.90, we are not adding inline redirection functions.
The transition is easy and should affect few users. (#2743, #7417) [@cfillion]
Other changes:
- Windows: Scrollbar visibility decision uses current size when both size and contents
size are submitted by API. (#7252)
- Windows: Double-click to collapse may be disabled via key-ownership mechanism. (#7369)
- Windows: BeginChild(): Extend outer resize borders to the edges when there are no corner
grips. Essentially affects resizable child windows. (#7440, #1710) [@cfillion]
- Windows: BeginChild(): Resizing logic for child windows evaluates whether per-axis clamping
should be applied based on parent scrollbars, not child scrollbars. (#7440, #1710) [@cfillion]
Adjust those resizing limits to match window padding rather than inner clipping rectangle.
- Tables: Fixed auto-width columns when using synced-instances of same table, width of
one instance would bleed into next one instead of sharing their widths. (#7218)
- Tables: Angled headers: fixed border hit box extending beyond when used within
non-scrollable tables. (#7416) [@cfillion]
- Tables: Angled headers: fixed borders not moving back up after TableAngleHeadersRow()
stops being called. (#7416) [@cfillion]
- Tables: Angled headers: rounding header size to nearest integers, fixes some issues
when using clipper.
- Menus, Popups: Fixed an issue where sibling menu popups re-opening in successive
frames would erroneously close the window. While it is technically a popup issue
it would generally manifest when fast moving the mouse bottom to top in a sub-menu.
(#7325, #7287, #7063)
- ProgressBar: Fixed passing fraction==NaN from leading to a crash. (#7451)
- ListBox: Fixed text-baseline offset when using SameLine()+Text() after a labeled ListBox().
- Drags, Sliders, Inputs: Fixed io.PlatformLocaleDecimalPoint decimal point localization
feature not working regression from 1.90.1. (#7389, #6719, #2278) [@GamingMinds-DanielC]
- Style: Added ImGuiStyleVar_TabBorderSize, ImGuiStyleVar_TableAngledHeadersAngle for
consistency. (#7411) [@cfillion]
- DrawList: Added AddConcavePolyFilled(), PathFillConcave() concave filling. (#760) [@thedmd]
Note that only simple polygons (no self-intersections, no holes) are supported.
- DrawList: Allow AddText() to accept null ranges. (#3615, 7391)
- Docs: added more wiki links to headers of imgui.h/imgui.cpp to facilitate discovery
of interesting resources, because github doesn't allow Wiki to be crawled by search engines.
- This is the main wiki: https://github.com/ocornut/imgui/wiki
- This is the crawlable version: https://github-wiki-see.page/m/ocornut/imgui/wiki
Adding a link to the crawlable version, even though it is not intended for humans,
to increase its search rank.
-----------------------------------------------------------------------
VERSION 1.90.4 (Released 2024-02-22)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.4
Other changes:
- Nav: Fixed SetKeyboardFocusHere() or programmatic tabbing API from not working on
windows with the ImGuiWindowFlags_NoNavInputs flag (regression in 1.90.2, which
among other things broke imgui_memory_editor).
- Menus, Popups: Fixed an issue where hovering a parent-menu upward would
erroneously close the window. (#7325, #7287, #7063)
- Popups: Fixed resizable popup minimum size being too small. Standardized minimum
size logic. (#7329).
- Modals: Temporary changes of ImGuiCol_ModalWindowDimBg are properly handled by
BeginPopupModal(). (#7340)
- Tables: Angled headers: fixed support for multi-line labels. (#6917)
- Tables: Angled headers: various fixes to accurately handle CellPadding changes. (#6917)
- Tables: Angled headers: properly registers horizontal component of angled headers
for auto-resizing of columns. (#6917)
- Tables: Angled headers: fixed TableAngledHeadersRow() incorrect background fill
drawn too low, particularly visible with tables that have no scrolling. (#6917)
- ProgressBar: Fixed a minor tessellation issue when rendering rounded progress bars,
where in some situations the rounded section wouldn't follow regular tessellation rules.
- Debug Tools: Item Picker: Promoted ImGui::DebugStartItemPicker() to public API. (#2673)
- Debug Tools: Item Picker: Menu entry visible in Demo->Tools but greyed out unless
io.ConfigDebugIsDebuggerPresent is set. (#2673)
- Misc: Added optional alpha multiplier parameter to GetColorU32(ImU32) variant.
- Demo: Custom Rendering: better demonstrate PathArcTo(), PathBezierQuadraticCurveTo(),
PathBezierCubicCurveTo(), PathStroke(), PathFillConvex() functions.
-----------------------------------------------------------------------
VERSION 1.90.3 (Released 2024-02-14)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.3
Breaking changes:
- Backends: SDL2: Removed obsolete ImGui_ImplSDL2_NewFrame(SDL_Window*) signature which
was obsoleted in 1.84. Calling ImGui_ImplSDL2_NewFrame() is fine.
- Backends: Vulkan: Moved RenderPass parameter from ImGui_ImplVulkan_Init() function to
ImGui_ImplVulkan_InitInfo structure. Not required when using dynamic rendering. (#7308) [@shawnhatori]
- Backends: Vulkan: Using dynamic rendering now require filling the PipelineRenderingCreateInfo
structure in ImGui_ImplVulkan_InitInfo, allowing to configure color/depth/stencil formats.
Removed ColorAttachmentFormat field previously provided for dynamic rendering.
(#7166, #6855, #5446, #5037) [@shawnhatori]
Other changes:
- Menus, Popups: Fixed menus and popups with ChildWindow flag erroneously not displaying
a scrollbar when contents is over parent viewport size. (#7287, #7063) [@ZingBallyhoo]
- Backends: SDL2, SDL3: Handle gamepad disconnection + fixed increasing gamepad reference
counter continuously. Added support for multiple simultaneous gamepads.
Added ImGui_ImplSDL2_SetGamepadMode()) function to select whether to automatically pick
first available gamepad, all gamepads, or specific gamepads.
(#3884, #6559, #6890, #7180) [@ocornut, @lethal-guitar, @wn2000, @bog-dan-ro]
- Backends: SDL3: Fixed gamepad handling. (#7180) [@bog-dan-ro]
- Backends: SDLRenderer3: query newly added SDL_RenderViewportSet() to not restore
a wrong viewport if none was initially set.
- Backends: DirectX9: Using RGBA format when allowed by the driver to avoid CPU side
conversion. (#6575) [@Demonese]
- Internals: Fixed ImFileOpen not working before context is created, preventing creation
of a font atlas before main context creation. (#7314, #7315) [@PathogenDavid, @ocornut]
-----------------------------------------------------------------------
VERSION 1.90.2 (Released 2024-02-09)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.2
Breaking changes:
- Commented out ImGuiIO::ImeWindowHandle obsoleted in 1.87 in favor of writing
to 'void* ImGuiViewport::PlatformHandleRaw'.
- Backends: WebGPU: ImGui_ImplWGPU_Init() now takes a ImGui_ImplWGPU_InitInfo structure
instead of variety of parameters, allowing for easier further changes. (#7240)
Other changes:
- Nav: keyboard/gamepad activation mark widgets as held to give better visual feedback.
- Nav: tweak to logic marking navigated item as hovered when using keyboard, allowing
the hover highlight to stay even while another item is activated.
- Nav: Fixed SetKeyboardFocusHere() not working when current nav focus is in different scope,
regression from 1.90.1 related to code scoping Tab presses to local scope. (#7226) [@bratpilz]
- Nav: Fixed pressing Escape while in a child window with _NavFlattened flag. (#7237)
- Nav: Improve handling of Alt key to toggle menu so that key ownership may be claimed on
individual left/right alt key without interfering with the other.
- Nav, Menus: Fixed click on a BeginMenu() followed by right-arrow from making the child menu
reopen and flicker (using ImGuiPopupFlags_NoReopen).
- Nav: ImGuiWindowFlags_NoNavInputs is tested during scoring so NavFlattened windows can use it.
- Popups: OpenPopup(): added ImGuiPopupFlags_NoReopen flag to specifically not close and reopen
a popup when it is already open. (#1497, #1533)
(Note that this differs from specific handling we already have in place for the case of calling
OpenPopup() repeatedly every frame: we already didn't reopen in that specific situation, otherwise
the effect would be very disastrous in term of confusion, as reopening would steal focus).
- Popups: Slight change to popup closing logic (e.g. after focusing another window) which skipped
over popups that are also child windows.
- Combo: Fixed not reusing windows optimally when used inside a popup stack.
- Debug Tools: Metrics: Fixed debug break in SetShortcutRouting() not handling ImGuiMod_Shortcut redirect.
- Debug Tools: Metrics: Improved Monitors and Viewports minimap display. Highlight on hover.
- Debug Tools: Debug Log: Added "Input Routing" logging.
- Debug Tools: Added "nop" to IM_DEBUG_BREAK macro on GCC to work around GDB bug (#7266) [@Peter0x44]
- Backends: Vulkan: Fixed vkAcquireNextImageKHR() validation errors in VulkanSDK 1.3.275 by
allocating one extra semaphore than in-flight frames. (#7236) [@mklefrancois]
- Backends: Vulkan: Fixed vkMapMemory() calls unnecessarily using full buffer size. (#3957)
- Backends: Vulkan: Fixed handling of ImGui_ImplVulkan_InitInfo::MinAllocationSize field. (#7189, #4238)
- Backends: WebGPU: Added ImGui_ImplWGPU_InitInfo::PipelineMultisampleState. (#7240)
- Backends: WebGPU: Filling all WGPUDepthStencilState fields explicitly as a recent Dawn
update stopped setting default values. (#7232) [@GrigoryGraborenko]
- Backends: WebGPU: Fixed pipeline layout leak. (#7245) [@rajveermalviya]
- Backends: OpenGL3: Backup and restore GL_PIXEL_UNPACK_BUFFER. (#7253)
- Internals: Many improvements related to yet unpublicized shortcut routing and input ownership systems.
- Internals: InputText: Added internal helpers to force reload of user-buf when active. (#2890) [@kudaba, @ocornut]
Often requested in some form (#6962, #5219, #3290, #4627, #5054, #3878, #2881, #1506, #1216, #968),
and useful for interactive completion/suggestions popups (#2057, #718)
-----------------------------------------------------------------------
VERSION 1.90.1 (Released 2024-01-10)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.1
Breaking changes:
- imgui_freetype: commented out ImGuiFreeType::BuildFontAtlas() obsoleted in 1.81.
Prefer using #define IMGUI_ENABLE_FREETYPE or see commented code for manual calls.
- Removed CalcListClipping() marked obsolete in 1.86. (#3841)
Prefer using ImGuiListClipper which can return non-contiguous ranges.
- Internals, Columns: commented out legacy ImGuiColumnsFlags_XXX symbols redirecting
to ImGuiOldColumnsFlags_XXX, obsoleted from imgui_internal.h in 1.80.
- Commented out obsolete ImGuiKey_KeyPadEnter redirection to ImGuiKey_KeypadEnter. (#2625, #7143)
Other changes:
- Windows:
- BeginChild(): Fixed auto-resizing erroneously limiting size to host viewport
minus padding. There are no limit to a child width/height. (#7063) [@Devyre]
- BeginChild(): Resize borders rendered even when ImGuiWindowFlags_NoBackground
is specified. (#1710, #7194)
- Fixed some auto-resizing path using style.WindowMinSize.x (instead of x/y)
for both axises since 1.90. (#7106) [@n0bodysec]
- Scrolling: internal scrolling value is rounded instead of truncated, as a way to reduce
speed asymmetry when (incorrectly) attempting to scroll by non-integer amount. (#6677)
- Navigation (Keyboard/gamepad):
- Nav, IO: SetNextFrameWantCaptureKeyboard(false) calls are not overridden back to true when
navigation is enabled. SetNextFrameWantCaptureKeyboard() is always higher priority. (#6997)
- Nav: Activation can also be performed with Keypad Enter. (#5606)
- Drag and Drop:
- Fixed drop target highlight on items temporarily pushing a widened clip rect
(namely Selectables and Treenodes using SpanAllColumn flag) so the highlight properly covers
all columns. (#7049, #4281, #3272)
- InputText:
- InputTextMultiline: Fixed Tab character input not repeating (1.89.4 regression).
- InputTextMultiline: Tabbing through a multi-line text editor which allows Tab character inputs
(using the ImGuiInputTextFlags_AllowTabInput flag) doesn't automatically activate it, in order
to allow passing through multiple widgets easily. (#3092, #5759, #787)
- Drags, Sliders, Inputs:
- DragScalarN, SliderScalarN, InputScalarN: Fixed incorrect pushes into ItemWidth
stack when number of components is 1. [#7095] [@Nahor]
- Drags, Sliders, Inputs: removed all attempts to filter non-numerical characters during text
editing. Invalid inputs not applied to value, visibly reverted after validation. (#6810, #7096)
- Drags, Sliders, Inputs: removal of filter means that "nan" and "inf" values may be input. (#7096)
- DragScalarN, SliderScalarN, InputScalarN, PushMultiItemsWidths: improve multi-components
width computation to better distribute the error. (#7120, #7121) [@Nahor]
- Menus:
- Tweaked hover slack logic, adding an extra timeout to avoid situations where a slow vertical
movements toward another parent BeginMenu() can keep the wrong child menu open. (#6671, #6926)
- Color Editors:
- ColorEdit: Layout tweaks for very small sizes. (#7120, #7121)
- ColorPicker: Fixed saturation/value cursor radius not scaling properly.
- Tabs: Added ImGuiTabItemFlags_NoAssumedClosure to enable app to react on closure attempt,
without having to draw an unsaved document marker (ImGuiTabItemFlags_UnsavedDocument sets
_NoAssumedClosure automatically). (#7084)
- Debug Tools:
- Added io.ConfigDebugIsDebuggerPresent option. When enabled, this adds buttons in various
locations of Metrics/Debugger to manually request a debugger break:
- Request a debug break in a Begin() call.
- Request a debug break in a ItemAdd() call via debug log and hovering 0xXXXXXX identifiers.
- Request a debug break in a BeginTable() call.
- Request a debug break in a SetShortcutRouting()/Shortcut() call. [Internal]
- Metrics: Reorganize Tools menu.
- Added DebugFlashStyleColor() to identify a style color. Added to Style Editor.
- Debug Log: Hide its own clipper log to reduce noise in the output. (#5855)
- Debug Log: Clicking any filter with SHIFT held enables it for 2 frames only,
making it easier when dealing with spammy logs. (#5855)
- Settings: Fixed an issue marking settings as dirty when merely clicking on a border or resize
grip without moving it.
- Misc: Added IMGUI_USER_H_FILENAME to change the path included when using
IMGUI_INCLUDE_IMGUI_USER_H. (#7039) [@bryceberger]
- Misc: Rework debug display of texture id in Metrics window to avoid compile-error when
ImTextureID is defined to be larger than 64-bits. (#7090)
- Misc: Added extra courtesy ==/!= operators when IMGUI_DEFINE_MATH_OPERATORS is defined.
- Misc: Fixed text functions fast-path for handling "%s" and "%.*s" to handle null pointers gracefully,
like most printf implementations. (#7016, #3466, #6846) [@codefrog2002]
- Misc: Renamed some defines in imstb_textedit.h to avoid conflicts when using unity/jumbo builds
on a codebase where another copy of the library is used.
- Misc: During shutdown, check that io.BackendPlatformUserData and io.BackendRendererUserData are NULL
in order to catch cases where backend was not shut down. (#7175)
- Misc: Reworked Issue Template to a shinier and better form. (#5927) [@Panquesito7, @PathogenDavid, @ocornut]
- Backends:
- GLFW, Emscripten: Added ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback() to
register canvas selector and auto-resize GLFW window. (#6751) [@Traveller23, @ypujante]
- GLFW: Fixed Windows specific hooks to use Unicode version of WndProc even when
compiling in MBCS mode. (#7174) [@kimidaisuki22]
- OpenGL3: Update GL3W based imgui_impl_opengl3_loader.h to load libGL.so variants in
case of missing symlink. Fix 1.90 regression for some distros. (#6983)
- Vulkan: Fixed mismatching allocator passed to vkCreateCommandPool() vs
vkDestroyCommandPool(). (#7075) [@FoonTheRaccoon]
- Vulkan: Added MinAllocationSize field in ImGui_ImplVulkan_InitInfo to workaround zealous
"best practice" validation layer. (#7189, #4238) [@philae-ael]
- Vulkan: Stopped creating command pools with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
as we don't reset them.
- WebGPU: Fixed wgpuRenderPassEncoderSetScissorRect() crash when rendering modal window's
dimming layer, which has an unclipped value in ImDrawCmd::ClipRect. (#7191) [@aparis69]
- Examples:
- Examples: GLFW+Emscripten: Fixed examples not consistently resizing according to host canvas.
(#6751) [@Traveller23, @ypujante]
- Examples: SDL3: Minor fixes following recent SDL3 in-progress development.
-----------------------------------------------------------------------
VERSION 1.90.0 (Released 2023-11-15)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90
Breaking changes:
- BeginChild(): Upgraded 'bool border = false' parameter to 'ImGuiChildFlags flags = 0'.
Added ImGuiChildFlags_Border value. As with our prior "bool-to-flags" API updates,
the ImGuiChildFlags_Border value is guaranteed to be == true forever to ensure a
smoother transition, meaning all existing calls will still work.
If you want to neatly transition your call sites:
Before: BeginChild("Name", size, true)
After: BeginChild("Name", size, ImGuiChildFlags_Border)
Before: BeginChild("Name", size, false)
After: BeginChild("Name", size) or BeginChild("Name", 0) or BeginChild("Name", size, ImGuiChildFlags_None)
Existing code will still work as 'ImGuiChildFlags_Border == true', but you are encouraged to update call sites.
- BeginChild(): Added child-flag ImGuiChildFlags_AlwaysUseWindowPadding as a replacement for
the window-flag ImGuiWindowFlags_AlwaysUseWindowPadding: the feature only ever made sense
for use with BeginChild() anyhow, passing it to Begin() had no effect. Now that we accept
child-flags we are moving it there. (#462)
Before: BeginChild("Name", size, 0, ImGuiWindowFlags_AlwaysUseWindowPadding);
After: BeginChild("Name", size, ImGuiChildFlags_AlwaysUseWindowPadding, 0);
Kept inline redirection enum (will obsolete later) so existing code will work.
- BeginChildFrame()/EndChildFrame(): removed functions in favor of using BeginChild() with
the ImGuiChildFlags_FrameStyle flag. Kept inline redirection function (will obsolete).
Those functions were merely PushStyle/PopStyle helpers and custom versions are easy to create.
(The removal isn't so much motivated by needing to add the feature in BeginChild(), but by the
necessity to avoid BeginChildFrame() signature mismatching BeginChild() signature and features.)
- Debug Tools: Renamed ShowStackToolWindow() ("Stack Tool") to ShowIDStackToolWindow() ("ID Stack Tool"),
as earlier name was misleading. Kept inline redirection function. (#4631)
- IO: Removed io.MetricsActiveAllocations introduced in 1.63, was displayed in Metrics and unlikely to
be accessed by end-user. Value still visible in the UI and easily to recompute from a delta.
- Defining IMGUI_DISABLE_OBSOLETE_FUNCTIONS now automatically defines IMGUI_DISABLE_OBSOLETE_KEYIO. (#4921)
- Removed IM_OFFSETOF() macro in favor of using offsetof() available in C++11. Kept redirection define. (#4537)
- ListBox, Combo: Changed signature of "name getter" callback in old one-liner ListBox()/Combo() apis.
Before:
getter type: bool (*getter)(void* user_data, int idx, const char** out_text)
function: bool Combo(const char* label, int* current_item, bool (*getter)(void* user_data, int idx, const char** out_text), ...);
function: bool ListBox(const char* label, int* current_item, bool (*getting)(void* user_data, int idx, const char** out_text), ...);
After:
getter type: const char* (*getter)(void* user_data, int idx)
function: bool Combo(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), ...);
function: bool ListBox(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), ...);
Old type was unnecessarily complex and harder to wrap in e.g. a lambda. Kept inline redirection function (will obsolete).
- Commented out obsolete redirecting enums/functions that were marked obsolete two years ago:
- GetWindowContentRegionWidth() -> use GetWindowContentRegionMax().x - GetWindowContentRegionMin().x.
Consider that generally 'GetContentRegionAvail().x' is often more correct and more useful.
- ImDrawCornerFlags_XXX -> use ImDrawFlags_RoundCornersXXX names.
Read 1.82 changelog for details + grep commented names in sources.
- Commented out runtime support for hardcoded ~0 or 0x01..0x0F rounding flags values for
AddRect()/AddRectFilled()/PathRect()/AddImageRounded(). -> Use ImDrawFlags_RoundCornersXXX flags.
Read 1.82 changelog for details.
- Backends: Vulkan: Removed parameter from ImGui_ImplVulkan_CreateFontsTexture(): backend now creates its own
command-buffer to upload fonts. Removed ImGui_ImplVulkan_DestroyFontUploadObjects() which is now unnecessary.
No need to call ImGui_ImplVulkan_CreateFontsTexture() as it is done automatically in ImGui_ImplVulkan_NewFrame().
You can call ImGui_ImplVulkan_CreateFontsTexture() manually if you need to reload the font atlas texture.
(#6943, #6715, #6327, #3743, #4618)
Other changes:
- Windows:
- BeginChild(): Added ImGuiChildFlags_ResizeX and ImGuiChildFlags_ResizeY to allow resizing
child windows from the bottom/right border (toward layout direction). Resized child windows
settings are saved and persistent in .ini file. (#1710)
- BeginChild(): Added ImGuiChildFlags_Border as a replacement for 'bool border = true' parameter.
- BeginChild(): Added ImGuiChildFlags_AutoResizeX and ImGuiChildFlags_AutoResizeY to auto-resize
on one axis, while generally providing a size on the other axis. (#1666, #1395, #1496, #1710)
e.g. BeginChild("name", {-FLT_MIN, 0.0f}, ImGuiChildFlags_AutoResizeY);
- Size is only reevaluated if the child window is within visible boundaries or just appearing.
This allows coarse clipping to be performed and auto-resizing childs to return false when
hidden because of being scrolled out.
- Combining this with also specifying ImGuiChildFlags_AlwaysAutoResize disables
this optimization, meaning child contents will never be clipped (not recommended).
- Please be considerate that child are full windows and carry significant overhead:
combining auto-resizing for both axises to create a non-scrolling child to merely draw
a border would be better more optimally using BeginGroup(). (see #1496)
(until we come up with new helpers for framed groups and work-rect adjustments).
- BeginChild(): made it possible to use SetNextWindowSizeConstraints() rectangle, often
useful when ImGuiChildFlags_AutoResizeX or ImGuiChildFlags_AutoResizeY. (#1666, #1395, #1496)
Custom constraint callback are not supported with child window.
- BeginChild(): Added ImGuiChildFlags_FrameStyle as a replacement for BeginChildFrame(),
use it to make child window use FrameBg, FrameRounding, FrameBorderSize, FramePadding
instead of ChildBg, ChildRounding, ChildBorderSize, WindowPadding.
- Popups: clarified meaning of 'p_open != NULL' in BeginPopupModal() + set back user value
to false when popup is closed in ways other than clicking the close button. (#6900)
- Double-clicking lower-left resize grip auto-resize (like lower-right one).
- Double-clicking bottom or right window border auto-resize on a singles axis.
- Use relative mouse movement for border resize when the border geometry has moved
(e.g. resizing a child window triggering parent scroll) in order to avoid resizing
feedback loops. Unless manually mouse-wheeling while border resizing. (#1710)
- Separators:
- Altered end-points to use more standard boundaries. (#205, #4787, #1643)
Left position is always current cursor X position, right position is always work-rect
rightmost edge. It effectively means that:
- A separator in the root of a window will end up a little more distant from edges
than previously (essentially following WindowPadding instead of clipping edges).
- A separator inside a table cell end up a little distance from edges instead of
touching them (essentially following CellPadding instead of clipping edges).
- Matches tree indentation (was not the case before).
- Matches SeparatorText(). (#1643)
- Makes things correct inside groups without specific/hard-coded handling. (#205)
- Support legacy behavior when used inside old Columns(), as we favored that idiom back then,
only different is left position follows indentation level, to match calling a Separator()
inside or outside Columns().
- Tooltips:
- Made using SetItemTooltip()/IsItemHovered(ImGuiHoveredFlags_ForTooltip) defaults to
activate tooltips on disabled items. This is done by adding ImGuiHoveredFlags_AllowWhenDisabled
to the default value of style.HoverFlagsForTooltipMouse/HoverFlagsForTooltipNav. (#1485)
- Made is possible to combine ImGuiHoveredFlags_ForTooltip with a ImGuiHoveredFlags_DelayXXX
override. (#1485)
- Drag and Drop:
- Reworked drop target highlight: reduce rectangle to its visible portion, and then expand
slightly. A full rectangle is always visible and it may protrude slightly. (#4281, #3272)
- Fixed submitting a tooltip from drop target location when using AcceptDragDropPayload()
with ImGuiDragDropFlags_AcceptNoPreviewTooltip and submitting a tooltip manually.
- Tables:
- Added angled headers support. You need to set ImGuiTableColumnFlags_AngledHeader on selected
columns and call TableAngledHeadersRow(). Added style.TableAngledHeadersAngle style option. (#6917)
- Added ImGuiTableFlags_HighlightHoveredColumn flag, currently highlighting column header.
- Fixed an edge-case when no columns are visible + table scrollbar is visible + user
code is always testing return value of TableSetColumnIndex() to coarse clip. With an active
clipper it would have asserted. Without a clipper, the scrollbar range would be wrong.
- Request user to submit contents when outer host-window is requesting auto-resize,
so a scrolling table can contribute to initial window size. (#6510)
- Fixed subtle drawing overlap between borders in some situations.
- Fixed bottom-most and right-most outer border offset by one. (#6765, #3752) [@v-ein]
- Fixed top-most and left-most outer border overlapping inner clip-rect when scrolling. (#6765)
- Fixed top-most outer border being drawn with both TableBorderLight and TableBorderStrong
in some situations, causing the earlier to be visible underneath when alpha is not 1.0f.
- Fixed right-clicking right-most section (past right-most column) from highlighting a column.
- Fixed an issue with ScrollX enabled where an extraneous draw command would be created.
- Menus:
- Menus: Fixed a bug where activating an item in a child-menu and dragging mouse over the
parent-menu would erroneously close the child-menu. (Regression from 1.88). (#6869)
- MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously
register contents size in a way that would affect the scrolling layer.
Was most often noticeable when using an horizontal scrollbar. (#6789)
- InputText:
- InputTextMultiline: Fixed a crash pressing Down on last empty line of a multi-line buffer.
(regression from 1.89.2, only happened in some states). (#6783, #6000)
- InputTextMultiline: Fixed Tabbing cycle leading to a situation where Enter key wouldn't
be accepted by the widget when navigation highlight is visible. (#6802, #3092, #5759, #787)
- Nav: Tabbing always enable nav highlight when ImGuiConfigFlags_NavEnableKeyboard is set.
Previously was inconsistent and only enabled when stepping through a non-input item.
(#6802, #3092, #5759, #787)
- TreeNode: Added ImGuiTreeNodeFlags_SpanAllColumns for use in tables. (#3151, #3565, #2451, #2438)
- TabBar: Fixed position of unsaved document marker (ImGuiTabItemFlags_UnsavedDocument) which was
accidentally offset in 1.89.9. (#6862) [@alektron]
- ColorPicker4(): Fixed ImGuiColorEditFlags_NoTooltip not being forwarded to individual DragFloat3
sub-widgets which have a visible color preview when ImGuiColorEditFlags_NoSidePreview is also set. (#6957)
- BeginGroup(): Fixed a bug pushing line lower extent too far down when called after a call
to SameLine() followed by manual cursor manipulation.
- BeginCombo(): Added ImGuiComboFlags_WidthFitPreview flag. (#6881) [@mpv-enjoyer]
- BeginListBox(): Fixed not consuming SetNextWindowXXX() data when returning false.
- Fonts:
- Argument 'float size_pixels' passed to AddFontXXX() functions is now rounded to lowest integer.
This is because our layout/font system currently doesn't fully support non-integer sizes. Until
it does, this has been a common pitfall leading to more or less subtle issues. (#3164, #3309, #6800)
- Better assert during load when passing truncated font data or wrong data size. (#6822)
- Ensure calling AddFontXXX function doesn't invalidates ImFont's ConfigData pointers
prior to building again. (#6825)
- Added ImFontConfig::RasterizerDensity field to increase texture size of rendered glyphs
without altering other metrics. Among other things, this makes it easier to have zooming code
swapping between 2 fonts (e.g. a 100% and a 400% fonts) depending on current scale. (#6925) [@thedmd]
Important: if you increase this it is expected that you would render the font with a scale of
similar value or magnitude. Merely increasing this without increasing scale may lower quality.
- imgui_freetype: Added support for RasterizerDensity. (#6925) [@thedmd]
- imgui_freetype: Fixed a warning and leak in IMGUI_ENABLE_FREETYPE_LUNASVG support. (#6842, #6591)
- Inputs: Added IsKeyChordPressed() helper function e.g. IsKeyChordPressed(ImGuiMod_Ctrl | ImGuiKey_S).
(note that ImGuiMod_Shortcut may be used as an alias for Cmd on OSX and Ctrl on other systems).
- Misc: Most text functions also treat "%.*s" (along with "%s") specially to bypass formatting. (#3466, #6846)
- IO: Add extra keys to ImGuiKey enum: ImGuiKey_F13 to ImGuiKey_F24. (#6891, #4921)
- IO: Add extra keys to ImGuiKey enum: ImGuiKey_AppBack, ImGuiKey_AppForward. (#4921)
- IO: Setting io.WantSetMousePos ignores incoming MousePos events. (#6837, #228) [@bertaye]
- Debug Tools: Metrics: Added log of recent alloc/free calls.
- Debug Tools: Metrics: Added "Show groups rectangles" in tools.
- ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl]
- ImVector: Added find_index() helper.
- Demo: Added "Drag and Drop -> Tooltip at target location" demo.
- Demo: Added "Layout -> Child Windows -> Manual-resize" demo. (#1710)
- Demo: Added "Layout -> Child Windows -> Auto-resize with constraints" demo. (#1666, #1395, #1496, #1710)
- Demo: Partly fixed "Examples -> Constrained-resizing window" custom constrains demo. (#6210) [@cfillion]
- Backends: Vulkan: Removed parameter from ImGui_ImplVulkan_CreateFontsTexture(): backend now creates its own
command-buffer to upload fonts. Removed ImGui_ImplVulkan_DestroyFontUploadObjects() which is now unnecessary.
No need to call ImGui_ImplVulkan_CreateFontsTexture() as it is done automatically in ImGui_ImplVulkan_NewFrame().
You can call ImGui_ImplVulkan_CreateFontsTexture() manually if you need to reload font atlas texture.
Fixed leaks, and added ImGui_ImplVulkan_DestroyFontsTexture() (probably no need to call this directly).
(#6943, #6715, #6327, #3743, #4618)
[@helynranta, @thomasherzog, @guybrush77, @albin-johansson, @MiroKaku, @benbatya-fb, @ocornut]
- Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99]
- Backends: GLFW: Added support for F13 to F24 function keys. (#6891)
- Backends: SDL2, SDL3: Added support for F13 to F24 function keys, AppBack, AppForward. (#6891)
- Backends: SDL3: Updates for recent API changes. (#7000, #6974)
- Backends: Win32: Added support for F13 to F24 function keys, AppBack, AppForward. (#6891)
- Backends: Win32: Added support for keyboard codepage conversion for when application
is compiled in MBCS mode and using a non-Unicode window. (#6785, #6782, #5725, #5961) [@sneakyevil]
- Backends: Win32: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows
doesn't emit it (same behavior as GLFW/SDL). (#6859) [@thedmd, @SuperWangKai]
- Backends: OpenGL3: rename symbols in our internal loader so that LTO compilation with another
copy of gl3w becomes possible. (#6875, #6668, #4445) [@nicolasnoble]
- Backends: OpenGL3: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead
of "libGL.so.1", accommodating for NetBSD systems having only "libGL.so.3" available. (#6983)
- Backends: OSX: Added support for F13 to F20 function keys. Support mapping F13 to PrintScreen. (#6891)
- Examples: GLFW+Vulkan, SDL+Vulkan: Simplified and removed code due to backend improvements.
- Internals: Renamed ImFloor() to ImTrunc(). Renamed ImFloorSigned() to ImFloor(). (#6861)
-----------------------------------------------------------------------
VERSION 1.89.9 (Released 2023-09-04)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.89.9
Breaking changes:
- Clipper: Renamed IncludeRangeByIndices(), also called ForceDisplayRangeByIndices()
before 1.89.6, to IncludeItemsByIndex(). Kept inline redirection function. (#6424, #3841)
Other changes:
- Tables: Made it possible to use SameLine(0,0) after TableNextColumn() or
TableSetColumnIndex() in order to reuse line pos/height from previous cell. (#3740)
- Tables: Made it possible to change style.CellPadding.y between rows. (#3740)
- Nav, TreeNode: Pressing Left with ImGuiTreeNodeFlags_NavLeftJumpsBackHere now goes
through proper navigation logic: honor scrolling and selection. (#1079, #1131)
- Sliders: Fixed an integer overflow and div-by-zero in SliderInt() when
v_max=INT_MAX (#6675, #6679) [@jbarthelmes]
- Windows: Layout of Close/Collapse buttons uses style.ItemInnerSpacing.x between items,
stopped incorrectly using FramePadding in a way where hit-boxes could overlap when
setting large values. (#6749)
- TabBar, Style: added style.TabBarBorderSize and associated ImGuiStyleVar_TabBarBorderSize.
Tweaked rendering of that separator to allow thicker values. (#6820, #4859, #5022, #5239)
- InputFloat, SliderFloat, DragFloat: always turn both '.' and ',' into the current decimal
point character when using Decimal/Scientific character filter. (#6719, #2278) [@adamsepp]
- ColorEdit, ColorPicker: Manipulating options popup don't mark item as edited. (#6722)
(Note that they may still be marked as Active/Hovered.)
- Clipper: Added IncludeItemByIndex() helper to include a single item. (#6424, #3841)
- Clipper: Fixed a bug if attempt to force-include a range which matches an already
included range, clipper would end earlier. (#3841)
- ImDrawData: Fixed an issue where TotalVtxCount/TotalIdxCount does not match the sum
of individual ImDrawList's buffer sizes when a dimming/modal background is rendered. (#6716)
- ImDrawList: Automatically calling ChannelsMerge() if not done after a split.
- ImDrawList: Fixed OOB access in _CalcCircleAutoSegmentCount when passing excessively
large radius to AddCircle(). (#6657, #5317) [@EggsyCRO, @jdpatdiscord]
- IO: Exposed io.PlatformLocaleDecimalPoint to configure decimal point ('.' or ',') for
languages needing it. Should ideally be set to the value of '*localeconv()->decimal_point'
but our backends don't do it yet. (#6719, #2278)
- IO: Fixed io.AddMousePosEvent() and io.AddMouseButtonEvent() writing MouseSource to
wrong union section. Was semantically incorrect and accidentally had no side-effects
with default compiler alignment settings. (#6727) [@RickHuang2001]
- Misc: Made multiple calls to Render() during the same frame early out faster.
- Debug Tools: Metrics: Fixed "Drawlists" section and per-viewport equivalent
appearing empty (regression in 1.89.8).
- Demo: Reorganized "Examples" menu.
- Demo: Tables: Demonstrate using SameLine() between cells. (#3740)
- Demo: Tables: Demonstrate altering CellPadding.y between rows. (#3740)
- Demo: Custom Rendering: Demonstrate out-of-order rendering using ImDrawListSplitter.
- Backends: SDL2,SDL3: added ImGui_ImplSDL2_InitForOther()/ImGui_ImplSDL3_InitForOther()
for consistency (matching GLFW backend) and as most initialization paths don't actually
need to care about rendering backend.
- Examples: Emscripten+WebGPU: Fixed WGPUInstance creation process + use preferred
framebuffer format. (#6640, #6748) [@smileorigin]
-----------------------------------------------------------------------
VERSION 1.89.8 (Released 2023-08-01)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.89.8
Breaking changes:
- IO: Obsoleted io.ClearInputCharacters() (added in 1.47) as it now ambiguous
and often incorrect/misleading considering the existence of a higher-level
input queue. This is automatically cleared by io.ClearInputsKeys(). (#4921)
- ImDrawData: CmdLists[] array is now owned, changed from 'ImDrawList**' to
'ImVector<ImDrawList*>'. Majority of users shouldn't be affected, but you
cannot compare to NULL nor reassign manually anymore.
Instead use AddDrawList(). Allocation count are identical. (#6406, #4879, #1878)
Other changes:
- Fonts: ImFontConfig::OversampleH now defaults to 2 instead of 3, since the
quality increase is largely minimal.
- Fonts, imgui_freetype: Added support to render OpenType SVG fonts using lunasvg.
Requires enabling IMGUI_ENABLE_FREETYPE_LUNASVG along with IMGUI_ENABLE_FREETYPE,
and providing headers/libraries for lunasvg. (#6591, #6607) [@sakiodre]
- ImDrawData: CmdLists[] array is now an ImVector<> owned by ImDrawData rather
than a pointer to internal state.
- This makes it easier for user to create their own or append to an existing draw data.
Added a ImDrawData::AddDrawList() helper function to do that. (#6406, #4879, #1878)
- This makes it easier to perform a deep-swap instead of a deep-copy, as array
ownership is now clear. (#6597, #6475, #6167, #5776, #5109, #4763, #3515, #1860)
- Syntax and allocation count are otherwise identical.
- Fixed CTRL+Tab dimming background assert when target window has a callback
in the last ImDrawCmd. (#4857, #5937)
- IsItemHovered: Fixed ImGuiHoveredFlags_ForTooltip for Keyboard/Gamepad navigation,
got broken prior to 1.89.7 due to an unrelated change making flags conflict. (#6622, #1485)
- InputText: Fixed a case where deactivation frame would write to underlying
buffer or call CallbackResize although unnecessary, in a frame where the
return value was false.
- Tables: fixed GetContentRegionAvail().y report not taking account of lower cell
padding or of using ImGuiTableFlags_NoHostExtendY. Not taking it into account
would make the idiom of creating vertically bottom-aligned content (e.g. a child
window) inside a table make the parent window erroneously have a scrollbar. (#6619)
- Tables: fixed calculation of multi-instance shared decoration/scrollbar width of
scrolling tables, to avoid flickering width variation when resizing down a table
hosting a child window. (#5920, #6619)
- Scrollbar: layout needs to take account of window border size, so a border size
will slightly reduce scrollbar size. Generally we tried to make it that window
border size has no incidence on layout but this can't work with thick borders. (#2522)
- IO: Added io.ClearEventsQueue() to clear incoming inputs events. (#4921)
May be useful in conjunction with io.ClearInputsKeys() if you need to clear
both current inputs state and queued events (e.g. when using blocking native
dialogs such as Windows's ::MessageBox() or ::GetOpenFileName()).
- IO: Changed io.ClearInputsKeys() specs to also clear current frame character buffer
(what now obsoleted io.ClearInputCharacters() did), as this is effectively the
desirable behavior.
- Misc: Added IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION config macro to disable
stb_sprintf implementation when using IMGUI_USE_STB_SPRINTF. (#6626) [@septag]
- Misc: Avoid stb_textedit.h reincluding string.h while in a namespace, which
messes up with building with Clang Modules. (#6653, #4791) [@JohelEGP]
- Demo: Better showcase use of SetNextItemAllowOverlap(). (#6574, #6512, #3909, #517)
- Demo: Showcase a few more InputText() flags.
- Backends: Made all backends sources files support global IMGUI_DISABLE. (#6601)
- Backends: GLFW: Revert ignoring mouse data on GLFW_CURSOR_DISABLED as it can be used
differently. User may set ImGuiConfigFlags_NoMouse if desired. (#5625, #6609) [@scorpion-26]
- Backends: WebGPU: Update for changes in Dawn. (#6602, #6188) [@williamhCode]
- Examples: Vulkan: Creating minimal descriptor pools to fit only what is needed by
example. (#6642) [@SaschaWillem]
----------------------------------------------------------------------- -----------------------------------------------------------------------
VERSION 1.89.7 (Released 2023-07-04) VERSION 1.89.7 (Released 2023-07-04)
----------------------------------------------------------------------- -----------------------------------------------------------------------
@ -832,11 +48,6 @@ Breaking changes:
legacy 'SetItemAllowOverlap()' call (public API) + ImGuiButtonFlags_AllowOverlap (internal). legacy 'SetItemAllowOverlap()' call (public API) + ImGuiButtonFlags_AllowOverlap (internal).
- Obsoleted 'SetItemAllowOverlap()': it didn't and couldn't work reliably since 1.89 (2022-11-15), - Obsoleted 'SetItemAllowOverlap()': it didn't and couldn't work reliably since 1.89 (2022-11-15),
and relied on ambiguously defined design. Use 'SetNextItemAllowOverlap()' before item instead. and relied on ambiguously defined design. Use 'SetNextItemAllowOverlap()' before item instead.
- Selectable, TreeNode: When using ImGuiSelectableFlags_AllowOverlap/ImGuiTreeNodeFlags_AllowOverlap
and holding item held, overlapping widgets won't appear as hovered. (#6512, #3909)
While this fixes a common small visual issue, it also means that calling IsItemHovered()
after a non-reactive elements - e.g. Text() - overlapping an active one may fail if you don't
use IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem). (#6610)
- Renamed 'ImGuiTreeNodeFlags_AllowItemOverlap' to 'ImGuiTreeNodeFlags_AllowOverlap'. - Renamed 'ImGuiTreeNodeFlags_AllowItemOverlap' to 'ImGuiTreeNodeFlags_AllowOverlap'.
- Renamed 'ImGuiSelectableFlags_AllowItemOverlap' to 'ImGuiSelectableFlags_AllowOverlap' - Renamed 'ImGuiSelectableFlags_AllowItemOverlap' to 'ImGuiSelectableFlags_AllowOverlap'
- Kept redirecting enums (will obsolete). - Kept redirecting enums (will obsolete).
@ -872,6 +83,8 @@ Other changes:
- Fixed first frame of an overlap highlighting underlying item if previous frame didn't hover anything. - Fixed first frame of an overlap highlighting underlying item if previous frame didn't hover anything.
- IsItemHovered: Changed to return false when querying an item using AllowOverlap mode which - IsItemHovered: Changed to return false when querying an item using AllowOverlap mode which
is being overlapped. Added ImGuiHoveredFlags_AllowWhenOverlappedByItem to opt-out. (#6512, #3909, #517) is being overlapped. Added ImGuiHoveredFlags_AllowWhenOverlappedByItem to opt-out. (#6512, #3909, #517)
- Selectable, TreeNode: When using ImGuiSelectableFlags_AllowOverlap/ImGuiTreeNodeFlags_AllowOverlap
and holding item held, overlapping widgets won't appear as hovered. (#6512, #3909)
- IsWindowHovered: Added support for ImGuiHoveredFlags_Stationary. - IsWindowHovered: Added support for ImGuiHoveredFlags_Stationary.
- IsWindowHovered, IsItemHovered: Assert when passed any unsupported flags. - IsWindowHovered, IsItemHovered: Assert when passed any unsupported flags.
- Tables: Fixed a regression in 1.89.6 leading to the first column of tables with either - Tables: Fixed a regression in 1.89.6 leading to the first column of tables with either
@ -926,7 +139,7 @@ Breaking changes:
- ListBoxFooter() -> use EndListBox() - ListBoxFooter() -> use EndListBox()
- Note how two variants of ListBoxHeader() existed. Check commented versions in imgui.h for refeence. - Note how two variants of ListBoxHeader() existed. Check commented versions in imgui.h for refeence.
- Backends: SDL_Renderer: Renamed 'imgui_impl_sdlrenderer.h/cpp' to 'imgui_impl_sdlrenderer2.h/cpp', - Backends: SDL_Renderer: Renamed 'imgui_impl_sdlrenderer.h/cpp' to 'imgui_impl_sdlrenderer2.h/cpp',
in order to accommodate for upcoming SDL3 and change in its SDL_Renderer API. (#6286) in order to accomodate for upcoming SDL3 and change in its SDL_Renderer API. (#6286)
- Backends: GLUT: Removed call to ImGui::NewFrame() from ImGui_ImplGLUT_NewFrame(). - Backends: GLUT: Removed call to ImGui::NewFrame() from ImGui_ImplGLUT_NewFrame().
It needs to be called from the main app loop, like with every other backends. (#6337) [@GereonV] It needs to be called from the main app loop, like with every other backends. (#6337) [@GereonV]
@ -1489,7 +702,7 @@ Other Changes:
- Backends: Metal: Use __bridge for ARC based systems. (#5403) [@stack] - Backends: Metal: Use __bridge for ARC based systems. (#5403) [@stack]
- Backends: Metal: Add dispatch synchronization. (#5447) [@luigifcruz] - Backends: Metal: Add dispatch synchronization. (#5447) [@luigifcruz]
- Backends: Metal: Update deprecated property 'sampleCount'->'rasterSampleCount'. (#5603) [@dcvz] - Backends: Metal: Update deprecated property 'sampleCount'->'rasterSampleCount'. (#5603) [@dcvz]
- Backends: Vulkan: Added experimental ImGui_ImplVulkan_RemoveTexture() for api symmetry. (#914, #5738). - Backends: Vulkan: Added experimental ImGui_ImplVulkan_RemoveTexture() for api symetry. (#914, #5738).
- Backends: WebGPU: fixed rendering when a depth buffer is enabled. (#5869) [@brainlag] - Backends: WebGPU: fixed rendering when a depth buffer is enabled. (#5869) [@brainlag]
@ -1989,7 +1202,7 @@ Breaking Changes:
- Commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019): - Commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019):
- ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList() - ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList()
- ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder - ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder
- Backends: OpenGL3: added a third source file "imgui_impl_opengl3_loader.h". (#4445) [@rokups] - Backends: OpenGL3: added a third source file "imgui_impl_opengl3_loader.h". [@rokups]
- Backends: GLFW: backend now uses glfwSetCursorEnterCallback(). (#3751, #4377, #2445) - Backends: GLFW: backend now uses glfwSetCursorEnterCallback(). (#3751, #4377, #2445)
- Backends: GLFW: backend now uses glfwSetWindowFocusCallback(). (#4388) [@thedmd] - Backends: GLFW: backend now uses glfwSetWindowFocusCallback(). (#4388) [@thedmd]
- If calling ImGui_ImplGlfw_InitXXX with install_callbacks=true: this is already done for you. - If calling ImGui_ImplGlfw_InitXXX with install_callbacks=true: this is already done for you.
@ -2078,7 +1291,7 @@ Other Changes:
about building on 32-bit systems. (#4225) [@kingofthebongo2008] about building on 32-bit systems. (#4225) [@kingofthebongo2008]
- Backends: OpenGL3: Embed our own minimal GL headers/loader (imgui_impl_opengl3_loader.h) based on gl3w. - Backends: OpenGL3: Embed our own minimal GL headers/loader (imgui_impl_opengl3_loader.h) based on gl3w.
Reduces the frequent issues and confusion coming from having to support multiple loaders and requiring users to use and Reduces the frequent issues and confusion coming from having to support multiple loaders and requiring users to use and
initialize the same loader as the backend. (#4445) [@rokups] initialize the same loader as the backend. [@rokups]
Removed support for gl3w, glew, glad, glad2, glbinding2, glbinding3 (all now unnecessary). Removed support for gl3w, glew, glad, glad2, glbinding2, glbinding3 (all now unnecessary).
- Backends: OpenGL3: Handle GL_CLIP_ORIGIN on <4.5 contexts if "GL_ARB_clip_control" extension is detected. (#4170, #3998) - Backends: OpenGL3: Handle GL_CLIP_ORIGIN on <4.5 contexts if "GL_ARB_clip_control" extension is detected. (#4170, #3998)
- Backends: OpenGL3: Destroy vertex/fragment shader objects right after they are linked into main shader. (#4244) [@Crowbarous] - Backends: OpenGL3: Destroy vertex/fragment shader objects right after they are linked into main shader. (#4244) [@Crowbarous]
@ -2262,7 +1475,7 @@ Other Changes:
alpha compositing and transparent windows. (#2766, #3447 etc.). alpha compositing and transparent windows. (#2766, #3447 etc.).
- Backends: OpenGL, Vulkan, DX9, DX10, DX11, DX12, Metal, WebGPU, Allegro: Rework blending equation to - Backends: OpenGL, Vulkan, DX9, DX10, DX11, DX12, Metal, WebGPU, Allegro: Rework blending equation to
preserve alpha in output buffer (using SrcBlendAlpha = ONE, DstBlendAlpha = ONE_MINUS_SRC_ALPHA consistently preserve alpha in output buffer (using SrcBlendAlpha = ONE, DstBlendAlpha = ONE_MINUS_SRC_ALPHA consistently
across all backends), facilitating compositing of the output buffer with another buffer. accross all backends), facilitating compositing of the output buffer with another buffer.
(#2693, #2764, #2766, #2873, #3447, #3813, #3816) [@ocornut, @thedmd, @ShawnM427, @Ubpa, @aiekick] (#2693, #2764, #2766, #2873, #3447, #3813, #3816) [@ocornut, @thedmd, @ShawnM427, @Ubpa, @aiekick]
- Backends: DX9: Fix to support IMGUI_USE_BGRA_PACKED_COLOR. (#3844) [@Xiliusha] - Backends: DX9: Fix to support IMGUI_USE_BGRA_PACKED_COLOR. (#3844) [@Xiliusha]
- Backends: DX9: Fix to support colored glyphs, using newly introduced 'TexPixelsUseColors' info. (#3844) - Backends: DX9: Fix to support colored glyphs, using newly introduced 'TexPixelsUseColors' info. (#3844)
@ -5671,7 +4884,7 @@ Other Changes:
VERSION 1.08 (2014-08-25) VERSION 1.08 (2014-08-25)
----------------------------------------------------------------------- -----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.08 Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.09
- Fixed ImGuiTextFilter trimming of leading/trailing blanks. - Fixed ImGuiTextFilter trimming of leading/trailing blanks.
- Fixed file descriptor leak on LoadSettings() failure. - Fixed file descriptor leak on LoadSettings() failure.

View File

@ -12,29 +12,26 @@
- Article: [How To Ask Good Questions](https://bit.ly/3nwRnx1). - Article: [How To Ask Good Questions](https://bit.ly/3nwRnx1).
- Please browse the [Wiki](https://github.com/ocornut/imgui/wiki) to find code snippets, links and other resources (e.g. [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started), [Useful extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions)). - Please browse the [Wiki](https://github.com/ocornut/imgui/wiki) to find code snippets, links and other resources (e.g. [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started), [Useful extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions)).
- Please read [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) if your question relates to setting up Dear ImGui.
- Please read [docs/FAQ.md](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md). - Please read [docs/FAQ.md](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md).
- Please read [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) if your question relates to fonts or text. - Please read [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) if your question relates to fonts or text.
- Please read one of the [examples/](https://github.com/ocornut/imgui/tree/master/examples) application if your question relates to setting up Dear ImGui.
- Please run `ImGui::ShowDemoWindow()` to explore the demo and its sources. - Please run `ImGui::ShowDemoWindow()` to explore the demo and its sources.
- Please use the search function of your IDE to search for symbols and comments related to your situation. - Please use the search function of your IDE to search in for comments related to your situation.
- Please use the search function of GitHub to look for similar topics (always include 'Closed' issues/pr in your search). - Please use the search function of GitHub to look for similar issues. You may [browse issues by Labels](https://github.com/ocornut/imgui/labels).
- You may [browse issues by Labels](https://github.com/ocornut/imgui/labels).
- Please use a web search engine to look for similar issues. - Please use a web search engine to look for similar issues.
- If you get a crash or assert, use a debugger to locate the line triggering it and read the comments around. - If you get a crash or assert, use a debugger to locate the line triggering it and read the comments around.
- Please don't be a [Help Vampire](https://slash7.com/2006/12/22/vampires/). - Please don't be a [Help Vampire](https://slash7.com/2006/12/22/vampires/).
## 'Issues' vs 'Discussions' ## Issues vs Discussions
We are happy to use 'Issues' for many type of open-ended questions. We are encouraging 'Issues' becoming an enormous, centralized and cross-referenced database of Dear ImGui contents. If you:
Only if you:
- Cannot BUILD or LINK examples. - Cannot BUILD or LINK examples.
- Cannot BUILD, or LINK, or RUN Dear ImGui in your application or custom engine. - Cannot BUILD, or LINK, or RUN Dear ImGui in your application or custom engine.
- Cannot LOAD a font. - Cannot LOAD a font.
Then please [use the Discussions forums](https://github.com/ocornut/imgui/discussions) instead of opening an issue. Then please [use the Discussions forums](https://github.com/ocornut/imgui/discussions) instead of opening an issue.
If Dear ImGui is successfully showing in your app and you have used Dear ImGui before, you can open an Issue. Any form of discussions is welcome as a new issue. If Dear ImGui is successfully showing in your app and you have used Dear ImGui before, you can open an issue. Any form of discussions is welcome as a new issue.
## How to open an issue ## How to open an issue
@ -49,16 +46,16 @@ Steps:
- Article: [How To Ask Good Questions](https://bit.ly/3nwRnx1). - Article: [How To Ask Good Questions](https://bit.ly/3nwRnx1).
- **PLEASE DO FILL THE REQUESTED NEW ISSUE TEMPLATE.** Including Dear ImGui version number, branch name, platform/renderer back-ends (imgui_impl_XXX files), operating system. - **PLEASE DO FILL THE REQUESTED NEW ISSUE TEMPLATE.** Including Dear ImGui version number, branch name, platform/renderer back-ends (imgui_impl_XXX files), operating system.
- **Try to be explicit with your GOALS, your EXPECTATIONS and what you have tried**. Be mindful of [The XY Problem](http://xyproblem.info/). What you have in mind or in your code is not obvious to other people. People frequently discuss problems and suggest incorrect solutions without first clarifying their goals. When requesting a new feature, please describe the usage context (how you intend to use it, why you need it, etc.). If you tried something and it failed, show us what you tried. - **Try to be explicit with your GOALS, your EXPECTATIONS and what you have tried**. Be mindful of [The XY Problem](http://xyproblem.info/). What you have in mind or in your code is not obvious to other people. People frequently discuss problems and suggest incorrect solutions without first clarifying their goals. When requesting a new feature, please describe the usage context (how you intend to use it, why you need it, etc.). If you tried something and it failed, show us what you tried.
- **Please INCLUDE CODE. Provide a Minimal, Complete, and Verifiable Example ([MCVE](https://stackoverflow.com/help/mcve)) to demonstrate your problem**. An ideal submission includes a small piece of code that anyone can paste into one of the examples applications (examples/../main.cpp) or demo (imgui_demo.cpp) to understand and reproduce it. **Narrowing your problem to its shortest and purest form is the easiest way to understand it, explain it and fix it**. Please test your shortened code to ensure it exhibits the problem. **Often while creating the MCVE you will solve the problem!** Many questions that are missing a standalone verifiable example are missing the actual cause of their issue in the description, which ends up wasting everyone's time.
- **Attach screenshots (or GIF/video) to clarify the context**. They often convey useful information that is omitted by the description. You can drag pictures/files in the message edit box. Avoid using 3rd party image hosting services, prefer the long-term longevity of GitHub attachments (you can drag pictures into your post). On Windows, you can use [ScreenToGif](https://www.screentogif.com/) to easily capture .gif files. - **Attach screenshots (or GIF/video) to clarify the context**. They often convey useful information that is omitted by the description. You can drag pictures/files in the message edit box. Avoid using 3rd party image hosting services, prefer the long-term longevity of GitHub attachments (you can drag pictures into your post). On Windows, you can use [ScreenToGif](https://www.screentogif.com/) to easily capture .gif files.
- **If you are discussing an assert or a crash, please provide a debugger callstack**. Never state "it crashes" without additional information. If you don't know how to use a debugger and retrieve a callstack, learning about it will be useful. - **If you are discussing an assert or a crash, please provide a debugger callstack**. Never state "it crashes" without additional information. If you don't know how to use a debugger and retrieve a callstack, learning about it will be useful.
- **Please make sure that your project has asserts enabled.** Calls to IM_ASSERT() are scattered in the code to help catch common issues. When an assert is triggered read the comments around it. By default IM_ASSERT() calls the standard assert() function. To verify that your asserts are enabled, add the line `IM_ASSERT(false);` in your main() function. Your application should display an error message and abort. If your application doesn't report an error, your asserts are disabled. - **Please make sure that your project has asserts enabled.** Calls to IM_ASSERT() are scattered in the code to help catch common issues. When an assert is triggered read the comments around it. By default IM_ASSERT() calls the standard assert() function. To verify that your asserts are enabled, add the line `IM_ASSERT(false);` in your main() function. Your application should display an error message and abort. If your application doesn't report an error, your asserts are disabled.
- **Please provide a Minimal, Complete, and Verifiable Example ([MCVE](https://stackoverflow.com/help/mcve)) to demonstrate your problem**. An ideal submission includes a small piece of code that anyone can paste into one of the examples applications (examples/../main.cpp) or demo (imgui_demo.cpp) to understand and reproduce it. Narrowing your problem to its shortest and purest form is the easiest way to understand it. Please test your shortened code to ensure it exhibits the problem. **Often while creating the MCVE you will end up solving the problem!** Many questions that are missing a standalone verifiable example are missing the actual cause of their issue in the description, which ends up wasting everyone's time.
- Please state if you have made substantial modifications to your copy of Dear ImGui or the back-end. - Please state if you have made substantial modifications to your copy of Dear ImGui or the back-end.
- If you are not calling Dear ImGui directly from C++, please provide information about your Language and the wrapper/binding you are using. - If you are not calling Dear ImGui directly from C++, please provide information about your Language and the wrapper/binding you are using.
- Be mindful that messages are being sent to the mailbox of "Watching" users. Try to proofread your messages before sending them. Edits are not seen by those users unless they browse the site. - Be mindful that messages are being sent to the mailbox of "Watching" users. Try to proofread your messages before sending them. Edits are not seen by those users unless they browse the site.
**Some unfortunate words of warning** **Some unfortunate words of warning**
- If you are involved in cheating schemes (e.g. DLL injection) for competitive online multiplayer games, please don't post here. We won't answer and you will be blocked. It doesn't matter if your question relates to said project. We've had too many of you and need to protect our time and sanity. - If you are involved in cheating schemes (e.g. DLL injection) for competitive online multiplayer games, please don't try posting here. We won't answer and you will be blocked. It doesn't matter if your question relates to said project. We've had too many of you and need to project our time and sanity.
- Due to frequent abuse of this service from the aforementioned users, if your GitHub account is anonymous and was created five minutes ago please understand that your post will receive more scrutiny and incomplete questions will be harshly dismissed. - Due to frequent abuse of this service from the aforementioned users, if your GitHub account is anonymous and was created five minutes ago please understand that your post will receive more scrutiny and incomplete questions will be harshly dismissed.
If you have been using Dear ImGui for a while or have been using C/C++ for several years or have demonstrated good behavior here, it is ok to not fulfill every item to the letter. Those are guidelines and experienced users or members of the community will know which information is useful in a given context. If you have been using Dear ImGui for a while or have been using C/C++ for several years or have demonstrated good behavior here, it is ok to not fulfill every item to the letter. Those are guidelines and experienced users or members of the community will know which information is useful in a given context.
@ -66,13 +63,15 @@ If you have been using Dear ImGui for a while or have been using C/C++ for sever
## How to open a Pull Request ## How to open a Pull Request
- **Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance.** PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it. - **Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance.** PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it.
- Many PRs are useful to demonstrate a need and a possible solution but aren't adequate for merging (causing other issues, not seeing other aspects of the big picture, etc.). In doubt, don't hesitate to push a PR because that is always the first step toward pointing toward a problem, and finding the mergeable solution! Even if a PR stays unmerged for a long time, its presence can be useful for other users and helps toward finding a general solution. - Many PRs are useful to demonstrate a need and a possible solution but aren't adequate for merging (causing other issues, not seeing other aspects of the big picture, etc.). In doubt, don't hesitate to push a PR because that is always the first step toward finding the mergeable solution! Even if a PR stays unmerged for a long time, its presence can be useful for other users and helps toward finding a general solution.
- **When adding a feature,** please describe the usage context (how you intend to use it, why you need it, etc.). Be mindful of [The XY Problem](http://xyproblem.info/). - **When adding a feature,** please describe the usage context (how you intend to use it, why you need it, etc.). Be mindful of [The XY Problem](http://xyproblem.info/).
- **When fixing a warning or compilation problem,** please post the compiler log and specify the compiler version and platform you are using. - **When fixing a warning or compilation problem,** please post the compiler log and specify the compiler version and platform you are using.
- **Attach screenshots (or GIF/video) to clarify the context and demonstrate the feature at a glance.** You can drag pictures/files in the message edit box. Prefer the long-term longevity of GitHub attachments over 3rd party hosting (you can drag pictures into your post). - **Attach screenshots (or GIF/video) to clarify the context and demonstrate the feature at a glance.** You can drag pictures/files in the message edit box. Prefer the long-term longevity of GitHub attachments over 3rd party hosting (you can drag pictures into your post).
- **Make sure your code follows the coding style already used in the codebase:** 4 spaces indentations (no tabs), `local_variable`, `FunctionName()`, `MemberName`, `// Text Comment`, `//CodeComment();`, C-style casts, etc.. We don't use modern C++ idioms and tend to use only a minimum of C++11 features. The applications under examples/ are generally less consistent because they sometimes try to mimic the coding style often adopted by a certain ecosystem (e.g. DirectX-related code tend to use the style of their sample). - **Make sure your code follows the coding style already used in the codebase:** 4 spaces indentations (no tabs), `local_variable`, `FunctionName()`, `MemberName`, `// Text Comment`, `//CodeComment();`, C-style casts, etc.. We don't use modern C++ idioms and tend to use only a minimum of C++11 features. The applications under examples/ are generally less consistent because they sometimes try to mimic the coding style often adopted by a certain ecosystem (e.g. DirectX-related code tend to use the style of their sample).
- **Make sure you create a branch dedicated to the pull request**. In Git, 1 PR is associated to 1 branch. If you keep pushing to the same branch after you submitted the PR, your new commits will appear in the PR (we can still cherry-pick individual commits). - **Make sure you create a branch dedicated to the pull request**. In Git, 1 PR is associated to 1 branch. If you keep pushing to the same branch after you submitted the PR, your new commits will appear in the PR (we can still cherry-pick individual commits).
Thank you for reading!
## Copyright / Contributor License Agreement ## Copyright / Contributor License Agreement
Any code you submit will become part of the repository and be distributed under the [Dear ImGui license](https://github.com/ocornut/imgui/blob/master/LICENSE.txt). By submitting code to the project you agree that the code is your work and that you can give it to the project. Any code you submit will become part of the repository and be distributed under the [Dear ImGui license](https://github.com/ocornut/imgui/blob/master/LICENSE.txt). By submitting code to the project you agree that the code is your work and that you can give it to the project.

View File

@ -10,7 +10,7 @@ integrating Dear ImGui in your own application/game/engine.
**Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.** **Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.**
You can find Windows binaries for some of those example applications at: You can find Windows binaries for some of those example applications at:
https://www.dearimgui.com/binaries http://www.dearimgui.com/binaries
### Getting Started ### Getting Started
@ -74,7 +74,7 @@ ImGui::DestroyContext();
Please read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. Please read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup Dear ImGui in your codebase.
Please read the comments and instruction at the top of each file. Please read the comments and instruction at the top of each file.
Please read FAQ at https://www.dearimgui.com/faq Please read FAQ at http://www.dearimgui.com/faq
If you are using any of the backends provided here, you can add the backends/imgui_impl_xxxx(.cpp,.h) If you are using any of the backends provided here, you can add the backends/imgui_impl_xxxx(.cpp,.h)
files to your project and use as-in. Each imgui_impl_xxxx.cpp file comes with its own individual files to your project and use as-in. Each imgui_impl_xxxx.cpp file comes with its own individual
@ -104,8 +104,8 @@ OSX + OpenGL2 example. <BR>
(NB: imgui_impl_osx.mm is currently not as feature complete as other platforms backends. (NB: imgui_impl_osx.mm is currently not as feature complete as other platforms backends.
You may prefer to use the GLFW Or SDL backends, which will also support Windows and Linux.) You may prefer to use the GLFW Or SDL backends, which will also support Windows and Linux.)
[example_glfw_wgpu/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_wgpu/) <BR> [example_emscripten_wgpu/](https://github.com/ocornut/imgui/blob/master/examples/example_emscripten_wgpu/) <BR>
GLFW + WebGPU example. Supports Emscripten (web) or Dawn (desktop) <BR> Emcripten + GLFW + WebGPU example. <BR>
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_wgpu.cpp = main.cpp + imgui_impl_glfw.cpp + imgui_impl_wgpu.cpp
Note that the 'example_glfw_opengl3' and 'example_sdl2_opengl3' examples also supports Emscripten! Note that the 'example_glfw_opengl3' and 'example_sdl2_opengl3' examples also supports Emscripten!
@ -126,7 +126,7 @@ state, and might confuse your GPU driver. One star, not recommended.
GLFW (Win32, Mac, Linux) + OpenGL3+/ES2/ES3 example (modern, programmable pipeline). <BR> GLFW (Win32, Mac, Linux) + OpenGL3+/ES2/ES3 example (modern, programmable pipeline). <BR>
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp <BR> = main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp <BR>
This uses more modern GL calls and custom shaders.<BR> This uses more modern GL calls and custom shaders.<BR>
This support building with Emscripten and targeting WebGL.<BR> This support building with Emscripten and targetting WebGL.<BR>
Prefer using that if you are using modern GL or WebGL in your application. Prefer using that if you are using modern GL or WebGL in your application.
[example_glfw_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_vulkan/) <BR> [example_glfw_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_vulkan/) <BR>
@ -168,7 +168,7 @@ state, and might confuse your GPU driver. One star, not recommended.
SDL2 (Win32, Mac, Linux, etc.) + OpenGL3+/ES2/ES3 example. <BR> SDL2 (Win32, Mac, Linux, etc.) + OpenGL3+/ES2/ES3 example. <BR>
= main.cpp + imgui_impl_sdl2.cpp + imgui_impl_opengl3.cpp <BR> = main.cpp + imgui_impl_sdl2.cpp + imgui_impl_opengl3.cpp <BR>
This uses more modern GL calls and custom shaders. <BR> This uses more modern GL calls and custom shaders. <BR>
This support building with Emscripten and targeting WebGL.<BR> This support building with Emscripten and targetting WebGL.<BR>
Prefer using that if you are using modern GL or WebGL in your application. Prefer using that if you are using modern GL or WebGL in your application.
[example_sdl2_sdlrenderer2/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_sdlrenderer2/) <BR> [example_sdl2_sdlrenderer2/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_sdlrenderer2/) <BR>

View File

@ -23,7 +23,7 @@ or view this file with any Markdown viewer.
| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) | | [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) |
| [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) | | [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) |
| **Q&A: Usage** | | **Q&A: Usage** |
| **[About the ID Stack system..<br>Why is my widget not reacting when I click on it?<br>Why is the wrong widget reacting when I click on one?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?<br>How can I have multiple windows with the same label?](#q-about-the-id-stack-system)** | | **[About the ID Stack system..<br>Why is my widget not reacting when I click on it?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?<br>How can I have multiple windows with the same label?](#q-about-the-id-stack-system)** |
| [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)| | [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)|
| [How can I use maths operators with ImVec2?](#q-how-can-i-use-maths-operators-with-imvec2) | | [How can I use maths operators with ImVec2?](#q-how-can-i-use-maths-operators-with-imvec2) |
| [How can I use my own maths types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-maths-types-instead-of-imvec2imvec4) | | [How can I use my own maths types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-maths-types-instead-of-imvec2imvec4) |
@ -91,7 +91,6 @@ Many projects are using this branch and it is kept in sync with master regularly
### Q: How to get started? ### Q: How to get started?
Read [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started). <BR>
Read [EXAMPLES.md](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md). <BR> Read [EXAMPLES.md](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md). <BR>
Read [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md). <BR> Read [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md). <BR>
Read `PROGRAMMER GUIDE` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp). <BR> Read `PROGRAMMER GUIDE` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp). <BR>
@ -125,8 +124,13 @@ void MyLowLevelMouseButtonHandler(int button, bool down)
} }
``` ```
**Note:** The `io.WantCaptureMouse` is more correct that any manual attempt to "check if the mouse is hovering a window" (don't do that!). It handles mouse dragging correctly (both dragging that started over your application or over a Dear ImGui window) and handle e.g. popup and modal windows blocking inputs. **Note:** The `io.WantCaptureMouse` is more correct that any manual attempt to "check if the mouse is hovering a window" (don't do that!). It handles mouse dragging correctly (both dragging that started over your application or over a Dear ImGui window) and handle e.g. popup and modal windows blocking inputs.
**Note:** Those flags are updated by `ImGui::NewFrame()`. However it is generally more correct and easier that you poll flags from the previous frame, then submit your inputs, then call `NewFrame()`. If you attempt to do the opposite (which is generally harder) you are likely going to submit your inputs after `NewFrame()`, and therefore too late.
**Note:** If you are using a touch device, you may find use for an early call to `UpdateHoveredWindowAndCaptureFlags()` to correctly dispatch your initial touch. We will work on better out-of-the-box touch support in the future.
**Note:** Text input widget releases focus on the "KeyDown" event of the Return key, so the subsequent "KeyUp" event that your application receive will typically have `io.WantCaptureKeyboard == false`. Depending on your application logic it may or not be inconvenient to receive that KeyUp event. You might want to track which key-downs were targeted for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.) **Note:** Text input widget releases focus on the "KeyDown" event of the Return key, so the subsequent "KeyUp" event that your application receive will typically have `io.WantCaptureKeyboard == false`. Depending on your application logic it may or not be inconvenient to receive that KeyUp event. You might want to track which key-downs were targeted for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.)
##### [Return to Index](#index) ##### [Return to Index](#index)
@ -137,7 +141,7 @@ void MyLowLevelMouseButtonHandler(int button, bool down)
- The gamepad/keyboard navigation is fairly functional and keeps being improved. The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. Gamepad support is particularly useful to use Dear ImGui on a game console (e.g. PS4, Switch, XB1) without a mouse connected! - The gamepad/keyboard navigation is fairly functional and keeps being improved. The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. Gamepad support is particularly useful to use Dear ImGui on a game console (e.g. PS4, Switch, XB1) without a mouse connected!
- Keyboard: set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard` to enable. - Keyboard: set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard` to enable.
- Gamepad: set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad` to enable (with a supporting backend). - Gamepad: set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad` to enable (with a supporting backend).
- See [Control Sheets for Gamepads](https://www.dearimgui.com/controls_sheets) (reference PNG/PSD for PS4, XB1, Switch gamepads). - See [Control Sheets for Gamepads](http://www.dearimgui.com/controls_sheets) (reference PNG/PSD for PS4, XB1, Switch gamepads).
- See `USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) for more details. - See `USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) for more details.
##### [Return to Index](#index) ##### [Return to Index](#index)
@ -160,8 +164,8 @@ Console SDK also sometimes provide equivalent tooling or wrapper for Synergy-lik
--- ---
### Q: I integrated Dear ImGui in my engine and little squares are showing instead of text... ### Q: I integrated Dear ImGui in my engine and little squares are showing instead of text...
Your renderer backend is not using the font texture correctly or it hasn't been uploaded to the GPU. Your renderer is not using the font texture correctly or it hasn't been uploaded to the GPU.
- If this happens using the standard backends: A) have you modified the font atlas after `ImGui_ImplXXX_NewFrame()`? B) maybe the texture failed to upload, which **can if your texture atlas is too big**. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md). - If this happens using the standard backends: A) have you modified the font atlas after `ImGui_ImplXXX_NewFrame()`? B) maybe the texture failed to upload, which could happens if for some reason your texture is too big. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md).
- If this happens with a custom backend: make sure you have uploaded the font texture to the GPU, that all shaders are rendering states are setup properly (e.g. texture is bound). Compare your code to existing backends and use a graphics debugger such as [RenderDoc](https://renderdoc.org) to debug your rendering states. - If this happens with a custom backend: make sure you have uploaded the font texture to the GPU, that all shaders are rendering states are setup properly (e.g. texture is bound). Compare your code to existing backends and use a graphics debugger such as [RenderDoc](https://renderdoc.org) to debug your rendering states.
##### [Return to Index](#index) ##### [Return to Index](#index)
@ -199,42 +203,10 @@ ctx->RSSetScissorRects(1, &r);
### Q: About the ID Stack system... ### Q: About the ID Stack system...
### Q: Why is my widget not reacting when I click on it? ### Q: Why is my widget not reacting when I click on it?
### Q: Why is the wrong widget reacting when I click on one?
### Q: How can I have widgets with an empty label? ### Q: How can I have widgets with an empty label?
### Q: How can I have multiple widgets with the same label? ### Q: How can I have multiple widgets with the same label?
### Q: How can I have multiple windows with the same label? ### Q: How can I have multiple windows with the same label?
**USING THE SAME LABEL+ID IS THE MOST COMMON USER MISTAKE:**
<table>
<tr>
<td><img src="https://github.com/ocornut/imgui/assets/8225057/76eb9467-74d1-4e95-9f56-be81c6dd029d"></td>
<td>
<pre lang="cpp">
ImGui::Begin("Incorrect!");
ImGui::DragFloat2("My value", &objects[0]->pos.x);
ImGui::DragFloat2("My value", &objects[1]->pos.x);
ImGui::DragFloat2("My value", &objects[2]->pos.x);
ImGui::End();
&nbsp;
ImGui::Begin("Correct!");
ImGui::DragFloat2("My value", &objects[0]->pos.x);
ImGui::DragFloat2("My value##2", &objects[1]->pos.x);
ImGui::DragFloat2("My value##3", &objects[2]->pos.x);
ImGui::End();
&nbsp;
ImGui::Begin("Also Correct!");
for (int n = 0; n < 3; n++)
{
ImGui::PushID(n);
ImGui::DragFloat2("My value", &objects[n]->pos.x);
ImGui::PopID();
}
ImGui::End();
</pre>
</td>
</tr>
</table>
A primer on labels and the ID Stack... A primer on labels and the ID Stack...
Dear ImGui internally needs to uniquely identify UI elements. Dear ImGui internally needs to uniquely identify UI elements.
@ -244,7 +216,7 @@ Interactive widgets (such as calls to Button buttons) need a unique ID.
**Unique IDs are used internally to track active widgets and occasionally associate state to widgets.<BR> **Unique IDs are used internally to track active widgets and occasionally associate state to widgets.<BR>
Unique IDs are implicitly built from the hash of multiple elements that identify the "path" to the UI element.** Unique IDs are implicitly built from the hash of multiple elements that identify the "path" to the UI element.**
Since Dear ImGui 1.85, you can use `Demo>Tools>ID Stack Tool` or call `ImGui::ShowIDStackToolWindow()`. The tool display intermediate values leading to the creation of a unique ID, making things easier to debug and understand. Since Dear ImGui 1.85, you can use `Demo>Tools>Stack Tool` or call `ImGui::ShowStackToolWindow()`. The tool display intermediate values leading to the creation of a unique ID, making things easier to debug and understand.
![Stack tool](https://user-images.githubusercontent.com/8225057/136235657-a0ea5665-dcd1-423f-9be6-dc3f8ced8f12.png) ![Stack tool](https://user-images.githubusercontent.com/8225057/136235657-a0ea5665-dcd1-423f-9be6-dc3f8ced8f12.png)
@ -458,7 +430,7 @@ Finally, you may call `ImGui::ShowMetricsWindow()` to explore/visualize/understa
### Q: How can I use maths operators with ImVec2? ### Q: How can I use maths operators with ImVec2?
We do not export maths operators by default in imgui.h in order to not conflict with the use of your own maths types and maths operators. As a convenience, you may use `#define IMGUI_DEFINE_MATH_OPERATORS` + `#include "imgui.h"` to access our basic maths operators. We do not export maths operators by default in imgui.h in order to not conflict with the use of your own maths types and maths operators. As a convenience, you may use `#defne IMGUI_DEFINE_MATH_OPERATORS` + `#include "imgui.h"` to access our basic maths operators.
##### [Return to Index](#index) ##### [Return to Index](#index)
@ -557,7 +529,7 @@ This approach is relatively easy and functional but comes with two issues:
- Style override may be lost during the `Begin()` call crossing monitor boundaries. You may need to do some custom scaling mumbo-jumbo if you want your `OnChangedViewport()` handler to preserve style overrides. - Style override may be lost during the `Begin()` call crossing monitor boundaries. You may need to do some custom scaling mumbo-jumbo if you want your `OnChangedViewport()` handler to preserve style overrides.
Please note that if you are not using multi-viewports with multi-monitors using different DPI scales, you can ignore that and use the simpler technique recommended at the top. Please note that if you are not using multi-viewports with multi-monitors using different DPI scales, you can ignore that and use the simpler technique recommended at the top.
On Windows, in addition to scaling the font size (make sure to round to an integer) and using `style.ScaleAllSizes()`, you will need to inform Windows that your application is DPI aware. If this is not done, Windows will scale the application window and the UI text will be blurry. Potential solutions to indicate DPI awareness on Windows are: On Windows, in addition to scaling the font size (make sure to round to an integer) and using `style.ScaleAllSizes()`, you will need to inform Windows that your application is DPI aware. If this is not done, Windows will scale the application window and the UI text will be blurry. Potential solutions to indicate DPI awareness on Windows are:
- For SDL: the flag `SDL_WINDOW_ALLOW_HIGHDPI` needs to be passed to `SDL_CreateWindow()``. - For SDL: the flag `SDL_WINDOW_ALLOW_HIGHDPI` needs to be passed to `SDL_CreateWindow()``.
@ -597,15 +569,44 @@ io.Fonts->AddFontFromFileTTF("MyFolder/MyFont.ttf", size); // ALSO CORRECT
### Q: How can I easily use icons in my application? ### Q: How can I easily use icons in my application?
The most convenient and practical way is to merge an icon font such as FontAwesome inside your The most convenient and practical way is to merge an icon font such as FontAwesome inside your
main font. Then you can refer to icons within your strings. main font. Then you can refer to icons within your strings.
Read the [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) file for more details about icons font loading. You may want to see `ImFontConfig::GlyphMinAdvanceX` to make your icon look monospace to facilitate alignment.
(Read the [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) file for more details about icons font loading.)
With some extra effort, you may use colorful icons by registering custom rectangle space inside the font atlas,
and copying your own graphics data into it. See docs/FONTS.md about using the AddCustomRectFontGlyph API.
##### [Return to Index](#index) ##### [Return to Index](#index)
--- ---
### Q: How can I load multiple fonts? ### Q: How can I load multiple fonts?
Use the font atlas to pack them into a single texture:
(Read the [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) file and the code in ImFontAtlas for more details.)
Use the font atlas to pack them into a single texture. Read [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) for more details. ```cpp
ImGuiIO& io = ImGui::GetIO();
ImFont* font0 = io.Fonts->AddFontDefault();
ImFont* font1 = io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels);
ImFont* font2 = io.Fonts->AddFontFromFileTTF("myfontfile2.ttf", size_in_pixels);
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
// the first loaded font gets used by default
// use ImGui::PushFont()/ImGui::PopFont() to change the font at runtime
// Options
ImFontConfig config;
config.OversampleH = 2;
config.OversampleV = 1;
config.GlyphOffset.y -= 1.0f; // Move everything by 1 pixel up
config.GlyphExtraSpacing.x = 1.0f; // Increase spacing between characters
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_pixels, &config);
// Combine multiple fonts into one (e.g. for icon fonts)
static ImWchar ranges[] = { 0xf000, 0xf3ff, 0 };
ImFontConfig config;
config.MergeMode = true;
io.Fonts->AddFontDefault();
io.Fonts->AddFontFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges); // Merge icon font
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_pixels, nullptr, &config, io.Fonts->GetGlyphRangesJapanese()); // Merge japanese glyphs
```
##### [Return to Index](#index) ##### [Return to Index](#index)
@ -653,8 +654,8 @@ You may take a look at:
- [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) - [Quotes](https://github.com/ocornut/imgui/wiki/Quotes)
- [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui)
- [Funding & Sponsors](https://github.com/ocornut/imgui/wiki/Funding) - [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors)
- [Gallery](https://github.com/ocornut/imgui/issues/7503) - [Gallery](https://github.com/ocornut/imgui/issues/6478)
##### [Return to Index](#index) ##### [Return to Index](#index)
@ -696,11 +697,11 @@ There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/ci
# Q&A: Community # Q&A: Community
### Q: How can I help? ### Q: How can I help?
- Businesses: please reach out to `omar AT dearimgui.com` if you work in a place using Dear ImGui! We can discuss ways for your company to fund development via invoiced technical support, maintenance, or sponsoring contacts. This is among the most useful thing you can do for Dear ImGui. With increased funding, we can hire more people to work on this project. Please see [Funding](https://github.com/ocornut/imgui/wiki/Funding) page. - Businesses: please reach out to `contact AT dearimgui.com` if you work in a place using Dear ImGui! We can discuss ways for your company to fund development via invoiced technical support, maintenance, or sponsoring contacts. This is among the most useful thing you can do for Dear ImGui. With increased funding, we can hire more people to work on this project.
- Individuals: you can support continued maintenance and development via PayPal donations. See [README](https://github.com/ocornut/imgui/blob/master/docs/README.md). - Individuals: you can support continued maintenance and development via PayPal donations. See [README](https://github.com/ocornut/imgui/blob/master/docs/README.md).
- If you are experienced with Dear ImGui and C++, look at [GitHub Issues](https://github.com/ocornut/imgui/issues), [GitHub Discussions](https://github.com/ocornut/imgui/discussions), the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt), and see how you want to help and can help! - If you are experienced with Dear ImGui and C++, look at [GitHub Issues](https://github.com/ocornut/imgui/issues), [GitHub Discussions](https://github.com/ocornut/imgui/discussions), the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt), and see how you want to help and can help!
- Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere, etc. - Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere, etc.
You may post screenshots or links in the [gallery threads](https://github.com/ocornut/imgui/issues/7503). Visuals are ideal as they inspire other programmers. Disclosing your use of Dear ImGui helps the library grow credibility, and helps other teams and programmers with taking decisions. You may post screenshots or links in the [gallery threads](https://github.com/ocornut/imgui/issues/6478). Visuals are ideal as they inspire other programmers. Disclosing your use of Dear ImGui helps the library grow credibility, and helps other teams and programmers with taking decisions.
- If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues or sometimes incomplete PR. - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues or sometimes incomplete PR.
##### [Return to Index](#index) ##### [Return to Index](#index)

View File

@ -11,58 +11,118 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo
**Also read the FAQ:** https://www.dearimgui.com/faq (there is a Fonts section!) **Also read the FAQ:** https://www.dearimgui.com/faq (there is a Fonts section!)
## Index ## Index
- [Troubleshooting](#troubleshooting) - [Readme First](#readme-first)
- [About Filenames](#about-filenames)
- [About UTF-8 Encoding](#about-utf-8-encoding)
- [Debug Tools](#debug-tools)
- [How should I handle DPI in my application?](#how-should-i-handle-dpi-in-my-application) - [How should I handle DPI in my application?](#how-should-i-handle-dpi-in-my-application)
- [Fonts Loading Instructions](#fonts-loading-instructions) - [Fonts Loading Instructions](#fonts-loading-instructions)
- [Loading Font Data from Memory](#loading-font-data-from-memory)
- [Loading Font Data Embedded In Source Code](#loading-font-data-embedded-in-source-code)
- [Using Icon Fonts](#using-icon-fonts) - [Using Icon Fonts](#using-icon-fonts)
- [Using FreeType Rasterizer (imgui_freetype)](#using-freetype-rasterizer-imgui_freetype) - [Using FreeType Rasterizer (imgui_freetype)](#using-freetype-rasterizer-imgui_freetype)
- [Using Colorful Glyphs/Emojis](#using-colorful-glyphsemojis) - [Using Colorful Glyphs/Emojis](#using-colorful-glyphsemojis)
- [Using Custom Glyph Ranges](#using-custom-glyph-ranges) - [Using Custom Glyph Ranges](#using-custom-glyph-ranges)
- [Using Custom Colorful Icons](#using-custom-colorful-icons) - [Using Custom Colorful Icons](#using-custom-colorful-icons)
- [About Filenames](#about-filenames) - [Using Font Data Embedded In Source Code](#using-font-data-embedded-in-source-code)
- [About UTF-8 Encoding](#about-utf-8-encoding)
- [Debug Tools](#debug-tools)
- [Credits/Licenses For Fonts Included In Repository](#creditslicenses-for-fonts-included-in-repository) - [Credits/Licenses For Fonts Included In Repository](#creditslicenses-for-fonts-included-in-repository)
- [Font Links](#font-links) - [Font Links](#font-links)
--------------------------------------- ---------------------------------------
## Troubleshooting ## Readme First
**A vast majority of font and text related issues encountered comes from 4 things:** **A vast majority of font and text related issues encountered comes from 3 things:**
- Invalid filename due to use of `\` or unexpected working directory. See [About Filenames](#about-filenames). AddFontXXX functions should assert if the filename is incorrect.
- Invalid UTF-8 encoding of your non-ASCII strings. See [About UTF-8 Encoding](#about-utf-8-encoding). Use the encoding viewer to confirm yours is correct.
- You need to load a font with explicit glyph ranges if you want to use non-ASCII characters. See [Fonts Loading Instructions](#fonts-loading-instructions). Use Metrics/Debugger->Fonts to confirm loaded fonts and loaded glyph ranges.
### (1) Invalid filename due to use of `\` or unexpected working directory. The third point is a current constraint of Dear ImGui (which we will lift in the future): when loading a font you need to specify which characters glyphs to load.
All loaded fonts glyphs are rendered into a single texture atlas ahead of time. Calling either of `io.Fonts->GetTexDataAsAlpha8()`, `io.Fonts->GetTexDataAsRGBA32()` or `io.Fonts->Build()` will build the atlas. This is generally called by the Renderer backend, e.g. `ImGui_ImplDX11_NewFrame()` calls it.
See [About Filenames](#about-filenames). AddFontXXX functions should assert if the filename is incorrect. **If you use custom glyphs ranges, make sure the array is persistent** and available during the calls to `GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build()`.
### (2) Invalid UTF-8 encoding of your non-ASCII strings. ##### [Return to Index](#index)
See [About UTF-8 Encoding](#about-utf-8-encoding). Use the encoding viewer to confirm encoding of string literal in your source code is correct. ## About Filenames
### (3) Missing glyph ranges. **Please note that many new C/C++ users have issues loading their files _because the filename they provide is wrong_ due to incorrect assumption of what is the current directory.**
You need to load a font with explicit glyph ranges if you want to use non-ASCII characters. See [Fonts Loading Instructions](#fonts-loading-instructions). Use [Debug Tools](#debug-tools) confirm loaded fonts and loaded glyph ranges. Two things to watch for:
This is a current constraint of Dear ImGui (which we will lift in the future): when loading a font you need to specify which characters glyphs to load. (1) In C/C++ and most programming languages if you want to use a backslash `\` within a string literal, you need to write it double backslash `\\`. At it happens, Windows uses backslashes as a path separator, so be mindful.
All loaded fonts glyphs are rendered into a single texture atlas ahead of time. Calling either of `io.Fonts->GetTexDataAsAlpha8()`, `io.Fonts->GetTexDataAsRGBA32()` or `io.Fonts->Build()` will build the atlas. This is generally called by the Renderer backend, e.g. `ImGui_ImplDX11_NewFrame()` calls it. **If you use custom glyphs ranges, make sure the array is persistent** and available during the calls to `GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build()`. ```cpp
io.Fonts->AddFontFromFileTTF("MyFiles\MyImage01.jpg", ...); // This is INCORRECT!!
### (4) Font atlas texture fails to upload to GPU. io.Fonts->AddFontFromFileTTF("MyFiles\\MyImage01.jpg", ...); // This is CORRECT
```
This is often of byproduct of point 3. If you have large number of glyphs or multiple fonts, the texture may become too big for your graphics API. **The typical result of failing to upload a texture is if every glyph or everything appears as empty black or white rectangle.** Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours. In some situations, you may also use `/` path separator under Windows.
Some solutions: (2) Make sure your IDE/debugger settings starts your executable from the right working (current) directory. In Visual Studio you can change your working directory in project `Properties > General > Debugging > Working Directory`. People assume that their execution will start from the root folder of the project, where by default it often starts from the folder where object or executable files are stored.
- You may reduce oversampling, e.g. `font_config.OversampleH = 1`, this will half your texture size for a quality loss. ```cpp
Note that while OversampleH = 2 looks visibly very close to 3 in most situations, with OversampleH = 1 the quality drop will be noticeable. Read about oversampling [here](https://github.com/nothings/stb/blob/master/tests/oversample). io.Fonts->AddFontFromFileTTF("MyImage01.jpg", ...); // Relative filename depends on your Working Directory when running your program!
- Reduce glyphs ranges by calculating them from source localization data. io.Fonts->AddFontFromFileTTF("../MyImage01.jpg", ...); // Load from the parent folder of your Working Directory
You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win! ```
- Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two. ##### [Return to Index](#index)
- Set `io.Fonts.TexDesiredWidth` to specify a texture width to reduce maximum texture height (see comment in `ImFontAtlas::Build()` function).
## About UTF-8 Encoding
**For non-ASCII characters display, a common user issue is not passing correctly UTF-8 encoded strings.**
(1) We provide a function `ImGui::DebugTextEncoding(const char* text)` which you can call to verify the content of your UTF-8 strings.
This is a convenient way to confirm that your encoding is correct.
```cpp
ImGui::SeparatorText("CORRECT");
ImGui::DebugTextEncoding(u8"こんにちは");
ImGui::SeparatorText("INCORRECT");
ImGui::DebugTextEncoding("こんにちは");
```
![UTF-8 Encoding viewer](https://github.com/ocornut/imgui/assets/8225057/61c1696a-9a94-46c5-9627-cf91211111f0)
You can also find this tool under `Metrics/Debuggers->Tools->UTF-8 Encoding viewer` if you want to paste from clipboard, but this won't validate the UTF-8 encoding done by your compiler.
(2) To encode in UTF-8:
There are also compiler-specific ways to enforce UTF-8 encoding by default:
- Visual Studio compiler: `/utf-8` command-line flag.
- Visual Studio compiler: `#pragma execution_character_set("utf-8")` inside your code.
- Since May 2023 we have changed the Visual Studio projects of all our examples to use `/utf-8` ([see commit](https://github.com/ocornut/imgui/commit/513af1efc9080857bbd10000d98f98f2a0c96803)).
Or, since C++11, you can use the `u8"my text"` syntax to encode literal strings as UTF-8. e.g.:
```cpp
ImGui::Text(u8"hello");
ImGui::Text(u8"こんにちは"); // this will always be encoded as UTF-8
ImGui::Text("こんにちは"); // the encoding of this is depending on compiler settings/flags and may be incorrect.
```
Since C++20, because the C++ committee hate its users, they decided to change the `u8""` syntax to not return `const char*` but a new type `const char_t*` which doesn't cast to `const char*`.
Because of type usage of `u8""` in C++20 is a little more tedious:
```cpp
ImGui::Text((const char*)u8"こんにちは");
```
We suggest using a macro in your codebase:
```cpp
#define U8(_S) (const char*)u8##_S
ImGui::Text(U8("こんにちは"));
```
##### [Return to Index](#index)
## Debug Tools
#### Metrics/Debugger->Fonts
You can use the `Metrics/Debugger` window (available in `Demo>Tools`) to browse your fonts and understand what's going on if you have an issue. You can also reach it in `Demo->Tools->Style Editor->Fonts`. The same information are also available in the Style Editor under Fonts.
![Fonts debugging](https://user-images.githubusercontent.com/8225057/135429892-0e41ef8d-33c5-4991-bcf6-f997a0bcfd6b.png)
#### UTF-8 Encoding Viewer**
You can use the `UTF-8 Encoding viewer` in `Metrics/Debugger` to verify the content of your UTF-8 strings. From C/C++ code, you can call `ImGui::DebugTextEncoding("my string");` function to verify that your UTF-8 encoding is correct.
![UTF-8 Encoding viewer](https://user-images.githubusercontent.com/8225057/166505963-8a0d7899-8ee8-4558-abb2-1ae523dc02f9.png)
##### [Return to Index](#index) ##### [Return to Index](#index)
---------------------------------------
## How should I handle DPI in my application? ## How should I handle DPI in my application?
@ -70,7 +130,6 @@ See [FAQ entry](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-how-s
##### [Return to Index](#index) ##### [Return to Index](#index)
---------------------------------------
## Fonts Loading Instructions ## Fonts Loading Instructions
@ -85,7 +144,7 @@ io.Fonts->AddFontDefault();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
``` ```
If you get an assert stating "Could not load font file!", your font filename is likely incorrect. Read [About filenames](#about-filenames) carefully. If you get an assert stating "Could not load font file!", your font filename is likely incorrect. Read "[About filenames](#about-filenames)" carefully.
**Load multiple fonts:** **Load multiple fonts:**
```cpp ```cpp
@ -94,9 +153,8 @@ ImGuiIO& io = ImGui::GetIO();
ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels); ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels);
``` ```
In your application loop, select which font to use:
```cpp ```cpp
// In application loop: select font at runtime
ImGui::Text("Hello"); // use the default font (which is the first loaded font) ImGui::Text("Hello"); // use the default font (which is the first loaded font)
ImGui::PushFont(font2); ImGui::PushFont(font2);
ImGui::Text("Hello with another font"); ImGui::Text("Hello with another font");
@ -142,6 +200,7 @@ io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, nullptr, io.Fonts->GetGlyp
``` ```
See [Using Custom Glyph Ranges](#using-custom-glyph-ranges) section to create your own ranges. See [Using Custom Glyph Ranges](#using-custom-glyph-ranges) section to create your own ranges.
**Example loading and using a Japanese font:** **Example loading and using a Japanese font:**
```cpp ```cpp
@ -161,50 +220,24 @@ ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/code_sample_02_jp.png) ![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/code_sample_02_jp.png)
<br>_(settings: Dark style (left), Light style (right) / Font: NotoSansCJKjp-Medium, 20px / Rounding: 5)_ <br>_(settings: Dark style (left), Light style (right) / Font: NotoSansCJKjp-Medium, 20px / Rounding: 5)_
##### [Return to Index](#index) **Font Atlas too large?**
--------------------------------------- - If you have very large number of glyphs or multiple fonts, the texture may become too big for your graphics API. The typical result of failing to upload a texture is if every glyph appears as a white rectangle.
- Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
## Loading Font Data from Memory Some solutions:
```cpp 1. Reduce glyphs ranges by calculating them from source localization data.
ImFont* font = io.Fonts->AddFontFromMemoryTTF(data, data_size, size_pixels, ...); You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win!
``` 2. You may reduce oversampling, e.g. `font_config.OversampleH = 2`, this will largely reduce your texture size.
Note that while OversampleH = 2 looks visibly very close to 3 in most situations, with OversampleH = 1 the quality drop will be noticeable.
IMPORTANT: `AddFontFromMemoryTTF()` by default transfer ownership of the data buffer to the font atlas, which will attempt to free it on destruction. 3. Set `io.Fonts.TexDesiredWidth` to specify a texture width to minimize texture height (see comment in `ImFontAtlas::Build()` function).
This was to avoid an unnecessary copy, and is perhaps not a good API (a future version will redesign it). 4. Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two.
If you want to keep ownership of the data and free it yourself, you need to clear the `FontDataOwnedByAtlas` field: 5. Read about oversampling [here](https://github.com/nothings/stb/blob/master/tests/oversample).
6. To support the extended range of unicode beyond 0xFFFF (e.g. emoticons, dingbats, symbols, shapes, ancient languages, etc...) add `#define IMGUI_USE_WCHAR32`in your `imconfig.h`.
```cpp
ImFontConfig font_cfg;
font_cfg.FontDataOwnedByAtlas = false;
ImFont* font = io.Fonts->AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg);
```
##### [Return to Index](#index) ##### [Return to Index](#index)
---------------------------------------
## Loading Font Data Embedded In Source Code
- Compile and use [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) to create a compressed C style array that you can embed in source code.
- See the documentation in [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) for instructions on how to use the tool.
- You may find a precompiled version binary_to_compressed_c.exe for Windows inside the demo binaries package (see [README](https://github.com/ocornut/imgui/blob/master/docs/README.md)).
- The tool can optionally output Base85 encoding to reduce the size of _source code_ but the read-only arrays in the actual binary will be about 20% bigger.
Then load the font with:
```cpp
ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...);
```
or
```cpp
ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...);
```
##### [Return to Index](#index)
---------------------------------------
## Using Icon Fonts ## Using Icon Fonts
Using an icon font (such as [FontAwesome](http://fontawesome.io) or [OpenFontIcons](https://github.com/traverseda/OpenFontIcons)) is an easy and practical way to use icons in your Dear ImGui application. Using an icon font (such as [FontAwesome](http://fontawesome.io) or [OpenFontIcons](https://github.com/traverseda/OpenFontIcons)) is an easy and practical way to use icons in your Dear ImGui application.
@ -237,19 +270,11 @@ ImGui::Button(ICON_FA_SEARCH " Search");
``` ```
See Links below for other icons fonts and related tools. See Links below for other icons fonts and related tools.
**Monospace Icons?**
To make your icon look more monospace and facilitate alignment, you may want to set the ImFontConfig::GlyphMinAdvanceX value when loading an icon font.
**Screenshot**
Here's an application using icons ("Avoyd", https://www.avoyd.com): Here's an application using icons ("Avoyd", https://www.avoyd.com):
![avoyd](https://user-images.githubusercontent.com/8225057/81696852-c15d9e80-9464-11ea-9cab-2a4d4fc84396.jpg) ![avoyd](https://user-images.githubusercontent.com/8225057/81696852-c15d9e80-9464-11ea-9cab-2a4d4fc84396.jpg)
##### [Return to Index](#index) ##### [Return to Index](#index)
---------------------------------------
## Using FreeType Rasterizer (imgui_freetype) ## Using FreeType Rasterizer (imgui_freetype)
- Dear ImGui uses imstb\_truetype.h to rasterize fonts (with optional oversampling). This technique and its implementation are not ideal for fonts rendered at small sizes, which may appear a little blurry or hard to read. - Dear ImGui uses imstb\_truetype.h to rasterize fonts (with optional oversampling). This technique and its implementation are not ideal for fonts rendered at small sizes, which may appear a little blurry or hard to read.
@ -260,11 +285,9 @@ Here's an application using icons ("Avoyd", https://www.avoyd.com):
##### [Return to Index](#index) ##### [Return to Index](#index)
---------------------------------------
## Using Colorful Glyphs/Emojis ## Using Colorful Glyphs/Emojis
- Rendering of colored emojis is supported by imgui_freetype with FreeType 2.10+. - Rendering of colored emojis is only supported by imgui_freetype with FreeType 2.10+.
- You will need to load fonts with the `ImGuiFreeTypeBuilderFlags_LoadColor` flag. - You will need to load fonts with the `ImGuiFreeTypeBuilderFlags_LoadColor` flag.
- Emojis are frequently encoded in upper Unicode layers (character codes >0x10000) and will need dear imgui compiled with `IMGUI_USE_WCHAR32`. - Emojis are frequently encoded in upper Unicode layers (character codes >0x10000) and will need dear imgui compiled with `IMGUI_USE_WCHAR32`.
- Not all types of color fonts are supported by FreeType at the moment. - Not all types of color fonts are supported by FreeType at the moment.
@ -284,8 +307,6 @@ io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\seguiemj.ttf", 16.0f, &cfg, ra
##### [Return to Index](#index) ##### [Return to Index](#index)
---------------------------------------
## Using Custom Glyph Ranges ## Using Custom Glyph Ranges
You can use the `ImFontGlyphRangesBuilder` helper to create glyph ranges based on text input. For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs. You can use the `ImFontGlyphRangesBuilder` helper to create glyph ranges based on text input. For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs.
@ -303,8 +324,6 @@ io.Fonts->Build(); // Build the atlas while
##### [Return to Index](#index) ##### [Return to Index](#index)
---------------------------------------
## Using Custom Colorful Icons ## Using Custom Colorful Icons
As an alternative to rendering colorful glyphs using imgui_freetype with `ImGuiFreeTypeBuilderFlags_LoadColor`, you may allocate your own space in the texture atlas and write yourself into it. **(This is a BETA api, use if you are familiar with dear imgui and with your rendering backend)** As an alternative to rendering colorful glyphs using imgui_freetype with `ImGuiFreeTypeBuilderFlags_LoadColor`, you may allocate your own space in the texture atlas and write yourself into it. **(This is a BETA api, use if you are familiar with dear imgui and with your rendering backend)**
@ -347,89 +366,24 @@ for (int rect_n = 0; rect_n < IM_ARRAYSIZE(rect_ids); rect_n++)
##### [Return to Index](#index) ##### [Return to Index](#index)
--------------------------------------- ## Using Font Data Embedded In Source Code
## About Filenames - Compile and use [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) to create a compressed C style array that you can embed in source code.
- See the documentation in [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) for instructions on how to use the tool.
- You may find a precompiled version binary_to_compressed_c.exe for Windows inside the demo binaries package (see [README](https://github.com/ocornut/imgui/blob/master/docs/README.md)).
- The tool can optionally output Base85 encoding to reduce the size of _source code_ but the read-only arrays in the actual binary will be about 20% bigger.
**Please note that many new C/C++ users have issues loading their files _because the filename they provide is wrong_ due to incorrect assumption of what is the current directory.** Then load the font with:
Two things to watch for:
(1) In C/C++ and most programming languages if you want to use a backslash `\` within a string literal, you need to write it double backslash `\\`. At it happens, Windows uses backslashes as a path separator, so be mindful.
```cpp ```cpp
io.Fonts->AddFontFromFileTTF("MyFiles\MyImage01.jpg", ...); // This is INCORRECT!! ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...);
io.Fonts->AddFontFromFileTTF("MyFiles\\MyImage01.jpg", ...); // This is CORRECT
``` ```
In some situations, you may also use `/` path separator under Windows. or
(2) Make sure your IDE/debugger settings starts your executable from the right working (current) directory. In Visual Studio you can change your working directory in project `Properties > General > Debugging > Working Directory`. People assume that their execution will start from the root folder of the project, where by default it often starts from the folder where object or executable files are stored.
```cpp ```cpp
io.Fonts->AddFontFromFileTTF("MyImage01.jpg", ...); // Relative filename depends on your Working Directory when running your program! ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...);
io.Fonts->AddFontFromFileTTF("../MyImage01.jpg", ...); // Load from the parent folder of your Working Directory
``` ```
##### [Return to Index](#index)
---------------------------------------
## About UTF-8 Encoding
**For non-ASCII characters display, a common user issue is not passing correctly UTF-8 encoded strings.**
(1) We provide a function `ImGui::DebugTextEncoding(const char* text)` which you can call to verify the content of your UTF-8 strings.
This is a convenient way to confirm that your encoding is correct.
```cpp
ImGui::SeparatorText("CORRECT");
ImGui::DebugTextEncoding(u8"こんにちは");
ImGui::SeparatorText("INCORRECT");
ImGui::DebugTextEncoding("こんにちは");
```
![UTF-8 Encoding viewer](https://github.com/ocornut/imgui/assets/8225057/61c1696a-9a94-46c5-9627-cf91211111f0)
You can also find this tool under `Metrics/Debuggers->Tools->UTF-8 Encoding viewer` if you want to paste from clipboard, but this won't validate the UTF-8 encoding done by your compiler.
(2) To encode in UTF-8:
There are also compiler-specific ways to enforce UTF-8 encoding by default:
- Visual Studio compiler: `/utf-8` command-line flag.
- Visual Studio compiler: `#pragma execution_character_set("utf-8")` inside your code.
- Since May 2023 we have changed the Visual Studio projects of all our examples to use `/utf-8` ([see commit](https://github.com/ocornut/imgui/commit/513af1efc9080857bbd10000d98f98f2a0c96803)).
Or, since C++11, you can use the `u8"my text"` syntax to encode literal strings as UTF-8. e.g.:
```cpp
ImGui::Text(u8"hello");
ImGui::Text(u8"こんにちは"); // this will always be encoded as UTF-8
ImGui::Text("こんにちは"); // the encoding of this is depending on compiler settings/flags and may be incorrect.
```
Since C++20, because the C++ committee hate its users, they decided to change the `u8""` syntax to not return `const char*` but a new type `const char8_t*` which doesn't cast to `const char*`.
Because of type usage of `u8""` in C++20 is a little more tedious:
```cpp
ImGui::Text((const char*)u8"こんにちは");
```
However, you can disable this behavior completely using the compiler option [`/Zc:char8_t-`](https://learn.microsoft.com/en-us/cpp/build/reference/zc-char8-t?view=msvc-170) for MSVC and [`-fno-char8_t`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1423r3.html) for Clang and GCC.
##### [Return to Index](#index)
---------------------------------------
## Debug Tools
#### Metrics/Debugger->Fonts
You can use the `Metrics/Debugger` window (available in `Demo>Tools`) to browse your fonts and understand what's going on if you have an issue. You can also reach it in `Demo->Tools->Style Editor->Fonts`. The same information are also available in the Style Editor under Fonts.
![Fonts debugging](https://user-images.githubusercontent.com/8225057/135429892-0e41ef8d-33c5-4991-bcf6-f997a0bcfd6b.png)
#### UTF-8 Encoding Viewer**
You can use the `UTF-8 Encoding viewer` in `Metrics/Debugger` to verify the content of your UTF-8 strings. From C/C++ code, you can call `ImGui::DebugTextEncoding("my string");` function to verify that your UTF-8 encoding is correct.
![UTF-8 Encoding viewer](https://user-images.githubusercontent.com/8225057/166505963-8a0d7899-8ee8-4558-abb2-1ae523dc02f9.png)
##### [Return to Index](#index) ##### [Return to Index](#index)
---------------------------------------
## Credits/Licenses For Fonts Included In Repository ## Credits/Licenses For Fonts Included In Repository
Some fonts files are available in the `misc/fonts/` folder: Some fonts files are available in the `misc/fonts/` folder:
@ -482,7 +436,7 @@ Some fonts files are available in the `misc/fonts/` folder:
#### MONOSPACE FONTS #### MONOSPACE FONTS
Pixel Perfect: Pixel Perfect:
- Proggy Fonts, by Tristan Grimmer http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php - Proggy Fonts, by Tristan Grimmer http://www.proggyfonts.net or http://upperbounds.net
- Sweet16, Sweet16 Mono, by Martin Sedlak (Latin + Supplemental + Extended A) https://github.com/kmar/Sweet16Font (also include an .inl file to use directly in dear imgui.) - Sweet16, Sweet16 Mono, by Martin Sedlak (Latin + Supplemental + Extended A) https://github.com/kmar/Sweet16Font (also include an .inl file to use directly in dear imgui.)
Regular: Regular:

View File

@ -11,12 +11,12 @@ Dear ImGui
Businesses: support continued development and maintenance via invoiced sponsoring/support contracts: Businesses: support continued development and maintenance via invoiced sponsoring/support contracts:
<br>&nbsp;&nbsp;_E-mail: contact @ dearimgui dot com_ <br>&nbsp;&nbsp;_E-mail: contact @ dearimgui dot com_
<br>Individuals: support continued development and maintenance [here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S). Also see [Funding](https://github.com/ocornut/imgui/wiki/Funding) page. <br>Individuals: support continued development and maintenance [here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S). Also see [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors) page.
| [The Pitch](#the-pitch) - [Usage](#usage) - [How it works](#how-it-works) - [Releases & Changelogs](#releases--changelogs) - [Demo](#demo) - [Integration](#integration) | | [The Pitch](#the-pitch) - [Usage](#usage) - [How it works](#how-it-works) - [Releases & Changelogs](#releases--changelogs) - [Demo](#demo) - [Integration](#integration) |
:----------------------------------------------------------: | :----------------------------------------------------------: |
| [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - **[Funding & Sponsors](https://github.com/ocornut/imgui/wiki/Funding)** - [Credits](#credits) - [License](#license) | | [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors) - [Credits](#credits) - [License](#license) |
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions) - [Languages bindings & frameworks backends](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) | | [Wiki](https://github.com/ocornut/imgui/wiki) - [Languages & frameworks backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) |
### The Pitch ### The Pitch
@ -27,7 +27,7 @@ Dear ImGui is designed to **enable fast iterations** and to **empower programmer
Dear ImGui is particularly suited to integration in game engines (for tooling), real-time 3D applications, fullscreen applications, embedded applications, or any applications on console platforms where operating system features are non-standard. Dear ImGui is particularly suited to integration in game engines (for tooling), real-time 3D applications, fullscreen applications, embedded applications, or any applications on console platforms where operating system features are non-standard.
- Minimize state synchronization. - Minimize state synchronization.
- Minimize UI-related state storage on user side. - Minimize state storage on user side.
- Minimize setup and maintenance. - Minimize setup and maintenance.
- Easy to use to create dynamic UI which are the reflection of a dynamic data set. - Easy to use to create dynamic UI which are the reflection of a dynamic data set.
- Easy to use to create code-driven and data-driven tools. - Easy to use to create code-driven and data-driven tools.
@ -39,11 +39,9 @@ Dear ImGui is particularly suited to integration in game engines (for tooling),
### Usage ### Usage
**The core of Dear ImGui is self-contained within a few platform-agnostic files** which you can easily compile in your application/engine. They are all the files in the root folder of the repository (imgui*.cpp, imgui*.h). **No specific build process is required**. You can add the .cpp files into your existing project. **The core of Dear ImGui is self-contained within a few platform-agnostic files** which you can easily compile in your application/engine. They are all the files in the root folder of the repository (imgui*.cpp, imgui*.h). **No specific build process is required**. You can add the .cpp files into your existing project. See [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started).
**Backends for a variety of graphics API and rendering platforms** are provided in the [backends/](https://github.com/ocornut/imgui/tree/master/backends) folder, along with example applications in the [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder. You may also create your own backend. Anywhere where you can render textured triangles, you can render Dear ImGui. **Backends for a variety of graphics API and rendering platforms** are provided in the [backends/](https://github.com/ocornut/imgui/tree/master/backends) folder, along with example applications in the [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder. See the [Integration](#integration) section of this document for details. You may also create your own backend. Anywhere where you can render textured triangles, you can render Dear ImGui.
See the [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide and [Integration](#integration) section of this document for more details.
After Dear ImGui is set up in your application, you can use it from \_anywhere\_ in your program loop: After Dear ImGui is set up in your application, you can use it from \_anywhere\_ in your program loop:
```cpp ```cpp
@ -110,17 +108,15 @@ Reading the changelogs is a good way to keep up to date with the things Dear ImG
Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing a variety of features and examples. The code is always available for reference in `imgui_demo.cpp`. [Here's how the demo looks](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png). Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing a variety of features and examples. The code is always available for reference in `imgui_demo.cpp`. [Here's how the demo looks](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png).
You should be able to build the examples from sources. If you don't, let us know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here: You should be able to build the examples from sources. If you don't, let us know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here:
- [imgui-demo-binaries-20240105.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20240105.zip) (Windows, 1.90.1 WIP, built 2024/01/05, master) or [older binaries](https://www.dearimgui.com/binaries). - [imgui-demo-binaries-20230704.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20230704.zip) (Windows, 1.89.7, built 2023/07/04, master) or [older binaries](https://www.dearimgui.com/binaries).
The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at a different scale and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.com/faq)). The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at a different scale and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.com/faq)).
### Integration ### Integration
See the [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide for details.
On most platforms and when using C++, **you should be able to use a combination of the [imgui_impl_xxxx](https://github.com/ocornut/imgui/tree/master/backends) backends without modification** (e.g. `imgui_impl_win32.cpp` + `imgui_impl_dx11.cpp`). If your engine supports multiple platforms, consider using more imgui_impl_xxxx files instead of rewriting them: this will be less work for you, and you can get Dear ImGui running immediately. You can _later_ decide to rewrite a custom backend using your custom engine functions if you wish so. On most platforms and when using C++, **you should be able to use a combination of the [imgui_impl_xxxx](https://github.com/ocornut/imgui/tree/master/backends) backends without modification** (e.g. `imgui_impl_win32.cpp` + `imgui_impl_dx11.cpp`). If your engine supports multiple platforms, consider using more imgui_impl_xxxx files instead of rewriting them: this will be less work for you, and you can get Dear ImGui running immediately. You can _later_ decide to rewrite a custom backend using your custom engine functions if you wish so.
Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading a texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles, which is essentially what Backends are doing. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that: setting up a window and using backends. If you follow the [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide it should in theory takes you less than an hour to integrate Dear ImGui. **Make sure to spend time reading the [FAQ](https://www.dearimgui.com/faq), comments, and the examples applications!** See [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started). Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading a texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles, which is essentially what Backends are doing. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that: setting up a window and using backends. If you follow [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) it should in theory takes you less than an hour to integrate Dear ImGui. **Make sure to spend time reading the [FAQ](https://www.dearimgui.com/faq), comments, and the examples applications!**
Officially maintained backends/bindings (in repository): Officially maintained backends/bindings (in repository):
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, SDL_Renderer, Vulkan, WebGPU. - Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, SDL_Renderer, Vulkan, WebGPU.
@ -128,20 +124,18 @@ Officially maintained backends/bindings (in repository):
- Frameworks: Allegro5, Emscripten. - Frameworks: Allegro5, Emscripten.
[Third-party backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) wiki page: [Third-party backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) wiki page:
- Languages: C, C# and: Beef, ChaiScript, CovScript, Crystal, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lobster, Lua, Nim, Odin, Pascal, PureBasic, Python, ReaScript, Ruby, Rust, Swift, Zig... - Languages: C, C# and: Beef, ChaiScript, Crystal, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lobster, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
- Frameworks: AGS/Adventure Game Studio, Amethyst, Blender, bsf, Cinder, Cocos2d-x, Defold, Diligent Engine, Ebiten, Flexium, GML/Game Maker Studio, GLEQ, Godot, GTK3, Irrlicht Engine, JUCE, LÖVE+LUA, Mach Engine, Magnum, Marmalade, Monogame, NanoRT, nCine, Nim Game Lib, Nintendo 3DS/Switch/WiiU (homebrew), Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, raylib, SFML, Sokol, Unity, Unreal Engine 4/5, UWP, vtk, VulkanHpp, VulkanSceneGraph, Win32 GDI, WxWidgets. - Frameworks: AGS/Adventure Game Studio, Amethyst, Blender, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, GLEQ, Godot, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, Monogame, NanoRT, nCine, Nim Game Lib, Nintendo 3DS & Switch (homebrew), Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SDL_Renderer, SFML, Sokol, Unity, Unreal Engine 4, vtk, VulkanHpp, VulkanSceneGraph, Win32 GDI, WxWidgets.
- Many bindings are auto-generated (by good old [cimgui](https://github.com/cimgui/cimgui) or newer/experimental [dear_bindings](https://github.com/dearimgui/dear_bindings)), you can use their metadata output to generate bindings for other languages. - Many bindings are auto-generated (by good old [cimgui](https://github.com/cimgui/cimgui) or newer/experimental [dear_bindings](https://github.com/dearimgui/dear_bindings)), you can use their metadata output to generate bindings for other languages.
[Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page: [Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page:
- Automation/testing, Text editors, node editors, timeline editors, plotting, software renderers, remote network access, memory editors, gizmos, etc. Notable and well supported extensions include [ImPlot](https://github.com/epezent/implot) and [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine). - Automation/testing, Text editors, node editors, timeline editors, plotting, software renderers, remote network access, memory editors, gizmos, etc. One of the most notable and well supported extension is [ImPlot](https://github.com/epezent/implot).
Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas. Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas.
### Gallery ### Gallery
Examples projects using Dear ImGui: [Tracy](https://github.com/wolfpld/tracy) (profiler), [ImHex](https://github.com/WerWolv/ImHex) (hex editor/data analysis), [RemedyBG](https://remedybg.itch.io/remedybg) (debugger) and [hundreds of others](https://github.com/ocornut/imgui/wiki/Software-using-Dear-ImGui). For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/6478)!
For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/7503)!
For a list of third-party widgets and extensions, check out the [Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page. For a list of third-party widgets and extensions, check out the [Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page.
@ -162,9 +156,7 @@ See: [Upcoming Changes](https://github.com/ocornut/imgui/wiki/Upcoming-Changes).
See: [Dear ImGui Test Engine + Test Suite](https://github.com/ocornut/imgui_test_engine) for Automation & Testing. See: [Dear ImGui Test Engine + Test Suite](https://github.com/ocornut/imgui_test_engine) for Automation & Testing.
For the purposes of getting search engines to crawl the wiki, here's a link to the [Crawable Wiki](https://github-wiki-see.page/m/ocornut/imgui/wiki) (not for humans, [here's why](https://github-wiki-see.page/)). Getting started? For first-time users having issues compiling/linking/running or issues loading fonts, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). For other questions, bug reports, requests, feedback, you may post on [GitHub Issues](https://github.com/ocornut/imgui/issues). Please read and fill the New Issue template carefully.
Getting started? For first-time users having issues compiling/linking/running or issues loading fonts, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). For ANY other questions, bug reports, requests, feedback, please post on [GitHub Issues](https://github.com/ocornut/imgui/issues). Please read and fill the New Issue template carefully.
Private support is available for paying business customers (E-mail: _contact @ dearimgui dot com_). Private support is available for paying business customers (E-mail: _contact @ dearimgui dot com_).
@ -174,23 +166,23 @@ We occasionally tag [Releases](https://github.com/ocornut/imgui/releases) (with
**Who uses Dear ImGui?** **Who uses Dear ImGui?**
See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes), [Funding & Sponsors](https://github.com/ocornut/imgui/wiki/Funding), and [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for an idea of who is using Dear ImGui. Please add your game/software if you can! Also, see the [Gallery Threads](https://github.com/ocornut/imgui/issues/7503)! See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes), [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors), and [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for an idea of who is using Dear ImGui. Please add your game/software if you can! Also, see the [Gallery Threads](https://github.com/ocornut/imgui/issues/6478)!
How to help How to help
----------- -----------
**How can I help?** **How can I help?**
- See [GitHub Forum/Issues](https://github.com/ocornut/imgui/issues). - See [GitHub Forum/Issues](https://github.com/ocornut/imgui/issues) and [GitHub Discussions](https://github.com/ocornut/imgui/discussions).
- You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it. - You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it.
- See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas. - See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas.
- Be a [Funding Supporter](https://github.com/ocornut/imgui/wiki/Funding)! Have your company financially support this project via invoiced sponsors/maintenance or by buying a license for [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine) (please reach out: omar AT dearimgui DOT com). - Have your company financially support this project with invoiced sponsoring/support contracts or by buying a license for [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine) (please reach out: contact at dearimgui dot com).
Sponsors Sponsors
-------- --------
Ongoing Dear ImGui development is and has been financially supported by users and private sponsors. Ongoing Dear ImGui development is and has been financially supported by users and private sponsors.
<BR>Please see the **[detailed list of current and past Dear ImGui funding supporters and sponsors](https://github.com/ocornut/imgui/wiki/Funding)** for details. <BR>Please see the **[detailed list of current and past Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors)** for details.
<BR>From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations. <BR>From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations.
**THANK YOU to all past and present supporters for helping to keep this project alive and thriving!** **THANK YOU to all past and present supporters for helping to keep this project alive and thriving!**
@ -205,13 +197,13 @@ Credits
Developed by [Omar Cornut](https://www.miracleworld.net) and every direct or indirect [contributors](https://github.com/ocornut/imgui/graphs/contributors) to the GitHub. The early version of this library was developed with the support of [Media Molecule](https://www.mediamolecule.com) and first used internally on the game [Tearaway](https://tearaway.mediamolecule.com) (PS Vita). Developed by [Omar Cornut](https://www.miracleworld.net) and every direct or indirect [contributors](https://github.com/ocornut/imgui/graphs/contributors) to the GitHub. The early version of this library was developed with the support of [Media Molecule](https://www.mediamolecule.com) and first used internally on the game [Tearaway](https://tearaway.mediamolecule.com) (PS Vita).
Recurring contributors include Rokas Kupstys [@rokups](https://github.com/rokups) (2020-2022): a good portion of work on automation system and regression tests now available in [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine). Recurring contributors (2022): Omar Cornut [@ocornut](https://github.com/ocornut), Rokas Kupstys [@rokups](https://github.com/rokups) (a good portion of work on automation system and regression tests now available in [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine)).
Maintenance/support contracts, sponsoring invoices and other B2B transactions are hosted and handled by [Disco Hello](https://www.discohello.com). Sponsoring, support contracts and other B2B transactions are hosted and handled by [Disco Hello](https://www.discohello.com).
Omar: "I first discovered the IMGUI paradigm at [Q-Games](https://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it." Omar: "I first discovered the IMGUI paradigm at [Q-Games](https://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it."
Embeds [ProggyClean.ttf](https://www.proggyfonts.net) font by Tristan Grimmer (MIT license). Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license).
<br>Embeds [stb_textedit.h, stb_truetype.h, stb_rect_pack.h](https://github.com/nothings/stb/) by Sean Barrett (public domain). <br>Embeds [stb_textedit.h, stb_truetype.h, stb_rect_pack.h](https://github.com/nothings/stb/) by Sean Barrett (public domain).
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Also thank you to everyone posting feedback, questions and patches on GitHub. Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Also thank you to everyone posting feedback, questions and patches on GitHub.

View File

@ -126,7 +126,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- separator: expose flags (#759) - separator: expose flags (#759)
- separator: take indent into consideration (optional) - separator: take indent into consideration (optional)
- separator: width, thickness, centering (#1643, #2657) - separator: width, thickness, centering (#1643)
- splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) - splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
- docking: merge docking branch (#2109) - docking: merge docking branch (#2109)
@ -175,8 +175,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- tooltip: drag tooltip hovering over source widget with IsItemHovered/SetTooltip flickers (WIP branch) - tooltip: drag tooltip hovering over source widget with IsItemHovered/SetTooltip flickers (WIP branch)
- status-bar: add a per-window status bar helper similar to what menu-bar does. generalize concept of layer0 rect in window (can make _MenuBar window flag obsolete too). - status-bar: add a per-window status bar helper similar to what menu-bar does. generalize concept of layer0 rect in window (can make _MenuBar window flag obsolete too).
- shortcuts: store multiple keychords in ImGuiKeyChord
- shortcuts: Hovered route (lower than Focused, higher than Global)
- shortcuts: local-style shortcut api, e.g. parse "&Save" - shortcuts: local-style shortcut api, e.g. parse "&Save"
- shortcuts,menus: global-style shortcut api e.g. "Save (CTRL+S)" -> explicit flag for recursing into closed menu - shortcuts,menus: global-style shortcut api e.g. "Save (CTRL+S)" -> explicit flag for recursing into closed menu
- shortcuts: programmatically access shortcuts "Focus("&Save")) - shortcuts: programmatically access shortcuts "Focus("&Save"))
@ -189,6 +187,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer) - tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer)
- tree node: tweak color scheme to distinguish headers from selected tree node (#581) - tree node: tweak color scheme to distinguish headers from selected tree node (#581)
- tree node: leaf/non-leaf highlight mismatch. - tree node: leaf/non-leaf highlight mismatch.
- tree node: flag to disable formatting and/or detect "%s"
- tree node/opt: could avoid formatting when clipped (flag assuming we don't care about width/height, assume single line height? format only %s/%c to be able to count height?) - tree node/opt: could avoid formatting when clipped (flag assuming we don't care about width/height, assume single line height? format only %s/%c to be able to count height?)
- settings: write more decent code to allow saving/loading new fields: columns, selected tree nodes? - settings: write more decent code to allow saving/loading new fields: columns, selected tree nodes?

View File

@ -1,10 +1,6 @@
// Dear ImGui: standalone example application for Allegro 5 // Dear ImGui: standalone example application for Allegro 5
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// On Windows, you can install Allegro5 using vcpkg: // On Windows, you can install Allegro5 using vcpkg:
// git clone https://github.com/Microsoft/vcpkg // git clone https://github.com/Microsoft/vcpkg

View File

@ -1,10 +1,5 @@
// dear imgui: standalone example application for Android + OpenGL ES 3 // dear imgui: standalone example application for Android + OpenGL ES 3
// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp.
// 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
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_android.h" #include "imgui_impl_android.h"
@ -161,7 +156,7 @@ void Init(struct android_app* app)
// We load the default font with increased size to improve readability on many devices with "high" DPI. // We load the default font with increased size to improve readability on many devices with "high" DPI.
// FIXME: Put some effort into DPI awareness. // FIXME: Put some effort into DPI awareness.
// Important: when calling AddFontFromMemoryTTF(), ownership of font_data is transferred by Dear ImGui by default (deleted is handled by Dear ImGui), unless we set FontDataOwnedByAtlas=false in ImFontConfig // Important: when calling AddFontFromMemoryTTF(), ownership of font_data is transfered by Dear ImGui by default (deleted is handled by Dear ImGui), unless we set FontDataOwnedByAtlas=false in ImFontConfig
ImFontConfig font_cfg; ImFontConfig font_cfg;
font_cfg.SizePixels = 22.0f; font_cfg.SizePixels = 22.0f;
io.Fonts->AddFontDefault(&font_cfg); io.Fonts->AddFontDefault(&font_cfg);

View File

@ -1,10 +1,6 @@
// Dear ImGui: standalone example application for OSX + Metal. // Dear ImGui: standalone example application for OSX + Metal.
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>

View File

@ -1,10 +1,6 @@
// Dear ImGui: standalone example application for OSX + OpenGL2, using legacy fixed pipeline // Dear ImGui: standalone example application for OSX + OpenGL2, using legacy fixed pipeline
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <OpenGL/gl.h> #import <OpenGL/gl.h>

View File

@ -6,7 +6,7 @@
- You may also refer to our [Continuous Integration setup](https://github.com/ocornut/imgui/tree/master/.github/workflows) for Emscripten setup. - You may also refer to our [Continuous Integration setup](https://github.com/ocornut/imgui/tree/master/.github/workflows) for Emscripten setup.
- Then build using `make -f Makefile.emscripten` while in the `example_glfw_wgpu/` directory. - Then build using `make` while in the `example_emscripten_wgpu/` directory.
- Requires recent Emscripten as WGPU is still a work-in-progress API. - Requires recent Emscripten as WGPU is still a work-in-progress API.
@ -18,7 +18,7 @@ To run on a local machine:
- Otherwise, generally you will need a local webserver: - Otherwise, generally you will need a local webserver:
- Quoting [https://emscripten.org/docs/getting_started](https://emscripten.org/docs/getting_started/Tutorial.html#generating-html):<br> - Quoting [https://emscripten.org/docs/getting_started](https://emscripten.org/docs/getting_started/Tutorial.html#generating-html):<br>
_"Unfortunately several browsers (including Chrome, Safari, and Internet Explorer) do not support file:// [XHR](https://emscripten.org/docs/site/glossary.html#term-xhr) requests, and cant load extra files needed by the HTML (like a .wasm file, or packaged file data as mentioned lower down). For these browsers youll need to serve the files using a [local webserver](https://emscripten.org/docs/getting_started/FAQ.html#faq-local-webserver) and then open http://localhost:8000/hello.html."_ _"Unfortunately several browsers (including Chrome, Safari, and Internet Explorer) do not support file:// [XHR](https://emscripten.org/docs/site/glossary.html#term-xhr) requests, and cant load extra files needed by the HTML (like a .wasm file, or packaged file data as mentioned lower down). For these browsers youll need to serve the files using a [local webserver](https://emscripten.org/docs/getting_started/FAQ.html#faq-local-webserver) and then open http://localhost:8000/hello.html."_
- Emscripten SDK has a handy `emrun` command: `emrun web/example_glfw_wgpu.html --browser firefox` which will spawn a temporary local webserver (in Firefox). See https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html for details. - Emscripten SDK has a handy `emrun` command: `emrun web/example_emscripten_opengl3.html --browser firefox` which will spawn a temporary local webserver (in Firefox). See https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html for details.
- You may use Python 3 builtin webserver: `python -m http.server -d web` (this is what `make serve` uses). - You may use Python 3 builtin webserver: `python -m http.server -d web` (this is what `make serve` uses).
- You may use Python 2 builtin webserver: `cd web && python -m SimpleHTTPServer`. - You may use Python 2 builtin webserver: `cd web && python -m SimpleHTTPServer`.
- If you are accessing the files over a network, certain browsers, such as Firefox, will restrict Gamepad API access to secure contexts only (e.g. https only). - If you are accessing the files over a network, certain browsers, such as Firefox, will restrict Gamepad API access to secure contexts only (e.g. https only).

View File

@ -0,0 +1,246 @@
// Dear ImGui: standalone example application for Emscripten, using GLFW + WebGPU
// (Emscripten is a C++-to-javascript compiler, used to publish executables for the web. See https://emscripten.org/)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_wgpu.h"
#include <stdio.h>
#include <emscripten.h>
#include <emscripten/html5.h>
#include <emscripten/html5_webgpu.h>
#include <GLFW/glfw3.h>
#include <webgpu/webgpu.h>
#include <webgpu/webgpu_cpp.h>
// Global WebGPU required states
static WGPUDevice wgpu_device = nullptr;
static WGPUSurface wgpu_surface = nullptr;
static WGPUSwapChain wgpu_swap_chain = nullptr;
static int wgpu_swap_chain_width = 0;
static int wgpu_swap_chain_height = 0;
// Forward declarations
static void MainLoopStep(void* window);
static bool InitWGPU();
static void print_glfw_error(int error, const char* description);
static void print_wgpu_error(WGPUErrorType error_type, const char* message, void*);
// Main code
int main(int, char**)
{
glfwSetErrorCallback(print_glfw_error);
if (!glfwInit())
return 1;
// Make sure GLFW does not initialize any graphics context.
// This needs to be done explicitly later.
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr);
if (!window)
{
glfwTerminate();
return 1;
}
// Initialize the WebGPU environment
if (!InitWGPU())
{
if (window)
glfwDestroyWindow(window);
glfwTerminate();
return 1;
}
glfwShowWindow(window);
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
io.IniFilename = nullptr;
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsLight();
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOther(window, true);
ImGui_ImplWGPU_Init(wgpu_device, 3, WGPUTextureFormat_RGBA8Unorm, WGPUTextureFormat_Undefined);
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
// - Read 'docs/FONTS.md' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
// - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details.
//io.Fonts->AddFontDefault();
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
//io.Fonts->AddFontFromFileTTF("fonts/segoeui.ttf", 18.0f);
io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf", 15.0f);
//io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf", 10.0f);
//ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != nullptr);
#endif
// This function will directly return and exit the main function.
// Make sure that no required objects get cleaned up.
// This way we can use the browsers 'requestAnimationFrame' to control the rendering.
emscripten_set_main_loop_arg(MainLoopStep, window, 0, false);
return 0;
}
static bool InitWGPU()
{
wgpu_device = emscripten_webgpu_get_device();
if (!wgpu_device)
return false;
wgpuDeviceSetUncapturedErrorCallback(wgpu_device, print_wgpu_error, nullptr);
// Use C++ wrapper due to misbehavior in Emscripten.
// Some offset computation for wgpuInstanceCreateSurface in JavaScript
// seem to be inline with struct alignments in the C++ structure
wgpu::SurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
html_surface_desc.selector = "#canvas";
wgpu::SurfaceDescriptor surface_desc = {};
surface_desc.nextInChain = &html_surface_desc;
// Use 'null' instance
wgpu::Instance instance = {};
wgpu_surface = instance.CreateSurface(&surface_desc).Release();
return true;
}
static void MainLoopStep(void* window)
{
ImGuiIO& io = ImGui::GetIO();
glfwPollEvents();
int width, height;
glfwGetFramebufferSize((GLFWwindow*)window, &width, &height);
// React to changes in screen size
if (width != wgpu_swap_chain_width && height != wgpu_swap_chain_height)
{
ImGui_ImplWGPU_InvalidateDeviceObjects();
if (wgpu_swap_chain)
wgpuSwapChainRelease(wgpu_swap_chain);
wgpu_swap_chain_width = width;
wgpu_swap_chain_height = height;
WGPUSwapChainDescriptor swap_chain_desc = {};
swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment;
swap_chain_desc.format = WGPUTextureFormat_RGBA8Unorm;
swap_chain_desc.width = width;
swap_chain_desc.height = height;
swap_chain_desc.presentMode = WGPUPresentMode_Fifo;
wgpu_swap_chain = wgpuDeviceCreateSwapChain(wgpu_device, wgpu_surface, &swap_chain_desc);
ImGui_ImplWGPU_CreateDeviceObjects();
}
// Start the Dear ImGui frame
ImGui_ImplWGPU_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// Our state
// (we use static, which essentially makes the variable globals, as a convenience to keep the example code easy to follow)
static bool show_demo_window = true;
static bool show_another_window = false;
static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
{
static float f = 0.0f;
static int counter = 0;
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
ImGui::Checkbox("Another Window", &show_another_window);
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
counter++;
ImGui::SameLine();
ImGui::Text("counter = %d", counter);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
ImGui::End();
}
// 3. Show another simple window.
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
show_another_window = false;
ImGui::End();
}
// Rendering
ImGui::Render();
WGPURenderPassColorAttachment color_attachments = {};
color_attachments.loadOp = WGPULoadOp_Clear;
color_attachments.storeOp = WGPUStoreOp_Store;
color_attachments.clearValue = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
color_attachments.view = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain);
WGPURenderPassDescriptor render_pass_desc = {};
render_pass_desc.colorAttachmentCount = 1;
render_pass_desc.colorAttachments = &color_attachments;
render_pass_desc.depthStencilAttachment = nullptr;
WGPUCommandEncoderDescriptor enc_desc = {};
WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(wgpu_device, &enc_desc);
WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &render_pass_desc);
ImGui_ImplWGPU_RenderDrawData(ImGui::GetDrawData(), pass);
wgpuRenderPassEncoderEnd(pass);
WGPUCommandBufferDescriptor cmd_buffer_desc = {};
WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc);
WGPUQueue queue = wgpuDeviceGetQueue(wgpu_device);
wgpuQueueSubmit(queue, 1, &cmd_buffer);
}
static void print_glfw_error(int error, const char* description)
{
printf("GLFW Error %d: %s\n", error, description);
}
static void print_wgpu_error(WGPUErrorType error_type, const char* message, void*)
{
const char* error_type_lbl = "";
switch (error_type)
{
case WGPUErrorType_Validation: error_type_lbl = "Validation"; break;
case WGPUErrorType_OutOfMemory: error_type_lbl = "Out of memory"; break;
case WGPUErrorType_Unknown: error_type_lbl = "Unknown"; break;
case WGPUErrorType_DeviceLost: error_type_lbl = "Device lost"; break;
default: error_type_lbl = "Unknown";
}
printf("%s error: %s\n", error_type_lbl, message);
}

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
<title>Dear ImGui Emscripten+GLFW+WebGPU example</title> <title>Dear ImGui Emscripten+WebGPU example</title>
<style> <style>
body { margin: 0; background-color: black } body { margin: 0; background-color: black }
.emscripten { .emscripten {
@ -63,10 +63,6 @@
// Initialize the graphics adapter // Initialize the graphics adapter
{ {
if (!navigator.gpu) {
throw Error("WebGPU not supported.");
}
const adapter = await navigator.gpu.requestAdapter(); const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice(); const device = await adapter.requestDevice();
Module.preinitializedWebGPUDevice = device; Module.preinitializedWebGPUDevice = device;

View File

@ -14,10 +14,10 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore
LIBS += -L/usr/local/lib -L/opt/homebrew/lib -L/opt/local/lib LIBS += -L/usr/local/lib -L/opt/homebrew/lib
LIBS += -lglfw LIBS += -lglfw
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include -I/opt/local/include CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include
CXXFLAGS += -Wall -Wformat CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)

View File

@ -1,11 +1,7 @@
// Dear ImGui: standalone example application for GLFW + Metal, using programmable pipeline // Dear ImGui: standalone example application for GLFW + Metal, using programmable pipeline
// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_glfw.h" #include "imgui_impl_glfw.h"

View File

@ -1,11 +1,7 @@
// Dear ImGui: standalone example application for GLFW + OpenGL2, using legacy fixed pipeline // Dear ImGui: standalone example application for GLFW + OpenGL2, using legacy fixed pipeline
// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** // **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
// **Prefer using the code in the example_glfw_opengl2/ folder** // **Prefer using the code in the example_glfw_opengl2/ folder**

View File

@ -59,7 +59,7 @@ endif
CPPFLAGS += -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CPPFLAGS += -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
#CPPFLAGS += -g #CPPFLAGS += -g
CPPFLAGS += -Wall -Wformat -Os $(EMS) CPPFLAGS += -Wall -Wformat -Os $(EMS)
LDFLAGS += --shell-file ../libs/emscripten/shell_minimal.html # LDFLAGS += --shell-file ../libs/emscripten/shell_minimal.html
LDFLAGS += $(EMS) LDFLAGS += $(EMS)
##--------------------------------------------------------------------- ##---------------------------------------------------------------------

View File

@ -1,11 +1,7 @@
// Dear ImGui: standalone example application for GLFW + OpenGL 3, using programmable pipeline // Dear ImGui: standalone example application for GLFW + OpenGL 3, using programmable pipeline
// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_glfw.h" #include "imgui_impl_glfw.h"
@ -84,9 +80,6 @@ int main(int, char**)
// Setup Platform/Renderer backends // Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplGlfw_InitForOpenGL(window, true);
#ifdef __EMSCRIPTEN__
ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback("#canvas");
#endif
ImGui_ImplOpenGL3_Init(glsl_version); ImGui_ImplOpenGL3_Init(glsl_version);
// Load Fonts // Load Fonts

View File

@ -1,10 +1,6 @@
// Dear ImGui: standalone example application for Glfw + Vulkan // Dear ImGui: standalone example application for Glfw + Vulkan
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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_vulkan.cpp/.h in their own engine/app. // Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. // - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
@ -21,12 +17,8 @@
#define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_VULKAN #define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <vulkan/vulkan.h>
// Volk headers //#include <vulkan/vulkan_beta.h>
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
#define VOLK_IMPLEMENTATION
#include <Volk/volk.h>
#endif
// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. // [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers.
// To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma. // To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma.
@ -35,9 +27,9 @@
#pragma comment(lib, "legacy_stdio_definitions") #pragma comment(lib, "legacy_stdio_definitions")
#endif #endif
//#define APP_USE_UNLIMITED_FRAME_RATE //#define IMGUI_UNLIMITED_FRAME_RATE
#ifdef _DEBUG #ifdef _DEBUG
#define APP_USE_VULKAN_DEBUG_REPORT #define IMGUI_VULKAN_DEBUG_REPORT
#endif #endif
// Data // Data
@ -68,14 +60,14 @@ static void check_vk_result(VkResult err)
abort(); abort();
} }
#ifdef APP_USE_VULKAN_DEBUG_REPORT #ifdef IMGUI_VULKAN_DEBUG_REPORT
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
{ {
(void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments
fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
return VK_FALSE; return VK_FALSE;
} }
#endif // APP_USE_VULKAN_DEBUG_REPORT #endif // IMGUI_VULKAN_DEBUG_REPORT
static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properties, const char* extension) static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properties, const char* extension)
{ {
@ -117,9 +109,6 @@ static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice()
static void SetupVulkan(ImVector<const char*> instance_extensions) static void SetupVulkan(ImVector<const char*> instance_extensions)
{ {
VkResult err; VkResult err;
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
volkInitialize();
#endif
// Create Vulkan Instance // Create Vulkan Instance
{ {
@ -146,7 +135,7 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
#endif #endif
// Enabling validation layers // Enabling validation layers
#ifdef APP_USE_VULKAN_DEBUG_REPORT #ifdef IMGUI_VULKAN_DEBUG_REPORT
const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; const char* layers[] = { "VK_LAYER_KHRONOS_validation" };
create_info.enabledLayerCount = 1; create_info.enabledLayerCount = 1;
create_info.ppEnabledLayerNames = layers; create_info.ppEnabledLayerNames = layers;
@ -158,20 +147,17 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
create_info.ppEnabledExtensionNames = instance_extensions.Data; create_info.ppEnabledExtensionNames = instance_extensions.Data;
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err); check_vk_result(err);
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
volkLoadInstance(g_Instance);
#endif
// Setup the debug report callback // Setup the debug report callback
#ifdef APP_USE_VULKAN_DEBUG_REPORT #ifdef IMGUI_VULKAN_DEBUG_REPORT
auto f_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
IM_ASSERT(f_vkCreateDebugReportCallbackEXT != nullptr); IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
debug_report_ci.pfnCallback = debug_report; debug_report_ci.pfnCallback = debug_report;
debug_report_ci.pUserData = nullptr; debug_report_ci.pUserData = nullptr;
err = f_vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
check_vk_result(err); check_vk_result(err);
#endif #endif
} }
@ -229,17 +215,25 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
} }
// Create Descriptor Pool // Create Descriptor Pool
// The example only requires a single combined image sampler descriptor for the font image and only uses one descriptor set (for that)
// If you wish to load e.g. additional textures you may need to alter pools sizes.
{ {
VkDescriptorPoolSize pool_sizes[] = VkDescriptorPoolSize pool_sizes[] =
{ {
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 }, { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
}; };
VkDescriptorPoolCreateInfo pool_info = {}; VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1; pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes);
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes); pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
pool_info.pPoolSizes = pool_sizes; pool_info.pPoolSizes = pool_sizes;
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool); err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
@ -268,7 +262,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
// Select Present Mode // Select Present Mode
#ifdef APP_USE_UNLIMITED_FRAME_RATE #ifdef IMGUI_UNLIMITED_FRAME_RATE
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR }; VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
#else #else
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR }; VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR };
@ -285,11 +279,11 @@ static void CleanupVulkan()
{ {
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
#ifdef APP_USE_VULKAN_DEBUG_REPORT #ifdef IMGUI_VULKAN_DEBUG_REPORT
// Remove the debug report callback // Remove the debug report callback
auto f_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
f_vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
#endif // APP_USE_VULKAN_DEBUG_REPORT #endif // IMGUI_VULKAN_DEBUG_REPORT
vkDestroyDevice(g_Device, g_Allocator); vkDestroyDevice(g_Device, g_Allocator);
vkDestroyInstance(g_Instance, g_Allocator); vkDestroyInstance(g_Instance, g_Allocator);
@ -386,7 +380,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
return; return;
} }
check_vk_result(err); check_vk_result(err);
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores
} }
// Main code // Main code
@ -444,14 +438,13 @@ int main(int, char**)
init_info.Queue = g_Queue; init_info.Queue = g_Queue;
init_info.PipelineCache = g_PipelineCache; init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool; init_info.DescriptorPool = g_DescriptorPool;
init_info.RenderPass = wd->RenderPass;
init_info.Subpass = 0; init_info.Subpass = 0;
init_info.MinImageCount = g_MinImageCount; init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount; init_info.ImageCount = wd->ImageCount;
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.Allocator = g_Allocator; init_info.Allocator = g_Allocator;
init_info.CheckVkResultFn = check_vk_result; init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info); ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
// Load Fonts // Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
@ -469,6 +462,36 @@ int main(int, char**)
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese()); //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != nullptr); //IM_ASSERT(font != nullptr);
// Upload Fonts
{
// Use any command queue
VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool;
VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer;
err = vkResetCommandPool(g_Device, command_pool, 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(command_buffer, &begin_info);
check_vk_result(err);
ImGui_ImplVulkan_CreateFontsTexture(command_buffer);
VkSubmitInfo end_info = {};
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
end_info.commandBufferCount = 1;
end_info.pCommandBuffers = &command_buffer;
err = vkEndCommandBuffer(command_buffer);
check_vk_result(err);
err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE);
check_vk_result(err);
err = vkDeviceWaitIdle(g_Device);
check_vk_result(err);
ImGui_ImplVulkan_DestroyFontUploadObjects();
}
// Our state // Our state
bool show_demo_window = true; bool show_demo_window = true;
bool show_another_window = false; bool show_another_window = false;

View File

@ -1,100 +0,0 @@
# Building for desktop (WebGPU-native) with Dawn:
# 1. git clone https://github.com/google/dawn dawn
# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn
# 3. cmake --build build
# The resulting binary will be found at one of the following locations:
# * build/Debug/example_glfw_wgpu[.exe]
# * build/example_glfw_wgpu[.exe]
# Building for Emscripten:
# 1. Install Emscripten SDK following the instructions: https://emscripten.org/docs/getting_started/downloads.html
# 2. Install Ninja build system
# 3. emcmake cmake -G Ninja -B build
# 3. cmake --build build
# 4. emrun build/index.html
cmake_minimum_required(VERSION 3.10.2)
project(imgui_example_glfw_wgpu C CXX)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
endif()
set(CMAKE_CXX_STANDARD 17) # Dawn requires C++17
# Dear ImGui
set(IMGUI_DIR ../../)
# Libraries
if(EMSCRIPTEN)
set(LIBRARIES glfw)
add_compile_options(-sDISABLE_EXCEPTION_CATCHING=1 -DIMGUI_DISABLE_FILE_FUNCTIONS=1)
else()
# Dawn wgpu desktop
set(DAWN_FETCH_DEPENDENCIES ON)
set(IMGUI_DAWN_DIR CACHE PATH "Path to Dawn repository")
if (NOT IMGUI_DAWN_DIR)
message(FATAL_ERROR "Please specify the Dawn repository by setting IMGUI_DAWN_DIR")
endif()
option(DAWN_FETCH_DEPENDENCIES "Use fetch_dawn_dependencies.py as an alternative to using depot_tools" ON)
# Dawn builds many things by default - disable things we don't need
option(DAWN_BUILD_SAMPLES "Enables building Dawn's samples" OFF)
option(TINT_BUILD_CMD_TOOLS "Build the Tint command line tools" OFF)
option(TINT_BUILD_DOCS "Build documentation" OFF)
option(TINT_BUILD_TESTS "Build tests" OFF)
if (NOT APPLE)
option(TINT_BUILD_MSL_WRITER "Build the MSL output writer" OFF)
endif()
if(WIN32)
option(TINT_BUILD_SPV_READER "Build the SPIR-V input reader" OFF)
option(TINT_BUILD_WGSL_READER "Build the WGSL input reader" ON)
option(TINT_BUILD_GLSL_WRITER "Build the GLSL output writer" OFF)
option(TINT_BUILD_GLSL_VALIDATOR "Build the GLSL output validator" OFF)
option(TINT_BUILD_SPV_WRITER "Build the SPIR-V output writer" OFF)
option(TINT_BUILD_WGSL_WRITER "Build the WGSL output writer" ON)
endif()
add_subdirectory("${IMGUI_DAWN_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/dawn" EXCLUDE_FROM_ALL)
set(LIBRARIES webgpu_dawn webgpu_cpp webgpu_glfw glfw)
endif()
add_executable(example_glfw_wgpu
main.cpp
# backend files
${IMGUI_DIR}/backends/imgui_impl_glfw.cpp
${IMGUI_DIR}/backends/imgui_impl_wgpu.cpp
# Dear ImGui files
${IMGUI_DIR}/imgui.cpp
${IMGUI_DIR}/imgui_draw.cpp
${IMGUI_DIR}/imgui_demo.cpp
${IMGUI_DIR}/imgui_tables.cpp
${IMGUI_DIR}/imgui_widgets.cpp
)
target_include_directories(example_glfw_wgpu PUBLIC
${IMGUI_DIR}
${IMGUI_DIR}/backends
)
target_link_libraries(example_glfw_wgpu PUBLIC ${LIBRARIES})
# Emscripten settings
if(EMSCRIPTEN)
target_link_options(example_glfw_wgpu PRIVATE
"-sUSE_WEBGPU=1"
"-sUSE_GLFW=3"
"-sWASM=1"
"-sALLOW_MEMORY_GROWTH=1"
"-sNO_EXIT_RUNTIME=0"
"-sASSERTIONS=1"
"-sDISABLE_EXCEPTION_CATCHING=1"
"-sNO_FILESYSTEM=1"
)
set_target_properties(example_glfw_wgpu PROPERTIES OUTPUT_NAME "index")
# copy our custom index.html to build directory
add_custom_command(TARGET example_glfw_wgpu POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_LIST_DIR}/web/index.html" $<TARGET_FILE_DIR:example_glfw_wgpu>
)
endif()

View File

@ -1,345 +0,0 @@
// Dear ImGui: standalone example application for using GLFW + WebGPU
// - Emscripten is supported for publishing on web. See https://emscripten.org.
// - Dawn is used as a WebGPU implementation on desktop.
// 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
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_wgpu.h"
#include <stdio.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#include <emscripten/html5.h>
#include <emscripten/html5_webgpu.h>
#else
#include <webgpu/webgpu_glfw.h>
#endif
#include <GLFW/glfw3.h>
#include <webgpu/webgpu.h>
#include <webgpu/webgpu_cpp.h>
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
#ifdef __EMSCRIPTEN__
#include "../libs/emscripten/emscripten_mainloop_stub.h"
#endif
// Global WebGPU required states
static WGPUInstance wgpu_instance = nullptr;
static WGPUDevice wgpu_device = nullptr;
static WGPUSurface wgpu_surface = nullptr;
static WGPUTextureFormat wgpu_preferred_fmt = WGPUTextureFormat_RGBA8Unorm;
static WGPUSwapChain wgpu_swap_chain = nullptr;
static int wgpu_swap_chain_width = 1280;
static int wgpu_swap_chain_height = 720;
// Forward declarations
static bool InitWGPU(GLFWwindow* window);
static void CreateSwapChain(int width, int height);
static void glfw_error_callback(int error, const char* description)
{
printf("GLFW Error %d: %s\n", error, description);
}
static void wgpu_error_callback(WGPUErrorType error_type, const char* message, void*)
{
const char* error_type_lbl = "";
switch (error_type)
{
case WGPUErrorType_Validation: error_type_lbl = "Validation"; break;
case WGPUErrorType_OutOfMemory: error_type_lbl = "Out of memory"; break;
case WGPUErrorType_Unknown: error_type_lbl = "Unknown"; break;
case WGPUErrorType_DeviceLost: error_type_lbl = "Device lost"; break;
default: error_type_lbl = "Unknown";
}
printf("%s error: %s\n", error_type_lbl, message);
}
// Main code
int main(int, char**)
{
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
return 1;
// Make sure GLFW does not initialize any graphics context.
// This needs to be done explicitly later.
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(wgpu_swap_chain_width, wgpu_swap_chain_height, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr);
if (window == nullptr)
return 1;
// Initialize the WebGPU environment
if (!InitWGPU(window))
{
if (window)
glfwDestroyWindow(window);
glfwTerminate();
return 1;
}
CreateSwapChain(wgpu_swap_chain_width, wgpu_swap_chain_height);
glfwShowWindow(window);
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsLight();
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOther(window, true);
#ifdef __EMSCRIPTEN__
ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback("#canvas");
#endif
ImGui_ImplWGPU_InitInfo init_info;
init_info.Device = wgpu_device;
init_info.NumFramesInFlight = 3;
init_info.RenderTargetFormat = wgpu_preferred_fmt;
init_info.DepthStencilFormat = WGPUTextureFormat_Undefined;
ImGui_ImplWGPU_Init(&init_info);
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
// - Read 'docs/FONTS.md' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
// - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details.
//io.Fonts->AddFontDefault();
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
//io.Fonts->AddFontFromFileTTF("fonts/segoeui.ttf", 18.0f);
//io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf", 15.0f);
//io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf", 10.0f);
//ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != nullptr);
#endif
// Our state
bool show_demo_window = true;
bool show_another_window = false;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop
#ifdef __EMSCRIPTEN__
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
io.IniFilename = nullptr;
EMSCRIPTEN_MAINLOOP_BEGIN
#else
while (!glfwWindowShouldClose(window))
#endif
{
// Poll and handle events (inputs, window resize, etc.)
// 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.
glfwPollEvents();
// React to changes in screen size
int width, height;
glfwGetFramebufferSize((GLFWwindow*)window, &width, &height);
if (width != wgpu_swap_chain_width || height != wgpu_swap_chain_height)
{
ImGui_ImplWGPU_InvalidateDeviceObjects();
CreateSwapChain(width, height);
ImGui_ImplWGPU_CreateDeviceObjects();
}
// Start the Dear ImGui frame
ImGui_ImplWGPU_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
{
static float f = 0.0f;
static int counter = 0;
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
ImGui::Checkbox("Another Window", &show_another_window);
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
counter++;
ImGui::SameLine();
ImGui::Text("counter = %d", counter);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
ImGui::End();
}
// 3. Show another simple window.
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
show_another_window = false;
ImGui::End();
}
// Rendering
ImGui::Render();
#ifndef __EMSCRIPTEN__
// Tick needs to be called in Dawn to display validation errors
wgpuDeviceTick(wgpu_device);
#endif
WGPURenderPassColorAttachment color_attachments = {};
color_attachments.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
color_attachments.loadOp = WGPULoadOp_Clear;
color_attachments.storeOp = WGPUStoreOp_Store;
color_attachments.clearValue = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
color_attachments.view = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain);
WGPURenderPassDescriptor render_pass_desc = {};
render_pass_desc.colorAttachmentCount = 1;
render_pass_desc.colorAttachments = &color_attachments;
render_pass_desc.depthStencilAttachment = nullptr;
WGPUCommandEncoderDescriptor enc_desc = {};
WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(wgpu_device, &enc_desc);
WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &render_pass_desc);
ImGui_ImplWGPU_RenderDrawData(ImGui::GetDrawData(), pass);
wgpuRenderPassEncoderEnd(pass);
WGPUCommandBufferDescriptor cmd_buffer_desc = {};
WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc);
WGPUQueue queue = wgpuDeviceGetQueue(wgpu_device);
wgpuQueueSubmit(queue, 1, &cmd_buffer);
#ifndef __EMSCRIPTEN__
wgpuSwapChainPresent(wgpu_swap_chain);
#endif
wgpuTextureViewRelease(color_attachments.view);
wgpuRenderPassEncoderRelease(pass);
wgpuCommandEncoderRelease(encoder);
wgpuCommandBufferRelease(cmd_buffer);
}
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_MAINLOOP_END;
#endif
// Cleanup
ImGui_ImplWGPU_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
#ifndef __EMSCRIPTEN__
static WGPUAdapter RequestAdapter(WGPUInstance instance)
{
auto onAdapterRequestEnded = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, const char* message, void* pUserData)
{
if (status == WGPURequestAdapterStatus_Success)
*(WGPUAdapter*)(pUserData) = adapter;
else
printf("Could not get WebGPU adapter: %s\n", message);
};
WGPUAdapter adapter;
wgpuInstanceRequestAdapter(instance, nullptr, onAdapterRequestEnded, (void*)&adapter);
return adapter;
}
static WGPUDevice RequestDevice(WGPUAdapter& adapter)
{
auto onDeviceRequestEnded = [](WGPURequestDeviceStatus status, WGPUDevice device, const char* message, void* pUserData)
{
if (status == WGPURequestDeviceStatus_Success)
*(WGPUDevice*)(pUserData) = device;
else
printf("Could not get WebGPU device: %s\n", message);
};
WGPUDevice device;
wgpuAdapterRequestDevice(adapter, nullptr, onDeviceRequestEnded, (void*)&device);
return device;
}
#endif
static bool InitWGPU(GLFWwindow* window)
{
wgpu::Instance instance = wgpuCreateInstance(nullptr);
#ifdef __EMSCRIPTEN__
wgpu_device = emscripten_webgpu_get_device();
if (!wgpu_device)
return false;
#else
WGPUAdapter adapter = RequestAdapter(instance.Get());
if (!adapter)
return false;
wgpu_device = RequestDevice(adapter);
#endif
#ifdef __EMSCRIPTEN__
wgpu::SurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
html_surface_desc.selector = "#canvas";
wgpu::SurfaceDescriptor surface_desc = {};
surface_desc.nextInChain = &html_surface_desc;
wgpu::Surface surface = instance.CreateSurface(&surface_desc);
wgpu::Adapter adapter = {};
wgpu_preferred_fmt = (WGPUTextureFormat)surface.GetPreferredFormat(adapter);
#else
wgpu::Surface surface = wgpu::glfw::CreateSurfaceForWindow(instance, window);
if (!surface)
return false;
wgpu_preferred_fmt = WGPUTextureFormat_BGRA8Unorm;
#endif
wgpu_instance = instance.MoveToCHandle();
wgpu_surface = surface.MoveToCHandle();
wgpuDeviceSetUncapturedErrorCallback(wgpu_device, wgpu_error_callback, nullptr);
return true;
}
static void CreateSwapChain(int width, int height)
{
if (wgpu_swap_chain)
wgpuSwapChainRelease(wgpu_swap_chain);
wgpu_swap_chain_width = width;
wgpu_swap_chain_height = height;
WGPUSwapChainDescriptor swap_chain_desc = {};
swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment;
swap_chain_desc.format = wgpu_preferred_fmt;
swap_chain_desc.width = width;
swap_chain_desc.height = height;
swap_chain_desc.presentMode = WGPUPresentMode_Fifo;
wgpu_swap_chain = wgpuDeviceCreateSwapChain(wgpu_device, wgpu_surface, &swap_chain_desc);
}

View File

@ -1,10 +1,6 @@
// Dear ImGui: standalone example application for GLUT/FreeGLUT + OpenGL2, using legacy fixed pipeline // Dear ImGui: standalone example application for GLUT/FreeGLUT + OpenGL2, using legacy fixed pipeline
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!! // !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!! // !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!!

View File

@ -1,11 +1,7 @@
// Dear ImGui: standalone example application for SDL2 + DirectX 11 // Dear ImGui: standalone example application for SDL2 + DirectX 11
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_sdl2.h" #include "imgui_impl_sdl2.h"
@ -47,12 +43,6 @@ int main(int, char**)
// Setup window // Setup window
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
SDL_SysWMinfo wmInfo; SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version); SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo); SDL_GetWindowWMInfo(window, &wmInfo);

View File

@ -1,11 +1,7 @@
// Dear ImGui: standalone example application for SDL2 + Metal // Dear ImGui: standalone example application for SDL2 + Metal
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_sdl2.h" #include "imgui_impl_sdl2.h"

View File

@ -1,11 +1,7 @@
// Dear ImGui: standalone example application for SDL2 + OpenGL // Dear ImGui: standalone example application for SDL2 + OpenGL
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** // **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
// **Prefer using the code in the example_sdl2_opengl3/ folder** // **Prefer using the code in the example_sdl2_opengl3/ folder**
@ -41,12 +37,6 @@ int main(int, char**)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(window); SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context); SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync SDL_GL_SetSwapInterval(1); // Enable vsync

View File

@ -1,11 +1,7 @@
// Dear ImGui: standalone example application for SDL2 + OpenGL // Dear ImGui: standalone example application for SDL2 + OpenGL
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_sdl2.h" #include "imgui_impl_sdl2.h"
@ -68,12 +64,6 @@ int main(int, char**)
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(window); SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context); SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync SDL_GL_SetSwapInterval(1); // Enable vsync

View File

@ -1,11 +1,7 @@
// Dear ImGui: standalone example application for SDL2 + SDL_Renderer // Dear ImGui: standalone example application for SDL2 + SDL_Renderer
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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 to understand: SDL_Renderer is an _optional_ component of SDL2. // Important to understand: SDL_Renderer is an _optional_ component of SDL2.
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX. // For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
@ -38,11 +34,6 @@ int main(int, char**)
// Create window with SDL_Renderer graphics context // Create window with SDL_Renderer graphics context
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
if (renderer == nullptr) if (renderer == nullptr)
{ {
@ -155,7 +146,7 @@ int main(int, char**)
SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255)); SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255));
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), renderer); ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData());
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }

View File

@ -1,10 +1,6 @@
// Dear ImGui: standalone example application for SDL2 + Vulkan // Dear ImGui: standalone example application for SDL2 + Vulkan
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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_vulkan.cpp/.h in their own engine/app. // Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. // - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
@ -20,16 +16,12 @@
#include <stdlib.h> // abort #include <stdlib.h> // abort
#include <SDL.h> #include <SDL.h>
#include <SDL_vulkan.h> #include <SDL_vulkan.h>
#include <vulkan/vulkan.h>
//#include <vulkan/vulkan_beta.h>
// Volk headers //#define IMGUI_UNLIMITED_FRAME_RATE
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
#define VOLK_IMPLEMENTATION
#include <Volk/volk.h>
#endif
//#define APP_USE_UNLIMITED_FRAME_RATE
#ifdef _DEBUG #ifdef _DEBUG
#define APP_USE_VULKAN_DEBUG_REPORT #define IMGUI_VULKAN_DEBUG_REPORT
#endif #endif
// Data // Data
@ -56,14 +48,14 @@ static void check_vk_result(VkResult err)
abort(); abort();
} }
#ifdef APP_USE_VULKAN_DEBUG_REPORT #ifdef IMGUI_VULKAN_DEBUG_REPORT
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
{ {
(void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments
fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
return VK_FALSE; return VK_FALSE;
} }
#endif // APP_USE_VULKAN_DEBUG_REPORT #endif // IMGUI_VULKAN_DEBUG_REPORT
static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properties, const char* extension) static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properties, const char* extension)
{ {
@ -105,9 +97,6 @@ static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice()
static void SetupVulkan(ImVector<const char*> instance_extensions) static void SetupVulkan(ImVector<const char*> instance_extensions)
{ {
VkResult err; VkResult err;
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
volkInitialize();
#endif
// Create Vulkan Instance // Create Vulkan Instance
{ {
@ -134,7 +123,7 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
#endif #endif
// Enabling validation layers // Enabling validation layers
#ifdef APP_USE_VULKAN_DEBUG_REPORT #ifdef IMGUI_VULKAN_DEBUG_REPORT
const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; const char* layers[] = { "VK_LAYER_KHRONOS_validation" };
create_info.enabledLayerCount = 1; create_info.enabledLayerCount = 1;
create_info.ppEnabledLayerNames = layers; create_info.ppEnabledLayerNames = layers;
@ -146,20 +135,17 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
create_info.ppEnabledExtensionNames = instance_extensions.Data; create_info.ppEnabledExtensionNames = instance_extensions.Data;
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err); check_vk_result(err);
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
volkLoadInstance(g_Instance);
#endif
// Setup the debug report callback // Setup the debug report callback
#ifdef APP_USE_VULKAN_DEBUG_REPORT #ifdef IMGUI_VULKAN_DEBUG_REPORT
auto f_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
IM_ASSERT(f_vkCreateDebugReportCallbackEXT != nullptr); IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
debug_report_ci.pfnCallback = debug_report; debug_report_ci.pfnCallback = debug_report;
debug_report_ci.pUserData = nullptr; debug_report_ci.pUserData = nullptr;
err = f_vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
check_vk_result(err); check_vk_result(err);
#endif #endif
} }
@ -217,17 +203,25 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
} }
// Create Descriptor Pool // Create Descriptor Pool
// The example only requires a single combined image sampler descriptor for the font image and only uses one descriptor set (for that)
// If you wish to load e.g. additional textures you may need to alter pools sizes.
{ {
VkDescriptorPoolSize pool_sizes[] = VkDescriptorPoolSize pool_sizes[] =
{ {
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 }, { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
}; };
VkDescriptorPoolCreateInfo pool_info = {}; VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1; pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes);
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes); pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
pool_info.pPoolSizes = pool_sizes; pool_info.pPoolSizes = pool_sizes;
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool); err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
@ -256,7 +250,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
// Select Present Mode // Select Present Mode
#ifdef APP_UNLIMITED_FRAME_RATE #ifdef IMGUI_UNLIMITED_FRAME_RATE
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR }; VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
#else #else
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR }; VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR };
@ -273,11 +267,11 @@ static void CleanupVulkan()
{ {
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
#ifdef APP_USE_VULKAN_DEBUG_REPORT #ifdef IMGUI_VULKAN_DEBUG_REPORT
// Remove the debug report callback // Remove the debug report callback
auto f_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
f_vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
#endif // APP_USE_VULKAN_DEBUG_REPORT #endif // IMGUI_VULKAN_DEBUG_REPORT
vkDestroyDevice(g_Device, g_Allocator); vkDestroyDevice(g_Device, g_Allocator);
vkDestroyInstance(g_Instance, g_Allocator); vkDestroyInstance(g_Instance, g_Allocator);
@ -374,7 +368,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
return; return;
} }
check_vk_result(err); check_vk_result(err);
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores
} }
// Main code // Main code
@ -395,11 +389,6 @@ int main(int, char**)
// Create window with Vulkan graphics context // Create window with Vulkan graphics context
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
ImVector<const char*> extensions; ImVector<const char*> extensions;
uint32_t extensions_count = 0; uint32_t extensions_count = 0;
@ -444,14 +433,13 @@ int main(int, char**)
init_info.Queue = g_Queue; init_info.Queue = g_Queue;
init_info.PipelineCache = g_PipelineCache; init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool; init_info.DescriptorPool = g_DescriptorPool;
init_info.RenderPass = wd->RenderPass;
init_info.Subpass = 0; init_info.Subpass = 0;
init_info.MinImageCount = g_MinImageCount; init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount; init_info.ImageCount = wd->ImageCount;
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.Allocator = g_Allocator; init_info.Allocator = g_Allocator;
init_info.CheckVkResultFn = check_vk_result; init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info); ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
// Load Fonts // Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
@ -469,6 +457,36 @@ int main(int, char**)
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese()); //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != nullptr); //IM_ASSERT(font != nullptr);
// Upload Fonts
{
// Use any command queue
VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool;
VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer;
err = vkResetCommandPool(g_Device, command_pool, 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(command_buffer, &begin_info);
check_vk_result(err);
ImGui_ImplVulkan_CreateFontsTexture(command_buffer);
VkSubmitInfo end_info = {};
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
end_info.commandBufferCount = 1;
end_info.pCommandBuffers = &command_buffer;
err = vkEndCommandBuffer(command_buffer);
check_vk_result(err);
err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE);
check_vk_result(err);
err = vkDeviceWaitIdle(g_Device);
check_vk_result(err);
ImGui_ImplVulkan_DestroyFontUploadObjects();
}
// Our state // Our state
bool show_demo_window = true; bool show_demo_window = true;
bool show_another_window = false; bool show_another_window = false;

View File

@ -1,11 +1,7 @@
// Dear ImGui: standalone example application for SDL3 + OpenGL // Dear ImGui: standalone example application for SDL3 + OpenGL
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_sdl3.h" #include "imgui_impl_sdl3.h"
@ -64,7 +60,7 @@ int main(int, char**)
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN; SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+OpenGL3 example", 1280, 720, window_flags); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+OpenGL3 example", 1280, 720, window_flags);
if (window == nullptr) if (window == nullptr)
{ {

View File

@ -1,11 +1,7 @@
// Dear ImGui: standalone example application for SDL3 + SDL_Renderer // Dear ImGui: standalone example application for SDL3 + SDL_Renderer
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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 to understand: SDL_Renderer is an _optional_ component of SDL3. // Important to understand: 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. // For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
@ -35,20 +31,19 @@ int main(int, char**)
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
// Create window with SDL_Renderer graphics context // Create window with SDL_Renderer graphics context
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN; SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", 1280, 720, window_flags); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", 1280, 720, window_flags);
if (window == nullptr) if (window == nullptr)
{ {
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1; return -1;
} }
SDL_Renderer* renderer = SDL_CreateRenderer(window, nullptr); SDL_Renderer* renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
SDL_SetRenderVSync(renderer, 1);
if (renderer == nullptr) if (renderer == nullptr)
{ {
SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError()); SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError());
return -1; return -1;
} }
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
SDL_ShowWindow(window); SDL_ShowWindow(window);
@ -162,7 +157,7 @@ int main(int, char**)
//SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); //SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255)); SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255));
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), renderer); ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData());
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }

View File

@ -1,10 +1,6 @@
// Dear ImGui: standalone example application for DirectX 10 // Dear ImGui: standalone example application for DirectX 10
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_win32.h" #include "imgui_impl_win32.h"
@ -16,7 +12,6 @@
// Data // Data
static ID3D10Device* g_pd3dDevice = nullptr; static ID3D10Device* g_pd3dDevice = nullptr;
static IDXGISwapChain* g_pSwapChain = nullptr; static IDXGISwapChain* g_pSwapChain = nullptr;
static bool g_SwapChainOccluded = false;
static UINT g_ResizeWidth = 0, g_ResizeHeight = 0; static UINT g_ResizeWidth = 0, g_ResizeHeight = 0;
static ID3D10RenderTargetView* g_mainRenderTargetView = nullptr; static ID3D10RenderTargetView* g_mainRenderTargetView = nullptr;
@ -101,14 +96,6 @@ int main(int, char**)
if (done) if (done)
break; break;
// Handle window being minimized or screen locked
if (g_SwapChainOccluded && g_pSwapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED)
{
::Sleep(10);
continue;
}
g_SwapChainOccluded = false;
// Handle window resize (we don't resize directly in the WM_SIZE handler) // Handle window resize (we don't resize directly in the WM_SIZE handler)
if (g_ResizeWidth != 0 && g_ResizeHeight != 0) if (g_ResizeWidth != 0 && g_ResizeHeight != 0)
{ {
@ -167,13 +154,10 @@ int main(int, char**)
g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
ImGui_ImplDX10_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplDX10_RenderDrawData(ImGui::GetDrawData());
// Present g_pSwapChain->Present(1, 0); // Present with vsync
HRESULT hr = g_pSwapChain->Present(1, 0); // Present with vsync //g_pSwapChain->Present(0, 0); // Present without vsync
//HRESULT hr = g_pSwapChain->Present(0, 0); // Present without vsync
g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);
} }
// Cleanup
ImGui_ImplDX10_Shutdown(); ImGui_ImplDX10_Shutdown();
ImGui_ImplWin32_Shutdown(); ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();

View File

@ -1,10 +1,6 @@
// Dear ImGui: standalone example application for DirectX 11 // Dear ImGui: standalone example application for DirectX 11
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_win32.h" #include "imgui_impl_win32.h"
@ -16,7 +12,6 @@
static ID3D11Device* g_pd3dDevice = nullptr; static ID3D11Device* g_pd3dDevice = nullptr;
static ID3D11DeviceContext* g_pd3dDeviceContext = nullptr; static ID3D11DeviceContext* g_pd3dDeviceContext = nullptr;
static IDXGISwapChain* g_pSwapChain = nullptr; static IDXGISwapChain* g_pSwapChain = nullptr;
static bool g_SwapChainOccluded = false;
static UINT g_ResizeWidth = 0, g_ResizeHeight = 0; static UINT g_ResizeWidth = 0, g_ResizeHeight = 0;
static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr; static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr;
@ -101,14 +96,6 @@ int main(int, char**)
if (done) if (done)
break; break;
// Handle window being minimized or screen locked
if (g_SwapChainOccluded && g_pSwapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED)
{
::Sleep(10);
continue;
}
g_SwapChainOccluded = false;
// Handle window resize (we don't resize directly in the WM_SIZE handler) // Handle window resize (we don't resize directly in the WM_SIZE handler)
if (g_ResizeWidth != 0 && g_ResizeHeight != 0) if (g_ResizeWidth != 0 && g_ResizeHeight != 0)
{ {
@ -167,10 +154,8 @@ int main(int, char**)
g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
// Present g_pSwapChain->Present(1, 0); // Present with vsync
HRESULT hr = g_pSwapChain->Present(1, 0); // Present with vsync //g_pSwapChain->Present(0, 0); // Present without vsync
//HRESULT hr = g_pSwapChain->Present(0, 0); // Present without vsync
g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);
} }
// Cleanup // Cleanup

View File

@ -1,10 +1,6 @@
// Dear ImGui: standalone example application for DirectX 12 // Dear ImGui: standalone example application for DirectX 12
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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: to compile on 32-bit systems, the DirectX12 backend requires code to be compiled with '#define ImTextureID ImU64'. // Important: to compile on 32-bit systems, the DirectX12 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*. // This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
@ -26,8 +22,6 @@
#pragma comment(lib, "dxguid.lib") #pragma comment(lib, "dxguid.lib")
#endif #endif
#include "imgui_internal.h"
struct FrameContext struct FrameContext
{ {
ID3D12CommandAllocator* CommandAllocator; ID3D12CommandAllocator* CommandAllocator;
@ -49,7 +43,6 @@ static ID3D12Fence* g_fence = nullptr;
static HANDLE g_fenceEvent = nullptr; static HANDLE g_fenceEvent = nullptr;
static UINT64 g_fenceLastSignaledValue = 0; static UINT64 g_fenceLastSignaledValue = 0;
static IDXGISwapChain3* g_pSwapChain = nullptr; static IDXGISwapChain3* g_pSwapChain = nullptr;
static bool g_SwapChainOccluded = false;
static HANDLE g_hSwapChainWaitableObject = nullptr; static HANDLE g_hSwapChainWaitableObject = nullptr;
static ID3D12Resource* g_mainRenderTargetResource[NUM_BACK_BUFFERS] = {}; static ID3D12Resource* g_mainRenderTargetResource[NUM_BACK_BUFFERS] = {};
static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFERS] = {}; static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFERS] = {};
@ -140,14 +133,6 @@ int main(int, char**)
if (done) if (done)
break; break;
// Handle window screen locked
if (g_SwapChainOccluded && g_pSwapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED)
{
::Sleep(10);
continue;
}
g_SwapChainOccluded = false;
// Start the Dear ImGui frame // Start the Dear ImGui frame
ImGui_ImplDX12_NewFrame(); ImGui_ImplDX12_NewFrame();
ImGui_ImplWin32_NewFrame(); ImGui_ImplWin32_NewFrame();
@ -220,10 +205,8 @@ int main(int, char**)
g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList); g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList);
// Present g_pSwapChain->Present(1, 0); // Present with vsync
HRESULT hr = g_pSwapChain->Present(1, 0); // Present with vsync //g_pSwapChain->Present(0, 0); // Present without vsync
//HRESULT hr = g_pSwapChain->Present(0, 0); // Present without vsync
g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);
UINT64 fenceValue = g_fenceLastSignaledValue + 1; UINT64 fenceValue = g_fenceLastSignaledValue + 1;
g_pd3dCommandQueue->Signal(g_fence, fenceValue); g_pd3dCommandQueue->Signal(g_fence, fenceValue);

View File

@ -1,10 +1,6 @@
// Dear ImGui: standalone example application for DirectX 9 // Dear ImGui: standalone example application for DirectX 9
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Learn about Dear ImGui: // Read online: https://github.com/ocornut/imgui/tree/master/docs
// - 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
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_dx9.h" #include "imgui_impl_dx9.h"
@ -15,7 +11,6 @@
// Data // Data
static LPDIRECT3D9 g_pD3D = nullptr; static LPDIRECT3D9 g_pD3D = nullptr;
static LPDIRECT3DDEVICE9 g_pd3dDevice = nullptr; static LPDIRECT3DDEVICE9 g_pd3dDevice = nullptr;
static bool g_DeviceLost = false;
static UINT g_ResizeWidth = 0, g_ResizeHeight = 0; static UINT g_ResizeWidth = 0, g_ResizeHeight = 0;
static D3DPRESENT_PARAMETERS g_d3dpp = {}; static D3DPRESENT_PARAMETERS g_d3dpp = {};
@ -99,20 +94,6 @@ int main(int, char**)
if (done) if (done)
break; break;
// Handle lost D3D9 device
if (g_DeviceLost)
{
HRESULT hr = g_pd3dDevice->TestCooperativeLevel();
if (hr == D3DERR_DEVICELOST)
{
::Sleep(10);
continue;
}
if (hr == D3DERR_DEVICENOTRESET)
ResetDevice();
g_DeviceLost = false;
}
// Handle window resize (we don't resize directly in the WM_SIZE handler) // Handle window resize (we don't resize directly in the WM_SIZE handler)
if (g_ResizeWidth != 0 && g_ResizeHeight != 0) if (g_ResizeWidth != 0 && g_ResizeHeight != 0)
{ {
@ -178,11 +159,12 @@ int main(int, char**)
g_pd3dDevice->EndScene(); g_pd3dDevice->EndScene();
} }
HRESULT result = g_pd3dDevice->Present(nullptr, nullptr, nullptr, nullptr); HRESULT result = g_pd3dDevice->Present(nullptr, nullptr, nullptr, nullptr);
if (result == D3DERR_DEVICELOST)
g_DeviceLost = true; // Handle loss of D3D9 device
if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET)
ResetDevice();
} }
// Cleanup
ImGui_ImplDX9_Shutdown(); ImGui_ImplDX9_Shutdown();
ImGui_ImplWin32_Shutdown(); ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();

View File

@ -1,12 +1,8 @@
// Dear ImGui: standalone example application for Win32 + OpenGL 3 // Dear ImGui: standalone example application for Win32 + OpenGL 3
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
// Learn about Dear ImGui: // This is provided for completeness, however it is strogly recommended you use OpenGL with SDL or GLFW.
// - 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
// This is provided for completeness, however it is strongly recommended you use OpenGL with SDL or GLFW.
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_opengl3.h" #include "imgui_impl_opengl3.h"
@ -38,9 +34,9 @@ int main(int, char**)
{ {
// Create application window // Create application window
//ImGui_ImplWin32_EnableDpiAwareness(); //ImGui_ImplWin32_EnableDpiAwareness();
WNDCLASSEXW wc = { sizeof(wc), CS_OWNDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr }; WNDCLASSEXW wc = { sizeof(wc), CS_OWNDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"ImGui Example", NULL };
::RegisterClassExW(&wc); ::RegisterClassExW(&wc);
HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+OpenGL3 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, nullptr, nullptr, wc.hInstance, nullptr); HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+OpenGL3 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
// Initialize OpenGL // Initialize OpenGL
if (!CreateDeviceWGL(hwnd, &g_MainWindow)) if (!CreateDeviceWGL(hwnd, &g_MainWindow))
@ -74,7 +70,7 @@ int main(int, char**)
// Load Fonts // Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
// - Read 'docs/FONTS.md' for more instructions and details. // - Read 'docs/FONTS.md' for more instructions and details.
@ -84,8 +80,8 @@ int main(int, char**)
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese()); //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != nullptr); //IM_ASSERT(font != NULL);
// Our state // Our state
bool show_demo_window = true; bool show_demo_window = true;
@ -99,7 +95,7 @@ int main(int, char**)
// Poll and handle messages (inputs, window resize, etc.) // Poll and handle messages (inputs, window resize, etc.)
// See the WndProc() function below for our to dispatch events to the Win32 backend. // See the WndProc() function below for our to dispatch events to the Win32 backend.
MSG msg; MSG msg;
while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)) while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{ {
::TranslateMessage(&msg); ::TranslateMessage(&msg);
::DispatchMessage(&msg); ::DispatchMessage(&msg);
@ -200,7 +196,7 @@ bool CreateDeviceWGL(HWND hWnd, WGL_WindowData* data)
void CleanupDeviceWGL(HWND hWnd, WGL_WindowData* data) void CleanupDeviceWGL(HWND hWnd, WGL_WindowData* data)
{ {
wglMakeCurrent(nullptr, nullptr); wglMakeCurrent(NULL, NULL);
::ReleaseDC(hWnd, data->hDC); ::ReleaseDC(hWnd, data->hDC);
} }

View File

@ -200,7 +200,7 @@ typedef void (*uSynergySleepFunc)(uSynergyCookie cookie, int timeMs);
@brief Get time function @brief Get time function
This function is called when uSynergy needs to know the current time. This is used to determine when timeouts This function is called when uSynergy needs to know the current time. This is used to determine when timeouts
have occurred. The time base should be a cyclic millisecond time value. have occured. The time base should be a cyclic millisecond time value.
@returns Time value in milliseconds @returns Time value in milliseconds
**/ **/

View File

@ -1,5 +1,5 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// DEAR IMGUI COMPILE-TIME OPTIONS // COMPILE-TIME OPTIONS FOR DEAR IMGUI
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -9,7 +9,7 @@
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp // You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. // files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using. // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#pragma once #pragma once
@ -26,21 +26,21 @@
//#define IMGUI_API __declspec( dllexport ) //#define IMGUI_API __declspec( dllexport )
//#define IMGUI_API __declspec( dllimport ) //#define IMGUI_API __declspec( dllimport )
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names. //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by IMGUI_DISABLE_OBSOLETE_FUNCTIONS. //#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
//---- Disable all of Dear ImGui or don't implement standard windows/tools. //---- Disable all of Dear ImGui or don't implement standard windows/tools.
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp. // It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty. //#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowStackToolWindow() will be empty (this was called IMGUI_DISABLE_METRICS_WINDOW before 1.88).
//---- Don't implement some functions to reduce linkage requirements. //---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW) //#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a) //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME). //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
@ -50,24 +50,21 @@
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
//---- Include imgui_user.h at the end of imgui.h as a convenience //---- Include imgui_user.h at the end of imgui.h as a convenience
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
//#define IMGUI_INCLUDE_IMGUI_USER_H //#define IMGUI_INCLUDE_IMGUI_USER_H
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
//#define IMGUI_USE_BGRA_PACKED_COLOR //#define IMGUI_USE_BGRA_PACKED_COLOR
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...) //---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
//#define IMGUI_USE_WCHAR32 //#define IMGUI_USE_WCHAR32
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files. // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined. //#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if enabled
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined) //---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h. // Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
@ -78,12 +75,6 @@
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'. // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
//#define IMGUI_ENABLE_FREETYPE //#define IMGUI_ENABLE_FREETYPE
//---- Use FreeType+lunasvg library to render OpenType SVG fonts (SVGinOT)
// Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided).
// Only works in combination with IMGUI_ENABLE_FREETYPE.
// (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
//---- Use stb_truetype to build and rasterize the font atlas (default) //---- Use stb_truetype to build and rasterize the font atlas (default)
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend. // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
//#define IMGUI_ENABLE_STB_TRUETYPE //#define IMGUI_ENABLE_STB_TRUETYPE
@ -114,7 +105,7 @@
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
//#define ImDrawCallback MyImDrawCallback //#define ImDrawCallback MyImDrawCallback
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase) //---- Debug Tools: Macro to break in Debugger
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
//#define IM_DEBUG_BREAK IM_ASSERT(0) //#define IM_DEBUG_BREAK IM_ASSERT(0)
//#define IM_DEBUG_BREAK __debugbreak() //#define IM_DEBUG_BREAK __debugbreak()
@ -122,10 +113,10 @@
//---- Debug Tools: Enable slower asserts //---- Debug Tools: Enable slower asserts
//#define IMGUI_DEBUG_PARANOID //#define IMGUI_DEBUG_PARANOID
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files) //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
/* /*
namespace ImGui namespace ImGui
{ {
void MyFunction(const char* name, MyMatrix44* mtx); void MyFunction(const char* name, const MyMatrix44& v);
} }
*/ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// dear imgui, v1.90.7 // dear imgui, v1.89.7
// (drawing and font code) // (drawing and font code)
/* /*
@ -8,7 +8,6 @@ Index of this file:
// [SECTION] STB libraries implementation // [SECTION] STB libraries implementation
// [SECTION] Style functions // [SECTION] Style functions
// [SECTION] ImDrawList // [SECTION] ImDrawList
// [SECTION] ImTriangulator, ImDrawList concave polygon fill
// [SECTION] ImDrawListSplitter // [SECTION] ImDrawListSplitter
// [SECTION] ImDrawData // [SECTION] ImDrawData
// [SECTION] Helpers ShadeVertsXXX functions // [SECTION] Helpers ShadeVertsXXX functions
@ -64,8 +63,6 @@ Index of this file:
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
@ -137,7 +134,7 @@ namespace IMGUI_STB_NAMESPACE
#define STBTT_sqrt(x) ImSqrt(x) #define STBTT_sqrt(x) ImSqrt(x)
#define STBTT_pow(x,y) ImPow(x,y) #define STBTT_pow(x,y) ImPow(x,y)
#define STBTT_fabs(x) ImFabs(x) #define STBTT_fabs(x) ImFabs(x)
#define STBTT_ifloor(x) ((int)ImFloor(x)) #define STBTT_ifloor(x) ((int)ImFloorSigned(x))
#define STBTT_iceil(x) ((int)ImCeil(x)) #define STBTT_iceil(x) ((int)ImCeil(x))
#define STBTT_STATIC #define STBTT_STATIC
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
@ -385,13 +382,12 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error)
} }
// Initialize before use in a new frame. We always have a command ready in the buffer. // Initialize before use in a new frame. We always have a command ready in the buffer.
// In the majority of cases, you would want to call PushClipRect() and PushTextureID() after this.
void ImDrawList::_ResetForNewFrame() void ImDrawList::_ResetForNewFrame()
{ {
// Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory. // Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory.
IM_STATIC_ASSERT(offsetof(ImDrawCmd, ClipRect) == 0); IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, ClipRect) == 0);
IM_STATIC_ASSERT(offsetof(ImDrawCmd, TextureId) == sizeof(ImVec4)); IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, TextureId) == sizeof(ImVec4));
IM_STATIC_ASSERT(offsetof(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID)); IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID));
if (_Splitter._Count > 1) if (_Splitter._Count > 1)
_Splitter.Merge(this); _Splitter.Merge(this);
@ -478,7 +474,7 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
} }
// Compare ClipRect, TextureId and VtxOffset with a single memcmp() // Compare ClipRect, TextureId and VtxOffset with a single memcmp()
#define ImDrawCmd_HeaderSize (offsetof(ImDrawCmd, VtxOffset) + sizeof(unsigned int)) #define ImDrawCmd_HeaderSize (IM_OFFSETOF(ImDrawCmd, VtxOffset) + sizeof(unsigned int))
#define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset #define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset
#define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset #define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset
#define ImDrawCmd_AreSequentialIdxOffset(CMD_0, CMD_1) (CMD_0->IdxOffset + CMD_0->ElemCount == CMD_1->IdxOffset) #define ImDrawCmd_AreSequentialIdxOffset(CMD_0, CMD_1) (CMD_0->IdxOffset + CMD_0->ElemCount == CMD_1->IdxOffset)
@ -564,7 +560,7 @@ int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const
{ {
// Automatic segment count // Automatic segment count
const int radius_idx = (int)(radius + 0.999999f); // ceil to never reduce accuracy const int radius_idx = (int)(radius + 0.999999f); // ceil to never reduce accuracy
if (radius_idx >= 0 && radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts)) if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
return _Data->CircleSegmentCounts[radius_idx]; // Use cached value return _Data->CircleSegmentCounts[radius_idx]; // Use cached value
else else
return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError); return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError);
@ -644,7 +640,7 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count)
_IdxWritePtr = IdxBuffer.Data + idx_buffer_old_size; _IdxWritePtr = IdxBuffer.Data + idx_buffer_old_size;
} }
// Release the number of reserved vertices/indices from the end of the last reservation made with PrimReserve(). // Release the a number of reserved vertices/indices from the end of the last reservation made with PrimReserve().
void ImDrawList::PrimUnreserve(int idx_count, int vtx_count) void ImDrawList::PrimUnreserve(int idx_count, int vtx_count)
{ {
IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0); IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0);
@ -1194,8 +1190,8 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
const float a_min_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f); const float a_min_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f);
const float a_max_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f); const float a_max_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f);
const int a_min_sample = a_is_reverse ? (int)ImFloor(a_min_sample_f) : (int)ImCeil(a_min_sample_f); const int a_min_sample = a_is_reverse ? (int)ImFloorSigned(a_min_sample_f) : (int)ImCeil(a_min_sample_f);
const int a_max_sample = a_is_reverse ? (int)ImCeil(a_max_sample_f) : (int)ImFloor(a_max_sample_f); const int a_max_sample = a_is_reverse ? (int)ImCeil(a_max_sample_f) : (int)ImFloorSigned(a_max_sample_f);
const int a_mid_samples = a_is_reverse ? ImMax(a_min_sample - a_max_sample, 0) : ImMax(a_max_sample - a_min_sample, 0); const int a_mid_samples = a_is_reverse ? ImMax(a_min_sample - a_max_sample, 0) : ImMax(a_max_sample - a_min_sample, 0);
const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
@ -1220,26 +1216,6 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
} }
} }
void ImDrawList::PathEllipticalArcTo(const ImVec2& center, const ImVec2& radius, float rot, float a_min, float a_max, int num_segments)
{
if (num_segments <= 0)
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here.
_Path.reserve(_Path.Size + (num_segments + 1));
const float cos_rot = ImCos(rot);
const float sin_rot = ImSin(rot);
for (int i = 0; i <= num_segments; i++)
{
const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min);
ImVec2 point(ImCos(a) * radius.x, ImSin(a) * radius.y);
const ImVec2 rel((point.x * cos_rot) - (point.y * sin_rot), (point.x * sin_rot) + (point.y * cos_rot));
point.x = rel.x + center.x;
point.y = rel.y + center.y;
_Path.push_back(point);
}
}
ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t) ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t)
{ {
float u = 1.0f - t; float u = 1.0f - t;
@ -1335,22 +1311,33 @@ void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3,
} }
} }
IM_STATIC_ASSERT(ImDrawFlags_RoundCornersTopLeft == (1 << 4));
static inline ImDrawFlags FixRectCornerFlags(ImDrawFlags flags) static inline ImDrawFlags FixRectCornerFlags(ImDrawFlags flags)
{ {
/*
IM_STATIC_ASSERT(ImDrawFlags_RoundCornersTopLeft == (1 << 4));
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Obsoleted in 1.82 (from February 2021). This code was stripped/simplified and mostly commented in 1.90 (from September 2023) // Obsoleted in 1.82 (from February 2021)
// - Legacy Support for hard coded ~0 (used to be a suggested equivalent to ImDrawCornerFlags_All) // Legacy Support for hard coded ~0 (used to be a suggested equivalent to ImDrawCornerFlags_All)
if (flags == ~0) { return ImDrawFlags_RoundCornersAll; } // ~0 --> ImDrawFlags_RoundCornersAll or 0
// - Legacy Support for hard coded 0x01 to 0x0F (matching 15 out of 16 old flags combinations). Read details in older version of this code. if (flags == ~0)
if (flags >= 0x01 && flags <= 0x0F) { return (flags << 4); } return ImDrawFlags_RoundCornersAll;
// Legacy Support for hard coded 0x01 to 0x0F (matching 15 out of 16 old flags combinations)
// 0x01 --> ImDrawFlags_RoundCornersTopLeft (VALUE 0x01 OVERLAPS ImDrawFlags_Closed but ImDrawFlags_Closed is never valid in this path!)
// 0x02 --> ImDrawFlags_RoundCornersTopRight
// 0x03 --> ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight
// 0x04 --> ImDrawFlags_RoundCornersBotLeft
// 0x05 --> ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBotLeft
// ...
// 0x0F --> ImDrawFlags_RoundCornersAll or 0
// (See all values in ImDrawCornerFlags_)
if (flags >= 0x01 && flags <= 0x0F)
return (flags << 4);
// We cannot support hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f' // We cannot support hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f'
#endif #endif
*/
// If this assert triggers, please update your code replacing hardcoded values with new ImDrawFlags_RoundCorners* values. // If this triggers, please update your code replacing hardcoded values with new ImDrawFlags_RoundCorners* values.
// Note that ImDrawFlags_Closed (== 0x01) is an invalid flag for AddRect(), AddRectFilled(), PathRect() etc. anyway. // Note that ImDrawFlags_Closed (== 0x01) is an invalid flag for AddRect(), AddRectFilled(), PathRect() etc...
// See details in 1.82 Changelog as well as 2021/03/12 and 2023/09/08 entries in "API BREAKING CHANGES" section.
IM_ASSERT((flags & 0x0F) == 0 && "Misuse of legacy hardcoded ImDrawCornerFlags values!"); IM_ASSERT((flags & 0x0F) == 0 && "Misuse of legacy hardcoded ImDrawCornerFlags values!");
if ((flags & ImDrawFlags_RoundCornersMask_) == 0) if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
@ -1361,12 +1348,10 @@ static inline ImDrawFlags FixRectCornerFlags(ImDrawFlags flags)
void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDrawFlags flags) void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDrawFlags flags)
{ {
if (rounding >= 0.5f) flags = FixRectCornerFlags(flags);
{ rounding = ImMin(rounding, ImFabs(b.x - a.x) * ( ((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f ) - 1.0f);
flags = FixRectCornerFlags(flags); rounding = ImMin(rounding, ImFabs(b.y - a.y) * ( ((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f ) - 1.0f);
rounding = ImMin(rounding, ImFabs(b.x - a.x) * (((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f) - 1.0f);
rounding = ImMin(rounding, ImFabs(b.y - a.y) * (((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f) - 1.0f);
}
if (rounding < 0.5f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) if (rounding < 0.5f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
{ {
PathLineTo(a); PathLineTo(a);
@ -1559,35 +1544,6 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in
PathFillConvex(col); PathFillConvex(col);
} }
// Ellipse
void ImDrawList::AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments, float thickness)
{
if ((col & IM_COL32_A_MASK) == 0)
return;
if (num_segments <= 0)
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here.
// Because we are filling a closed shape we remove 1 from the count of segments/points
const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1);
PathStroke(col, true, thickness);
}
void ImDrawList::AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments)
{
if ((col & IM_COL32_A_MASK) == 0)
return;
if (num_segments <= 0)
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here.
// Because we are filling a closed shape we remove 1 from the count of segments/points
const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1);
PathFillConvex(col);
}
// Cubic Bezier takes 4 controls points // Cubic Bezier takes 4 controls points
void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments) void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments)
{ {
@ -1615,11 +1571,10 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
if ((col & IM_COL32_A_MASK) == 0) if ((col & IM_COL32_A_MASK) == 0)
return; return;
// Accept null ranges
if (text_begin == text_end || text_begin[0] == 0)
return;
if (text_end == NULL) if (text_end == NULL)
text_end = text_begin + strlen(text_begin); text_end = text_begin + strlen(text_begin);
if (text_begin == text_end)
return;
// Pull default font/size from the shared ImDrawListSharedData instance // Pull default font/size from the shared ImDrawListSharedData instance
if (font == NULL) if (font == NULL)
@ -1703,316 +1658,6 @@ void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_mi
PopTextureID(); PopTextureID();
} }
//-----------------------------------------------------------------------------
// [SECTION] ImTriangulator, ImDrawList concave polygon fill
//-----------------------------------------------------------------------------
// Triangulate concave polygons. Based on "Triangulation by Ear Clipping" paper, O(N^2) complexity.
// Reference: https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
// Provided as a convenience for user but not used by main library.
//-----------------------------------------------------------------------------
// - ImTriangulator [Internal]
// - AddConcavePolyFilled()
//-----------------------------------------------------------------------------
enum ImTriangulatorNodeType
{
ImTriangulatorNodeType_Convex,
ImTriangulatorNodeType_Ear,
ImTriangulatorNodeType_Reflex
};
struct ImTriangulatorNode
{
ImTriangulatorNodeType Type;
int Index;
ImVec2 Pos;
ImTriangulatorNode* Next;
ImTriangulatorNode* Prev;
void Unlink() { Next->Prev = Prev; Prev->Next = Next; }
};
struct ImTriangulatorNodeSpan
{
ImTriangulatorNode** Data = NULL;
int Size = 0;
void push_back(ImTriangulatorNode* node) { Data[Size++] = node; }
void find_erase_unsorted(int idx) { for (int i = Size - 1; i >= 0; i--) if (Data[i]->Index == idx) { Data[i] = Data[Size - 1]; Size--; return; } }
};
struct ImTriangulator
{
static int EstimateTriangleCount(int points_count) { return (points_count < 3) ? 0 : points_count - 2; }
static int EstimateScratchBufferSize(int points_count) { return sizeof(ImTriangulatorNode) * points_count + sizeof(ImTriangulatorNode*) * points_count * 2; }
void Init(const ImVec2* points, int points_count, void* scratch_buffer);
void GetNextTriangle(unsigned int out_triangle[3]); // Return relative indexes for next triangle
// Internal functions
void BuildNodes(const ImVec2* points, int points_count);
void BuildReflexes();
void BuildEars();
void FlipNodeList();
bool IsEar(int i0, int i1, int i2, const ImVec2& v0, const ImVec2& v1, const ImVec2& v2) const;
void ReclassifyNode(ImTriangulatorNode* node);
// Internal members
int _TrianglesLeft = 0;
ImTriangulatorNode* _Nodes = NULL;
ImTriangulatorNodeSpan _Ears;
ImTriangulatorNodeSpan _Reflexes;
};
// Distribute storage for nodes, ears and reflexes.
// FIXME-OPT: if everything is convex, we could report it to caller and let it switch to an convex renderer
// (this would require first building reflexes to bail to convex if empty, without even building nodes)
void ImTriangulator::Init(const ImVec2* points, int points_count, void* scratch_buffer)
{
IM_ASSERT(scratch_buffer != NULL && points_count >= 3);
_TrianglesLeft = EstimateTriangleCount(points_count);
_Nodes = (ImTriangulatorNode*)scratch_buffer; // points_count x Node
_Ears.Data = (ImTriangulatorNode**)(_Nodes + points_count); // points_count x Node*
_Reflexes.Data = (ImTriangulatorNode**)(_Nodes + points_count) + points_count; // points_count x Node*
BuildNodes(points, points_count);
BuildReflexes();
BuildEars();
}
void ImTriangulator::BuildNodes(const ImVec2* points, int points_count)
{
for (int i = 0; i < points_count; i++)
{
_Nodes[i].Type = ImTriangulatorNodeType_Convex;
_Nodes[i].Index = i;
_Nodes[i].Pos = points[i];
_Nodes[i].Next = _Nodes + i + 1;
_Nodes[i].Prev = _Nodes + i - 1;
}
_Nodes[0].Prev = _Nodes + points_count - 1;
_Nodes[points_count - 1].Next = _Nodes;
}
void ImTriangulator::BuildReflexes()
{
ImTriangulatorNode* n1 = _Nodes;
for (int i = _TrianglesLeft; i >= 0; i--, n1 = n1->Next)
{
if (ImTriangleIsClockwise(n1->Prev->Pos, n1->Pos, n1->Next->Pos))
continue;
n1->Type = ImTriangulatorNodeType_Reflex;
_Reflexes.push_back(n1);
}
}
void ImTriangulator::BuildEars()
{
ImTriangulatorNode* n1 = _Nodes;
for (int i = _TrianglesLeft; i >= 0; i--, n1 = n1->Next)
{
if (n1->Type != ImTriangulatorNodeType_Convex)
continue;
if (!IsEar(n1->Prev->Index, n1->Index, n1->Next->Index, n1->Prev->Pos, n1->Pos, n1->Next->Pos))
continue;
n1->Type = ImTriangulatorNodeType_Ear;
_Ears.push_back(n1);
}
}
void ImTriangulator::GetNextTriangle(unsigned int out_triangle[3])
{
if (_Ears.Size == 0)
{
FlipNodeList();
ImTriangulatorNode* node = _Nodes;
for (int i = _TrianglesLeft; i >= 0; i--, node = node->Next)
node->Type = ImTriangulatorNodeType_Convex;
_Reflexes.Size = 0;
BuildReflexes();
BuildEars();
// If we still don't have ears, it means geometry is degenerated.
if (_Ears.Size == 0)
{
// Return first triangle available, mimicking the behavior of convex fill.
IM_ASSERT(_TrianglesLeft > 0); // Geometry is degenerated
_Ears.Data[0] = _Nodes;
_Ears.Size = 1;
}
}
ImTriangulatorNode* ear = _Ears.Data[--_Ears.Size];
out_triangle[0] = ear->Prev->Index;
out_triangle[1] = ear->Index;
out_triangle[2] = ear->Next->Index;
ear->Unlink();
if (ear == _Nodes)
_Nodes = ear->Next;
ReclassifyNode(ear->Prev);
ReclassifyNode(ear->Next);
_TrianglesLeft--;
}
void ImTriangulator::FlipNodeList()
{
ImTriangulatorNode* prev = _Nodes;
ImTriangulatorNode* temp = _Nodes;
ImTriangulatorNode* current = _Nodes->Next;
prev->Next = prev;
prev->Prev = prev;
while (current != _Nodes)
{
temp = current->Next;
current->Next = prev;
prev->Prev = current;
_Nodes->Next = current;
current->Prev = _Nodes;
prev = current;
current = temp;
}
_Nodes = prev;
}
// A triangle is an ear is no other vertex is inside it. We can test reflexes vertices only (see reference algorithm)
bool ImTriangulator::IsEar(int i0, int i1, int i2, const ImVec2& v0, const ImVec2& v1, const ImVec2& v2) const
{
ImTriangulatorNode** p_end = _Reflexes.Data + _Reflexes.Size;
for (ImTriangulatorNode** p = _Reflexes.Data; p < p_end; p++)
{
ImTriangulatorNode* reflex = *p;
if (reflex->Index != i0 && reflex->Index != i1 && reflex->Index != i2)
if (ImTriangleContainsPoint(v0, v1, v2, reflex->Pos))
return false;
}
return true;
}
void ImTriangulator::ReclassifyNode(ImTriangulatorNode* n1)
{
// Classify node
ImTriangulatorNodeType type;
const ImTriangulatorNode* n0 = n1->Prev;
const ImTriangulatorNode* n2 = n1->Next;
if (!ImTriangleIsClockwise(n0->Pos, n1->Pos, n2->Pos))
type = ImTriangulatorNodeType_Reflex;
else if (IsEar(n0->Index, n1->Index, n2->Index, n0->Pos, n1->Pos, n2->Pos))
type = ImTriangulatorNodeType_Ear;
else
type = ImTriangulatorNodeType_Convex;
// Update lists when a type changes
if (type == n1->Type)
return;
if (n1->Type == ImTriangulatorNodeType_Reflex)
_Reflexes.find_erase_unsorted(n1->Index);
else if (n1->Type == ImTriangulatorNodeType_Ear)
_Ears.find_erase_unsorted(n1->Index);
if (type == ImTriangulatorNodeType_Reflex)
_Reflexes.push_back(n1);
else if (type == ImTriangulatorNodeType_Ear)
_Ears.push_back(n1);
n1->Type = type;
}
// Use ear-clipping algorithm to triangulate a simple polygon (no self-interaction, no holes).
// (Reminder: we don't perform any coarse clipping/culling in ImDrawList layer!
// It is up to caller to ensure not making costly calls that will be outside of visible area.
// As concave fill is noticeably more expensive than other primitives, be mindful of this...
// Caller can build AABB of points, and avoid filling if 'draw_list->_CmdHeader.ClipRect.Overlays(points_bb) == false')
void ImDrawList::AddConcavePolyFilled(const ImVec2* points, const int points_count, ImU32 col)
{
if (points_count < 3 || (col & IM_COL32_A_MASK) == 0)
return;
const ImVec2 uv = _Data->TexUvWhitePixel;
ImTriangulator triangulator;
unsigned int triangle[3];
if (Flags & ImDrawListFlags_AntiAliasedFill)
{
// Anti-aliased Fill
const float AA_SIZE = _FringeScale;
const ImU32 col_trans = col & ~IM_COL32_A_MASK;
const int idx_count = (points_count - 2) * 3 + points_count * 6;
const int vtx_count = (points_count * 2);
PrimReserve(idx_count, vtx_count);
// Add indexes for fill
unsigned int vtx_inner_idx = _VtxCurrentIdx;
unsigned int vtx_outer_idx = _VtxCurrentIdx + 1;
_Data->TempBuffer.reserve_discard((ImTriangulator::EstimateScratchBufferSize(points_count) + sizeof(ImVec2)) / sizeof(ImVec2));
triangulator.Init(points, points_count, _Data->TempBuffer.Data);
while (triangulator._TrianglesLeft > 0)
{
triangulator.GetNextTriangle(triangle);
_IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (triangle[0] << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (triangle[1] << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx + (triangle[2] << 1));
_IdxWritePtr += 3;
}
// Compute normals
_Data->TempBuffer.reserve_discard(points_count);
ImVec2* temp_normals = _Data->TempBuffer.Data;
for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++)
{
const ImVec2& p0 = points[i0];
const ImVec2& p1 = points[i1];
float dx = p1.x - p0.x;
float dy = p1.y - p0.y;
IM_NORMALIZE2F_OVER_ZERO(dx, dy);
temp_normals[i0].x = dy;
temp_normals[i0].y = -dx;
}
for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++)
{
// Average normals
const ImVec2& n0 = temp_normals[i0];
const ImVec2& n1 = temp_normals[i1];
float dm_x = (n0.x + n1.x) * 0.5f;
float dm_y = (n0.y + n1.y) * 0.5f;
IM_FIXNORMAL2F(dm_x, dm_y);
dm_x *= AA_SIZE * 0.5f;
dm_y *= AA_SIZE * 0.5f;
// Add vertices
_VtxWritePtr[0].pos.x = (points[i1].x - dm_x); _VtxWritePtr[0].pos.y = (points[i1].y - dm_y); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner
_VtxWritePtr[1].pos.x = (points[i1].x + dm_x); _VtxWritePtr[1].pos.y = (points[i1].y + dm_y); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer
_VtxWritePtr += 2;
// Add indexes for fringes
_IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1));
_IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1));
_IdxWritePtr += 6;
}
_VtxCurrentIdx += (ImDrawIdx)vtx_count;
}
else
{
// Non Anti-aliased Fill
const int idx_count = (points_count - 2) * 3;
const int vtx_count = points_count;
PrimReserve(idx_count, vtx_count);
for (int i = 0; i < vtx_count; i++)
{
_VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col;
_VtxWritePtr++;
}
_Data->TempBuffer.reserve_discard((ImTriangulator::EstimateScratchBufferSize(points_count) + sizeof(ImVec2)) / sizeof(ImVec2));
triangulator.Init(points, points_count, _Data->TempBuffer.Data);
while (triangulator._TrianglesLeft > 0)
{
triangulator.GetNextTriangle(triangle);
_IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx + triangle[0]); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + triangle[1]); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + triangle[2]);
_IdxWritePtr += 3;
}
_VtxCurrentIdx += (ImDrawIdx)vtx_count;
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ImDrawListSplitter // [SECTION] ImDrawListSplitter
@ -2163,63 +1808,6 @@ void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
// [SECTION] ImDrawData // [SECTION] ImDrawData
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ImDrawData::Clear()
{
Valid = false;
CmdListsCount = TotalIdxCount = TotalVtxCount = 0;
CmdLists.resize(0); // The ImDrawList are NOT owned by ImDrawData but e.g. by ImGuiContext, so we don't clear them.
DisplayPos = DisplaySize = FramebufferScale = ImVec2(0.0f, 0.0f);
OwnerViewport = NULL;
}
// Important: 'out_list' is generally going to be draw_data->CmdLists, but may be another temporary list
// as long at it is expected that the result will be later merged into draw_data->CmdLists[].
void ImGui::AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>* out_list, ImDrawList* draw_list)
{
if (draw_list->CmdBuffer.Size == 0)
return;
if (draw_list->CmdBuffer.Size == 1 && draw_list->CmdBuffer[0].ElemCount == 0 && draw_list->CmdBuffer[0].UserCallback == NULL)
return;
// Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
// May trigger for you if you are using PrimXXX functions incorrectly.
IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size);
IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size);
if (!(draw_list->Flags & ImDrawListFlags_AllowVtxOffset))
IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size);
// Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window)
// If this assert triggers because you are drawing lots of stuff manually:
// - First, make sure you are coarse clipping yourself and not trying to draw many things outside visible bounds.
// Be mindful that the lower-level ImDrawList API doesn't filter vertices. Use the Metrics/Debugger window to inspect draw list contents.
// - If you want large meshes with more than 64K vertices, you can either:
// (A) Handle the ImDrawCmd::VtxOffset value in your renderer backend, and set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset'.
// Most example backends already support this from 1.71. Pre-1.71 backends won't.
// Some graphics API such as GL ES 1/2 don't have a way to offset the starting vertex so it is not supported for them.
// (B) Or handle 32-bit indices in your renderer backend, and uncomment '#define ImDrawIdx unsigned int' line in imconfig.h.
// Most example backends already support this. For example, the OpenGL example code detect index size at compile-time:
// glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
// Your own engine or render API may use different parameters or function calls to specify index sizes.
// 2 and 4 bytes indices are generally supported by most graphics API.
// - If for some reason neither of those solutions works for you, a workaround is to call BeginChild()/EndChild() before reaching
// the 64K limit to split your draw commands in multiple draw lists.
if (sizeof(ImDrawIdx) == 2)
IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above");
// Add to output list + records state in ImDrawData
out_list->push_back(draw_list);
draw_data->CmdListsCount++;
draw_data->TotalVtxCount += draw_list->VtxBuffer.Size;
draw_data->TotalIdxCount += draw_list->IdxBuffer.Size;
}
void ImDrawData::AddDrawList(ImDrawList* draw_list)
{
IM_ASSERT(CmdLists.Size == CmdListsCount);
draw_list->_PopUnusedDrawCmd();
ImGui::AddDrawListToDrawDataEx(this, &CmdLists, draw_list);
}
// For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! // For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
void ImDrawData::DeIndexAllBuffers() void ImDrawData::DeIndexAllBuffers()
{ {
@ -2244,9 +1832,15 @@ void ImDrawData::DeIndexAllBuffers()
// or if there is a difference between your window resolution and framebuffer resolution. // or if there is a difference between your window resolution and framebuffer resolution.
void ImDrawData::ScaleClipRects(const ImVec2& fb_scale) void ImDrawData::ScaleClipRects(const ImVec2& fb_scale)
{ {
for (ImDrawList* draw_list : CmdLists) for (int i = 0; i < CmdListsCount; i++)
for (ImDrawCmd& cmd : draw_list->CmdBuffer) {
cmd.ClipRect = ImVec4(cmd.ClipRect.x * fb_scale.x, cmd.ClipRect.y * fb_scale.y, cmd.ClipRect.z * fb_scale.x, cmd.ClipRect.w * fb_scale.y); ImDrawList* cmd_list = CmdLists[i];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
ImDrawCmd* cmd = &cmd_list->CmdBuffer[cmd_i];
cmd->ClipRect = ImVec4(cmd->ClipRect.x * fb_scale.x, cmd->ClipRect.y * fb_scale.y, cmd->ClipRect.z * fb_scale.x, cmd->ClipRect.w * fb_scale.y);
}
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2302,14 +1896,6 @@ void ImGui::ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int ve
} }
} }
void ImGui::ShadeVertsTransformPos(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, const ImVec2& pivot_in, float cos_a, float sin_a, const ImVec2& pivot_out)
{
ImDrawVert* vert_start = draw_list->VtxBuffer.Data + vert_start_idx;
ImDrawVert* vert_end = draw_list->VtxBuffer.Data + vert_end_idx;
for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex)
vertex->pos = ImRotate(vertex->pos- pivot_in, cos_a, sin_a) + pivot_out;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ImFontConfig // [SECTION] ImFontConfig
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2318,11 +1904,10 @@ ImFontConfig::ImFontConfig()
{ {
memset(this, 0, sizeof(*this)); memset(this, 0, sizeof(*this));
FontDataOwnedByAtlas = true; FontDataOwnedByAtlas = true;
OversampleH = 2; OversampleH = 3; // FIXME: 2 may be a better default?
OversampleV = 1; OversampleV = 1;
GlyphMaxAdvanceX = FLT_MAX; GlyphMaxAdvanceX = FLT_MAX;
RasterizerMultiply = 1.0f; RasterizerMultiply = 1.0f;
RasterizerDensity = 1.0f;
EllipsisChar = (ImWchar)-1; EllipsisChar = (ImWchar)-1;
} }
@ -2396,19 +1981,19 @@ ImFontAtlas::~ImFontAtlas()
void ImFontAtlas::ClearInputData() void ImFontAtlas::ClearInputData()
{ {
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
for (ImFontConfig& font_cfg : ConfigData) for (int i = 0; i < ConfigData.Size; i++)
if (font_cfg.FontData && font_cfg.FontDataOwnedByAtlas) if (ConfigData[i].FontData && ConfigData[i].FontDataOwnedByAtlas)
{ {
IM_FREE(font_cfg.FontData); IM_FREE(ConfigData[i].FontData);
font_cfg.FontData = NULL; ConfigData[i].FontData = NULL;
} }
// When clearing this we lose access to the font name and other information used to build the font. // When clearing this we lose access to the font name and other information used to build the font.
for (ImFont* font : Fonts) for (int i = 0; i < Fonts.Size; i++)
if (font->ConfigData >= ConfigData.Data && font->ConfigData < ConfigData.Data + ConfigData.Size) if (Fonts[i]->ConfigData >= ConfigData.Data && Fonts[i]->ConfigData < ConfigData.Data + ConfigData.Size)
{ {
font->ConfigData = NULL; Fonts[i]->ConfigData = NULL;
font->ConfigDataCount = 0; Fonts[i]->ConfigDataCount = 0;
} }
ConfigData.clear(); ConfigData.clear();
CustomRects.clear(); CustomRects.clear();
@ -2505,8 +2090,6 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
if (new_font_cfg.DstFont->EllipsisChar == (ImWchar)-1) if (new_font_cfg.DstFont->EllipsisChar == (ImWchar)-1)
new_font_cfg.DstFont->EllipsisChar = font_cfg->EllipsisChar; new_font_cfg.DstFont->EllipsisChar = font_cfg->EllipsisChar;
ImFontAtlasUpdateConfigDataPointers(this);
// Invalidate texture // Invalidate texture
TexReady = false; TexReady = false;
ClearTexData(); ClearTexData();
@ -2543,7 +2126,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
if (font_cfg.Name[0] == '\0') if (font_cfg.Name[0] == '\0')
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf, %dpx", (int)font_cfg.SizePixels); ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf, %dpx", (int)font_cfg.SizePixels);
font_cfg.EllipsisChar = (ImWchar)0x0085; font_cfg.EllipsisChar = (ImWchar)0x0085;
font_cfg.GlyphOffset.y = 1.0f * IM_TRUNC(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units font_cfg.GlyphOffset.y = 1.0f * IM_FLOOR(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85(); const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault(); const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault();
@ -2573,14 +2156,13 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels,
} }
// NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build(). // NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build().
ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* font_data, int font_data_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges)
{ {
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
IM_ASSERT(font_cfg.FontData == NULL); IM_ASSERT(font_cfg.FontData == NULL);
IM_ASSERT(font_data_size > 100 && "Incorrect value for font_data_size!"); // Heuristic to prevent accidentally passing a wrong value to font_data_size. font_cfg.FontData = ttf_data;
font_cfg.FontData = font_data; font_cfg.FontDataSize = ttf_size;
font_cfg.FontDataSize = font_data_size;
font_cfg.SizePixels = size_pixels > 0.0f ? size_pixels : font_cfg.SizePixels; font_cfg.SizePixels = size_pixels > 0.0f ? size_pixels : font_cfg.SizePixels;
if (glyph_ranges) if (glyph_ranges)
font_cfg.GlyphRanges = glyph_ranges; font_cfg.GlyphRanges = glyph_ranges;
@ -2795,10 +2377,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found."); IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found.");
if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset))
{
IM_ASSERT(0 && "stbtt_InitFont(): failed to parse FontData. It is correct and complete? Check FontDataSize.");
return false; return false;
}
// Measure highest codepoints // Measure highest codepoints
ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex]; ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
@ -2880,7 +2459,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
// Convert our ranges in the format stb_truetype wants // Convert our ranges in the format stb_truetype wants
ImFontConfig& cfg = atlas->ConfigData[src_i]; ImFontConfig& cfg = atlas->ConfigData[src_i];
src_tmp.PackRange.font_size = cfg.SizePixels * cfg.RasterizerDensity; src_tmp.PackRange.font_size = cfg.SizePixels;
src_tmp.PackRange.first_unicode_codepoint_in_range = 0; src_tmp.PackRange.first_unicode_codepoint_in_range = 0;
src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data; src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data;
src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size; src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size;
@ -2889,7 +2468,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV; src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV;
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects) // Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
const float scale = (cfg.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity); const float scale = (cfg.SizePixels > 0) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels);
const int padding = atlas->TexGlyphPadding; const int padding = atlas->TexGlyphPadding;
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++) for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
{ {
@ -2985,14 +2564,12 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
int unscaled_ascent, unscaled_descent, unscaled_line_gap; int unscaled_ascent, unscaled_descent, unscaled_line_gap;
stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap); stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
const float ascent = ImCeil(unscaled_ascent * font_scale); const float ascent = ImFloor(unscaled_ascent * font_scale + ((unscaled_ascent > 0.0f) ? +1 : -1));
const float descent = ImFloor(unscaled_descent * font_scale); const float descent = ImFloor(unscaled_descent * font_scale + ((unscaled_descent > 0.0f) ? +1 : -1));
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
const float font_off_x = cfg.GlyphOffset.x; const float font_off_x = cfg.GlyphOffset.x;
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent); const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
const float inv_rasterization_scale = 1.0f / cfg.RasterizerDensity;
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++) for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
{ {
// Register glyph // Register glyph
@ -3001,11 +2578,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
stbtt_aligned_quad q; stbtt_aligned_quad q;
float unused_x = 0.0f, unused_y = 0.0f; float unused_x = 0.0f, unused_y = 0.0f;
stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &unused_x, &unused_y, &q, 0); stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &unused_x, &unused_y, &q, 0);
float x0 = q.x0 * inv_rasterization_scale + font_off_x; dst_font->AddGlyph(&cfg, (ImWchar)codepoint, q.x0 + font_off_x, q.y0 + font_off_y, q.x1 + font_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance);
float y0 = q.y0 * inv_rasterization_scale + font_off_y;
float x1 = q.x1 * inv_rasterization_scale + font_off_x;
float y1 = q.y1 * inv_rasterization_scale + font_off_y;
dst_font->AddGlyph(&cfg, (ImWchar)codepoint, x0, y0, x1, y1, q.s0, q.t0, q.s1, q.t1, pc.xadvance * inv_rasterization_scale);
} }
} }
@ -3025,31 +2598,19 @@ const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype()
#endif // IMGUI_ENABLE_STB_TRUETYPE #endif // IMGUI_ENABLE_STB_TRUETYPE
void ImFontAtlasUpdateConfigDataPointers(ImFontAtlas* atlas)
{
for (ImFontConfig& font_cfg : atlas->ConfigData)
{
ImFont* font = font_cfg.DstFont;
if (!font_cfg.MergeMode)
{
font->ConfigData = &font_cfg;
font->ConfigDataCount = 0;
}
font->ConfigDataCount++;
}
}
void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent) void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent)
{ {
if (!font_config->MergeMode) if (!font_config->MergeMode)
{ {
font->ClearOutputData(); font->ClearOutputData();
font->FontSize = font_config->SizePixels; font->FontSize = font_config->SizePixels;
IM_ASSERT(font->ConfigData == font_config); font->ConfigData = font_config;
font->ConfigDataCount = 0;
font->ContainerAtlas = atlas; font->ContainerAtlas = atlas;
font->Ascent = ascent; font->Ascent = ascent;
font->Descent = descent; font->Descent = descent;
} }
font->ConfigDataCount++;
} }
void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque) void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque)
@ -3196,13 +2757,6 @@ static void ImFontAtlasBuildRenderLinesTexData(ImFontAtlas* atlas)
// Note: this is called / shared by both the stb_truetype and the FreeType builder // Note: this is called / shared by both the stb_truetype and the FreeType builder
void ImFontAtlasBuildInit(ImFontAtlas* atlas) void ImFontAtlasBuildInit(ImFontAtlas* atlas)
{ {
// Round font size
// - We started rounding in 1.90 WIP (18991) as our layout system currently doesn't support non-rounded font size well yet.
// - Note that using io.FontGlobalScale or SetWindowFontScale(), with are legacy-ish, partially supported features, can still lead to unrounded sizes.
// - We may support it better later and remove this rounding.
for (ImFontConfig& cfg : atlas->ConfigData)
cfg.SizePixels = ImTrunc(cfg.SizePixels);
// Register texture region for mouse cursors or standard white pixels // Register texture region for mouse cursors or standard white pixels
if (atlas->PackIdMouseCursors < 0) if (atlas->PackIdMouseCursors < 0)
{ {
@ -3244,9 +2798,9 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
} }
// Build all fonts lookup tables // Build all fonts lookup tables
for (ImFont* font : atlas->Fonts) for (int i = 0; i < atlas->Fonts.Size; i++)
if (font->DirtyLookupTables) if (atlas->Fonts[i]->DirtyLookupTables)
font->BuildLookupTable(); atlas->Fonts[i]->BuildLookupTable();
atlas->TexReady = true; atlas->TexReady = true;
} }
@ -3611,7 +3165,6 @@ void ImFont::BuildLookupTable()
max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint);
// Build lookup table // Build lookup table
IM_ASSERT(Glyphs.Size > 0 && "Font has not loaded glyph!");
IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved
IndexAdvanceX.clear(); IndexAdvanceX.clear();
IndexLookup.clear(); IndexLookup.clear();
@ -3728,7 +3281,7 @@ void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, floa
advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX); advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX);
if (advance_x != advance_x_original) if (advance_x != advance_x_original)
{ {
float char_off_x = cfg->PixelSnapH ? ImTrunc((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f; float char_off_x = cfg->PixelSnapH ? ImFloor((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f;
x0 += char_off_x; x0 += char_off_x;
x1 += char_off_x; x1 += char_off_x;
} }
@ -3996,8 +3549,8 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
if (glyph->Colored) if (glyph->Colored)
col |= ~IM_COL32_A_MASK; col |= ~IM_COL32_A_MASK;
float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f;
float x = IM_TRUNC(pos.x); float x = IM_FLOOR(pos.x);
float y = IM_TRUNC(pos.y); float y = IM_FLOOR(pos.y);
draw_list->PrimReserve(6, 4); draw_list->PrimReserve(6, 4);
draw_list->PrimRectUV(ImVec2(x + glyph->X0 * scale, y + glyph->Y0 * scale), ImVec2(x + glyph->X1 * scale, y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); draw_list->PrimRectUV(ImVec2(x + glyph->X0 * scale, y + glyph->Y0 * scale), ImVec2(x + glyph->X1 * scale, y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col);
} }
@ -4009,8 +3562,8 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls. text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
// Align to be pixel perfect // Align to be pixel perfect
float x = IM_TRUNC(pos.x); float x = IM_FLOOR(pos.x);
float y = IM_TRUNC(pos.y); float y = IM_FLOOR(pos.y);
if (y > clip_rect.w) if (y > clip_rect.w)
return; return;
@ -4081,8 +3634,6 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
{ {
x = start_x; x = start_x;
y += line_height; y += line_height;
if (y > clip_rect.w)
break; // break out of main loop
word_wrap_eol = NULL; word_wrap_eol = NULL;
s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks
continue; continue;
@ -4312,8 +3863,8 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
} }
else else
{ {
draw_list->PathArcTo(ImVec2(x0, p1.y - rounding), rounding, IM_PI - arc0_e, IM_PI - arc0_b); // BL draw_list->PathArcTo(ImVec2(x0, p1.y - rounding), rounding, IM_PI - arc0_e, IM_PI - arc0_b, 3); // BL
draw_list->PathArcTo(ImVec2(x0, p0.y + rounding), rounding, IM_PI + arc0_b, IM_PI + arc0_e); // TR draw_list->PathArcTo(ImVec2(x0, p0.y + rounding), rounding, IM_PI + arc0_b, IM_PI + arc0_e, 3); // TR
} }
if (p1.x > rect.Min.x + rounding) if (p1.x > rect.Min.x + rounding)
{ {
@ -4332,8 +3883,8 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
} }
else else
{ {
draw_list->PathArcTo(ImVec2(x1, p0.y + rounding), rounding, -arc1_e, -arc1_b); // TR draw_list->PathArcTo(ImVec2(x1, p0.y + rounding), rounding, -arc1_e, -arc1_b, 3); // TR
draw_list->PathArcTo(ImVec2(x1, p1.y - rounding), rounding, +arc1_b, +arc1_e); // BR draw_list->PathArcTo(ImVec2(x1, p1.y - rounding), rounding, +arc1_b, +arc1_e, 3); // BR
} }
} }
draw_list->PathFillConvex(col); draw_list->PathFillConvex(col);
@ -4520,8 +4071,8 @@ static unsigned int stb_decompress(unsigned char *output, const unsigned char *i
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// ProggyClean.ttf // ProggyClean.ttf
// Copyright (c) 2004, 2005 Tristan Grimmer // Copyright (c) 2004, 2005 Tristan Grimmer
// MIT license (see License.txt in http://www.proggyfonts.net/index.php?menu=download) // MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip)
// Download and more information at http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php // Download and more information at http://upperbounds.net
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// File: 'ProggyClean.ttf' (41208 bytes) // File: 'ProggyClean.ttf' (41208 bytes)
// Exported using misc/fonts/binary_to_compressed_c.cpp (with compression + base85 string encoding). // Exported using misc/fonts/binary_to_compressed_c.cpp (with compression + base85 string encoding).

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,8 @@
// This is a slightly modified version of stb_textedit.h 1.14. // This is a slightly modified version of stb_textedit.h 1.14.
// Those changes would need to be pushed into nothings/stb: // Those changes would need to be pushed into nothings/stb:
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321) // - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783) // - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000)
// Grep for [DEAR IMGUI] to find the changes. // Grep for [DEAR IMGUI] to find the changes.
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
// stb_textedit.h - v1.14 - public domain - Sean Barrett // stb_textedit.h - v1.14 - public domain - Sean Barrett
// Development of this library was sponsored by RAD Game Tools // Development of this library was sponsored by RAD Game Tools
@ -31,7 +30,7 @@
// DEPENDENCIES // DEPENDENCIES
// //
// Uses the C runtime function 'memmove', which you can override // Uses the C runtime function 'memmove', which you can override
// by defining IMSTB_TEXTEDIT_memmove before the implementation. // by defining STB_TEXTEDIT_memmove before the implementation.
// Uses no other functions. Performs no runtime allocations. // Uses no other functions. Performs no runtime allocations.
// //
// //
@ -41,7 +40,7 @@
// 1.13 (2019-02-07) fix bug in undo size management // 1.13 (2019-02-07) fix bug in undo size management
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash // 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
// 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield // 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield
// 1.10 (2016-10-25) suppress warnings about casting away const with -Wcast-qual // 1.10 (2016-10-25) supress warnings about casting away const with -Wcast-qual
// 1.9 (2016-08-27) customizable move-by-word // 1.9 (2016-08-27) customizable move-by-word
// 1.8 (2016-04-02) better keyboard handling when mouse button is down // 1.8 (2016-04-02) better keyboard handling when mouse button is down
// 1.7 (2015-09-13) change y range handling in case baseline is non-0 // 1.7 (2015-09-13) change y range handling in case baseline is non-0
@ -275,8 +274,8 @@
//// ////
//// ////
#ifndef INCLUDE_IMSTB_TEXTEDIT_H #ifndef INCLUDE_STB_TEXTEDIT_H
#define INCLUDE_IMSTB_TEXTEDIT_H #define INCLUDE_STB_TEXTEDIT_H
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// //
@ -287,33 +286,33 @@
// and undo state. // and undo state.
// //
#ifndef IMSTB_TEXTEDIT_UNDOSTATECOUNT #ifndef STB_TEXTEDIT_UNDOSTATECOUNT
#define IMSTB_TEXTEDIT_UNDOSTATECOUNT 99 #define STB_TEXTEDIT_UNDOSTATECOUNT 99
#endif #endif
#ifndef IMSTB_TEXTEDIT_UNDOCHARCOUNT #ifndef STB_TEXTEDIT_UNDOCHARCOUNT
#define IMSTB_TEXTEDIT_UNDOCHARCOUNT 999 #define STB_TEXTEDIT_UNDOCHARCOUNT 999
#endif #endif
#ifndef IMSTB_TEXTEDIT_CHARTYPE #ifndef STB_TEXTEDIT_CHARTYPE
#define IMSTB_TEXTEDIT_CHARTYPE int #define STB_TEXTEDIT_CHARTYPE int
#endif #endif
#ifndef IMSTB_TEXTEDIT_POSITIONTYPE #ifndef STB_TEXTEDIT_POSITIONTYPE
#define IMSTB_TEXTEDIT_POSITIONTYPE int #define STB_TEXTEDIT_POSITIONTYPE int
#endif #endif
typedef struct typedef struct
{ {
// private data // private data
IMSTB_TEXTEDIT_POSITIONTYPE where; STB_TEXTEDIT_POSITIONTYPE where;
IMSTB_TEXTEDIT_POSITIONTYPE insert_length; STB_TEXTEDIT_POSITIONTYPE insert_length;
IMSTB_TEXTEDIT_POSITIONTYPE delete_length; STB_TEXTEDIT_POSITIONTYPE delete_length;
int char_storage; int char_storage;
} StbUndoRecord; } StbUndoRecord;
typedef struct typedef struct
{ {
// private data // private data
StbUndoRecord undo_rec [IMSTB_TEXTEDIT_UNDOSTATECOUNT]; StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT];
IMSTB_TEXTEDIT_CHARTYPE undo_char[IMSTB_TEXTEDIT_UNDOCHARCOUNT]; STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT];
short undo_point, redo_point; short undo_point, redo_point;
int undo_char_point, redo_char_point; int undo_char_point, redo_char_point;
} StbUndoState; } StbUndoState;
@ -372,7 +371,7 @@ typedef struct
float ymin,ymax; // height of row above and below baseline float ymin,ymax; // height of row above and below baseline
int num_chars; int num_chars;
} StbTexteditRow; } StbTexteditRow;
#endif //INCLUDE_IMSTB_TEXTEDIT_H #endif //INCLUDE_STB_TEXTEDIT_H
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -385,11 +384,11 @@ typedef struct
// implementation isn't include-guarded, since it might have indirectly // implementation isn't include-guarded, since it might have indirectly
// included just the "header" portion // included just the "header" portion
#ifdef IMSTB_TEXTEDIT_IMPLEMENTATION #ifdef STB_TEXTEDIT_IMPLEMENTATION
#ifndef IMSTB_TEXTEDIT_memmove #ifndef STB_TEXTEDIT_memmove
#include <string.h> #include <string.h>
#define IMSTB_TEXTEDIT_memmove memmove #define STB_TEXTEDIT_memmove memmove
#endif #endif
@ -399,7 +398,7 @@ typedef struct
// //
// traverse the layout to locate the nearest character to a display position // traverse the layout to locate the nearest character to a display position
static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y) static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
{ {
StbTexteditRow r; StbTexteditRow r;
int n = STB_TEXTEDIT_STRINGLEN(str); int n = STB_TEXTEDIT_STRINGLEN(str);
@ -459,7 +458,7 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
} }
// API click: on mouse down, move the cursor to the clicked location, and reset the selection // API click: on mouse down, move the cursor to the clicked location, and reset the selection
static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
{ {
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
// goes off the top or bottom of the text // goes off the top or bottom of the text
@ -477,7 +476,7 @@ static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *st
} }
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location // API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
{ {
int p = 0; int p = 0;
@ -503,11 +502,11 @@ static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *sta
// //
// forward declarations // forward declarations
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state); static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state); static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length); static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length); static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length); static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
typedef struct typedef struct
{ {
@ -519,7 +518,7 @@ typedef struct
// find the x/y location of a character, and remember info about the previous row in // find the x/y location of a character, and remember info about the previous row in
// case we get a move-up event (for page up, we'll have to rescan) // case we get a move-up event (for page up, we'll have to rescan)
static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING *str, int n, int single_line) static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line)
{ {
StbTexteditRow r; StbTexteditRow r;
int prev_start = 0; int prev_start = 0;
@ -550,10 +549,7 @@ static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING
i += r.num_chars; i += r.num_chars;
find->y += r.baseline_y_delta; find->y += r.baseline_y_delta;
if (i == z) // [DEAR IMGUI] if (i == z) // [DEAR IMGUI]
{
r.num_chars = 0; // [DEAR IMGUI]
break; // [DEAR IMGUI] break; // [DEAR IMGUI]
}
} }
find->first_char = first = i; find->first_char = first = i;
@ -570,7 +566,7 @@ static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) #define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
// make the selection/cursor state valid if client altered the string // make the selection/cursor state valid if client altered the string
static void stb_textedit_clamp(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state) static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{ {
int n = STB_TEXTEDIT_STRINGLEN(str); int n = STB_TEXTEDIT_STRINGLEN(str);
if (STB_TEXT_HAS_SELECTION(state)) { if (STB_TEXT_HAS_SELECTION(state)) {
@ -584,7 +580,7 @@ static void stb_textedit_clamp(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *st
} }
// delete characters while updating undo // delete characters while updating undo
static void stb_textedit_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len) static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
{ {
stb_text_makeundo_delete(str, state, where, len); stb_text_makeundo_delete(str, state, where, len);
STB_TEXTEDIT_DELETECHARS(str, where, len); STB_TEXTEDIT_DELETECHARS(str, where, len);
@ -592,7 +588,7 @@ static void stb_textedit_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *s
} }
// delete the section // delete the section
static void stb_textedit_delete_selection(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state) static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{ {
stb_textedit_clamp(str, state); stb_textedit_clamp(str, state);
if (STB_TEXT_HAS_SELECTION(state)) { if (STB_TEXT_HAS_SELECTION(state)) {
@ -629,7 +625,7 @@ static void stb_textedit_move_to_first(STB_TexteditState *state)
} }
// move cursor to last character of selection // move cursor to last character of selection
static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state) static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{ {
if (STB_TEXT_HAS_SELECTION(state)) { if (STB_TEXT_HAS_SELECTION(state)) {
stb_textedit_sortselection(state); stb_textedit_sortselection(state);
@ -641,13 +637,13 @@ static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditSt
} }
#ifdef STB_TEXTEDIT_IS_SPACE #ifdef STB_TEXTEDIT_IS_SPACE
static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx ) static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
{ {
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1; return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
} }
#ifndef STB_TEXTEDIT_MOVEWORDLEFT #ifndef STB_TEXTEDIT_MOVEWORDLEFT
static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c ) static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
{ {
--c; // always move at least one character --c; // always move at least one character
while( c >= 0 && !is_word_boundary( str, c ) ) while( c >= 0 && !is_word_boundary( str, c ) )
@ -662,7 +658,7 @@ static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c
#endif #endif
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT #ifndef STB_TEXTEDIT_MOVEWORDRIGHT
static int stb_textedit_move_to_word_next( IMSTB_TEXTEDIT_STRING *str, int c ) static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c )
{ {
const int len = STB_TEXTEDIT_STRINGLEN(str); const int len = STB_TEXTEDIT_STRINGLEN(str);
++c; // always move at least one character ++c; // always move at least one character
@ -689,7 +685,7 @@ static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
} }
// API cut: delete selection // API cut: delete selection
static int stb_textedit_cut(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state) static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{ {
if (STB_TEXT_HAS_SELECTION(state)) { if (STB_TEXT_HAS_SELECTION(state)) {
stb_textedit_delete_selection(str,state); // implicitly clamps stb_textedit_delete_selection(str,state); // implicitly clamps
@ -700,7 +696,7 @@ static int stb_textedit_cut(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state
} }
// API paste: replace existing selection with passed-in text // API paste: replace existing selection with passed-in text
static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE *text, int len) static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
{ {
// if there's a selection, the paste should delete it // if there's a selection, the paste should delete it
stb_textedit_clamp(str, state); stb_textedit_clamp(str, state);
@ -721,14 +717,14 @@ static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditS
#endif #endif
// API key: process a keyboard input // API key: process a keyboard input
static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key) static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
{ {
retry: retry:
switch (key) { switch (key) {
default: { default: {
int c = STB_TEXTEDIT_KEYTOTEXT(key); int c = STB_TEXTEDIT_KEYTOTEXT(key);
if (c > 0) { if (c > 0) {
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE) c; STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c;
// can't add newline in single-line mode // can't add newline in single-line mode
if (c == '\n' && state->single_line) if (c == '\n' && state->single_line)
@ -893,8 +889,8 @@ retry:
x = row.x0; x = row.x0;
for (i=0; i < row.num_chars; ++i) { for (i=0; i < row.num_chars; ++i) {
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i); float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE) if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
break; break;
#endif #endif
x += dx; x += dx;
@ -955,8 +951,8 @@ retry:
x = row.x0; x = row.x0;
for (i=0; i < row.num_chars; ++i) { for (i=0; i < row.num_chars; ++i) {
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i); float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE) if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
break; break;
#endif #endif
x += dx; x += dx;
@ -1113,8 +1109,8 @@ retry:
static void stb_textedit_flush_redo(StbUndoState *state) static void stb_textedit_flush_redo(StbUndoState *state)
{ {
state->redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT; state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
state->redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT; state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
} }
// discard the oldest entry in the undo list // discard the oldest entry in the undo list
@ -1126,13 +1122,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
int n = state->undo_rec[0].insert_length, i; int n = state->undo_rec[0].insert_length, i;
// delete n characters from all other records // delete n characters from all other records
state->undo_char_point -= n; state->undo_char_point -= n;
IMSTB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(IMSTB_TEXTEDIT_CHARTYPE))); STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=0; i < state->undo_point; ++i) for (i=0; i < state->undo_point; ++i)
if (state->undo_rec[i].char_storage >= 0) if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
} }
--state->undo_point; --state->undo_point;
IMSTB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0]))); STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
} }
} }
@ -1142,7 +1138,7 @@ static void stb_textedit_discard_undo(StbUndoState *state)
// fill up even though the undo buffer didn't // fill up even though the undo buffer didn't
static void stb_textedit_discard_redo(StbUndoState *state) static void stb_textedit_discard_redo(StbUndoState *state)
{ {
int k = IMSTB_TEXTEDIT_UNDOSTATECOUNT-1; int k = STB_TEXTEDIT_UNDOSTATECOUNT-1;
if (state->redo_point <= k) { if (state->redo_point <= k) {
// if the k'th undo state has characters, clean those up // if the k'th undo state has characters, clean those up
@ -1150,7 +1146,7 @@ static void stb_textedit_discard_redo(StbUndoState *state)
int n = state->undo_rec[k].insert_length, i; int n = state->undo_rec[k].insert_length, i;
// move the remaining redo character data to the end of the buffer // move the remaining redo character data to the end of the buffer
state->redo_char_point += n; state->redo_char_point += n;
IMSTB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((IMSTB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(IMSTB_TEXTEDIT_CHARTYPE))); STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
// adjust the position of all the other records to account for above memmove // adjust the position of all the other records to account for above memmove
for (i=state->redo_point; i < k; ++i) for (i=state->redo_point; i < k; ++i)
if (state->undo_rec[i].char_storage >= 0) if (state->undo_rec[i].char_storage >= 0)
@ -1158,12 +1154,12 @@ static void stb_textedit_discard_redo(StbUndoState *state)
} }
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point' // now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
// [DEAR IMGUI] // [DEAR IMGUI]
size_t move_size = (size_t)((IMSTB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0])); size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin; const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end; const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin); IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end); IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
IMSTB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size); STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
// now move redo_point to point to the new one // now move redo_point to point to the new one
++state->redo_point; ++state->redo_point;
@ -1177,32 +1173,32 @@ static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numch
// if we have no free records, we have to make room, by sliding the // if we have no free records, we have to make room, by sliding the
// existing records down // existing records down
if (state->undo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT) if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
stb_textedit_discard_undo(state); stb_textedit_discard_undo(state);
// if the characters to store won't possibly fit in the buffer, we can't undo // if the characters to store won't possibly fit in the buffer, we can't undo
if (numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT) { if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) {
state->undo_point = 0; state->undo_point = 0;
state->undo_char_point = 0; state->undo_char_point = 0;
return NULL; return NULL;
} }
// if we don't have enough free characters in the buffer, we have to make room // if we don't have enough free characters in the buffer, we have to make room
while (state->undo_char_point + numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT) while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT)
stb_textedit_discard_undo(state); stb_textedit_discard_undo(state);
return &state->undo_rec[state->undo_point++]; return &state->undo_rec[state->undo_point++];
} }
static IMSTB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len) static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
{ {
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len); StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
if (r == NULL) if (r == NULL)
return NULL; return NULL;
r->where = pos; r->where = pos;
r->insert_length = (IMSTB_TEXTEDIT_POSITIONTYPE) insert_len; r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len;
r->delete_length = (IMSTB_TEXTEDIT_POSITIONTYPE) delete_len; r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len;
if (insert_len == 0) { if (insert_len == 0) {
r->char_storage = -1; r->char_storage = -1;
@ -1214,7 +1210,7 @@ static IMSTB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos
} }
} }
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state) static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{ {
StbUndoState *s = &state->undostate; StbUndoState *s = &state->undostate;
StbUndoRecord u, *r; StbUndoRecord u, *r;
@ -1241,7 +1237,7 @@ static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
// characters stored for *undoing* don't leave room for redo // characters stored for *undoing* don't leave room for redo
// if the last is true, we have to bail // if the last is true, we have to bail
if (s->undo_char_point + u.delete_length >= IMSTB_TEXTEDIT_UNDOCHARCOUNT) { if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) {
// the undo records take up too much character space; there's no space to store the redo characters // the undo records take up too much character space; there's no space to store the redo characters
r->insert_length = 0; r->insert_length = 0;
} else { } else {
@ -1250,7 +1246,7 @@ static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
// there's definitely room to store the characters eventually // there's definitely room to store the characters eventually
while (s->undo_char_point + u.delete_length > s->redo_char_point) { while (s->undo_char_point + u.delete_length > s->redo_char_point) {
// should never happen: // should never happen:
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT) if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
return; return;
// there's currently not enough room, so discard a redo record // there's currently not enough room, so discard a redo record
stb_textedit_discard_redo(s); stb_textedit_discard_redo(s);
@ -1282,11 +1278,11 @@ static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
s->redo_point--; s->redo_point--;
} }
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state) static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{ {
StbUndoState *s = &state->undostate; StbUndoState *s = &state->undostate;
StbUndoRecord *u, r; StbUndoRecord *u, r;
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT) if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
return; return;
// we need to do two things: apply the redo record, and create an undo record // we need to do two things: apply the redo record, and create an undo record
@ -1338,20 +1334,20 @@ static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int le
stb_text_createundo(&state->undostate, where, 0, length); stb_text_createundo(&state->undostate, where, 0, length);
} }
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length) static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
{ {
int i; int i;
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0); STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
if (p) { if (p) {
for (i=0; i < length; ++i) for (i=0; i < length; ++i)
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
} }
} }
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length) static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
{ {
int i; int i;
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length); STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
if (p) { if (p) {
for (i=0; i < old_length; ++i) for (i=0; i < old_length; ++i)
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
@ -1363,8 +1359,8 @@ static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_lin
{ {
state->undostate.undo_point = 0; state->undostate.undo_point = 0;
state->undostate.undo_char_point = 0; state->undostate.undo_char_point = 0;
state->undostate.redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT; state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
state->undostate.redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT; state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
state->select_end = state->select_start = 0; state->select_end = state->select_start = 0;
state->cursor = 0; state->cursor = 0;
state->has_preferred_x = 0; state->has_preferred_x = 0;
@ -1387,16 +1383,16 @@ static void stb_textedit_initialize_state(STB_TexteditState *state, int is_singl
#pragma GCC diagnostic ignored "-Wcast-qual" #pragma GCC diagnostic ignored "-Wcast-qual"
#endif #endif
static int stb_textedit_paste(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE const *ctext, int len) static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len)
{ {
return stb_textedit_paste_internal(str, state, (IMSTB_TEXTEDIT_CHARTYPE *) ctext, len); return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len);
} }
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#endif//IMSTB_TEXTEDIT_IMPLEMENTATION #endif//STB_TEXTEDIT_IMPLEMENTATION
/* /*
------------------------------------------------------------------------------ ------------------------------------------------------------------------------

Some files were not shown because too many files have changed in this diff Show More