├── .github └── workflows │ ├── build_all.yml │ ├── linux.yml │ ├── linux_arm64.yml │ ├── linux_cross.yml │ ├── macos.yml │ └── windows.yml ├── .gitignore ├── .gitmodules ├── ChangeLog ├── LICENSE.txt ├── README.md ├── doc └── jpfont_test.png ├── examples ├── .gitkeep ├── about_window.rb ├── basic_usage.rb ├── basic_usage_layout.ini ├── basic_usage_sdl2_opengl2.rb ├── glfw3.dll ├── iconfont │ ├── README.md │ └── fontawesome-webfont.ttf ├── imgui_and_testgl2.rb ├── imnodes_basic_sdl2_opengl2.rb ├── imnodes_editable_sdl2_opengl2.rb ├── jpfont │ ├── GenShinGothic-Normal.ttf │ ├── README.md │ ├── README_GenShin.txt │ ├── SIL_Open_Font_License_1.1.txt │ └── jpfont.txt ├── libSDL2-2.0.dylib ├── libSDL2.dylib ├── libglfw.3.4.dylib ├── libglfw.3.dylib ├── libglfw.dylib ├── raylib_with_imgui.rb ├── test_glfw_opengl2.rb ├── test_glfw_opengl3.rb ├── test_sdl2_opengl2.rb ├── test_sdl2_opengl3.rb ├── test_sdl2_sdlrenderer.rb └── util │ ├── setup_dll.rb │ ├── setup_opengl_dll.rb │ └── setup_sdl2_dll.rb ├── generator ├── README.md ├── common.rb ├── dearbindings.json └── generate_imgui.rb ├── imgui-bindings.gemspec ├── imgui_dll ├── CMakeLists.txt ├── build_imgui_linux.sh ├── build_imgui_linux_cross.sh ├── build_imgui_macos.sh ├── build_imgui_windows.cmd ├── cimgui_internal.cpp ├── cimgui_internal.h └── imgui_dll_build_debug.sh ├── imnodes_dll ├── CMakeLists.txt ├── ImNodesCAPI.cpp ├── ImNodesCAPI.h ├── README.md ├── build_imnodes_linux.sh ├── build_imnodes_linux_cross.sh ├── build_imnodes_macos.sh └── build_imnodes_windows.cmd ├── lib ├── imgui.aarch64.so ├── imgui.arm64.dylib ├── imgui.dll ├── imgui.rb ├── imgui.x86_64.dylib ├── imgui.x86_64.so ├── imgui_impl_glfw.rb ├── imgui_impl_opengl2.rb ├── imgui_impl_opengl3.rb ├── imgui_impl_raylib.rb ├── imgui_impl_sdl2.rb ├── imgui_impl_sdlrenderer.rb ├── imgui_internal.rb ├── imnodes.aarch64.so ├── imnodes.arm64.dylib ├── imnodes.dll ├── imnodes.rb ├── imnodes.x86_64.dylib └── imnodes.x86_64.so ├── script ├── check_syntax.cmd ├── dearbindings_generate_schema.cmd ├── dearbindings_generate_schema.sh ├── gems_build.cmd ├── gems_build.sh ├── gems_push.cmd ├── gems_push.sh ├── rebuild_libs_linux.sh ├── rebuild_libs_linux_cross.sh ├── rebuild_libs_macos.sh └── rebuild_libs_windows.cmd └── third_party ├── glfw_build.bat ├── glfw_build.sh ├── glfw_build_linux.sh ├── sdl2_build_dll.cmd └── sdl2_build_dylib.sh /.github/workflows/build_all.yml: -------------------------------------------------------------------------------- 1 | name: Build all platforms 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | imgui_commit: 7 | description: 'ImGui SHA-1 commit hash to checkout' 8 | default: '' 9 | required: false 10 | imgui_branch: 11 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 12 | default: 'master' 13 | required: false 14 | fetch_depth: 15 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 16 | default: '1' 17 | required: false 18 | 19 | jobs: 20 | call-build-linux: 21 | uses: ./.github/workflows/linux.yml 22 | call-build-linux-arm64: 23 | needs: call-build-linux 24 | uses: ./.github/workflows/linux_arm64.yml 25 | call-build-macos: 26 | needs: call-build-linux-arm64 27 | uses: ./.github/workflows/macos.yml 28 | call-build-windows: 29 | needs: call-build-macos 30 | uses: ./.github/workflows/windows.yml 31 | -------------------------------------------------------------------------------- /.github/workflows/linux.yml: -------------------------------------------------------------------------------- 1 | name: Build (Linux) 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | imgui_commit: 7 | description: 'SHA-1 hash to checkout' 8 | default: '' 9 | required: false 10 | type: string 11 | imgui_branch: 12 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 13 | default: 'master' 14 | required: false 15 | type: string 16 | fetch_depth: 17 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 18 | default: '1' 19 | required: false 20 | type: string 21 | workflow_dispatch: 22 | inputs: 23 | imgui_commit: 24 | description: 'SHA-1 hash to checkout' 25 | default: '' 26 | required: false 27 | imgui_branch: 28 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 29 | default: 'master' 30 | required: false 31 | fetch_depth: 32 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 33 | default: '1' 34 | required: false 35 | 36 | jobs: 37 | build: 38 | permissions: 39 | contents: write 40 | runs-on: ubuntu-latest 41 | strategy: 42 | fail-fast: false 43 | max-parallel: 1 44 | 45 | steps: 46 | - name: Checkout 47 | uses: actions/checkout@v4 48 | with: 49 | ref: ${{github.ref}} 50 | fetch-depth: ${{ github.event.inputs.fetch_depth }} 51 | submodules: recursive 52 | 53 | # - name: Setup OpenGL 54 | # run: sudo apt -y install libopengl-dev libxrandr-dev mesa-common-dev libxinerama-dev libxcursor-dev libxi-dev 55 | 56 | - name: Checkout specific ImGui commit 57 | if: "${{ github.event.inputs.imgui_commit != ''}}" 58 | run: | 59 | cd imgui_dll/cimgui/imgui 60 | git fetch --all 61 | git switch ${{ github.event.inputs.imgui_branch }} 62 | git checkout -f --detach ${{ github.event.inputs.imgui_commit }} 63 | cd ../../.. 64 | 65 | - name: Install luajit 66 | continue-on-error: true 67 | run: | 68 | sudo apt install luajit 69 | luajit -v 70 | 71 | - name: Generate cimgui code 72 | run: | 73 | cd imgui_dll/cimgui/generator 74 | luajit generator.lua gcc "" 75 | cd ../../.. 76 | 77 | - name: Build imgui so 78 | run: | 79 | cd imgui_dll 80 | bash ./build_imgui_linux.sh 81 | cd .. 82 | 83 | - name: Build imnodes so 84 | run: | 85 | cd imnodes_dll 86 | bash ./build_imnodes_linux.sh 87 | cd .. 88 | 89 | - name: Commit new libraries 90 | continue-on-error: true 91 | run: | 92 | git config user.name "${GITHUB_ACTOR}" 93 | git config user.email "${GITHUB_ACTOR}" 94 | git add lib/* 95 | git commit -a -m "commit by ${GITHUB_ACTOR} via GitHub Actions" 96 | git push --force-with-lease -u origin ${{github.ref}} 97 | -------------------------------------------------------------------------------- /.github/workflows/linux_arm64.yml: -------------------------------------------------------------------------------- 1 | name: Build (Linux ARM64) 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | imgui_commit: 7 | description: 'SHA-1 hash to checkout' 8 | default: '' 9 | required: false 10 | type: string 11 | imgui_branch: 12 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 13 | default: 'master' 14 | required: false 15 | type: string 16 | fetch_depth: 17 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 18 | default: '1' 19 | required: false 20 | type: string 21 | workflow_dispatch: 22 | inputs: 23 | imgui_commit: 24 | description: 'SHA-1 hash to checkout' 25 | default: '' 26 | required: false 27 | imgui_branch: 28 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 29 | default: 'master' 30 | required: false 31 | fetch_depth: 32 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 33 | default: '1' 34 | required: false 35 | 36 | jobs: 37 | build: 38 | permissions: 39 | contents: write 40 | runs-on: ubuntu-22.04-arm 41 | strategy: 42 | fail-fast: false 43 | max-parallel: 1 44 | 45 | steps: 46 | - name: Checkout 47 | uses: actions/checkout@v4 48 | with: 49 | ref: ${{github.ref}} 50 | fetch-depth: ${{ github.event.inputs.fetch_depth }} 51 | submodules: recursive 52 | 53 | # - name: Setup OpenGL 54 | # run: sudo apt -y install libopengl-dev libxrandr-dev mesa-common-dev libxinerama-dev libxcursor-dev libxi-dev 55 | 56 | - name: Checkout specific ImGui commit 57 | if: "${{ github.event.inputs.imgui_commit != ''}}" 58 | run: | 59 | cd imgui_dll/cimgui/imgui 60 | git fetch --all 61 | git switch ${{ github.event.inputs.imgui_branch }} 62 | git checkout -f --detach ${{ github.event.inputs.imgui_commit }} 63 | cd ../../.. 64 | 65 | - name: Install luajit 66 | continue-on-error: true 67 | run: | 68 | sudo apt install luajit 69 | luajit -v 70 | 71 | - name: Generate cimgui code 72 | run: | 73 | cd imgui_dll/cimgui/generator 74 | luajit generator.lua gcc "" 75 | cd ../../.. 76 | 77 | - name: Build imgui so 78 | run: | 79 | cd imgui_dll 80 | bash ./build_imgui_linux.sh 81 | cd .. 82 | 83 | - name: Build imnodes so 84 | run: | 85 | cd imnodes_dll 86 | bash ./build_imnodes_linux.sh 87 | cd .. 88 | 89 | - name: Commit new libraries 90 | continue-on-error: true 91 | run: | 92 | git config user.name "${GITHUB_ACTOR}" 93 | git config user.email "${GITHUB_ACTOR}" 94 | git add lib/* 95 | git commit -a -m "commit by ${GITHUB_ACTOR} via GitHub Actions" 96 | git push --force-with-lease -u origin ${{github.ref}} 97 | -------------------------------------------------------------------------------- /.github/workflows/linux_cross.yml: -------------------------------------------------------------------------------- 1 | name: Build (Linux Cross) 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | imgui_commit: 7 | description: 'SHA-1 hash to checkout' 8 | default: '' 9 | required: false 10 | type: string 11 | imgui_branch: 12 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 13 | default: 'master' 14 | required: false 15 | type: string 16 | fetch_depth: 17 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 18 | default: '1' 19 | required: false 20 | type: string 21 | workflow_dispatch: 22 | inputs: 23 | imgui_commit: 24 | description: 'SHA-1 hash to checkout' 25 | default: '' 26 | required: false 27 | imgui_branch: 28 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 29 | default: 'master' 30 | required: false 31 | fetch_depth: 32 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 33 | default: '1' 34 | required: false 35 | 36 | jobs: 37 | build: 38 | permissions: 39 | contents: write 40 | runs-on: ubuntu-24.04 41 | strategy: 42 | fail-fast: false 43 | max-parallel: 1 44 | 45 | steps: 46 | - name: Update sources.list for cross compilation tools 47 | continue-on-error: true 48 | run: | 49 | # - https://askubuntu.com/a/1323570 50 | # Apt can't find packages on Ubuntu 20.04 arm64 (Raspberry Pi 4) 51 | # - https://askubuntu.com/questions/1255707/apt-cant-find-packages-on-ubuntu-20-04-arm64-raspberry-pi-4 52 | sudo dpkg --add-architecture arm64 53 | sudo touch /etc/apt/sources.list.d/arm-cross-compile-sources.list 54 | sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble main multiverse universe" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 55 | # sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble-security main multiverse universe" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 56 | sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble-backports main multiverse universe" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 57 | sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble-updates main multiverse universe" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 58 | sudo apt update 59 | 60 | # # Ref.: How to use apt-get to download multi-arch library? 61 | # # https://askubuntu.com/a/1323570 62 | # sudo dpkg --add-architecture arm64 63 | # sudo touch /etc/apt/sources.list.d/arm-cross-compile-sources.list 64 | # sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble main restricted" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 65 | # sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble-updates main restricted" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 66 | # sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble universe" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 67 | # sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble-updates universe" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 68 | # sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble multiverse" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 69 | # sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble-updates multiverse" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 70 | # sudo bash -c 'echo "deb [arch=arm64] http://ports.ubuntu.com/ noble-backports main restricted universe multiverse" >> /etc/apt/sources.list.d/arm-cross-compile-sources.list' 71 | # sudo apt update 72 | 73 | - name: Setup OpenGL and cross compilation tools 74 | run: | 75 | sudo apt -y install libc6-arm64-cross libc6-dev-arm64-cross libstdc++-12-dev-arm64-cross g++-12-aarch64-linux-gnu g++-aarch64-linux-gnu 76 | # sudo apt -y install libc6-dev-arm64-cross libstdc++-12-dev-arm64-cross g++-aarch64-linux-gnu 77 | # sudo apt -y install gcc-multilib g++-multilib libc6-dev-arm64-cross libstdc++-10-dev-arm64-cross g++-aarch64-linux-gnu 78 | # sudo apt -y install libopengl-dev:arm64 libxrandr-dev:arm64 mesa-common-dev:arm64 libxinerama-dev:arm64 libxcursor-dev:arm64 libxi-dev:arm64 79 | 80 | - name: Checkout 81 | uses: actions/checkout@v4 82 | with: 83 | ref: ${{github.ref}} 84 | fetch-depth: ${{ github.event.inputs.fetch_depth }} 85 | submodules: recursive 86 | 87 | - name: Checkout specific ImGui commit 88 | if: "${{ github.event.inputs.imgui_commit != ''}}" 89 | run: | 90 | cd imgui_dll/cimgui/imgui 91 | git fetch --all 92 | git switch ${{ github.event.inputs.imgui_branch }} 93 | git checkout -f --detach ${{ github.event.inputs.imgui_commit }} 94 | cd ../../.. 95 | 96 | - name: Install luajit 97 | continue-on-error: true 98 | run: | 99 | sudo apt install luajit 100 | luajit -v 101 | 102 | - name: Generate cimgui code 103 | run: | 104 | cd imgui_dll/cimgui/generator 105 | luajit generator.lua gcc "" 106 | cd ../../.. 107 | 108 | - name: Build imgui so 109 | run: | 110 | cd imgui_dll 111 | bash ./build_imgui_linux_cross.sh 112 | cd .. 113 | 114 | - name: Build imnodes so 115 | run: | 116 | cd imnodes_dll 117 | bash ./build_imnodes_linux_cross.sh 118 | cd .. 119 | 120 | - name: Commit new libraries 121 | continue-on-error: true 122 | run: | 123 | git config user.name "${GITHUB_ACTOR}" 124 | git config user.email "${GITHUB_ACTOR}" 125 | git add lib/* 126 | git commit -a -m "commit by ${GITHUB_ACTOR} via GitHub Actions" 127 | git push --force-with-lease -u origin ${{github.ref}} 128 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: Build (macOS) 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | imgui_commit: 7 | description: 'SHA-1 hash to checkout' 8 | default: '' 9 | required: false 10 | type: string 11 | imgui_branch: 12 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 13 | default: 'master' 14 | required: false 15 | type: string 16 | fetch_depth: 17 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 18 | default: '1' 19 | required: false 20 | type: string 21 | workflow_dispatch: 22 | inputs: 23 | imgui_commit: 24 | description: 'SHA-1 hash to checkout' 25 | default: '' 26 | required: false 27 | imgui_branch: 28 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 29 | default: 'master' 30 | required: false 31 | fetch_depth: 32 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 33 | default: '1' 34 | required: false 35 | 36 | jobs: 37 | build: 38 | permissions: 39 | contents: write 40 | runs-on: macos-latest 41 | strategy: 42 | fail-fast: false 43 | max-parallel: 1 44 | 45 | steps: 46 | - name: Install luajit 47 | run: | 48 | brew install luajit 49 | luajit -v 50 | 51 | - name: Checkout 52 | uses: actions/checkout@v4 53 | with: 54 | ref: ${{github.ref}} 55 | fetch-depth: ${{ github.event.inputs.fetch_depth }} 56 | submodules: recursive 57 | 58 | - name: Checkout specific ImGui commit 59 | if: "${{ github.event.inputs.imgui_commit != ''}}" 60 | run: | 61 | cd imgui_dll/cimgui/imgui 62 | git fetch --all 63 | git switch ${{ github.event.inputs.imgui_branch }} 64 | git checkout -f --detach ${{ github.event.inputs.imgui_commit }} 65 | cd ../../.. 66 | 67 | - name: Generate cimgui code 68 | run: | 69 | cd imgui_dll/cimgui/generator 70 | luajit generator.lua gcc "" 71 | cd ../../.. 72 | 73 | - name: Build imgui so 74 | run: | 75 | cd imgui_dll 76 | bash ./build_imgui_macos.sh 77 | cd .. 78 | 79 | - name: Build imnodes so 80 | run: | 81 | cd imnodes_dll 82 | bash ./build_imnodes_macos.sh 83 | cd .. 84 | 85 | - name: Commit new libraries 86 | continue-on-error: true 87 | run: | 88 | git config user.name "${GITHUB_ACTOR}" 89 | git config user.email "${GITHUB_ACTOR}" 90 | git add lib/* 91 | git commit -a -m "commit by ${GITHUB_ACTOR} via GitHub Actions" 92 | git push --force-with-lease -u origin ${{github.ref}} 93 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Build (Windows) 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | imgui_commit: 7 | description: 'SHA-1 hash to checkout' 8 | default: '' 9 | required: false 10 | type: string 11 | imgui_branch: 12 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 13 | default: 'master' 14 | required: false 15 | type: string 16 | fetch_depth: 17 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 18 | default: '1' 19 | required: false 20 | type: string 21 | workflow_dispatch: 22 | inputs: 23 | imgui_commit: 24 | description: 'SHA-1 hash to checkout' 25 | default: '' 26 | required: false 27 | imgui_branch: 28 | description: 'ImGui branch to checkout. If you change this value from default, please set `fetch_depth` to 0.' 29 | default: 'master' 30 | required: false 31 | fetch_depth: 32 | description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' 33 | default: '1' 34 | required: false 35 | 36 | jobs: 37 | build: 38 | permissions: 39 | contents: write 40 | runs-on: windows-latest 41 | strategy: 42 | fail-fast: false 43 | max-parallel: 1 44 | 45 | steps: 46 | - name: Checkout 47 | uses: actions/checkout@v4 48 | with: 49 | ref: ${{github.ref}} 50 | fetch-depth: ${{ github.event.inputs.fetch_depth }} 51 | submodules: recursive 52 | 53 | - name: Checkout specific ImGui commit 54 | if: "${{ github.event.inputs.imgui_commit != ''}}" 55 | run: | 56 | cd imgui_dll/cimgui/imgui 57 | git fetch --all 58 | git switch ${{ github.event.inputs.imgui_branch }} 59 | git checkout -f --detach ${{ github.event.inputs.imgui_commit }} 60 | cd ../../.. 61 | 62 | - name: Install MSYS2 luajit 63 | continue-on-error: true 64 | shell: cmd 65 | run: | 66 | C:\msys64\usr\bin\pacman -S --noconfirm mingw-w64-x86_64-luajit 67 | C:\msys64\mingw64\bin\luajit.exe -v 68 | 69 | - name: Generate cimgui code 70 | shell: cmd 71 | run: | 72 | cd imgui_dll\cimgui\generator 73 | C:\msys64\mingw64\bin\luajit.exe generator.lua gcc "" 74 | git diff 75 | cd ..\..\.. 76 | 77 | - name: Build imgui dll 78 | shell: cmd 79 | run: | 80 | cd imgui_dll 81 | build_imgui_windows.cmd cmake 82 | cd .. 83 | 84 | - name: Build imnodes dll 85 | shell: cmd 86 | run: | 87 | cd imnodes_dll 88 | build_imnodes_windows.cmd cmake 89 | cd .. 90 | 91 | - name: Commit new libraries 92 | continue-on-error: true 93 | run: | 94 | git config user.name "$env:GITHUB_ACTOR" 95 | git config user.email "$env:GITHUB_ACTOR" 96 | git add lib/* 97 | git commit -a -m "commit by $env:GITHUB_ACTOR via GitHub Actions" 98 | git push --force-with-lease -u origin ${{github.ref}} 99 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | archive/* 2 | backup/* 3 | imgui_dll/build/* 4 | imgui_dll/build_x86_64/* 5 | imgui_dll/build_arm64/* 6 | imgui_dll/bak/* 7 | imnodes_dll/build/* 8 | imnodes_dll/build_x86_64/* 9 | imnodes_dll/build_arm64/* 10 | imnodes_dll/bak/* 11 | implot_dll/build/* 12 | implot_dll/build_x86_64/* 13 | implot_dll/build_arm64/* 14 | implot_dll/bak/* 15 | third_party/SDL2-* 16 | third_party/glfw/* 17 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "cimgui"] 2 | path = imgui_dll/cimgui 3 | url = https://github.com/cimgui/cimgui.git 4 | branch = master 5 | [submodule "imnodes_dll/ImNodes"] 6 | path = imnodes_dll/ImNodes 7 | url = https://github.com/rokups/ImNodes.git 8 | [submodule "third_party/dear_bindings"] 9 | path = third_party/dear_bindings 10 | url = https://github.com/dearimgui/dear_bindings.git 11 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2025-02-02 vaiorabbit 2 | 3 | * ImGui v1.91.8-WIP 4 | 5 | 2025-01-01 vaiorabbit 6 | 7 | * ImGui v1.91.7-WIP 8 | 9 | 2024-09-22 vaiorabbit 10 | 11 | * ImGui v1.91.1 12 | 13 | 2024-08-04 vaiorabbit 14 | 15 | * ImGui v1.91.0 16 | 17 | 2024-07-14 vaiorabbit 18 | 19 | * ImGui v1.90.9 20 | 21 | 2024-04-13 vaiorabbit 22 | 23 | * ImGui v1.90.5 24 | 25 | 2024-02-25 vaiorabbit 26 | 27 | * ImGui v1.90.4 28 | 29 | 2024-01-12 vaiorabbit 30 | 31 | * ImGui v1.90.1 32 | 33 | 2023-12-10 vaiorabbit 34 | 35 | * macOS : Generate libraries for each platform 36 | 37 | 2023-11-19 vaiorabbit 38 | 39 | * ImGui v1.90.0 40 | 41 | 2023-09-09 vaiorabbit 42 | 43 | * ImGui v1.89.9 44 | * Added several structs 45 | 46 | 2023-08-10 vaiorabbit 47 | 48 | * ImGui v1.89.8 49 | 50 | 2023-07-29 vaiorabbit 51 | 52 | * ImGui v1.89.7 53 | 54 | 2023-07-02 vaiorabbit 55 | 56 | * ImGui v1.89.6 57 | 58 | 2023-04-15 vaiorabbit 59 | 60 | * ImGui v1.89.5 61 | 62 | 2023-03-19 vaiorabbit 63 | 64 | * ImGui v1.89.4 65 | 66 | 2023-02-23 vaiorabbit 67 | 68 | * ImGui v1.89.3 69 | * sample/basic_usage.rb: Added ImGui::SeparatorText demo 70 | 71 | 2023-01-09 vaiorabbit 72 | 73 | * Added Linux binaries (Only tested on aarch64 Chromebook Linux) 74 | 75 | 2023-01-08 vaiorabbit 76 | 77 | * Generate function comments in bindings codes 78 | 79 | 2023-01-07 vaiorabbit 80 | 81 | * ImGui v1.89.2 82 | 83 | 2023-01-04 vaiorabbit 84 | 85 | * lib/imgui_impl_raylib.rb: Removed codes manipulating blend function. Now it seems there's no need to do so. 86 | * imgui_dll/cimgui_internal.cpp: Internal functions I need are now imported manually 87 | 88 | 2022-12-25 vaiorabbit 89 | 90 | * ImGui v1.89.1 91 | 92 | 2022-08-14 vaiorabbit 93 | 94 | * Added ImNodes ( https://github.com/rokups/ImNodes ) support 95 | * Moved cimgui location 96 | * Removed unmaintained debug version of shared libraries 97 | * Added hand-written binding code for imgui_internal.h 98 | 99 | 2022-08-06 vaiorabbit 100 | 101 | * Fixed several warnings 102 | 103 | 2022-07-02 vaiorabbit 104 | 105 | * (macOS) ImGui 1.88 106 | * (Windows) ImGui 1.88 107 | * Updated tested Ruby version 108 | 109 | 2022-02-12 vaiorabbit 110 | 111 | * imgui_impl_sdl2.rb: Updated to use event API 112 | * imgui_impl_sdlrenderer.rb: Updated to use new API / Applied https://github.com/ocornut/imgui/commit/c39192ba6403d963d5983fa3e5973f5170cb0e31 113 | * imgui_impl_raylib.rb: Updated to use event API 114 | * basic_usage_sdl2_opengl2.rb: Updated to use new API 115 | * (Windows) ImGui 1.87 116 | 117 | 2022-02-11 vaiorabbit 118 | 119 | * (macOS) ImGui 1.87 120 | * imgui_impl_glfw.rb: Updated to use event API 121 | 122 | 2022-01-08 vaiorabbit 123 | 124 | * imgui_impl_raylib.rb: Added. Use this with Ruby raylib-bindings ( https://github.com/vaiorabbit/raylib-bindings ) 125 | 126 | 2022-01-07 vaiorabbit 127 | 128 | * Use opengl-bindings2 129 | 130 | 2022-01-01 vaiorabbit 131 | 132 | * imgui-bindings.gemspec: Added 133 | 134 | 2021-12-31 vaiorabbit 135 | 136 | * Added setup_dll.rb etc. for automatic library loading 137 | * Changed generator output paths 138 | * (Windows) Build binary with the latest ImGui 139 | 140 | 2021-12-26 vaiorabbit 141 | 142 | * (macOS) ImGui 1.86 143 | * imgui_impl_sdlrenderer.rb, sample/test_sdl2_sdlrenderer.rb: Temporary fix to render correctly 144 | 145 | 2021-12-15 vaiorabbit 146 | 147 | * imgui_impl_sdlrenderer.rb, sample/test_sdl2_sdlrenderer.rb: Added 148 | 149 | 2021-12-09 vaiorabbit 150 | 151 | * (macOS) ImGui 1.86 WIP 152 | 153 | 2021-10-16 vaiorabbit 154 | 155 | * (macOS) ImGui 1.85 156 | * basic_usage.rb: Added ImGuiDemo::StackToolWindow 157 | 158 | 2021-09-05 vaiorabbit 159 | 160 | * (macOS) ImGui 1.84.2 161 | 162 | 2021-08-22 vaiorabbit 163 | 164 | * (macOS) ImGui 1.84.1 165 | 166 | 2021-08-07 vaiorabbit 167 | 168 | * imgui_impl_sdl2.rb: Applied https://github.com/ocornut/imgui/commit/1cdd110eb41830ed3c852eade976a066946b7071 (See https://github.com/ocornut/imgui/pull/2696#issuecomment-889336981 ) 169 | * imgui_impl_glfw.rb: Applied https://github.com/ocornut/imgui/commit/044fd0cd2d976b31962689afa73c9824a6a08146 (See https://github.com/ocornut/imgui/pull/2696#issuecomment-889336981 ) 170 | 171 | 2021-07-05 vaiorabbit 172 | 173 | * imgui_impl_sdl2.rb: Partially applied changes in https://github.com/ocornut/imgui/commit/6792e1a3e08c30c6e9015cf51658d14f7872b10b https://github.com/ocornut/imgui/blob/6792e1a3e08c30c6e9015cf51658d14f7872b10b/backends/imgui_impl_sdl.cpp 174 | 175 | 2021-06-21 vaiorabbit 176 | 177 | * imgui_impl_opengl3.rb: Applied changes in https://github.com/ocornut/imgui/pull/4244 178 | 179 | 2021-06-20 vaiorabbit 180 | 181 | * (Windows) ImGui 1.83 182 | * (macOS) ImGui 1.83 183 | * (macOS) Build script now generates ARM64 binary 184 | * Added reference comments of arguments and return value 185 | * Several APIs now contain underscore in its name due to cimgui change (e.g. GetColorU32Col -> GetColorU32_Col) 186 | * (Experimental) Added overload functions (e.g.: ImGui::Combo, ImGui::MenuItem) 187 | 188 | 2021-03-27 vaiorabbit 189 | 190 | * (Windows) ImGui 1.82 191 | 192 | 2021-03-21 vaiorabbit 193 | 194 | * (macOS) ImGui 1.82 195 | 196 | 2021-02-20 vaiorabbit 197 | 198 | * Applied https://github.com/ocornut/imgui/commit/bda12e5fdd829e44e01a25aac015e156f3dad761 199 | 200 | 2021-02-12 vaiorabbit 201 | 202 | * (Windows) ImGui 1.81 203 | 204 | 2021-02-11 vaiorabbit 205 | 206 | * (macOS) ImGui 1.81 207 | * sample: Cleaned up Japanese font initialization 208 | 209 | 2021-02-07 vaiorabbit 210 | 211 | * (Windows) ImGui 1.80 212 | * (Windows) Built imgui.dll and imgui_debug.dll with: 213 | * ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x64-mingw32] 214 | * gcc (Rev6, Built by MSYS2 project) 10.2.0 215 | * (macOS) ImGui 1.80 216 | * (macOS) Built imgui.dylib with: 217 | * ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [arm64-darwin20] 218 | * Apple clang version 12.0.0 (clang-1200.0.32.29) / Target: arm64-apple-darwin20.2.0 219 | * imgui_impl_opengl2.rb, imgui_impl_opengl3.rb: Applied same changes made at https://github.com/ocornut/imgui/commit/7d5d5711c20d2448fb379de245ddc3b950289873 220 | * generator/generate_imgui.rb: Modified to handle exceptions 221 | 222 | 2020-12-20 vaiorabbit 223 | 224 | * third_party/glfw_build.sh, third_party/sdl2_build_dylib.sh: Modified/added to support x86_64|arm64 Universal Binary 225 | 226 | 2020-11-15 vaiorabbit 227 | 228 | * (Windows) ImGui 1.79 229 | * (macOS) ImGui 1.79 230 | 231 | 2020-08-24 vaiorabbit 232 | 233 | * (macOS) ImGui 1.78 234 | 235 | 2020-08-22 vaiorabbit 236 | 237 | * (Windows) ImGui 1.78 238 | * (Windows) Added imgui_debug.dll (Built with 'CMAKE_BUILD_TYPE=Debug') 239 | 240 | 2020-07-04 vaiorabbit 241 | 242 | * (Windows) ImGui 1.77 243 | 244 | 2020-06-14 vaiorabbit 245 | 246 | * imgui_impl_sdl2.rb: Fixed forcing 'include SDL2' 247 | 248 | 2020-06-12 vaiorabbit 249 | 250 | * basic_usage.rb: Fixed ImGui::End() mismatch 251 | 252 | 2020-06-11 vaiorabbit 253 | 254 | * imgui_impl_sdl2.rb: Renamed ImplSDL2_InitForOpenGL to ImplSDL2_Init 255 | 256 | 2020-05-13 vaiorabbit 257 | 258 | * 'Added support for pointer to struct. Now you can call like 'io[:Fonts].AddFontDefault()'. 259 | * Constructors now return FFI::Struct, not :pointer 260 | 261 | 2020-05-12 vaiorabbit 262 | 263 | * Added instance methods (e.g.: ImGui::FontAtlas_AddFontDefault(io[:Fonts]) -> ImFontAtlas.new(io[:Fonts]).AddFontDefault()) 264 | 265 | 2020-05-10 vaiorabbit 266 | 267 | * imgui_impl_opengl3.rb: Changed default GLSL version string from 130 to 150 (Ref.: https://github.com/ocornut/imgui/pull/3199 ) 268 | * generator: Read "stname", "constructor" and "destructor" from "definitions.json" 269 | 270 | 2020-05-05 vaiorabbit 271 | 272 | * Added ImDrawList support / Added ImColor.col32 273 | * Added support for ImFontConfig / Added icon font sample 274 | * Added support for FontGlyphRangesBuilder, ImWchar vector / Now constructors return :pointer 275 | * Added support for ImGuiTextFilter, etc. / public interfaces are changed a bit ("ImGuixxx" prefixes are omitted) 276 | * Fixed ImColor.create argument conversion 277 | * Fixed wrong default argument (sizeof(float)) 278 | * Added provisional callback signature analyzer / Added callback typedef generation 279 | * Added some CallbackData / Added ImGuiTypedefMapEntry for later use 280 | * Returns ImVec2/4/Color correctly / Added default augument values to ImVec2.create, etc. 281 | 282 | 2020-05-03 vaiorabbit 283 | 284 | * Added provisional ImGuiStyle_ methods 285 | * Added provisional ImGuiIO_ methods 286 | * Added sample/basic_usage_sdl2_opengl2.rb 287 | * (Windows) Catching up with ImGui 1.76 288 | 289 | 2020-04-19 vaiorabbit 290 | 291 | * Supported default value of public API arguments 292 | 293 | 2020-04-18 vaiorabbit 294 | 295 | * (macOS) Catching up with ImGui 1.76 296 | * Generate APIs as wrapper methods (to support default arguments/method overloading in the future) 297 | 298 | 2020-02-11 vaiorabbit 299 | 300 | * (macOS) Catching up with ImGui 1.75 301 | * Fixed wrong array argument generation (e.g. arguments like 'float[3]' are now converted into :pointer.) 302 | * Added OpenGL3 render backend (Note that this feature is only tested only on macOS) 303 | 304 | 2020-01-26 vaiorabbit 305 | 306 | * Applied changes made in https://github.com/ocornut/imgui/commit/f6da5000bfaf3a035e8d8a7db9b5150644f4630b 307 | "Backends: OpenGL2: Explicitly backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications." 308 | 309 | 2019-11-27 vaiorabbit 310 | 311 | * (macOS) Catching up with ImGui 1.74 312 | 313 | 2019-11-02 vaiorabbit 314 | 315 | * (Windows) Catching up with ImGui 1.73 316 | 317 | 2019-10-25 vaiorabbit 318 | 319 | * (macOS) Catching up with ImGui 1.73 320 | 321 | 2019-09-11 vaiorabbit 322 | 323 | * Revised folder structures 324 | * Moved some older codes into backup/ 325 | 326 | 2019-09-01 vaiorabbit 327 | 328 | * Design change: Libraries are separated into imgui.rb, imgui_impl_glfw.rb and imgui_impl_opengl2.rb 329 | * See sample/test_glfw_opengl2.rb for new usage 330 | * imgui_impl_sdl2.rb, sample/test_sdl2_opengl2.rb, sample/imgui_and_testgl2.rb: Added. 331 | * Note that imgui_glfw_opengl2.rb will not be supported any more. 332 | 333 | 2019-08-25 vaiorabbit 334 | 335 | * Revised folder names 336 | 337 | 2019-08-20 vaiorabbit 338 | 339 | * linux build tweak https://github.com/vaiorabbit/ruby-imgui/pull/1 (Thanks: Jake Vandereay https://github.com/lunarfyre7) 340 | 341 | 2019-08-03 vaiorabbit 342 | 343 | * (Windows) Catching up with ImGui 1.72 344 | * `imgui_glfw_opengl2.dll` was built against ruby 2.6.0p0 (2018-12-25 revision 66547) [x64-mingw32]. 345 | 346 | 2019-07-29 vaiorabbit 347 | 348 | * (macOS) Catching up with ImGui 1.72 349 | 350 | 2019-07-28 vaiorabbit 351 | 352 | * (macOS) Catching up with ImGui 1.71 353 | 354 | 2019-06-09 vaiorabbit 355 | 356 | * (macOS) Catching up with ImGui 1.70 357 | 358 | 2019-03-24 vaiorabbit 359 | 360 | * (macOS) Catching up with ImGui 1.69 361 | 362 | 2019-02-22 vaiorabbit 363 | 364 | * (macOS) Catching up with ImGui 1.68 365 | 366 | 2019-01-15 vaiorabbit 367 | 368 | * Catching up with ImGui 1.67 369 | 370 | 2019-01-14 vaiorabbit 371 | 372 | * ImFont, ImFontAtlas (imgui_glfw_opengl2.rb): Added 373 | 374 | 2019-01-13 vaiorabbit 375 | 376 | * Tested on Windows. 377 | * cimgui_build.sh, cimgui_build.bat: Added. 378 | 379 | 2019-01-06 vaiorabbit 380 | 381 | * ImGuiBindings.build_ffi_typedef_map(common.rb): Changed usage 382 | * imgui_glfw_opengl2.dylib: Specified the terms of use. 383 | 384 | 2019-01-05 vaiorabbit 385 | 386 | * initial commmit 387 | * Fixed API names (ex. igShowDemoWindow -> ImGui::ShowDemoWindow) 388 | * [Fixed] Failed to generate array type member of struct. 389 | * Added Japanese font loading & rendering example (test.rb) 390 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Ruby-ImGui : Yet another ImGui wrapper for Ruby 2 | Copyright (c) 2019-2025 vaiorabbit 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source 21 | distribution. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Yet another ImGui wrapper for Ruby # 4 | 5 | * Created : 2019-01-05 6 | * Last modified : 2025-02-02 7 | 8 | 9 | 10 | ## Prerequisites ## 11 | 12 | * Ruby interpreter 13 | * Tested on: 14 | * [Windows] https://rubyinstaller.org/downloads/ Ruby+Devkit 15 | * ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x64-mingw-ucrt] 16 | * [macOS] 17 | * ruby 3.3.3 (2024-06-12 revision f1c7b6f435) [arm64-darwin23] 18 | * [Linux] 19 | * ruby 3.2.0 (2022-12-25 revision a528908271) [aarch64-linux] 20 | * Ruby Gems 21 | * opengl-bindings2 22 | * gem install opengl-bindings2 23 | * ffi 24 | * gem install ffi 25 | * Compiler 26 | * Tested on: 27 | * [Windows] gcc (Rev2, Built by MSYS2 project) 14.2.0 28 | * [macOS] Apple clang version 15.0.0 (clang-1500.3.9.4) 29 | * [Linux] gcc (Debian 10.2.1-6) 10.2.1 20210110 30 | * CMake https://cmake.org/download/ 31 | 32 |
33 | Older versions 34 | 35 | * Ruby interpreter 36 | * Tested on: 37 | * [Windows] https://rubyinstaller.org/downloads/ Ruby+Devkit 38 | * ruby 3.2.0 (2022-12-25 revision a528908271) [x64-mingw-ucrt] 39 | * ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x64-mingw-ucrt] 40 | * ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x64-mingw32] 41 | * ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x64-mingw32] 42 | * ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x64-mingw32] 43 | * [macOS] 44 | * ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] 45 | * ruby 3.2.1 (2023-02-08 revision 31819e82c8) [arm64-darwin22] 46 | * ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin21] 47 | * ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [arm64-darwin21] 48 | * ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [arm64-darwin21] 49 | * ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [arm64-darwin20] 50 | * ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [arm64-darwin20] 51 | * ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [arm64-darwin20] 52 | * ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [arm64-darwin20] 53 | * ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-darwin19] 54 | * ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-darwin18] 55 | 56 | * Compiler 57 | * Tested on: 58 | * [Windows] gcc (Rev7, Built by MSYS2 project) 12.2.0 59 | * [Windows] gcc (Rev10, Built by MSYS2 project) 11.2.0 60 | * [Windows] gcc (Rev1, Built by MSYS2 project) 8.2.1 20181214 61 | * [macOS] Apple clang version 14.0.0 (clang-1400.0.29.202), Target: arm64-apple-darwin22.2.0 62 | * [macOS] clang (Apple clang version 13.1.6 (clang-1316.0.21.2.5), Target: arm64-apple-darwin21.5.0) 63 | * [macOS] clang (Apple clang version 12.0.5 (clang-1205.0.22.11), Target: arm64-apple-darwin20.6.0) 64 |
65 | 66 | ## Setting up and run sample ## 67 | 68 | 1. Install pre-built binaries 69 | * $ gem install imgui-bindings 70 | 2. Get GLFW or SDL2 71 | * put dylib/dll/so into sample/ 72 | 4. Run test.rb 73 | * cd sample/ 74 | * ruby test_glfw_opengl2.rb (GLFW) 75 | * ruby test_sld2_opengl2.rb (SDL2) 76 | 77 | ## Building binaries ## 78 | 79 | 1. Update submodules 80 | * git submodule update --recursive --remote 81 | 2. Update cimgui.c and cimgui.h 82 | * $ cd imgui_dll/cimgui/generator 83 | * $ luajit ./generator.lua clang "" 84 | 3. Build library 85 | * Use build_imgui_macos.sh, etc. 86 | 87 | ## License ## 88 | 89 | All shared libraries found in `lib` directory are built on top of these products and are available under the terms of the MIT License. 90 | * cimgui ( https://github.com/cimgui/cimgui ) 91 | * https://github.com/cimgui/cimgui/blob/master/LICENSE 92 | * Dear ImGui ( https://github.com/ocornut/imgui ) 93 | * https://github.com/ocornut/imgui/blob/master/LICENSE.txt 94 | * ImNodes ( https://github.com/rokups/ImNodes ) 95 | * https://github.com/rokups/ImNodes/blob/master/LICENSE 96 | 97 | All ruby codes here are available under the terms of the zlib/libpng License ( http://opensource.org/licenses/Zlib ). 98 | 99 | ``` 100 | Ruby-Imgui : Yet another ImGui wrapper for Ruby 101 | Copyright (c) 2019-2025 vaiorabbit 102 | 103 | This software is provided 'as-is', without any express or implied 104 | warranty. In no event will the authors be held liable for any damages 105 | arising from the use of this software. 106 | 107 | Permission is granted to anyone to use this software for any purpose, 108 | including commercial applications, and to alter it and redistribute it 109 | freely, subject to the following restrictions: 110 | 111 | 1. The origin of this software must not be misrepresented; you must not 112 | claim that you wrote the original software. If you use this software 113 | in a product, an acknowledgment in the product documentation would be 114 | appreciated but is not required. 115 | 116 | 2. Altered source versions must be plainly marked as such, and must not be 117 | misrepresented as being the original software. 118 | 119 | 3. This notice may not be removed or altered from any source 120 | distribution. 121 | ``` 122 | -------------------------------------------------------------------------------- /doc/jpfont_test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/doc/jpfont_test.png -------------------------------------------------------------------------------- /examples/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/examples/.gitkeep -------------------------------------------------------------------------------- /examples/about_window.rb: -------------------------------------------------------------------------------- 1 | # Ref.: imgui_demo.cpp (v1.76) 2 | # https://github.com/ocornut/imgui/blob/v1.76/imgui_demo.cpp 3 | 4 | module ImGuiDemo 5 | 6 | # ShowAboutWindow 7 | @@show_config_info = FFI::MemoryPointer.new(:bool, 1) 8 | 9 | def self.ShowAboutWindow(p_open) 10 | ImGui::Begin("About Dear ImGui", p_open, ImGuiWindowFlags_AlwaysAutoResize) 11 | ImGui::Text("Dear ImGui, %s", :pointer, ImGui::GetVersion()) 12 | ImGui::Separator() 13 | ImGui::Text("By Omar Cornut and all dear imgui contributors.") 14 | ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information.") 15 | 16 | ImGui::Checkbox("Config/Build Information", @@show_config_info) 17 | if @@show_config_info.read(:bool) == true 18 | io = ImGuiIO.new(ImGui::GetIO()) 19 | style = ImGuiStyle.new(ImGui::GetStyle()) 20 | 21 | cfginfos_frame = ImVec2.create(0, ImGui::GetTextLineHeightWithSpacing() * 18) 22 | copy_to_clipboard = ImGui::Button("Copy to clipboard") 23 | ImGui::BeginChildFrame(ImGui::GetID("cfginfos"), cfginfos_frame, ImGuiWindowFlags_NoMove) 24 | max_depth = -1 25 | ImGui::LogToClipboard(max_depth) if copy_to_clipboard 26 | 27 | ImGui::Text("Dear ImGui %s", :pointer, ImGui::GetVersion().read_string()) 28 | ImGui::Separator(); 29 | 30 | ImGui::Text("io.ConfigFlags: 0x%08X", :uint, io[:ConfigFlags]) 31 | ImGui::Text(" NavEnableKeyboard") if (io[:ConfigFlags] & ImGuiConfigFlags_NavEnableKeyboard) != 0 32 | ImGui::Text(" NavEnableGamepad") if (io[:ConfigFlags] & ImGuiConfigFlags_NavEnableGamepad) != 0 33 | ImGui::Text(" NavEnableSetMousePos") if (io[:ConfigFlags] & ImGuiConfigFlags_NavEnableSetMousePos) != 0 34 | ImGui::Text(" NavNoCaptureKeyboard") if (io[:ConfigFlags] & ImGuiConfigFlags_NavNoCaptureKeyboard) != 0 35 | ImGui::Text(" NoMouse") if (io[:ConfigFlags] & ImGuiConfigFlags_NoMouse) != 0 36 | ImGui::Text(" NoMouseCursorChange") if (io[:ConfigFlags] & ImGuiConfigFlags_NoMouseCursorChange) != 0 37 | ImGui::Text(" IsSRGB") if (io[:ConfigFlags] & ImGuiConfigFlags_IsSRGB) != 0 38 | ImGui::Text(" IsTouchScreen") if (io[:ConfigFlags] & ImGuiConfigFlags_IsTouchScreen) != 0 39 | ImGui::Text(" MouseDrawCursor") if io[:MouseDrawCursor] 40 | ImGui::Text(" ConfigMacOSXBehaviors") if io[:ConfigMacOSXBehaviors] 41 | ImGui::Text(" ConfigInputTextCursorBlink") if io[:ConfigInputTextCursorBlink] 42 | ImGui::Text(" ConfigResizeWindowsFromEdges") if io[:ConfigWindowsResizeFromEdges] 43 | ImGui::Text("io.BackendFlags: 0x%08X", :uint, io[:BackendFlags]) 44 | ImGui::Text(" HasGamepad") if (io[:BackendFlags] & ImGuiBackendFlags_HasGamepad) != 0 45 | ImGui::Text(" HasMouseCursors") if (io[:BackendFlags] & ImGuiBackendFlags_HasMouseCursors) != 0 46 | ImGui::Text(" HasSetMousePos") if (io[:BackendFlags] & ImGuiBackendFlags_HasSetMousePos) != 0 47 | ImGui::Text("io.BackendPlatformName: %s", :pointer, io[:BackendPlatformName] != nil ? io[:BackendPlatformName].read_string_to_null : "NULL") 48 | ImGui::Text("io.BackendRendererName: %s", :pointer, io[:BackendRendererName] != nil ? io[:BackendRendererName].read_string_to_null : "NULL") 49 | 50 | ImGui::Separator() 51 | font_atlas = io[:Fonts] 52 | ImGui::Text("io.Fonts: %d fonts, Flags: 0x%08X, TexSize: %d,%d", :int, font_atlas[:Fonts][:Size], :uint, font_atlas[:Flags], :int, font_atlas[:TexWidth], :int, font_atlas[:TexHeight]) 53 | ImGui::Text("io.DisplaySize: %.2f,%.2f", :float, io[:DisplaySize][:x], :float, io[:DisplaySize][:y]) 54 | ImGui::Separator() 55 | ImGui::Text("style[:WindowPadding]: %.2f,%.2f", :float, style[:WindowPadding][:x], :float, style[:WindowPadding][:y]) 56 | ImGui::Text("style.WindowBorderSize: %.2f", :float, style[:WindowBorderSize]) 57 | ImGui::Text("style.FramePadding: %.2f,%.2f", :float, style[:FramePadding][:x], :float, style[:FramePadding][:y]) 58 | ImGui::Text("style.FrameRounding: %.2f", :float, style[:FrameRounding]) 59 | ImGui::Text("style.FrameBorderSize: %.2f", :float, style[:FrameBorderSize]) 60 | ImGui::Text("style.ItemSpacing: %.2f,%.2f", :float, style[:ItemSpacing][:x], :float, style[:ItemSpacing][:y]) 61 | ImGui::Text("style.ItemInnerSpacing: %.2f,%.2f", :float, style[:ItemInnerSpacing][:x], :float, style[:ItemInnerSpacing][:y]) 62 | 63 | ImGui::LogFinish() if copy_to_clipboard 64 | ImGui::EndChildFrame() 65 | end 66 | 67 | ImGui::End() 68 | end 69 | 70 | end # module ImGuiDemo 71 | 72 | -------------------------------------------------------------------------------- /examples/basic_usage_layout.ini: -------------------------------------------------------------------------------- 1 | [Window][ウィンドウタイトル] 2 | Pos=2,25 3 | Size=288,321 4 | Collapsed=0 5 | 6 | [Window][別のウィンドウ] 7 | Pos=60,60 8 | Size=189,69 9 | Collapsed=0 10 | 11 | [Window][ボタンとチェックボックス] 12 | Pos=4,347 13 | Size=215,58 14 | Collapsed=0 15 | 16 | [Window][別のウィンドウ@ボタンとチェックボックス] 17 | Pos=227,344 18 | Size=320,59 19 | Collapsed=0 20 | 21 | [Window][ラジオボタン] 22 | Pos=4,408 23 | Size=385,81 24 | Collapsed=0 25 | 26 | [Window][長押しで急増/急減する三角矢印ボタン] 27 | Pos=7,492 28 | Size=273,61 29 | Collapsed=0 30 | 31 | [Window][ドロップダウンリストと文章入力欄/数字入力欄] 32 | Pos=5,604 33 | Size=453,265 34 | Collapsed=0 35 | 36 | [Window][スライダー] 37 | Pos=304,5 38 | Size=503,420 39 | Collapsed=0 40 | 41 | [Window][スライダー(2)] 42 | Pos=292,216 43 | Size=488,143 44 | Collapsed=0 45 | 46 | [Window][スライダー(1)] 47 | Pos=292,23 48 | Size=487,192 49 | Collapsed=0 50 | 51 | [Window][スライダー(3)] 52 | Pos=396,399 53 | Size=173,198 54 | Collapsed=0 55 | 56 | [Window][enum選択UIとカラー選択UI] 57 | Pos=7,885 58 | Size=286,142 59 | Collapsed=0 60 | 61 | [Window][リストボックス/複数選択] 62 | Pos=461,607 63 | Size=354,425 64 | Collapsed=0 65 | 66 | [Window][文章入力欄] 67 | Pos=783,24 68 | Size=316,251 69 | Collapsed=0 70 | 71 | [Window][ツリーノード] 72 | Pos=785,280 73 | Size=300,150 74 | Collapsed=0 75 | 76 | [Window][ツールチップ/ポップアップ] 77 | Pos=569,361 78 | Size=211,83 79 | Collapsed=0 80 | 81 | [Window][折れ線グラフ・ヒストグラム・プログレスバー] 82 | Pos=571,444 83 | Size=321,165 84 | Collapsed=0 85 | 86 | [Window][子ウィンドウ] 87 | Pos=902,589 88 | Size=386,325 89 | Collapsed=0 90 | 91 | [Window][タブ] 92 | Pos=818,933 93 | Size=651,93 94 | Collapsed=0 95 | 96 | [Window][文字検索機能・フィルタリング] 97 | Pos=1103,26 98 | Size=388,477 99 | Collapsed=0 100 | 101 | [Window][メインメニューバー] 102 | Pos=856,317 103 | Size=490,157 104 | Collapsed=0 105 | 106 | [Window][クリッピング/ダミー] 107 | Pos=1313,505 108 | Size=216,245 109 | Collapsed=0 110 | 111 | [Window][Debug##Default] 112 | Pos=60,60 113 | Size=400,400 114 | Collapsed=0 115 | 116 | [Window][ポップアップ] 117 | Pos=1317,767 118 | Size=118,68 119 | Collapsed=0 120 | 121 | [Window][Dear ImGui Stack Tool] 122 | Pos=1493,28 123 | Size=335,153 124 | Collapsed=0 125 | 126 | [Window][セパレーター] 127 | Pos=908,447 128 | Size=178,104 129 | Collapsed=0 130 | 131 | -------------------------------------------------------------------------------- /examples/basic_usage_sdl2_opengl2.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | require_relative 'util/setup_dll' 4 | require_relative 'util/setup_opengl_dll' 5 | require_relative 'util/setup_sdl2_dll' 6 | 7 | require_relative './basic_usage' 8 | 9 | WINDOW_W = 1920 10 | WINDOW_H = 1080 11 | 12 | if __FILE__ == $PROGRAM_NAME 13 | 14 | success = SDL.Init(SDL::INIT_VIDEO | SDL::INIT_TIMER | SDL::INIT_GAMECONTROLLER) 15 | exit if success < 0 16 | 17 | # Setup window 18 | SDL.GL_SetAttribute(SDL::GL_DOUBLEBUFFER, 1) 19 | SDL.GL_SetAttribute(SDL::GL_DEPTH_SIZE, 24) 20 | SDL.GL_SetAttribute(SDL::GL_STENCIL_SIZE, 8) 21 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_MAJOR_VERSION, 2) 22 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_MINOR_VERSION, 2) 23 | window_flags = (SDL::WINDOW_OPENGL | SDL::WINDOW_RESIZABLE | SDL::WINDOW_ALLOW_HIGHDPI) 24 | window = SDL.CreateWindow("Ruby-ImGui (SDL2+OpenGL)", 0, 0, WINDOW_W, WINDOW_H, window_flags) 25 | gl_context = SDL.GL_CreateContext(window) 26 | SDL.GL_MakeCurrent(window, gl_context) 27 | SDL.GL_SetSwapInterval(1) # Enable vsync 28 | 29 | GL.load_lib() 30 | 31 | # Setup Dear ImGui context 32 | ImGui::CreateContext() 33 | io = ImGuiDemo::GetIO() 34 | # Load layout information fromm file, but never overwrite it 35 | ImGui::LoadIniSettingsFromDisk("./basic_usage_layout.ini") 36 | io[:IniFilename] = nil # FFI::MemoryPointer.from_string("./basic_usage_layout.ini") 37 | io[:WantSaveIniSettings] = false 38 | 39 | # Setup Dear ImGui style 40 | ImGui::StyleColorsDark() 41 | 42 | # Setup Platform/Renderer bindings 43 | ImGui::ImplSDL2_Init(window, nil) 44 | ImGui::ImplOpenGL2_Init() 45 | 46 | ImGuiDemo::AddFont('./jpfont/GenShinGothic-Normal.ttf', './iconfont/fontawesome-webfont.ttf') 47 | ImGuiDemo::SetGlobalScale(0.8) 48 | 49 | event = SDL::Event.new 50 | done = false 51 | until done 52 | while SDL.PollEvent(event) != 0 53 | ImGui::ImplSDL2_ProcessEvent(event) 54 | done = true if event[:type] == SDL::QUIT 55 | 56 | # 'type' and 'timestamp' are common members for all SDL Event structs. 57 | event_type = event[:common][:type] 58 | 59 | # puts "Event : type=0x#{event_type.to_s(16)}, timestamp=#{event_timestamp}" 60 | case event_type 61 | when SDL::KEYDOWN 62 | if event[:key][:keysym][:sym] == SDL::SDLK_ESCAPE 63 | done = true 64 | end 65 | end 66 | end 67 | 68 | # Start the Dear ImGui frame 69 | ImGui::ImplOpenGL2_NewFrame() 70 | ImGui::ImplSDL2_NewFrame() 71 | ImGui::NewFrame() 72 | 73 | ImGuiDemo::BasicWindow::Show() 74 | ImGuiDemo::ButtonAndCheckboxWindow::Show() 75 | ImGuiDemo::RadioButtonWindow::Show() 76 | ImGuiDemo::ArrowButtonWindow::Show() 77 | ImGuiDemo::DropdownListAndInputWindow::Show() 78 | ImGuiDemo::SlidersWindow1::Show() 79 | ImGuiDemo::SlidersWindow2::Show() 80 | ImGuiDemo::SlidersWindow3::Show() 81 | ImGuiDemo::EnumAndColorSelectionWindow::Show() 82 | ImGuiDemo::ListBoxWindow::Show() 83 | ImGuiDemo::InputTextWindow::Show() 84 | ImGuiDemo::TreeNodeWindow::Show() 85 | ImGuiDemo::TooltipAndPopupWindow::Show() 86 | ImGuiDemo::PlotAndProgressWindow::Show() 87 | ImGuiDemo::ChildWindow::Show() 88 | ImGuiDemo::TabWindow::Show() 89 | ImGuiDemo::SearchWindow::Show() 90 | ImGuiDemo::MainMenuBarWindow::Show() 91 | ImGuiDemo::ClippingAndDummyWindow::Show() 92 | ImGuiDemo::StackToolWindow::Show() 93 | ImGuiDemo::SeparatorTextWindow::Show() 94 | ok_clicked = ImGuiDemo::PopupWindow::Show() 95 | done = true if ok_clicked 96 | 97 | ImGui::Render() 98 | GL.Viewport(0, 0, io[:DisplaySize][:x].to_i, io[:DisplaySize][:y].to_i) 99 | GL.ClearColor(0.45, 0.55, 0.60, 1.00) 100 | GL.Clear(GL::COLOR_BUFFER_BIT) 101 | 102 | ImGui::ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()) 103 | SDL.GL_SwapWindow(window) 104 | end 105 | 106 | ImGui::ImplOpenGL2_Shutdown() 107 | ImGui::ImplSDL2_Shutdown() 108 | ImGui::DestroyContext(nil) 109 | 110 | SDL.GL_DeleteContext(gl_context) 111 | SDL.DestroyWindow(window) 112 | SDL.Quit() 113 | end 114 | -------------------------------------------------------------------------------- /examples/glfw3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/examples/glfw3.dll -------------------------------------------------------------------------------- /examples/iconfont/README.md: -------------------------------------------------------------------------------- 1 | * fontawesome-webfont.ttf (Font Awesome v4.7.0 https://github.com/FortAwesome/Font-Awesome/tree/fa-4 ) 2 | * Available under the terms of SIL Open FontLicense 1.1 ( http://scripts.sil.org/OFL ) 3 | -------------------------------------------------------------------------------- /examples/iconfont/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/examples/iconfont/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /examples/imgui_and_testgl2.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | # OpenGL Setup (https://github.com/vaiorabbit/ruby-opengl/) 3 | require 'opengl' 4 | include OpenGL 5 | case OpenGL.get_platform 6 | when :OPENGL_PLATFORM_WINDOWS 7 | OpenGL.load_lib('opengl32.dll', 'C:/Windows/System32') 8 | when :OPENGL_PLATFORM_MACOSX 9 | OpenGL.load_lib('libGL.dylib', '/System/Library/Frameworks/OpenGL.framework/Libraries') 10 | when :OPENGL_PLATFORM_LINUX 11 | OpenGL.load_lib() 12 | else 13 | raise RuntimeError, "Unsupported platform." 14 | end 15 | 16 | # SDL2 Setup (https://github.com/vaiorabbit/sdl2-bindings) 17 | require 'sdl2' 18 | include SDL2 19 | 20 | # ImGUI Setup (https://github.com/vaiorabbit/ruby-imgui/) 21 | require_relative '../imgui' 22 | require_relative '../imgui_impl_opengl2' 23 | require_relative '../imgui_impl_sdl2' 24 | case RUBY_PLATFORM 25 | when /mswin|msys|mingw|cygwin/ 26 | ImGui.load_lib(Dir.pwd + '/../' + 'imgui.dll') 27 | when /darwin/ 28 | ImGui.load_lib('../imgui.dylib') 29 | when /linux/ 30 | ImGui.load_lib('../imgui_dll/build/imgui.so') 31 | else 32 | raise RuntimeError, "Unsupported platform: #{RUBY_PLATFORM}" 33 | end 34 | 35 | # Ref.: testgl2.c (https://hg.libsdl.org/SDL/file/tip/test/testgl2.c) 36 | $color = 37 | [[ 1.0, 1.0, 0.0].pack("D3"), 38 | [ 1.0, 0.0, 0.0].pack("D3"), 39 | [ 0.0, 0.0, 0.0].pack("D3"), 40 | [ 0.0, 1.0, 0.0].pack("D3"), 41 | [ 0.0, 1.0, 1.0].pack("D3"), 42 | [ 1.0, 1.0, 1.0].pack("D3"), 43 | [ 1.0, 0.0, 1.0].pack("D3"), 44 | [ 0.0, 0.0, 1.0].pack("D3")] 45 | 46 | $cube = 47 | [[ 0.5, 0.5, -0.5].pack("D3"), 48 | [ 0.5, -0.5, -0.5].pack("D3"), 49 | [-0.5, -0.5, -0.5].pack("D3"), 50 | [-0.5, 0.5, -0.5].pack("D3"), 51 | [-0.5, 0.5, 0.5].pack("D3"), 52 | [ 0.5, 0.5, 0.5].pack("D3"), 53 | [ 0.5, -0.5, 0.5].pack("D3"), 54 | [-0.5, -0.5, 0.5].pack("D3")] 55 | 56 | def render() 57 | glClearColor(0.0, 0.0, 0.0, 1.0) 58 | glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) 59 | 60 | glBegin(GL_QUADS) 61 | 62 | glColor3dv($color[0]) 63 | glVertex3dv($cube[0]) 64 | glColor3dv($color[1]) 65 | glVertex3dv($cube[1]) 66 | glColor3dv($color[2]) 67 | glVertex3dv($cube[2]) 68 | glColor3dv($color[3]) 69 | glVertex3dv($cube[3]) 70 | 71 | glColor3dv($color[3]) 72 | glVertex3dv($cube[3]) 73 | glColor3dv($color[4]) 74 | glVertex3dv($cube[4]) 75 | glColor3dv($color[7]) 76 | glVertex3dv($cube[7]) 77 | glColor3dv($color[2]) 78 | glVertex3dv($cube[2]) 79 | 80 | glColor3dv($color[0]) 81 | glVertex3dv($cube[0]) 82 | glColor3dv($color[5]) 83 | glVertex3dv($cube[5]) 84 | glColor3dv($color[6]) 85 | glVertex3dv($cube[6]) 86 | glColor3dv($color[1]) 87 | glVertex3dv($cube[1]) 88 | 89 | glColor3dv($color[5]) 90 | glVertex3dv($cube[5]) 91 | glColor3dv($color[4]) 92 | glVertex3dv($cube[4]) 93 | glColor3dv($color[7]) 94 | glVertex3dv($cube[7]) 95 | glColor3dv($color[6]) 96 | glVertex3dv($cube[6]) 97 | 98 | glColor3dv($color[5]) 99 | glVertex3dv($cube[5]) 100 | glColor3dv($color[0]) 101 | glVertex3dv($cube[0]) 102 | glColor3dv($color[3]) 103 | glVertex3dv($cube[3]) 104 | glColor3dv($color[4]) 105 | glVertex3dv($cube[4]) 106 | 107 | glColor3dv($color[6]) 108 | glVertex3dv($cube[6]) 109 | glColor3dv($color[1]) 110 | glVertex3dv($cube[1]) 111 | glColor3dv($color[2]) 112 | glVertex3dv($cube[2]) 113 | glColor3dv($color[7]) 114 | glVertex3dv($cube[7]) 115 | 116 | glEnd() 117 | 118 | glMatrixMode(GL_MODELVIEW) 119 | glRotated(5.0, 1.0, 1.0, 1.0) 120 | end 121 | 122 | 123 | # Main 124 | if __FILE__ == $0 125 | 126 | # Initialize SDL2 127 | SDL2.load_lib('/usr/local/lib/libSDL2.dylib') 128 | success = SDL_Init(SDL_INIT_EVERYTHING) 129 | exit if success < 0 130 | 131 | WINDOW_W = 400 132 | WINDOW_H = 320 133 | window = SDL_CreateWindow("Ruby OpenGL + SDL2 + ImGUI bindings", 0, 0, WINDOW_W, WINDOW_H, SDL_WINDOW_OPENGL) 134 | 135 | ratio = WINDOW_W.to_f / WINDOW_H 136 | 137 | context = SDL_GL_CreateContext(window) 138 | SDL_GL_MakeCurrent(window, context) 139 | SDL_GL_SetSwapInterval(1) 140 | 141 | # Initialize ImGUI 142 | ImGui::CreateContext(nil) 143 | ImGui::ImplSDL2_Init(window) 144 | ImGui::ImplOpenGL2_Init() 145 | 146 | glViewport( 0, 0, WINDOW_W, WINDOW_H ) 147 | glMatrixMode( GL_PROJECTION ) 148 | glLoadIdentity( ) 149 | glOrtho(-ratio, ratio, -1.0, 1.0, -1.0, 1.0) 150 | glMatrixMode( GL_MODELVIEW ) 151 | glLoadIdentity( ) 152 | 153 | glEnable(GL_DEPTH_TEST) 154 | glDepthFunc(GL_LESS) 155 | glShadeModel(GL_SMOOTH) 156 | 157 | delay_counter = 0 158 | 159 | # Main loop 160 | event = SDL_Event.new 161 | done = false 162 | while not done 163 | while SDL_PollEvent(event) != 0 164 | ImGui::ImplSDL2_ProcessEvent(event) 165 | done = true if event[:type] == SDL_QUIT 166 | 167 | event_type = event[:common][:type] 168 | event_timestamp = event[:common][:timestamp] 169 | case event_type 170 | when SDL_KEYDOWN 171 | if event[:key][:keysym][:sym] == SDLK_ESCAPE 172 | done = true 173 | end 174 | end 175 | end 176 | 177 | render() 178 | 179 | ImGui::ImplOpenGL2_NewFrame() 180 | ImGui::ImplSDL2_NewFrame(window) 181 | ImGui::NewFrame() 182 | 183 | # ImGui::ShowDemoWindow(nil) 184 | 185 | pos = ImVec2.create(50, 20) 186 | pivot = ImVec2.create(0, 0) 187 | size = ImVec2.create(150, 70) 188 | ImGui::SetNextWindowPos(pos, ImGuiCond_FirstUseEver, pivot) 189 | ImGui::SetNextWindowSize(size, 0) 190 | ImGui::SetNextWindowBgAlpha(0.35) 191 | 192 | p_open = nil 193 | window_flags = 0 # ImGuiWindowFlags_AlwaysAutoResize 194 | ImGui::Begin("SDL_Delay", p_open, window_flags) 195 | 196 | # Arrow buttons with Repeater 197 | spacing = ImGuiStyle.new(ImGui::GetStyle())[:ItemInnerSpacing][:x] 198 | 199 | ImGui::PushButtonRepeat(true) 200 | delay_counter -= 1 if ImGui::ArrowButton("##left", ImGuiDir_Left) and delay_counter > 0 201 | ImGui::SameLine(0.0, spacing) 202 | delay_counter += 1 if ImGui::ArrowButton("##right", ImGuiDir_Right) and delay_counter < 100 203 | ImGui::PopButtonRepeat() 204 | ImGui::SameLine(0.0, -1.0) 205 | ImGui::Text("%3d", :int, delay_counter) 206 | 207 | ImGui::End() 208 | 209 | 210 | ImGui::Render() 211 | ImGui::ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()) 212 | 213 | SDL_GL_SwapWindow(window) 214 | 215 | SDL_Delay(delay_counter) 216 | end 217 | 218 | ImGui::ImplOpenGL2_Shutdown() 219 | ImGui::ImplSDL2_Shutdown() 220 | ImGui::DestroyContext(nil) 221 | 222 | SDL_GL_DeleteContext(context) 223 | SDL_DestroyWindow(window) 224 | SDL_Quit() 225 | end 226 | -------------------------------------------------------------------------------- /examples/imnodes_basic_sdl2_opengl2.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | require_relative 'util/setup_dll' 3 | require_relative 'util/setup_opengl_dll' 4 | require_relative 'util/setup_sdl2_dll' 5 | 6 | WINDOW_W = 480 7 | WINDOW_H = 320 8 | 9 | Node = Struct.new( :name, :pos, :selected, :inslot, :outslot, keyword_init: true ) 10 | 11 | if __FILE__ == $0 12 | 13 | success = SDL.Init(SDL::INIT_VIDEO | SDL::INIT_TIMER | SDL::INIT_GAMECONTROLLER) 14 | exit if success < 0 15 | 16 | # Setup window 17 | SDL.GL_SetAttribute(SDL::GL_DOUBLEBUFFER, 1) 18 | SDL.GL_SetAttribute(SDL::GL_DEPTH_SIZE, 24) 19 | SDL.GL_SetAttribute(SDL::GL_STENCIL_SIZE, 8) 20 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_MAJOR_VERSION, 2) 21 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_MINOR_VERSION, 2) 22 | window_flags = (SDL::WINDOW_OPENGL | SDL::WINDOW_RESIZABLE | SDL::WINDOW_ALLOW_HIGHDPI) 23 | window = SDL.CreateWindow("ImNodes/Ruby-ImGui (SDL2+OpenGL)", 64, 64, WINDOW_W, WINDOW_H, window_flags) 24 | 25 | gl_context = SDL.GL_CreateContext(window) 26 | SDL.GL_MakeCurrent(window, gl_context) 27 | SDL.GL_SetSwapInterval(1) # Enable vsync 28 | 29 | GL.load_lib() 30 | 31 | # Setup Dear ImGui context 32 | ImGui::CreateContext() 33 | 34 | io = ImGuiIO.new(ImGui::GetIO()) 35 | io[:Fonts].AddFontDefault() 36 | 37 | # Setup Dear ImGui style 38 | ImGui::StyleColorsDark() 39 | 40 | # Setup Platform/Renderer bindings 41 | ImGui::ImplSDL2_Init(window, nil) 42 | ImGui::ImplOpenGL2_Init() 43 | 44 | # Setup ImNodes 45 | imnodes_context = ImNodes::EzCreateContext() 46 | 47 | # Setup nodes 48 | node_src = Node.new(name: FFI::MemoryPointer.from_string("src"), 49 | pos: ImVec2.create(50, 50), 50 | selected: FFI::MemoryPointer.new(:bool, 1), 51 | inslot: ImNodes::SlotInfo.create("InSlot", 1), 52 | outslot: ImNodes::SlotInfo.create("OutSlot", 1)) 53 | node_dst = Node.new(name: FFI::MemoryPointer.from_string("dst"), 54 | pos: ImVec2.create(150, 150), 55 | selected: FFI::MemoryPointer.new(:bool, 1), 56 | inslot: ImNodes::SlotInfo.create("InSlot", 1), 57 | outslot: ImNodes::SlotInfo.create("OutSlot", 1)) 58 | 59 | event = SDL::Event.new 60 | done = false 61 | until done 62 | while SDL.PollEvent(event) != 0 63 | ImGui::ImplSDL2_ProcessEvent(event) 64 | done = true if event[:type] == SDL::QUIT 65 | 66 | # 'type' and 'timestamp' are common members for all SDL Event structs. 67 | event_type = event[:common][:type] 68 | # event_timestamp = event[:common][:timestamp] 69 | # puts "Event : type=0x#{event_type.to_s(16)}, timestamp=#{event_timestamp}" 70 | case event_type 71 | when SDL::KEYDOWN 72 | if event[:key][:keysym][:sym] == SDL::SDLK_ESCAPE 73 | done = true 74 | end 75 | end 76 | end 77 | 78 | ImGui::ImplOpenGL2_NewFrame() 79 | ImGui::ImplSDL2_NewFrame() 80 | ImGui::NewFrame() 81 | 82 | ImGui::SetNextWindowPos(ImVec2.create(30, 30), ImGuiCond_Once) 83 | ImGui::SetNextWindowSize(ImVec2.create(400, 260), ImGuiCond_Once) 84 | 85 | # Node editor view starts here 86 | ImGui::Begin("Basic") 87 | ImNodes::EzBeginCanvas() 88 | 89 | if ImNodes::EzBeginNode(node_src.name, node_src.name, node_src.pos, node_src.selected) 90 | ImNodes::EzInputSlots(nil, 0) 91 | ImGui::Text("Source Node") 92 | ImNodes::EzOutputSlots(node_src.outslot, 1) 93 | end 94 | ImNodes::EzEndNode() 95 | 96 | if ImNodes::EzBeginNode(node_dst.name, node_dst.name, node_dst.pos, node_dst.selected) 97 | ImNodes::EzInputSlots(node_dst.inslot, 1) 98 | ImGui::Text("Destination Node") 99 | ImNodes::EzOutputSlots(nil, 0) 100 | end 101 | ImNodes::EzEndNode() 102 | 103 | ImNodes::EzConnection(node_dst.name, node_dst.inslot[:title], node_src.name, node_src.outslot[:title]) 104 | ImNodes::EzEndCanvas() 105 | ImGui::End() 106 | # End of node editor view 107 | 108 | ImGui::Render() 109 | GL.Viewport(0, 0, io[:DisplaySize][:x].to_i, io[:DisplaySize][:y].to_i) 110 | GL.ClearColor(0.45, 0.55, 0.60, 1.00) 111 | GL.Clear(GL::COLOR_BUFFER_BIT) 112 | 113 | ImGui::ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()) 114 | SDL.GL_SwapWindow(window) 115 | end 116 | 117 | ImNodes::EzFreeContext(imnodes_context) 118 | 119 | ImGui::ImplOpenGL2_Shutdown() 120 | ImGui::ImplSDL2_Shutdown() 121 | ImGui::DestroyContext(nil) 122 | 123 | SDL.GL_DeleteContext(gl_context) 124 | SDL.DestroyWindow(window) 125 | SDL.Quit() 126 | end 127 | -------------------------------------------------------------------------------- /examples/imnodes_editable_sdl2_opengl2.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | require_relative 'util/setup_dll' 3 | require_relative 'util/setup_opengl_dll' 4 | require_relative 'util/setup_sdl2_dll' 5 | 6 | WINDOW_W = 1280 7 | WINDOW_H = 720 8 | 9 | $nodes = [] 10 | 11 | class Connection 12 | attr_reader :input_node_ptr, :input_slot_ptr, :output_node_ptr, :output_slot_ptr 13 | 14 | def initialize 15 | @input_node_ptr = FFI::MemoryPointer.new(:pointer, 1) 16 | @input_slot_ptr = FFI::MemoryPointer.new(:pointer, 1) 17 | @output_node_ptr = FFI::MemoryPointer.new(:pointer, 1) 18 | @output_slot_ptr = FFI::MemoryPointer.new(:pointer, 1) 19 | end 20 | 21 | def input_node = @input_node_ptr.read_pointer; 22 | def input_slot = @input_slot_ptr.read_pointer; 23 | def output_node = @output_node_ptr.read_pointer; 24 | def output_slot = @output_slot_ptr.read_pointer; 25 | 26 | def ==(other) 27 | return @input_node_ptr.read_pointer == other.input_node_ptr.read_pointer && 28 | @input_slot_ptr.read_pointer == other.input_slot_ptr.read_pointer && 29 | @output_node_ptr.read_pointer == other.output_node_ptr.read_pointer && 30 | @output_slot_ptr.read_pointer == other.output_slot_ptr.read_pointer 31 | end 32 | 33 | def get_nodes 34 | input_node = $nodes.find {|n| n.id == @input_node_ptr.read_pointer} 35 | output_node = $nodes.find {|n| n.id == @output_node_ptr.read_pointer} 36 | return input_node, output_node 37 | end 38 | end 39 | 40 | NodeSlotPosition = 1 41 | NodeSlotRotation = 2 42 | NodeSlotMatrix = 3 43 | 44 | class MyNode 45 | attr_reader :title, :id, :selected, :pos, :connections, :input_slots, :output_slots 46 | 47 | def initialize(title, input_slots, output_slots) 48 | @title = title 49 | @id = FFI::MemoryPointer.from_string(@title) 50 | @selected = FFI::MemoryPointer.new(:bool, 1) 51 | @pos = ImVec2.create(0, 0) 52 | @connections = [] # array of Connection 53 | @input_slots = input_slots # array of ImNodesEzSlotInfo 54 | @output_slots = output_slots # array of ImNodesEzSlotInfo 55 | end 56 | 57 | def delete_connection(connection) 58 | @connections.delete_if {|c| c == connection} 59 | end 60 | 61 | def is_selected? 62 | @selected.read(FFI::NativeType::BOOL) 63 | end 64 | 65 | # Make on-memory data suitable for ImNodes::EzInputSlots from @input_slots 66 | def input_slots_memory 67 | memory = FFI::MemoryPointer.new(ImNodes::SlotInfo, @input_slots.length) # [TODO] cache 68 | @input_slots.length.times do |i| 69 | si = ImNodes::SlotInfo.new(memory + i * ImNodes::SlotInfo.size) 70 | si[:title] = @input_slots[i][:title] 71 | si[:kind] = @input_slots[i][:kind] 72 | end 73 | memory 74 | end 75 | 76 | # Make on-memory data suitable for ImNodes::EzOutputSlots from @output_slots 77 | def output_slots_memory 78 | memory = FFI::MemoryPointer.new(ImNodes::SlotInfo, @output_slots.length) # [TODO] cache 79 | @output_slots.length.times do |i| 80 | si = ImNodes::SlotInfo.new(memory + i * ImNodes::SlotInfo.size) 81 | si[:title] = @output_slots[i][:title] 82 | si[:kind] = @output_slots[i][:kind] 83 | end 84 | memory 85 | end 86 | 87 | end 88 | 89 | $available_nodes = { 90 | "Compose" => lambda { return MyNode.new("Compose", 91 | [ImNodes::SlotInfo.create("Position", NodeSlotPosition), # Input slots 92 | ImNodes::SlotInfo.create("Rotation", NodeSlotRotation)], 93 | [ImNodes::SlotInfo.create("Matrix", NodeSlotMatrix)]) }, # Output slot 94 | "Decompose" => lambda { return MyNode.new("Decompose", 95 | [ImNodes::SlotInfo.create("Matrix", NodeSlotMatrix)], # Input slot 96 | [ImNodes::SlotInfo.create("Position", NodeSlotPosition), # Output slots 97 | ImNodes::SlotInfo.create("Rotation", NodeSlotRotation)]) }, 98 | } 99 | 100 | if __FILE__ == $0 101 | 102 | success = SDL.Init(SDL::INIT_VIDEO | SDL::INIT_TIMER | SDL::INIT_GAMECONTROLLER) 103 | exit if success < 0 104 | 105 | # Setup window 106 | SDL.GL_SetAttribute(SDL::GL_DOUBLEBUFFER, 1) 107 | SDL.GL_SetAttribute(SDL::GL_DEPTH_SIZE, 24) 108 | SDL.GL_SetAttribute(SDL::GL_STENCIL_SIZE, 8) 109 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_MAJOR_VERSION, 2) 110 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_MINOR_VERSION, 2) 111 | window_flags = (SDL::WINDOW_OPENGL | SDL::WINDOW_RESIZABLE | SDL::WINDOW_ALLOW_HIGHDPI) 112 | window = SDL.CreateWindow("ImNodes/Ruby-ImGui (SDL2+OpenGL)", 64, 64, WINDOW_W, WINDOW_H, window_flags) 113 | 114 | gl_context = SDL.GL_CreateContext(window) 115 | SDL.GL_MakeCurrent(window, gl_context) 116 | SDL.GL_SetSwapInterval(1) # Enable vsync 117 | 118 | GL.load_lib() 119 | 120 | # Setup Dear ImGui context 121 | ImGui::CreateContext() 122 | 123 | io = ImGuiIO.new(ImGui::GetIO()) 124 | io[:Fonts].AddFontDefault() 125 | 126 | # Setup Dear ImGui style 127 | ImGui::StyleColorsDark() 128 | 129 | # Setup Platform/Renderer bindings 130 | ImGui::ImplSDL2_Init(window, nil) 131 | ImGui::ImplOpenGL2_Init() 132 | 133 | # Setup ImNodes 134 | imnodes_context = ImNodes::EzCreateContext() 135 | 136 | event = SDL::Event.new 137 | done = false 138 | until done 139 | while SDL.PollEvent(event) != 0 140 | ImGui::ImplSDL2_ProcessEvent(event) 141 | done = true if event[:type] == SDL::QUIT 142 | 143 | # 'type' and 'timestamp' are common members for all SDL Event structs. 144 | event_type = event[:common][:type] 145 | # event_timestamp = event[:common][:timestamp] 146 | # puts "Event : type=0x#{event_type.to_s(16)}, timestamp=#{event_timestamp}" 147 | case event_type 148 | when SDL::KEYDOWN 149 | if event[:key][:keysym][:sym] == SDL::SDLK_ESCAPE 150 | done = true 151 | end 152 | end 153 | end 154 | 155 | ImGui::ImplOpenGL2_NewFrame() 156 | ImGui::ImplSDL2_NewFrame() 157 | ImGui::NewFrame() 158 | 159 | ImGui::SetNextWindowPos(ImVec2.create(30, 30), ImGuiCond_Once) 160 | ImGui::SetNextWindowSize(ImVec2.create(1000, 500), ImGuiCond_Once) 161 | 162 | # Node editor view starts here 163 | ImGui::Begin("Node Editor : Click right button to show available nodes") 164 | ImNodes::EzBeginCanvas() 165 | 166 | node_deleted = [] 167 | 168 | $nodes.each do |node| 169 | if ImNodes::EzBeginNode(node.id, node.title, node.pos, node.selected) 170 | ImNodes::EzInputSlots(node.input_slots_memory, node.input_slots.length) 171 | ImGui::Text("Content of #{node.title}") 172 | ImNodes::EzOutputSlots(node.output_slots_memory, node.output_slots.length) 173 | 174 | new_connection = Connection.new 175 | if ImNodes::GetNewConnection(new_connection.input_node_ptr, new_connection.input_slot_ptr, new_connection.output_node_ptr, new_connection.output_slot_ptr) 176 | input_node, output_node = new_connection.get_nodes 177 | input_node.connections << new_connection 178 | output_node.connections << new_connection 179 | end 180 | 181 | node.connections.each do |connection| 182 | input_node, output_node = connection.get_nodes 183 | next if output_node.id != node.id 184 | if !ImNodes::Connection(connection.input_node, connection.input_slot, connection.output_node, connection.output_slot) 185 | input_node.delete_connection(connection) 186 | output_node.delete_connection(connection) 187 | end 188 | end 189 | end 190 | ImNodes::EzEndNode() 191 | 192 | if node.is_selected? && (ImGui::IsKeyPressed(ImGuiKey_Delete) || ImGui::IsKeyPressed(ImGuiKey_Backspace)) && ImGui::IsWindowFocused() 193 | node.connections.each do |connection| 194 | input_node, output_node = connection.get_nodes 195 | if output_node.id == node.id 196 | input_node.delete_connection(connection) 197 | else 198 | output_node.delete_connection(connection) 199 | end 200 | end 201 | node.connections.clear 202 | node_deleted << node 203 | end 204 | 205 | end 206 | 207 | node_deleted.each do |node| 208 | $nodes.delete(node) 209 | end 210 | 211 | # Context Menu 212 | if ImGui::IsMouseReleased(1) && ImGui::IsWindowHovered() && !ImGui::IsMouseDragging(1) 213 | ImGui::FocusWindow(ImGui::GetCurrentWindow()) 214 | ImGui::OpenPopup("NodesContextMenu", 0) 215 | end 216 | 217 | if ImGui::BeginPopup("NodesContextMenu") 218 | $available_nodes.each do |name, node_creator| 219 | if ImGui::MenuItem(name, "", false, true) # [TODO] support default arguments for MenuItem 220 | $nodes << node_creator.call() 221 | ImNodes::AutoPositionNode($nodes.last.id) 222 | end 223 | end 224 | 225 | ImGui::Separator() 226 | if ImGui::MenuItem("Reset Zoom", "", false, true) # [TODO] support default arguments for MenuItem 227 | ImNodes::CanvasState.new(ImNodes::GetCurrentCanvas())[:Zoom] = 1 228 | end 229 | if ImGui::IsAnyMouseDown() && !ImGui::IsWindowHovered() 230 | ImGui::CloseCurrentPopup() 231 | end 232 | ImGui::EndPopup() 233 | end 234 | 235 | ImNodes::EzEndCanvas() 236 | ImGui::End() 237 | # End of node editor view 238 | 239 | ImGui::Render() 240 | GL.Viewport(0, 0, io[:DisplaySize][:x].to_i, io[:DisplaySize][:y].to_i) 241 | GL.ClearColor(0.45, 0.55, 0.60, 1.00) 242 | GL.Clear(GL::COLOR_BUFFER_BIT) 243 | 244 | ImGui::ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()) 245 | SDL.GL_SwapWindow(window) 246 | end 247 | 248 | ImNodes::EzFreeContext(imnodes_context) 249 | 250 | ImGui::ImplOpenGL2_Shutdown() 251 | ImGui::ImplSDL2_Shutdown() 252 | ImGui::DestroyContext(nil) 253 | 254 | SDL.GL_DeleteContext(gl_context) 255 | SDL.DestroyWindow(window) 256 | SDL.Quit() 257 | end 258 | -------------------------------------------------------------------------------- /examples/jpfont/GenShinGothic-Normal.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/examples/jpfont/GenShinGothic-Normal.ttf -------------------------------------------------------------------------------- /examples/jpfont/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/examples/jpfont/README.md -------------------------------------------------------------------------------- /examples/jpfont/README_GenShin.txt: -------------------------------------------------------------------------------- 1 | 源真ゴシック (げんしんゴシック) 2 | Version 1.002.20150607 3 | 4 | 5 | ■ このフォントについて 6 | 7 | 源真ゴシック (げんしんゴシック) は、フリーの OpenType フォントである 8 | 「源ノ角ゴシック (Noto Sans CJK / Source Han Sans の日本語部分)」を 9 | TrueType 形式に変換し、使い勝手を向上するカスタマイズを施したフォントです。 10 | 11 | 詳細は、以下のサイトをごらんください。 12 | http://jikasei.me/font/genshin/ 13 | 14 | 15 | ■ ライセンスと著作権について 16 | 17 | ・源真ゴシックは源ノ角ゴシックを改変して制作したもので、M+ OUTLINE FONTS 由来の文字グリフも一部含みます。 18 | ・フォントデータに含まれる、源ノ角ゴシック由来の文字グリフの著作権は Adobe が所有しています。 19 | ・フォントデータに含まれる、M+ OUTLINE FONTS 由来の文字グリフの著作権は M+ FONTS PROJECT が所有しています。 20 | ・源真ゴシックのフォントファイルは、源ノ角ゴシックと同じ SIL Open Font License 1.1 のもとで使用することができます。 21 | 22 | SIL Open Font License 1.1 の内容は、アーカイブに同梱の LICENSE.txt に記載されています。 23 | この日本語訳は、以下から参照することができます。 24 | http://osdn.jp/projects/opensource/wiki/SIL_Open_Font_License_1.1 25 | 26 | M+ OUTLINE FONTS のグリフは、同梱のファイル LICENSE_J に記載された自由な 27 | M+ FONTS LICENSE に基づき使用しています。 28 | 29 | 30 | ■ 頒布元 31 | 32 | 源真ゴシックの最新版は、以下のサイトで頒布しています。 33 | 不具合などが修正された場合、新しいバージョンとして公開されますので、 34 | 定期的にサイトをご確認いただければ幸いです。 35 | 36 | 自家製フォント工房 37 | http://jikasei.me/ 38 | 39 | 40 | ■ 改変元 41 | 42 | Mgen+ は、以下のフォントを改変して制作しました。 43 | 素晴らしいフリーフォントの制作に関わる全ての方に深くお礼申し上げます。 44 | 45 | 源ノ角ゴシック (Source Hans Sans) 46 | http://store1.adobe.com/cfusion/store/html/index.cfm?store=OLS-JP&event=displayFontPackage&code=1967 47 | 48 | M+ OUTLINE FONTS 49 | http://mplus-fonts.sourceforge.jp/ 50 | 51 | 52 | ■ 改版履歴 53 | 54 | 55 | ●Version 1.002.20150607 56 | 57 | ・縦書きが機能しなくなっていたのを修正しました。 58 | 59 | 60 | ●Version 1.002.20150531 61 | 62 | ・源ノ角ゴシック Ver.1.002 ベースになりました。 63 | Ver.1.002 でサポートされた、「あ行+濁点」などの合字に対応しました。 64 | 65 | ・源ノ角ゴシックのライセンス変更に伴い、フォントファイルのライセンスが 66 | Apache License 2.0 から SIL Open Font License 1.1 に変更になりました。 67 | 68 | ・「ff」「fi」「fl」「ffi」「ffl」のリガチャ (合字) に対応しました。 69 | 70 | ・「か+半濁点」など、源ノ角ゴシックではサポートされていたものの未対応だった 71 | ひらがな・カタカナの合字に対応しました。 72 | 73 | ・JIS78, JIS83, JIS90 の正確な文字リストを保持するようになりました。 74 | Illustrator、InDesign の字形パネルで、異字体を源ノ角ゴシックと同様に扱えるようになりました。 75 | 76 | ・小文字のクシスト (U+31F0 ~ U+31F3) が欠落していたのを修正しました。 77 | 78 | 79 | ●Version 1.001.20150116 80 | 81 | ・1.001.20150110 より、一部括弧の文字で縦書きが機能しなくなっていたのを修正しました。 82 | 83 | ・縦書きに対応した記号を追加しました。 84 | 85 | 86 | ●Version 1.001.20150110 87 | 88 | ・源ノ角ゴシック Ver.1.001 ベースになり、いくつかの字形が修正されました。 89 | 90 | ・FullFontName が "Gen Shin Gothic" (「源真ゴシック」のもの) になっていたのを修正しました。 91 | 92 | ・ウェイトクラス (数字による太さ表記) を、源ノ角ゴシックと同じ値に変更しました。 93 | ・ExtraLight : 200 → 100 94 | ・Light : 300 → 200 95 | ・Normal : 350 → 300 96 | ・Heavy : 800 → 900 97 | 98 | ・小文字のクシスト (U+31F0 ~ U+31F3) が欠けていたのを修正しました。 99 | 100 | 101 | ●Version 1.000.20140828 102 | 103 | ・プロポーショナルフォント (源真ゴシックP) が縦書きに対応しました。 104 | 105 | ・源柔ゴシック (P や等幅を除く) のフォント名設定が不適切だったのを修正しました。 106 | 107 | 108 | ●Version 1.000.20140824 109 | 110 | ・縦書き時、全角スペースの高さが 0 になっていたのを修正しました。 111 | 112 | ・Normal ウエイトの M+ 由来のグリフが太かったのを修正しました。 113 | 114 | ・縦書き専用のグリフに M+ OUTLINE FONTS のものが混在していたのを修正しました。 115 | 116 | ・全角数字、全角のセミコロン、「i」「l」がプロポーショナル幅で不自然にならないように 117 | 調整しました。 118 | 119 | ・一部の矢印グリフ (U+21D0~U+21D9) が、矢印の方向によって源ノ角ゴシック由来と 120 | M+ 由来のものが混在していましたが、これを源ノ角ゴシック由来のものに統一しました。 121 | (源ノ角ゴシックにない方向の矢印は、回転して作成しています) 122 | 123 | ・一部の点線罫線のグリフ (U+2504~U+250B) で、本来横線なのが縦線になっていたのを修正しました。 124 | 125 | ・ほとんどのハイフン、ダッシュ、罫線、矢印関連のグリフが、縦書きの時に回転するようになりました。 126 | 127 | ・フォントの中に含まれていた、日本語フォントとして不要なグリフ (未使用の特殊文字、 128 | ハングルの半角文字や記号、中国語の注音記号) を削除しました。 129 | 130 | ・源柔ゴシックP において、縦書き時にひらがな・カタカナが左に寄らないようにしました。 131 | 132 | 133 | ●Version 1.000.20140812 134 | 135 | ・M+ 由来の一部文字において、文字のアウトラインが不正 (交差して内側に入り込んでいる) なのを 136 | 修正しました。 137 | 138 | ・等幅フォントにおいて、OS/2 のウエイト情報の設定が正しくないのを修正しました。 139 | たとえば、Ubuntu Linux において、すべてのウエイトが thin と表示されていました。 140 | 141 | 142 | ●Version 1.000.20140807 143 | 144 | ・源真ゴシックP (かなもプロポーショナル幅のファミリー) において、 145 |  全角約物 (全角スペース、句読点、括弧など) の幅を再調整しました。 146 | 147 | ・幅が全角1文字分を越えるグリフの幅が、全角1文字に切り詰められていたのを修正しました。 148 | 149 | 150 | ●Version.1.000.20140806 151 | 152 | ・初回リリース 153 | ・源ノ角ゴシック Ver.1.000 ベース 154 | -------------------------------------------------------------------------------- /examples/jpfont/SIL_Open_Font_License_1.1.txt: -------------------------------------------------------------------------------- 1 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 2 | This license is copied below, and is also available with a FAQ at: 3 | http://scripts.sil.org/OFL 4 | 5 | 6 | ----------------------------------------------------------- 7 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 8 | ----------------------------------------------------------- 9 | 10 | PREAMBLE 11 | The goals of the Open Font License (OFL) are to stimulate worldwide 12 | development of collaborative font projects, to support the font creation 13 | efforts of academic and linguistic communities, and to provide a free and 14 | open framework in which fonts may be shared and improved in partnership 15 | with others. 16 | 17 | The OFL allows the licensed fonts to be used, studied, modified and 18 | redistributed freely as long as they are not sold by themselves. The 19 | fonts, including any derivative works, can be bundled, embedded, 20 | redistributed and/or sold with any software provided that any reserved 21 | names are not used by derivative works. The fonts and derivatives, 22 | however, cannot be released under any other type of license. The 23 | requirement for fonts to remain under this license does not apply 24 | to any document created using the fonts or their derivatives. 25 | 26 | DEFINITIONS 27 | "Font Software" refers to the set of files released by the Copyright 28 | Holder(s) under this license and clearly marked as such. This may 29 | include source files, build scripts and documentation. 30 | 31 | "Reserved Font Name" refers to any names specified as such after the 32 | copyright statement(s). 33 | 34 | "Original Version" refers to the collection of Font Software components as 35 | distributed by the Copyright Holder(s). 36 | 37 | "Modified Version" refers to any derivative made by adding to, deleting, 38 | or substituting -- in part or in whole -- any of the components of the 39 | Original Version, by changing formats or by porting the Font Software to a 40 | new environment. 41 | 42 | "Author" refers to any designer, engineer, programmer, technical 43 | writer or other person who contributed to the Font Software. 44 | 45 | PERMISSION & CONDITIONS 46 | Permission is hereby granted, free of charge, to any person obtaining 47 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 48 | redistribute, and sell modified and unmodified copies of the Font 49 | Software, subject to the following conditions: 50 | 51 | 1) Neither the Font Software nor any of its individual components, 52 | in Original or Modified Versions, may be sold by itself. 53 | 54 | 2) Original or Modified Versions of the Font Software may be bundled, 55 | redistributed and/or sold with any software, provided that each copy 56 | contains the above copyright notice and this license. These can be 57 | included either as stand-alone text files, human-readable headers or 58 | in the appropriate machine-readable metadata fields within text or 59 | binary files as long as those fields can be easily viewed by the user. 60 | 61 | 3) No Modified Version of the Font Software may use the Reserved Font 62 | Name(s) unless explicit written permission is granted by the corresponding 63 | Copyright Holder. This restriction only applies to the primary font name as 64 | presented to the users. 65 | 66 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 67 | Software shall not be used to promote, endorse or advertise any 68 | Modified Version, except to acknowledge the contribution(s) of the 69 | Copyright Holder(s) and the Author(s) or with their explicit written 70 | permission. 71 | 72 | 5) The Font Software, modified or unmodified, in part or in whole, 73 | must be distributed entirely under this license, and must not be 74 | distributed under any other license. The requirement for fonts to 75 | remain under this license does not apply to any document created 76 | using the Font Software. 77 | 78 | TERMINATION 79 | This license becomes null and void if any of the above conditions are 80 | not met. 81 | 82 | DISCLAIMER 83 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 84 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 85 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 86 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 87 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 88 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 89 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 90 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 91 | OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /examples/jpfont/jpfont.txt: -------------------------------------------------------------------------------- 1 |  夏目漱石 吾輩は猫である [1905(明治38)年] 2 |  吾輩は猫である。名前はまだ無い。 3 |  どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕かまえて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。 4 | -------------------------------------------------------------------------------- /examples/libSDL2-2.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/examples/libSDL2-2.0.dylib -------------------------------------------------------------------------------- /examples/libSDL2.dylib: -------------------------------------------------------------------------------- 1 | libSDL2-2.0.dylib -------------------------------------------------------------------------------- /examples/libglfw.3.4.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/examples/libglfw.3.4.dylib -------------------------------------------------------------------------------- /examples/libglfw.3.dylib: -------------------------------------------------------------------------------- 1 | libglfw.3.4.dylib -------------------------------------------------------------------------------- /examples/libglfw.dylib: -------------------------------------------------------------------------------- 1 | libglfw.3.dylib -------------------------------------------------------------------------------- /examples/raylib_with_imgui.rb: -------------------------------------------------------------------------------- 1 | # [Usage] 2 | # $ gem install raylib-bindings 3 | # $ gem install imgui-bindings 4 | # $ ruby test_raylib.rb 5 | 6 | require 'raylib' 7 | require 'imgui' 8 | require 'imgui_impl_raylib' 9 | 10 | if __FILE__ == $PROGRAM_NAME 11 | shared_lib_suffix = case RUBY_PLATFORM 12 | when /mswin|msys|mingw/ 13 | 'dll' 14 | when /darwin/ 15 | arch = RUBY_PLATFORM.split('-')[0] 16 | "#{arch}.dylib" 17 | when /linux/ 18 | arch = RUBY_PLATFORM.split('-')[0] 19 | "#{arch}.so" 20 | else 21 | raise RuntimeError, "Unknown OS: #{RUBY_PLATFORM}" 22 | end 23 | 24 | raylib_spec = Gem::Specification.find_by_name('raylib-bindings') 25 | shared_lib_path = raylib_spec.full_gem_path + '/lib/' 26 | Raylib.load_lib("#{shared_lib_path}libraylib.#{shared_lib_suffix}") 27 | 28 | imgui_spec = Gem::Specification.find_by_name('imgui-bindings') 29 | shared_lib_path = imgui_spec.full_gem_path + '/lib/' 30 | ImGui.load_lib("#{shared_lib_path}imgui.#{shared_lib_suffix}") 31 | 32 | screen_width = 1280 33 | screen_height = 720 34 | 35 | Raylib.InitWindow(screen_width, screen_height, "Ruby raylib+ImGui") 36 | 37 | camera = Raylib::Camera.new 38 | .with_position(2.5, 10.0, 10.0) 39 | .with_target(2.5, 0.0, 0.0) 40 | .with_up(0.0, 1.0, 0.0) 41 | .with_fovy(45.0) 42 | .with_projection(Raylib::CAMERA_PERSPECTIVE) 43 | 44 | ImGui.CreateContext() 45 | ImGui.StyleColorsDark() 46 | 47 | ImGui.ImplRaylib_Init() 48 | 49 | io = ImGuiIO.new(ImGui.GetIO()) 50 | io[:Fonts].AddFontDefault() 51 | 52 | # Build texture atlas 53 | pixels = FFI::MemoryPointer.new :pointer 54 | width = FFI::MemoryPointer.new :int 55 | height = FFI::MemoryPointer.new :int 56 | io[:Fonts].GetTexDataAsRGBA32(pixels, width, height, nil) 57 | 58 | # Upload texture to graphics system 59 | # [TODO] find standard and safe way to convert RGBA32 array into texture 60 | image = Raylib.GenImageColor(width.read_int, height.read_int, Raylib::BLUE) 61 | original_data = image[:data] 62 | image[:data] = pixels.read_pointer 63 | 64 | texture = Raylib.LoadTextureFromImage(image) 65 | image[:data] = original_data 66 | Raylib.UnloadImage(image) 67 | 68 | # Store our identifier 69 | texture_ptr = FFI::MemoryPointer.new(:uint32) 70 | texture_ptr.write(:uint32, texture[:id]) 71 | io[:Fonts].SetTexID(texture_ptr) 72 | 73 | cube_color = Raylib::GREEN 74 | 75 | Raylib.SetTargetFPS(60) 76 | 77 | until Raylib.WindowShouldClose() 78 | # Check io[:WantCaptureMouse] to detect the timing when ImGui exclusively requires Mosue/Keyboard information 79 | cube_color = if not io[:WantCaptureMouse] 80 | # Change cube color to Raylib::RED when user clicked outside of ImGui window 81 | if Raylib.IsMouseButtonDown(Raylib::MOUSE_BUTTON_LEFT) 82 | Raylib::RED 83 | else 84 | Raylib::GREEN 85 | end 86 | else 87 | Raylib::GREEN 88 | end 89 | 90 | # [NOTE] We can't use UpdateCamera because Keyboard API (IsKeyDown, etc.) and 91 | # Mouse API (GetMouseWheelMove, etc.) are used inside without checking io[:WantCaptureMouse]. 92 | # Raylib.UpdateCamera(camera.pointer, Raylib::CAMERA_ORBITAL) 93 | 94 | Raylib.BeginDrawing() 95 | Raylib.ClearBackground(Raylib::RAYWHITE) 96 | 97 | Raylib.DrawFPS(screen_width - 100, 10) 98 | Raylib.BeginMode3D(camera) 99 | Raylib.DrawCube(Raylib::Vector3.create(0, 0, 0), 1.0, 1.0, 1.0, cube_color) 100 | Raylib.DrawCubeWires(Raylib::Vector3.create(0, 0, 0), 1.0, 1.0, 1.0, Raylib::BLUE) 101 | Raylib.DrawGrid(10, 1) 102 | Raylib.EndMode3D() 103 | 104 | ImGui.ImplRaylib_NewFrame() 105 | ImGui.NewFrame() 106 | ImGui.ShowDemoWindow() 107 | ImGui.Render() 108 | ImGui.ImplRaylib_RenderDrawData(ImGui.GetDrawData()) 109 | Raylib.EndDrawing() 110 | end 111 | 112 | ImGui.ImplRaylib_Shutdown() 113 | ImGui.DestroyContext(nil) 114 | Raylib.CloseWindow() 115 | end 116 | -------------------------------------------------------------------------------- /examples/test_glfw_opengl2.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | require_relative 'util/setup_dll' 3 | require_relative 'util/setup_opengl_dll' 4 | require_relative 'about_window' 5 | 6 | errorcb = GLFW::create_callback(:GLFWerrorfun) do |error, desc| 7 | printf("GLFW error %d: %s\n", error, desc) 8 | end 9 | 10 | # Press ESC to exit. 11 | key = GLFW::create_callback(:GLFWkeyfun) do |window, key, scancode, action, mods| 12 | if key == GLFW::KEY_ESCAPE && action == GLFW::PRESS 13 | GLFW.SetWindowShouldClose(window, GL::TRUE) 14 | end 15 | end 16 | 17 | if __FILE__ == $PROGRAM_NAME 18 | 19 | GLFW.load_lib(SampleUtil.glfw_library_path) 20 | 21 | if GLFW.Init() == GL::FALSE 22 | puts("Failed to init GLFW.") 23 | exit 24 | end 25 | 26 | GLFW.SetErrorCallback(errorcb) 27 | 28 | GLFW.WindowHint(GLFW::CONTEXT_VERSION_MAJOR, 2) 29 | GLFW.WindowHint(GLFW::CONTEXT_VERSION_MINOR, 0) 30 | 31 | window = GLFW.CreateWindow(1280, 720, "Ruby-ImGui (GLFW+OpenGL)", nil, nil) 32 | if window == 0 33 | GLFW.Terminate() 34 | exit 35 | end 36 | 37 | GLFW.SetKeyCallback( window, key ) 38 | 39 | # Init 40 | GLFW.MakeContextCurrent( window ) 41 | GLFW.SwapInterval(1) 42 | 43 | GL.load_lib() 44 | 45 | japanese_utf8_text = IO.readlines('./jpfont/jpfont.txt').join() 46 | 47 | ImGui::CreateContext() 48 | 49 | ImGui::ImplGlfw_InitForOpenGL(window, true) 50 | ImGui::ImplOpenGL2_Init() 51 | 52 | io = ImGuiIO.new(ImGui::GetIO()) 53 | 54 | config = ImFontConfig.create 55 | builder = ImFontGlyphRangesBuilder.create 56 | 57 | additional_ranges = ImGui::ImVector_ImWchar_create() # ranges == ImVector_ImWchar* 58 | builder.AddRanges(io[:Fonts].GetGlyphRangesJapanese()) # 常用漢字・人名用漢字を追加します。 59 | builder.AddText(FFI::MemoryPointer.from_string("獰")) # GetGlyphRangesJapaneseに追加したい文字を並べて書きます。 60 | builder.BuildRanges(additional_ranges) 61 | 62 | io[:Fonts].AddFontDefault() 63 | japanese_font = io[:Fonts].AddFontFromFileTTF('./jpfont/GenShinGothic-Normal.ttf', 24.0, config, ImVector.new(additional_ranges)[:Data]) 64 | 65 | mx_buf = ' ' * 8 66 | my_buf = ' ' * 8 67 | winWidth_buf = ' ' * 8 68 | winHeight_buf = ' ' * 8 69 | fbWidth_buf = ' ' * 8 70 | fbHeight_buf = ' ' * 8 71 | while GLFW.WindowShouldClose( window ) == 0 72 | GLFW.PollEvents() 73 | 74 | ImGui::ImplOpenGL2_NewFrame() 75 | ImGui::ImplGlfw_NewFrame() 76 | ImGui::NewFrame() 77 | 78 | ImGui::ShowDemoWindow() 79 | 80 | ImGuiDemo::ShowAboutWindow(nil) 81 | 82 | pos = ImVec2.create(780,320) 83 | ImGui::SetNextWindowPos(pos, ImGuiCond_FirstUseEver) 84 | size = ImVec2.create(480, 700) 85 | ImGui::SetNextWindowSize(size, ImGuiCond_FirstUseEver) 86 | 87 | p_open = nil 88 | window_flags = 0 89 | ImGui::PushFont(japanese_font) 90 | ImGui::Begin("Ruby-ImGui : はじめてのウィンドウ&日本語", p_open, window_flags) 91 | ImGui::TextWrapped(japanese_utf8_text) 92 | ImGui::End() 93 | ImGui::PopFont() 94 | 95 | tab_bar_flags = ImGuiTabBarFlags_None 96 | if ImGui::BeginTabBar("MyTabBar", tab_bar_flags) 97 | if ImGui::BeginTabItem("Avocado") 98 | ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah") 99 | ImGui::EndTabItem() 100 | end 101 | if ImGui::BeginTabItem("Broccoli") 102 | ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah") 103 | ImGui::EndTabItem() 104 | end 105 | if ImGui::BeginTabItem("Cucumber") 106 | ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah") 107 | ImGui::EndTabItem() 108 | end 109 | ImGui::EndTabBar() 110 | end 111 | 112 | ImGui::Render() 113 | GLFW.GetCursorPos(window, mx_buf, my_buf) 114 | GLFW.GetWindowSize(window, winWidth_buf, winHeight_buf) 115 | GLFW.GetFramebufferSize(window, fbWidth_buf, fbHeight_buf) 116 | fbWidth = fbWidth_buf.unpack('L')[0] 117 | fbHeight = fbHeight_buf.unpack('L')[0] 118 | 119 | GL.Viewport(0, 0, fbWidth, fbHeight) 120 | GL.ClearColor(0.45, 0.55, 0.60, 1.00) 121 | GL.Clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT|GL::STENCIL_BUFFER_BIT) 122 | 123 | ImGui::ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()) 124 | 125 | GLFW.MakeContextCurrent( window ) 126 | GLFW.SwapBuffers( window ) 127 | end 128 | 129 | ImGui::ImplOpenGL2_Shutdown() 130 | ImGui::ImplGlfw_Shutdown() 131 | ImGui::DestroyContext(nil) 132 | 133 | GLFW.DestroyWindow(window) 134 | GLFW.Terminate() 135 | end 136 | -------------------------------------------------------------------------------- /examples/test_glfw_opengl3.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | require_relative 'util/setup_dll' 3 | require_relative 'util/setup_opengl_dll' 4 | require_relative './about_window' 5 | 6 | def check_error( desc ) 7 | e = GL.GetError() 8 | if e != GL::NO_ERROR 9 | $stderr.printf "OpenGL error in \"#{desc}\": e=0x%08x\n", e.to_i 10 | exit 11 | else 12 | $stderr.printf "OpenGL no error in \"#{desc}\"\n", e.to_i 13 | end 14 | end 15 | 16 | errorcb = GLFW::create_callback(:GLFWerrorfun) do |error, desc| 17 | printf("GLFW error %d: %s\n", error, desc) 18 | end 19 | 20 | # Press ESC to exit. 21 | key = GLFW::create_callback(:GLFWkeyfun) do |window, key, scancode, action, mods| 22 | if key == GLFW::KEY_ESCAPE && action == GLFW::PRESS 23 | GLFW.SetWindowShouldClose(window, GL::TRUE) 24 | end 25 | end 26 | 27 | if __FILE__ == $PROGRAM_NAME 28 | 29 | GLFW.load_lib(SampleUtil.glfw_library_path) 30 | 31 | if GLFW.Init() == GL::FALSE 32 | puts("Failed to init GLFW.") 33 | exit 34 | end 35 | 36 | w = 1280 37 | h = 720 38 | 39 | window = 0 40 | versions = [[4, 5], [4, 4], [4, 3], [4, 2], [4, 1], [4, 0], 41 | [3, 3], [3, 2], [3, 1], [3, 0], 42 | [2, 1], [2, 0], 43 | [1, 5], [1, 4], [1, 3], [1, 2], [1, 1], [1, 0]] 44 | versions.each do |version| 45 | ver_major = version[0] 46 | ver_minor = version[1] 47 | GLFW.DefaultWindowHints() 48 | if GL.get_platform == :OPENGL_PLATFORM_MACOSX 49 | GLFW.WindowHint(GLFW::OPENGL_FORWARD_COMPAT, GL::TRUE) 50 | end 51 | if ver_major >= 4 || (ver_major >= 3 && ver_minor >= 2) 52 | GLFW.WindowHint(GLFW::OPENGL_PROFILE, GLFW::OPENGL_CORE_PROFILE) 53 | else 54 | GLFW.WindowHint(GLFW::OPENGL_PROFILE, GLFW::OPENGL_ANY_PROFILE) 55 | end 56 | GLFW.WindowHint(GLFW::CONTEXT_VERSION_MAJOR, ver_major) 57 | GLFW.WindowHint(GLFW::CONTEXT_VERSION_MINOR, ver_minor) 58 | window = GLFW.CreateWindow(w, h, "Ruby-ImGui (GLFW+OpenGL3)", nil, nil) 59 | break unless window.null? 60 | end 61 | 62 | if window == 0 63 | GLFW.Terminate() 64 | exit() 65 | end 66 | 67 | GLFW.SetErrorCallback(errorcb) 68 | 69 | 70 | GLFW.SetKeyCallback( window, key ) 71 | 72 | # Init 73 | GLFW.MakeContextCurrent( window ) 74 | GLFW.SwapInterval(1) 75 | 76 | GL.load_lib() 77 | 78 | japanese_utf8_text = IO.readlines('./jpfont/jpfont.txt').join() 79 | 80 | ImGui::CreateContext() 81 | 82 | glsl_version = "#version 410"; 83 | 84 | # ImGui::ImplGlfw_InitForOpenGL(window_ffi, true) 85 | ImGui::ImplGlfw_InitForOpenGL(window, true) 86 | ImGui::ImplOpenGL3_Init(glsl_version) 87 | 88 | io = ImGuiIO.new(ImGui::GetIO()) 89 | 90 | config = ImFontConfig.create 91 | builder = ImFontGlyphRangesBuilder.create 92 | 93 | additional_ranges = ImGui::ImVector_ImWchar_create() # ranges == ImVector_ImWchar* 94 | builder.AddRanges(io[:Fonts].GetGlyphRangesJapanese()) # 常用漢字・人名用漢字を追加します。 95 | builder.AddText(FFI::MemoryPointer.from_string("獰")) # GetGlyphRangesJapaneseに追加したい文字を並べて書きます。 96 | builder.BuildRanges(additional_ranges) 97 | 98 | io[:Fonts].AddFontDefault() 99 | japanese_font = io[:Fonts].AddFontFromFileTTF('./jpfont/GenShinGothic-Normal.ttf', 24.0, config, ImVector.new(additional_ranges)[:Data]) 100 | 101 | mx_buf = ' ' * 8 102 | my_buf = ' ' * 8 103 | winWidth_buf = ' ' * 8 104 | winHeight_buf = ' ' * 8 105 | fbWidth_buf = ' ' * 8 106 | fbHeight_buf = ' ' * 8 107 | while GLFW.WindowShouldClose( window ) == 0 108 | GLFW.PollEvents() 109 | 110 | ImGui::ImplOpenGL3_NewFrame() 111 | ImGui::ImplGlfw_NewFrame() 112 | ImGui::NewFrame() 113 | 114 | ImGui::ShowDemoWindow() 115 | 116 | ImGuiDemo::ShowAboutWindow(nil) 117 | 118 | # See https://github.com/ffi/ffi/wiki/Structs 119 | pos = ImVec2.create(780,320) 120 | ImGui::SetNextWindowPos(pos, ImGuiCond_FirstUseEver) 121 | size = ImVec2.create(480, 700) 122 | ImGui::SetNextWindowSize(size, ImGuiCond_FirstUseEver) 123 | 124 | p_open = nil 125 | window_flags = 0 126 | ImGui::PushFont(japanese_font) 127 | ImGui::Begin("Ruby-ImGui : はじめてのウィンドウ&日本語", p_open, window_flags) 128 | ImGui::TextWrapped(japanese_utf8_text) 129 | ImGui::End() 130 | ImGui::PopFont() 131 | 132 | tab_bar_flags = ImGuiTabBarFlags_None 133 | if ImGui::BeginTabBar("MyTabBar", tab_bar_flags) 134 | if ImGui::BeginTabItem("Avocado") 135 | ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah") 136 | ImGui::EndTabItem() 137 | end 138 | if ImGui::BeginTabItem("Broccoli") 139 | ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah") 140 | ImGui::EndTabItem() 141 | end 142 | if ImGui::BeginTabItem("Cucumber") 143 | ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah") 144 | ImGui::EndTabItem() 145 | end 146 | ImGui::EndTabBar() 147 | end 148 | 149 | ImGui::Render() 150 | GLFW.GetCursorPos(window, mx_buf, my_buf) 151 | GLFW.GetWindowSize(window, winWidth_buf, winHeight_buf) 152 | GLFW.GetFramebufferSize(window, fbWidth_buf, fbHeight_buf) 153 | fbWidth = fbWidth_buf.unpack('L')[0] 154 | fbHeight = fbHeight_buf.unpack('L')[0] 155 | 156 | GL.Viewport(0, 0, fbWidth, fbHeight) 157 | GL.ClearColor(0.45, 0.55, 0.60, 1.00) 158 | GL.Clear(GL::COLOR_BUFFER_BIT) 159 | 160 | ImGui::ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()) 161 | 162 | GLFW.MakeContextCurrent( window ) 163 | GLFW.SwapBuffers( window ) 164 | end 165 | 166 | ImGui::ImplOpenGL3_Shutdown() 167 | ImGui::ImplGlfw_Shutdown() 168 | ImGui::DestroyContext(nil) 169 | 170 | GLFW.DestroyWindow(window) 171 | GLFW.Terminate() 172 | end 173 | -------------------------------------------------------------------------------- /examples/test_sdl2_opengl2.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | require_relative 'util/setup_dll' 3 | require_relative 'util/setup_opengl_dll' 4 | require_relative 'util/setup_sdl2_dll' 5 | require_relative './about_window' 6 | 7 | WINDOW_W = 1280 8 | WINDOW_H = 720 9 | 10 | if __FILE__ == $0 11 | 12 | success = SDL.Init(SDL::INIT_VIDEO | SDL::INIT_TIMER | SDL::INIT_GAMECONTROLLER) 13 | exit if success < 0 14 | 15 | # Setup window 16 | SDL.GL_SetAttribute(SDL::GL_DOUBLEBUFFER, 1) 17 | SDL.GL_SetAttribute(SDL::GL_DEPTH_SIZE, 24) 18 | SDL.GL_SetAttribute(SDL::GL_STENCIL_SIZE, 8) 19 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_MAJOR_VERSION, 2) 20 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_MINOR_VERSION, 2) 21 | window_flags = (SDL::WINDOW_OPENGL | SDL::WINDOW_RESIZABLE | SDL::WINDOW_ALLOW_HIGHDPI) 22 | window = SDL.CreateWindow("Ruby-ImGui (SDL2+OpenGL)", 0, 0, WINDOW_W, WINDOW_H, window_flags) 23 | 24 | gl_context = SDL.GL_CreateContext(window) 25 | SDL.GL_MakeCurrent(window, gl_context) 26 | SDL.GL_SetSwapInterval(1) # Enable vsync 27 | 28 | GL.load_lib() 29 | 30 | japanese_utf8_text = IO.readlines('./jpfont/jpfont.txt').join() 31 | 32 | # Setup Dear ImGui context 33 | ImGui::CreateContext() 34 | io = ImGuiIO.new(ImGui::GetIO()) 35 | 36 | config = ImFontConfig.create 37 | builder = ImFontGlyphRangesBuilder.create 38 | 39 | additional_ranges = ImGui::ImVector_ImWchar_create() # ranges == ImVector_ImWchar* 40 | builder.AddRanges(io[:Fonts].GetGlyphRangesJapanese()) # 常用漢字・人名用漢字を追加します。 41 | builder.AddText(FFI::MemoryPointer.from_string("獰")) # GetGlyphRangesJapaneseに追加したい文字を並べて書きます。 42 | builder.BuildRanges(additional_ranges) 43 | 44 | io[:Fonts].AddFontDefault() 45 | japanese_font = io[:Fonts].AddFontFromFileTTF('./jpfont/GenShinGothic-Normal.ttf', 24.0, config, ImVector.new(additional_ranges)[:Data]) 46 | 47 | # Setup Dear ImGui style 48 | ImGui::StyleColorsDark() 49 | 50 | # Setup Platform/Renderer bindings 51 | ImGui::ImplSDL2_Init(window, nil) 52 | ImGui::ImplOpenGL2_Init() 53 | 54 | event = SDL::Event.new 55 | done = false 56 | until done 57 | while SDL.PollEvent(event) != 0 58 | ImGui::ImplSDL2_ProcessEvent(event) 59 | done = true if event[:type] == SDL::QUIT 60 | 61 | # 'type' and 'timestamp' are common members for all SDL Event structs. 62 | event_type = event[:common][:type] 63 | # event_timestamp = event[:common][:timestamp] 64 | # puts "Event : type=0x#{event_type.to_s(16)}, timestamp=#{event_timestamp}" 65 | case event_type 66 | when SDL::KEYDOWN 67 | if event[:key][:keysym][:sym] == SDL::SDLK_ESCAPE 68 | done = true 69 | end 70 | end 71 | end 72 | 73 | # Start the Dear ImGui frame 74 | ImGui::ImplOpenGL2_NewFrame() 75 | ImGui::ImplSDL2_NewFrame() 76 | ImGui::NewFrame() 77 | 78 | ImGui::ShowDemoWindow() 79 | 80 | ImGuiDemo::ShowAboutWindow(nil) 81 | 82 | # See https://github.com/ffi/ffi/wiki/Structs 83 | pos = ImVec2.create(780,320) 84 | ImGui::SetNextWindowPos(pos, ImGuiCond_FirstUseEver) 85 | size = ImVec2.create(480, 700) 86 | ImGui::SetNextWindowSize(size, ImGuiCond_FirstUseEver) 87 | 88 | p_open = nil 89 | window_flags = 0 90 | ImGui::PushFont(japanese_font) 91 | ImGui::Begin("Ruby-ImGui : はじめてのウィンドウ&日本語", p_open, window_flags) 92 | ImGui::TextWrapped(japanese_utf8_text) 93 | ImGui::End() 94 | ImGui::PopFont() 95 | 96 | tab_bar_flags = ImGuiTabBarFlags_None 97 | if ImGui::BeginTabBar("MyTabBar", tab_bar_flags) 98 | if ImGui::BeginTabItem("Avocado") 99 | ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah") 100 | ImGui::EndTabItem() 101 | end 102 | if ImGui::BeginTabItem("Broccoli") 103 | ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah") 104 | ImGui::EndTabItem() 105 | end 106 | if ImGui::BeginTabItem("Cucumber") 107 | ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah") 108 | ImGui::EndTabItem() 109 | end 110 | ImGui::EndTabBar() 111 | end 112 | 113 | ImGui::Render() 114 | GL.Viewport(0, 0, io[:DisplaySize][:x].to_i, io[:DisplaySize][:y].to_i) 115 | GL.ClearColor(0.45, 0.55, 0.60, 1.00) 116 | GL.Clear(GL::COLOR_BUFFER_BIT) 117 | 118 | ImGui::ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()) 119 | SDL.GL_SwapWindow(window) 120 | end 121 | 122 | ImGui::ImplOpenGL2_Shutdown() 123 | ImGui::ImplSDL2_Shutdown() 124 | ImGui::DestroyContext(nil) 125 | 126 | SDL.GL_DeleteContext(gl_context) 127 | SDL.DestroyWindow(window) 128 | SDL.Quit() 129 | end 130 | -------------------------------------------------------------------------------- /examples/test_sdl2_opengl3.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | require_relative 'util/setup_dll' 4 | require_relative 'util/setup_opengl_dll' 5 | require_relative 'util/setup_sdl2_dll' 6 | require_relative './about_window' 7 | 8 | WINDOW_W = 1280 9 | WINDOW_H = 720 10 | 11 | def check_error( desc ) 12 | e = glGetError() 13 | if e != GL_NO_ERROR 14 | $stderr.printf "OpenGL error in \"#{desc}\": e=0x%08x\n", e.to_i 15 | exit 16 | else 17 | $stderr.printf "OpenGL no error in \"#{desc}\"\n", e.to_i 18 | end 19 | end 20 | 21 | if __FILE__ == $PROGRAM_NAME 22 | 23 | success = SDL.Init(SDL::INIT_VIDEO | SDL::INIT_TIMER | SDL::INIT_GAMECONTROLLER) 24 | exit if success < 0 25 | 26 | # Setup window 27 | # __APPLE__ 28 | glsl_version = "#version 410"; 29 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_FLAGS, SDL::GL_CONTEXT_FORWARD_COMPATIBLE_FLAG) # __APPLE__ 30 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_PROFILE_MASK, SDL::GL_CONTEXT_PROFILE_CORE) 31 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_MAJOR_VERSION, 4) 32 | SDL.GL_SetAttribute(SDL::GL_CONTEXT_MINOR_VERSION, 1) 33 | 34 | SDL.GL_SetAttribute(SDL::GL_DOUBLEBUFFER, 1) 35 | SDL.GL_SetAttribute(SDL::GL_DEPTH_SIZE, 24) 36 | SDL.GL_SetAttribute(SDL::GL_STENCIL_SIZE, 8) 37 | window_flags = (SDL::WINDOW_OPENGL | SDL::WINDOW_RESIZABLE | SDL::WINDOW_ALLOW_HIGHDPI) 38 | window = SDL.CreateWindow("Ruby-ImGui (SDL2+OpenGL3)", 0, 0, WINDOW_W, WINDOW_H, window_flags) 39 | gl_context = SDL.GL_CreateContext(window) 40 | 41 | SDL.GL_MakeCurrent(window, gl_context) 42 | SDL.GL_SetSwapInterval(1) # Enable vsync 43 | 44 | GL.load_lib() 45 | 46 | japanese_utf8_text = IO.readlines('./jpfont/jpfont.txt').join() 47 | 48 | # Setup Dear ImGui context 49 | ImGui::CreateContext() 50 | io = ImGuiIO.new(ImGui::GetIO()) 51 | 52 | config = ImFontConfig.create 53 | builder = ImFontGlyphRangesBuilder.create 54 | 55 | additional_ranges = ImGui::ImVector_ImWchar_create() # ranges == ImVector_ImWchar* 56 | builder.AddRanges(io[:Fonts].GetGlyphRangesJapanese()) # 常用漢字・人名用漢字を追加します。 57 | builder.AddText(FFI::MemoryPointer.from_string("獰")) # GetGlyphRangesJapaneseに追加したい文字を並べて書きます。 58 | builder.BuildRanges(additional_ranges) 59 | 60 | io[:Fonts].AddFontDefault() 61 | japanese_font = io[:Fonts].AddFontFromFileTTF('./jpfont/GenShinGothic-Normal.ttf', 24.0, config, ImVector.new(additional_ranges)[:Data]) 62 | 63 | # Setup Dear ImGui style 64 | ImGui::StyleColorsDark() 65 | 66 | # Setup Platform/Renderer bindings 67 | ImGui::ImplSDL2_Init(window, nil) 68 | ImGui::ImplOpenGL3_Init(glsl_version) 69 | 70 | event = SDL::Event.new 71 | done = false 72 | until done 73 | while SDL.PollEvent(event) != 0 74 | ImGui::ImplSDL2_ProcessEvent(event) 75 | done = true if event[:type] == SDL::QUIT 76 | 77 | # 'type' and 'timestamp' are common members for all SDL Event structs. 78 | event_type = event[:common][:type] 79 | # event_timestamp = event[:common][:timestamp] 80 | # puts "Event : type=0x#{event_type.to_s(16)}, timestamp=#{event_timestamp}" 81 | case event_type 82 | when SDL::KEYDOWN 83 | if event[:key][:keysym][:sym] == SDL::SDLK_ESCAPE 84 | done = true 85 | end 86 | end 87 | end 88 | 89 | # Start the Dear ImGui frame 90 | ImGui::ImplOpenGL3_NewFrame() 91 | ImGui::ImplSDL2_NewFrame() 92 | ImGui::NewFrame() 93 | 94 | ImGui::ShowDemoWindow() 95 | 96 | ImGuiDemo::ShowAboutWindow(nil) 97 | 98 | # See https://github.com/ffi/ffi/wiki/Structs 99 | pos = ImVec2.create(780,320) 100 | ImGui::SetNextWindowPos(pos, ImGuiCond_FirstUseEver) 101 | size = ImVec2.create(480, 700) 102 | ImGui::SetNextWindowSize(size, ImGuiCond_FirstUseEver) 103 | 104 | p_open = nil 105 | window_flags = 0 106 | ImGui::PushFont(japanese_font) 107 | ImGui::Begin("Ruby-ImGui : はじめてのウィンドウ&日本語", p_open, window_flags) 108 | ImGui::TextWrapped(japanese_utf8_text) 109 | ImGui::End() 110 | ImGui::PopFont() 111 | 112 | tab_bar_flags = ImGuiTabBarFlags_None 113 | if ImGui::BeginTabBar("MyTabBar", tab_bar_flags) 114 | if ImGui::BeginTabItem("Avocado") 115 | ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah") 116 | ImGui::EndTabItem() 117 | end 118 | if ImGui::BeginTabItem("Broccoli") 119 | ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah") 120 | ImGui::EndTabItem() 121 | end 122 | if ImGui::BeginTabItem("Cucumber") 123 | ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah") 124 | ImGui::EndTabItem() 125 | end 126 | ImGui::EndTabBar() 127 | end 128 | 129 | ImGui::Render() 130 | GL.Viewport(0, 0, io[:DisplaySize][:x].to_i, io[:DisplaySize][:y].to_i) 131 | GL.ClearColor(0.45, 0.55, 0.60, 1.00) 132 | GL.Clear(GL::COLOR_BUFFER_BIT) 133 | 134 | ImGui::ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()) 135 | SDL.GL_SwapWindow(window) 136 | end 137 | 138 | ImGui::ImplOpenGL3_Shutdown() 139 | ImGui::ImplSDL2_Shutdown() 140 | ImGui::DestroyContext(nil) 141 | 142 | SDL.GL_DeleteContext(gl_context) 143 | SDL.DestroyWindow(window) 144 | SDL.Quit() 145 | end 146 | -------------------------------------------------------------------------------- /examples/test_sdl2_sdlrenderer.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | require_relative 'util/setup_dll' 4 | require_relative 'util/setup_sdl2_dll' 5 | require_relative './about_window' 6 | 7 | WINDOW_W = 1280 8 | WINDOW_H = 720 9 | 10 | if __FILE__ == $PROGRAM_NAME 11 | 12 | # Windows 13 | # SDL_SetHint(SDL_HINT_RENDER_DRIVER, "direct3d11") 14 | 15 | success = SDL.Init(SDL::INIT_VIDEO | SDL::INIT_TIMER | SDL::INIT_GAMECONTROLLER) 16 | exit if success < 0 17 | 18 | # Setup window 19 | window_flags = (SDL::WINDOW_RESIZABLE)# | SDL::WINDOW_ALLOW_HIGHDPI) # [FIXME] Correct wrong clipping problem caused when we enable ALLOW_HIGHDPI 20 | window = SDL.CreateWindow("Ruby-ImGui (SDL2+SDL_Renderer)", 64, 64, WINDOW_W, WINDOW_H, window_flags) 21 | 22 | # Setup SDL_Renderer instance 23 | renderer = SDL.CreateRenderer(window, -1, SDL::RENDERER_PRESENTVSYNC | SDL::RENDERER_ACCELERATED) 24 | if renderer == nil 25 | SDL.Log("Error creating SDL_Renderer!") 26 | exit 27 | end 28 | 29 | japanese_utf8_text = IO.readlines('./jpfont/jpfont.txt').join() 30 | 31 | # Setup Dear ImGui context 32 | ImGui::CreateContext() 33 | io = ImGuiIO.new(ImGui::GetIO()) 34 | 35 | config = ImFontConfig.create 36 | builder = ImFontGlyphRangesBuilder.create 37 | 38 | additional_ranges = ImGui::ImVector_ImWchar_create() # ranges == ImVector_ImWchar* 39 | builder.AddRanges(io[:Fonts].GetGlyphRangesJapanese()) # 常用漢字・人名用漢字を追加します。 40 | builder.AddText(FFI::MemoryPointer.from_string("獰")) # GetGlyphRangesJapaneseに追加したい文字を並べて書きます。 41 | builder.BuildRanges(additional_ranges) 42 | 43 | io[:Fonts].AddFontDefault() 44 | japanese_font = io[:Fonts].AddFontFromFileTTF('./jpfont/GenShinGothic-Normal.ttf', 24.0, config, ImVector.new(additional_ranges)[:Data]) 45 | 46 | # Setup Dear ImGui style 47 | ImGui::StyleColorsDark() 48 | 49 | # Setup Platform/Renderer bindings 50 | ImGui::ImplSDL2_Init(window, nil) 51 | ImGui::ImplSDLRenderer_Init(renderer) 52 | 53 | event = SDL::Event.new 54 | done = false 55 | until done 56 | while SDL.PollEvent(event) != 0 57 | ImGui::ImplSDL2_ProcessEvent(event) 58 | done = true if event[:type] == SDL::QUIT 59 | 60 | # 'type' and 'timestamp' are common members for all SDL Event structs. 61 | event_type = event[:common][:type] 62 | event_timestamp = event[:common][:timestamp] 63 | # puts "Event : type=0x#{event_type.to_s(16)}, timestamp=#{event_timestamp}" 64 | case event_type 65 | when SDL::KEYDOWN 66 | if event[:key][:keysym][:sym] == SDL::SDLK_ESCAPE 67 | done = true 68 | end 69 | end 70 | end 71 | 72 | # Start the Dear ImGui frame 73 | ImGui::ImplSDLRenderer_NewFrame() 74 | ImGui::ImplSDL2_NewFrame() 75 | ImGui::NewFrame() 76 | 77 | ImGui::ShowDemoWindow() 78 | 79 | ImGuiDemo::ShowAboutWindow(nil) 80 | 81 | # See https://github.com/ffi/ffi/wiki/Structs 82 | pos = ImVec2.create(50, 20) 83 | ImGui::SetNextWindowPos(pos, ImGuiCond_FirstUseEver) 84 | 85 | p_open = nil 86 | window_flags = ImGuiWindowFlags_AlwaysAutoResize 87 | ImGui::PushFont(japanese_font) 88 | ImGui::Begin("Ruby-ImGui : はじめてのウィンドウ&日本語", p_open, window_flags) 89 | ImGui::Text("Loaded shared library '%s'", :string, $lib_path) # See https://github.com/ffi/ffi/wiki/Examples#using-varargs 90 | ImGui::TextWrapped(japanese_utf8_text) 91 | ImGui::End() 92 | ImGui::PopFont() 93 | 94 | tab_bar_flags = ImGuiTabBarFlags_None 95 | if ImGui::BeginTabBar("MyTabBar", tab_bar_flags) 96 | if ImGui::BeginTabItem("Avocado") 97 | ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah") 98 | ImGui::EndTabItem() 99 | end 100 | if ImGui::BeginTabItem("Broccoli") 101 | ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah") 102 | ImGui::EndTabItem() 103 | end 104 | if ImGui::BeginTabItem("Cucumber") 105 | ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah") 106 | ImGui::EndTabItem() 107 | end 108 | ImGui::EndTabBar() 109 | end 110 | 111 | ImGui::Render() 112 | SDL.SetRenderDrawColor(renderer, (0.45 * 255).to_i, (0.55 * 255).to_i, (0.60 * 255).to_i, (1.0 * 255).to_i) 113 | SDL.RenderClear(renderer) 114 | ImGui::ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData()) 115 | SDL.RenderPresent(renderer) 116 | end 117 | 118 | ImGui::ImplSDLRenderer_Shutdown() 119 | ImGui::ImplSDL2_Shutdown() 120 | ImGui::DestroyContext(nil) 121 | 122 | SDL.DestroyRenderer(renderer) 123 | SDL.DestroyWindow(window) 124 | SDL.Quit() 125 | end 126 | -------------------------------------------------------------------------------- /examples/util/setup_dll.rb: -------------------------------------------------------------------------------- 1 | def imgui_bindings_gem_available? 2 | Gem::Specification.find_by_name('imgui-bindings') 3 | rescue Gem::LoadError 4 | false 5 | rescue 6 | Gem.available?('imgui-bindings') 7 | end 8 | 9 | if imgui_bindings_gem_available? 10 | # puts("Loading from Gem system path.") 11 | require 'imgui' 12 | require 'imgui_impl_opengl2' 13 | require 'imgui_impl_opengl3' 14 | require 'imgui_impl_glfw' 15 | 16 | s = Gem::Specification.find_by_name('imgui-bindings') 17 | shared_lib_path = s.full_gem_path + '/lib/' 18 | 19 | case RUBY_PLATFORM 20 | when /mswin|msys|mingw|cygwin/ 21 | ImGui.load_lib(shared_lib_path + 'imgui.dll') 22 | when /darwin/ 23 | arch = RUBY_PLATFORM.split('-')[0] 24 | ImGui.load_lib(shared_lib_path + "imgui.#{arch}.dylib") 25 | when /linux/ 26 | arch = RUBY_PLATFORM.split('-')[0] 27 | ImGui.load_lib(shared_lib_path + "imgui.#{arch}.so") 28 | else 29 | raise RuntimeError, "setup_dll.rb : Unknown OS: #{RUBY_PLATFORM}" 30 | end 31 | else 32 | # puts("Loaging from local path.") 33 | require '../lib/imgui' 34 | require_relative '../../lib/imgui_impl_opengl2' 35 | require_relative '../../lib/imgui_impl_opengl3' 36 | require_relative '../../lib/imgui_impl_glfw' 37 | 38 | case RUBY_PLATFORM 39 | when /mswin|msys|mingw|cygwin/ 40 | ImGui.load_lib(Dir.pwd + '/../lib/' + 'imgui.dll') 41 | when /darwin/ 42 | arch = RUBY_PLATFORM.split('-')[0] 43 | ImGui.load_lib(Dir.pwd + '/../lib/' + "imgui.#{arch}.dylib") 44 | when /linux/ 45 | arch = RUBY_PLATFORM.split('-')[0] 46 | ImGui.load_lib(Dir.pwd + '/../lib/' + "imgui.#{arch}.so") 47 | else 48 | raise RuntimeError, "setup_dll.rb : Unknown OS: #{RUBY_PLATFORM}" 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /examples/util/setup_opengl_dll.rb: -------------------------------------------------------------------------------- 1 | require 'opengl' 2 | require 'glfw' 3 | 4 | module SampleUtil 5 | 6 | def self.gl_library_path() 7 | case GL.get_platform 8 | when :OPENGL_PLATFORM_WINDOWS 9 | 'C:/Windows/System32/opengl32.dll' 10 | when :OPENGL_PLATFORM_MACOSX 11 | '/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib' 12 | when :OPENGL_PLATFORM_LINUX 13 | "/usr/lib/#{RUBY_PLATFORM}-gnu/libGL.so" 14 | else 15 | raise RuntimeError, "Unsupported platform." 16 | end 17 | end 18 | 19 | def self.glfw_library_path() 20 | case GL.get_platform 21 | when :OPENGL_PLATFORM_WINDOWS 22 | Dir.pwd + '/glfw3.dll' 23 | when :OPENGL_PLATFORM_MACOSX 24 | './libglfw.dylib' 25 | when :OPENGL_PLATFORM_LINUX 26 | "/usr/lib/#{RUBY_PLATFORM}-gnu/libglfw.so.3" 27 | else 28 | raise RuntimeError, "Unsupported platform." 29 | end 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /examples/util/setup_sdl2_dll.rb: -------------------------------------------------------------------------------- 1 | def sdl2_bindings_gem_available? 2 | Gem::Specification.find_by_name('sdl2-bindings') 3 | rescue Gem::LoadError 4 | false 5 | rescue 6 | Gem.available?('sdl2-bindings') 7 | end 8 | 9 | if sdl2_bindings_gem_available? 10 | # puts("Loading from Gem system path.") 11 | require 'sdl2' 12 | require_relative 'imgui_impl_sdl2' 13 | require_relative 'imgui_impl_sdlrenderer' 14 | else 15 | # puts("Loaging from local path.") 16 | require '../../lib/sdl2' 17 | require_relative '../../lib/imgui_impl_sdl2' 18 | require_relative '../../lib/imgui_impl_sdlrenderer' 19 | end 20 | 21 | case RUBY_PLATFORM 22 | when /mswin|msys|mingw|cygwin/ 23 | SDL.load_lib(Dir.pwd + '/' + 'SDL2.dll') 24 | when /darwin/ 25 | SDL.load_lib(Dir.pwd + '/' + 'libSDL2.dylib') 26 | when /linux/ 27 | SDL.load_lib("/usr/lib/#{RUBY_PLATFORM}-gnu/libSDL2.so") 28 | else 29 | raise RuntimeError, "Unknown OS: #{RUBY_PLATFORM}" 30 | end 31 | -------------------------------------------------------------------------------- /generator/README.md: -------------------------------------------------------------------------------- 1 | # Using generate_imgui.rb # 2 | 3 | ## Update cimgui ## 4 | 5 | $ pwd 6 | ~/ruby-imgui 7 | 8 | $ cd cimgui 9 | $ git pull origin master <- get latest cimgui 10 | $ git submodule update <- get cimgui/imgui 11 | 12 | ## Generate JSON files ## 13 | 14 | Setup luajit first: 15 | 16 | On macOS: 17 | $ brew install luajit 18 | 19 | On Windows you can obtain LuaJIT via MSYS2 package manager: 20 | > pacman -S mingw-w64-ucrt-x86_64-luajit 21 | 22 | Generate JSON (definitions.json, etc.) files that contain only public definitions: 23 | 24 | $ pwd 25 | ~/ruby-imgui 26 | 27 | $ cd cimgui/generator 28 | $ luajit ./generator.lua {clang|gcc} "" 29 | 30 | ## Run generator ## 31 | 32 | $ pwd 33 | ~/ruby-imgui 34 | 35 | $ cd generator 36 | $ ruby generate_imgui.rb 37 | -------------------------------------------------------------------------------- /imgui-bindings.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "imgui-bindings" 7 | spec.version = "0.1.17" 8 | spec.authors = ["vaiorabbit"] 9 | spec.email = ["vaiorabbit@gmail.com"] 10 | spec.summary = %q{Bindings for Dear ImGui} 11 | spec.homepage = "https://github.com/vaiorabbit/ruby-imgui" 12 | spec.require_paths = ["lib"] 13 | spec.license = "Zlib" 14 | spec.description = <<-DESC 15 | Ruby bindings for Dear ImGui ( https://github.com/ocornut/imgui ). 16 | DESC 17 | 18 | spec.required_ruby_version = '>= 3.0.0' 19 | 20 | spec.add_runtime_dependency 'ffi', '~> 1.16' 21 | spec.add_runtime_dependency 'opengl-bindings2', '~> 2' 22 | 23 | spec.files = Dir.glob("lib/*.rb") + 24 | ["README.md", "LICENSE.txt", "ChangeLog"] 25 | 26 | if spec.platform == "ruby" 27 | spec.files += Dir.glob("lib/*") 28 | else 29 | case spec.platform.os 30 | when "linux" 31 | if spec.platform.cpu == "aarch64" 32 | spec.files += Dir.glob("lib/*.aarch64.so") 33 | elsif spec.platform.cpu == "x86_64" 34 | spec.files += Dir.glob("lib/*.x86_64.so") 35 | else 36 | raise ArgumentError 37 | end 38 | when "darwin" 39 | if spec.platform.cpu == "arm64" 40 | spec.files += Dir.glob("lib/*.arm64.dylib") 41 | elsif spec.platform.cpu == "x86_64" 42 | spec.files += Dir.glob("lib/*.x86_64.dylib") 43 | else 44 | raise ArgumentError 45 | end 46 | when "mingw" 47 | if spec.platform.cpu == "x64" 48 | spec.files += Dir.glob("lib/*.dll") 49 | else 50 | raise ArgumentError 51 | end 52 | else 53 | raise ArgumentError 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /imgui_dll/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | Project(imgui) 2 | cmake_minimum_required(VERSION 3.0) 3 | 4 | set (CMAKE_CXX_STANDARD 11) 5 | 6 | include_directories( ${CMAKE_CURRENT_LIST_DIR}/cimgui ) 7 | include_directories( ${CMAKE_CURRENT_LIST_DIR}/cimgui/imgui ) 8 | include_directories(.) 9 | 10 | add_definitions("-DIMGUI_DISABLE_OBSOLETE_FUNCTIONS=1") 11 | 12 | set(IMGUI_SOURCES 13 | ${CMAKE_CURRENT_LIST_DIR}/cimgui/cimgui.cpp 14 | ${CMAKE_CURRENT_LIST_DIR}/cimgui/imgui/imgui.cpp 15 | ${CMAKE_CURRENT_LIST_DIR}/cimgui/imgui/imgui_draw.cpp 16 | ${CMAKE_CURRENT_LIST_DIR}/cimgui/imgui/imgui_demo.cpp 17 | ${CMAKE_CURRENT_LIST_DIR}/cimgui/imgui/imgui_tables.cpp 18 | ${CMAKE_CURRENT_LIST_DIR}/cimgui/imgui/imgui_widgets.cpp 19 | ${CMAKE_CURRENT_LIST_DIR}/cimgui_internal.cpp 20 | ) 21 | 22 | set(IMGUI_LIBRARIES ) 23 | 24 | # For " Policy CMP0042 is not set: MACOSX_RPATH is enabled by default." 25 | if (APPLE) 26 | set(CMAKE_MACOSX_RPATH ON) 27 | endif (APPLE) 28 | 29 | if (WIN32) 30 | add_definitions("-DIMGUI_IMPL_API=extern \"C\" __declspec\(dllexport\)") 31 | else(WIN32) 32 | add_definitions("-DIMGUI_IMPL_API=extern \"C\" ") 33 | endif(WIN32) 34 | 35 | set(IMGUI_STATIC "no" CACHE STRING "Build as a static library") 36 | 37 | #add library and link 38 | if (IMGUI_STATIC) 39 | add_library(imgui STATIC ${IMGUI_SOURCES}) 40 | else (IMGUI_STATIC) 41 | add_library(imgui SHARED ${IMGUI_SOURCES}) 42 | if (WIN32) 43 | target_link_libraries(imgui imm32) 44 | # Export all original ImGui symbols to support other libraries (e.g. ImNodes) 45 | # Note that these settings below didn't work as I expeced on Windows/MSys2 environment. 46 | # set(WINDOWS_EXPORT_ALL_SYMBOLS ON) 47 | # set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1) 48 | # So I add linker option 'export-all-symbols' explicitly. 49 | set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols") 50 | endif(WIN32) 51 | endif (IMGUI_STATIC) 52 | 53 | set_target_properties(imgui PROPERTIES PREFIX "") 54 | 55 | if (APPLE) 56 | set_target_properties(imgui PROPERTIES 57 | XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "" 58 | ) 59 | endif (APPLE) 60 | 61 | 62 | #install 63 | install(TARGETS imgui 64 | RUNTIME DESTINATION . 65 | LIBRARY DESTINATION . 66 | ARCHIVE DESTINATION . 67 | ) 68 | -------------------------------------------------------------------------------- /imgui_dll/build_imgui_linux.sh: -------------------------------------------------------------------------------- 1 | mkdir build 2 | cd build 3 | cmake -D CMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=ON -D CMAKE_CXX_COMPILER=clang++ ../ 4 | cmake --build . 5 | arch=`uname -m` 6 | cp imgui.so ../../lib/imgui.${arch}.so 7 | -------------------------------------------------------------------------------- /imgui_dll/build_imgui_linux_cross.sh: -------------------------------------------------------------------------------- 1 | mkdir -p build 2 | cd build 3 | cmake -D CMAKE_VERBOSE_MAKEFILE:BOOL=ON -D CMAKE_CXX_FLAGS=-isystem\ /usr/aarch64-linux-gnu/include -D CMAKE_BUILD_TYPE=Release -D CMAKE_CXX_COMPILER_TARGET=aarch64-linux-gnu -D CMAKE_SYSTEM_PROCESSOR=ARM -D BUILD_SHARED_LIBS=ON -D CMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ ../ 4 | cmake --build . 5 | export ARCH=aarch64 6 | cp imgui.so ../../lib/imgui.${ARCH}.so 7 | -------------------------------------------------------------------------------- /imgui_dll/build_imgui_macos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export CMAKE_OSX_DEPLOYMENT_TARGET=15.0 3 | 4 | mkdir -p build_x86_64 5 | cd build_x86_64 6 | cmake -D CMAKE_C_FLAGS="" -D CMAKE_BUILD_TYPE=Release -D CMAKE_OSX_ARCHITECTURES="x86_64" -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=clang ../ 7 | cmake --build . 8 | cp imgui.dylib ../../lib/imgui.x86_64.dylib 9 | 10 | cd .. 11 | 12 | mkdir -p build_arm64 13 | cd build_arm64 14 | cmake -D CMAKE_C_FLAGS="" -D CMAKE_BUILD_TYPE=Release -D CMAKE_OSX_ARCHITECTURES="arm64" -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=clang ../ 15 | cmake --build . 16 | cp imgui.dylib ../../lib/imgui.arm64.dylib 17 | -------------------------------------------------------------------------------- /imgui_dll/build_imgui_windows.cmd: -------------------------------------------------------------------------------- 1 | :: 2 | :: For Windows + RubyInstaller2 with DevKit(MSYS2 gcc & make) + CMake users. 3 | :: - Use this script after "ridk enable"d. See https://github.com/oneclick/rubyinstaller2/wiki/The-ridk-tool for details. 4 | :: 5 | :: Usage 6 | :: > ridk enable 7 | :: > imgui_dll_build.bat <- %PROGRAMFILES%\CMake\bin\cmake.exe will be used. 8 | :: > imgui_dll_build.bat "D:\Program Files\CMake\bin\cmake.exe" <- You can give full path to 'cmake.exe'. 9 | 10 | @echo off 11 | setlocal enabledelayedexpansion 12 | set CMAKE_EXE=%1 13 | if "%CMAKE_EXE%"=="" ( 14 | set CMAKE_EXE="%PROGRAMFILES%\CMake\bin\cmake" 15 | ) 16 | 17 | pushd %~dp0 18 | if not exist build ( 19 | mkdir build 20 | ) 21 | cd build 22 | %CMAKE_EXE% -G "MSYS Makefiles" -D CMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=gcc ../ 23 | %CMAKE_EXE% --build . 24 | copy imgui.dll ..\..\lib 25 | popd 26 | -------------------------------------------------------------------------------- /imgui_dll/cimgui_internal.cpp: -------------------------------------------------------------------------------- 1 | #include "cimgui/imgui/imgui.h" 2 | #include "cimgui/imgui/imgui_internal.h" 3 | #include "./cimgui_internal.h" 4 | 5 | CIMGUI_API void igFocusWindow(ImGuiWindow* window) 6 | { 7 | return ImGui::FocusWindow(window); 8 | } 9 | CIMGUI_API ImGuiWindow* igGetCurrentWindow() 10 | { 11 | return ImGui::GetCurrentWindow(); 12 | } 13 | -------------------------------------------------------------------------------- /imgui_dll/cimgui_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef CIMGUI_INTERNAL_INCLUDED 2 | #define CIMGUI_INTERNAL_INCLUDED 3 | 4 | #include "cimgui/cimgui.h" 5 | 6 | CIMGUI_API void igFocusWindow(ImGuiWindow* window); 7 | CIMGUI_API ImGuiWindow* igGetCurrentWindow(void); 8 | 9 | #endif //CIMGUI_INTERNAL_INCLUDED 10 | -------------------------------------------------------------------------------- /imgui_dll/imgui_dll_build_debug.sh: -------------------------------------------------------------------------------- 1 | # 2 | # For Mac OS X + Xcode + CMake users. 3 | # 4 | mkdir build 5 | cd build 6 | export MACOSX_DEPLOYMENT_TARGET=11.5 7 | # cmake -D CMAKE_BUILD_TYPE=Debug -D CMAKE_OSX_ARCHITECTURES="x86_64;arm64" -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=clang ../ 8 | cmake -D CMAKE_BUILD_TYPE=Debug -D CMAKE_OSX_ARCHITECTURES="arm64" -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=clang ../ 9 | make 10 | cp *.dylib ../../lib 11 | -------------------------------------------------------------------------------- /imnodes_dll/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.17.1 ) 2 | project( ImNodes ) 3 | 4 | file(GLOB IMNODES_LIB_HDRS "${CMAKE_CURRENT_LIST_DIR}/ImNodes/Im*.h") 5 | file(GLOB IMNODES_LIB_SRCS "${CMAKE_CURRENT_LIST_DIR}/ImNodes/Im*.cpp") 6 | add_library(ImNodes SHARED ${IMNODES_LIB_HDRS} ${IMNODES_LIB_SRCS}) 7 | target_sources(ImNodes PUBLIC "${CMAKE_CURRENT_LIST_DIR}/ImNodesCAPI.h") 8 | target_sources(ImNodes PRIVATE "${CMAKE_CURRENT_LIST_DIR}/ImNodesCAPI.cpp") 9 | include_directories( ${CMAKE_CURRENT_LIST_DIR}/../imgui_dll/cimgui/imgui ) 10 | 11 | if (CMAKE_HOST_WIN32) 12 | add_library(imgui SHARED IMPORTED) 13 | set_target_properties(imgui PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../imgui_dll/build) 14 | set_target_properties(imgui PROPERTIES IMPORTED_IMPLIB ${CMAKE_CURRENT_SOURCE_DIR}/../imgui_dll/build/libimgui.dll.a) 15 | target_link_libraries(ImNodes imgui) 16 | elseif (CMAKE_HOST_APPLE) 17 | target_link_libraries(ImNodes ${CMAKE_CURRENT_SOURCE_DIR}/../lib/imgui.${CMAKE_OSX_ARCHITECTURES}.dylib) 18 | else() 19 | add_library(imgui SHARED IMPORTED) 20 | if (DEFINED CROSS_BUILD_PLATFORM) 21 | set_target_properties(imgui PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../lib/imgui.${CROSS_BUILD_PLATFORM}.so) 22 | #set_target_properties(imgui PROPERTIES IMPORTED_SONAME ${CMAKE_CURRENT_SOURCE_DIR}/../lib/imgui.${CROSS_BUILD_PLATFORM}.so) 23 | target_link_libraries(ImNodes imgui) 24 | else() 25 | set_target_properties(imgui PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../lib/imgui.${CMAKE_HOST_SYSTEM_PROCESSOR}.so) 26 | #set_target_properties(imgui PROPERTIES IMPORTED_SONAME ${CMAKE_CURRENT_SOURCE_DIR}/../lib/imgui.${CMAKE_HOST_SYSTEM_PROCESSOR}.so) 27 | target_link_libraries(ImNodes imgui) 28 | endif() 29 | endif() 30 | 31 | set_target_properties(ImNodes PROPERTIES PREFIX "") 32 | set_target_properties(ImNodes PROPERTIES OUTPUT_NAME "imnodes") 33 | 34 | set_target_properties(ImNodes PROPERTIES 35 | CXX_STANDARD 14 36 | CXX_STANDARD_REQUIRED YES 37 | CXX_EXTENSIONS NO 38 | ) 39 | -------------------------------------------------------------------------------- /imnodes_dll/ImNodesCAPI.cpp: -------------------------------------------------------------------------------- 1 | #include "ImNodesCAPI.h" 2 | 3 | //////////////////////////////////////////////////////////////////////////////////////////////////// 4 | // CanvasState 5 | 6 | ImNodesCanvasState* ImNodesCanvasStateCtor() 7 | { 8 | return IM_NEW(ImNodes::CanvasState); 9 | } 10 | 11 | void ImNodesCanvasStateDtor(ImNodesCanvasState* instance) 12 | { 13 | IM_DELETE(instance); 14 | } 15 | 16 | //////////////////////////////////////////////////////////////////////////////////////////////////// 17 | // Public API (Base) 18 | 19 | void ImNodesBeginCanvas(ImNodesCanvasState* canvas) 20 | { 21 | ImNodes::BeginCanvas(canvas); 22 | } 23 | 24 | void ImNodesEndCanvas() 25 | { 26 | ImNodes::EndCanvas(); 27 | } 28 | 29 | bool ImNodesBeginNode(void* node_id, ImVec2* pos, bool* selected) 30 | { 31 | return ImNodes::BeginNode(node_id, pos, selected); 32 | } 33 | 34 | void ImNodesEndNode() 35 | { 36 | ImNodes::EndNode(); 37 | } 38 | 39 | bool ImNodesIsNodeHovered() 40 | { 41 | return ImNodes::IsNodeHovered(); 42 | } 43 | 44 | void ImNodesAutoPositionNode(void* node_id) 45 | { 46 | ImNodes::AutoPositionNode(node_id); 47 | } 48 | 49 | bool ImNodesGetNewConnection(void** input_node, const char** input_slot_title, void** output_node, const char** output_slot_title) 50 | { 51 | return ImNodes::GetNewConnection(input_node, input_slot_title, output_node, output_slot_title); 52 | } 53 | 54 | bool ImNodesGetPendingConnection(void** node_id, const char** slot_title, int* slot_kind) 55 | { 56 | return ImNodes::GetPendingConnection(node_id, slot_title, slot_kind); 57 | } 58 | 59 | bool ImNodesConnection(void* input_node, const char* input_slot, void* output_node, const char* output_slot) 60 | { 61 | return ImNodes::Connection(input_node, input_slot, output_node, output_slot); 62 | } 63 | 64 | ImNodesCanvasState* ImNodesGetCurrentCanvas() 65 | { 66 | return ImNodes::GetCurrentCanvas(); 67 | } 68 | 69 | int ImNodesInputSlotKind(int kind) 70 | { 71 | return ImNodes::InputSlotKind(kind); 72 | } 73 | 74 | int ImNodesOutputSlotKind(int kind) 75 | { 76 | return ImNodes::OutputSlotKind(kind); 77 | } 78 | 79 | bool ImNodesIsInputSlotKind(int kind) 80 | { 81 | return ImNodes::IsInputSlotKind(kind); 82 | } 83 | 84 | bool ImNodesIsOutputSlotKind(int kind) 85 | { 86 | return ImNodes::IsOutputSlotKind(kind); 87 | } 88 | 89 | bool ImNodesBeginSlot(const char* title, int kind) 90 | { 91 | return ImNodes::BeginSlot(title, kind); 92 | } 93 | 94 | bool ImNodesBeginInputSlot(const char* title, int kind) 95 | { 96 | return ImNodes::BeginInputSlot(title, kind); 97 | } 98 | 99 | bool ImNodesBeginOutputSlot(const char* title, int kind) 100 | { 101 | return ImNodes::BeginOutputSlot(title, kind); 102 | } 103 | 104 | void ImNodesEndSlot() 105 | { 106 | ImNodes::EndSlot(); 107 | } 108 | 109 | bool ImNodesIsSlotCurveHovered() 110 | { 111 | return ImNodes::IsSlotCurveHovered(); 112 | } 113 | 114 | bool ImNodesIsConnectingCompatibleSlot() 115 | { 116 | return ImNodes::IsConnectingCompatibleSlot(); 117 | } 118 | 119 | //////////////////////////////////////////////////////////////////////////////////////////////////// 120 | // Public API (Ez) 121 | 122 | ImNodesEzContext* ImNodesEzCreateContext() 123 | { 124 | return ImNodes::Ez::CreateContext(); 125 | } 126 | 127 | void ImNodesEzFreeContext(ImNodesEzContext *ctx) 128 | { 129 | ImNodes::Ez::FreeContext(ctx); 130 | } 131 | 132 | void ImNodesEzSetContext(ImNodesEzContext *ctx) 133 | { 134 | ImNodes::Ez::SetContext(ctx); 135 | } 136 | 137 | ImNodesCanvasState* ImNodesEzGetState() 138 | { 139 | return &ImNodes::Ez::GetState(); 140 | } 141 | 142 | void ImNodesEzBeginCanvas() 143 | { 144 | ImNodes::Ez::BeginCanvas(); 145 | } 146 | 147 | void ImNodesEzEndCanvas() 148 | { 149 | ImNodes::Ez::EndCanvas(); 150 | } 151 | 152 | bool ImNodesEzBeginNode(void* node_id, const char* title, ImVec2* pos, bool* selected) 153 | { 154 | return ImNodes::Ez::BeginNode(node_id, title, pos, selected); 155 | } 156 | 157 | void ImNodesEzEndNode() 158 | { 159 | ImNodes::Ez::EndNode(); 160 | } 161 | 162 | void ImNodesEzInputSlots(const ImNodesEzSlotInfo* slots, int snum) 163 | { 164 | ImNodes::Ez::InputSlots(slots, snum); 165 | } 166 | 167 | void ImNodesEzOutputSlots(const ImNodesEzSlotInfo* slots, int snum) 168 | { 169 | ImNodes::Ez::OutputSlots(slots, snum); 170 | } 171 | 172 | bool ImNodesEzConnection(void* input_node, const char* input_slot, void* output_node, const char* output_slot) 173 | { 174 | return ImNodes::Ez::Connection(input_node, input_slot, output_node, output_slot); 175 | } 176 | 177 | void ImNodesEzPushStyleVarFloat(ImNodesStyleVar idx, float val) 178 | { 179 | ImNodes::Ez::PushStyleVar(idx, val); 180 | } 181 | 182 | void ImNodesEzPushStyleVarVec2(ImNodesStyleVar idx, const ImVec2 *val) 183 | { 184 | ImNodes::Ez::PushStyleVar(idx, *val); 185 | } 186 | 187 | void ImNodesEzPopStyleVar(int count) 188 | { 189 | ImNodes::Ez::PopStyleVar(count); 190 | } 191 | 192 | void ImNodesEzPushStyleColorU32(ImNodesStyleCol idx, ImU32 col) 193 | { 194 | ImNodes::Ez::PushStyleColor(idx, col); 195 | } 196 | 197 | void ImNodesEzPushStyleColorVec4(ImNodesStyleCol idx, const ImVec4* col) 198 | { 199 | ImNodes::Ez::PushStyleColor(idx, *col); 200 | } 201 | 202 | void ImNodesEzPopStyleColor(int count) 203 | { 204 | ImNodes::Ez::PopStyleVar(count); 205 | } 206 | -------------------------------------------------------------------------------- /imnodes_dll/ImNodesCAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ImNodes/ImNodes.h" 4 | #include "ImNodes/ImNodesEz.h" 5 | 6 | //////////////////////////////////////////////////////////////////////////////////////////////////// 7 | // Typedefs, Enums, Structs 8 | 9 | typedef ImNodes::CanvasState ImNodesCanvasState; 10 | typedef ImNodes::Ez::SlotInfo ImNodesEzSlotInfo; 11 | typedef ImNodes::Ez::Context ImNodesEzContext; 12 | 13 | //////////////////////////////////////////////////////////////////////////////////////////////////// 14 | // Public API (Base) 15 | 16 | extern "C" { 17 | 18 | IMGUI_API ImNodesCanvasState* ImNodesCanvasStateCtor(); 19 | IMGUI_API void ImNodesCanvasStateDtor(ImNodesCanvasState* instance); 20 | 21 | /// Create a node graph canvas in current window. 22 | IMGUI_API void ImNodesBeginCanvas(ImNodesCanvasState* canvas); 23 | /// Terminate a node graph canvas that was created by calling BeginCanvas(). 24 | IMGUI_API void ImNodesEndCanvas(); 25 | /// Begin rendering of node in a graph. Render node content when returns `true`. 26 | IMGUI_API bool ImNodesBeginNode(void* node_id, ImVec2* pos, bool* selected); 27 | /// Terminates current node. Should be called regardless of BeginNode() returns value. 28 | IMGUI_API void ImNodesEndNode(); 29 | /// Returns `true` if the current node is hovered. Call between `BeginNode()` and `EndNode()`. 30 | IMGUI_API bool ImNodesIsNodeHovered(); 31 | /// Specified node will be positioned at the mouse cursor on next frame. Call when new node is created. 32 | IMGUI_API void ImNodesAutoPositionNode(void* node_id); 33 | /// Returns `true` when new connection is made. Connection information is returned into `connection` parameter. Must be 34 | /// called at id scope created by BeginNode(). 35 | IMGUI_API bool ImNodesGetNewConnection(void** input_node, const char** input_slot_title, void** output_node, const char** output_slot_title); 36 | /// Get information of connection that is being made and has only one end connected. Returns true when pending connection exists, false otherwise. 37 | IMGUI_API bool ImNodesGetPendingConnection(void** node_id, const char** slot_title, int* slot_kind); 38 | /// Render a connection. Returns `true` when connection is present, `false` if it is deleted. 39 | IMGUI_API bool ImNodesConnection(void* input_node, const char* input_slot, void* output_node, const char* output_slot); 40 | /// Returns active canvas state when called between BeginCanvas() and EndCanvas(). Returns nullptr otherwise. This function is not thread-safe. 41 | IMGUI_API ImNodesCanvasState* ImNodesGetCurrentCanvas(); 42 | /// Convert kind id to input type. 43 | IMGUI_API int ImNodesInputSlotKind(int kind); 44 | /// Convert kind id to output type. 45 | IMGUI_API int ImNodesOutputSlotKind(int kind); 46 | /// Returns `true` if `kind` is from input slot. 47 | IMGUI_API bool ImNodesIsInputSlotKind(int kind); 48 | /// Returns `true` if `kind` is from output slot. 49 | IMGUI_API bool ImNodesIsOutputSlotKind(int kind); 50 | /// Begins slot region. Kind is unique value indicating slot type. Negative values mean input slots, positive - output slots. 51 | IMGUI_API bool ImNodesBeginSlot(const char* title, int kind); 52 | /// Begins slot region. Kind is unique value whose sign is ignored. 53 | IMGUI_API bool ImNodesBeginInputSlot(const char* title, int kind); 54 | /// Begins slot region. Kind is unique value whose sign is ignored. 55 | IMGUI_API bool ImNodesBeginOutputSlot(const char* title, int kind); 56 | /// Rends rendering of slot. Call only if Begin*Slot() returned `true`. 57 | IMGUI_API void ImNodesEndSlot(); 58 | /// Returns `true` if curve connected to current slot is hovered. Call between `Begin*Slot()` and `EndSlot()`. In-progress 59 | /// connection is considered hovered as well. 60 | IMGUI_API bool ImNodesIsSlotCurveHovered(); 61 | /// Returns `true` when new slot is being created and current slot can be connected. Call between `Begin*Slot()` and `EndSlot()`. 62 | IMGUI_API bool ImNodesIsConnectingCompatibleSlot(); 63 | 64 | //////////////////////////////////////////////////////////////////////////////////////////////////// 65 | // Public API (Ez) 66 | 67 | IMGUI_API ImNodesEzContext* ImNodesEzCreateContext(); 68 | IMGUI_API void ImNodesEzFreeContext(ImNodesEzContext *ctx); 69 | IMGUI_API void ImNodesEzSetContext(ImNodesEzContext *ctx); 70 | 71 | IMGUI_API ImNodesCanvasState* ImNodesEzGetState(); 72 | 73 | IMGUI_API void ImNodesEzBeginCanvas(); 74 | IMGUI_API void ImNodesEzEndCanvas(); 75 | 76 | /// Begin rendering of node in a graph. Render node content when returns `true`. 77 | IMGUI_API bool ImNodesEzBeginNode(void* node_id, const char* title, ImVec2* pos, bool* selected); 78 | /// Terminates current node. Should be called regardless of BeginNode() returns value. 79 | IMGUI_API void ImNodesEzEndNode(); 80 | /// Renders input slot region. Kind is unique value whose sign is ignored. 81 | /// This function must always be called after BeginNode() and before OutputSlots(). 82 | /// When no input slots are rendered call InputSlots(nullptr, 0); 83 | IMGUI_API void ImNodesEzInputSlots(const ImNodesEzSlotInfo* slots, int snum); 84 | /// Renders output slot region. Kind is unique value whose sign is ignored. This function must always be called after InputSlots() and function call is required (not optional). 85 | /// This function must always be called after InputSlots() and before EndNode(). 86 | /// When no input slots are rendered call OutputSlots(nullptr, 0); 87 | IMGUI_API void ImNodesEzOutputSlots(const ImNodesEzSlotInfo* slots, int snum); 88 | 89 | IMGUI_API bool ImNodesEzConnection(void* input_node, const char* input_slot, void* output_node, const char* output_slot); 90 | 91 | IMGUI_API void ImNodesEzPushStyleVarFloat(ImNodesStyleVar idx, float val); 92 | IMGUI_API void ImNodesEzPushStyleVarVec2(ImNodesStyleVar idx, const ImVec2 *val); 93 | IMGUI_API void ImNodesEzPopStyleVar(int count = 1); 94 | 95 | IMGUI_API void ImNodesEzPushStyleColorU32(ImNodesStyleCol idx, ImU32 col); 96 | IMGUI_API void ImNodesEzPushStyleColorVec4(ImNodesStyleCol idx, const ImVec4* col); 97 | IMGUI_API void ImNodesEzPopStyleColor(int count); 98 | 99 | } // extern "C" 100 | -------------------------------------------------------------------------------- /imnodes_dll/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Building ImNodes DLL # 4 | 5 | 1. Build `imgui_dll` first and keep its intermediate directory `build` untouched 6 | 2. Run `build_imnodes_macos.sh` or `build_imnodes_windows.cmd` 7 | * On Windows, make sure you have run `ridk enable` to use gcc 8 | 3. You will find `imnodes.dylib` or `imnodes.dll` generated in `lib` directory 9 | -------------------------------------------------------------------------------- /imnodes_dll/build_imnodes_linux.sh: -------------------------------------------------------------------------------- 1 | mkdir build 2 | cd build 3 | cmake -D CMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=ON -D CMAKE_CXX_COMPILER=clang++ ../ 4 | cmake --build . 5 | arch=`uname -m` 6 | cp imnodes.so ../../lib/imnodes.${arch}.so 7 | -------------------------------------------------------------------------------- /imnodes_dll/build_imnodes_linux_cross.sh: -------------------------------------------------------------------------------- 1 | mkdir -p build 2 | cd build 3 | 4 | export ARCH=aarch64 5 | 6 | cmake -D CMAKE_VERBOSE_MAKEFILE:BOOL=ON -D CMAKE_CXX_FLAGS=-isystem\ /usr/aarch64-linux-gnu/include -D CMAKE_BUILD_TYPE=Release -D CMAKE_CXX_COMPILER_TARGET=aarch64-linux-gnu -D CMAKE_SYSTEM_PROCESSOR=ARM -D BUILD_SHARED_LIBS=ON -D CROSS_BUILD_PLATFORM=${ARCH} -D CMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ ../ 7 | cmake --build . 8 | 9 | cp imnodes.so ../../lib/imnodes.${ARCH}.so 10 | -------------------------------------------------------------------------------- /imnodes_dll/build_imnodes_macos.sh: -------------------------------------------------------------------------------- 1 | export MACOSX_DEPLOYMENT_TARGET=15.0 2 | 3 | mkdir -p build_x86_64 4 | cd build_x86_64 5 | cmake -D CMAKE_C_FLAGS="" -D CMAKE_BUILD_TYPE=Release -D CMAKE_OSX_ARCHITECTURES="x86_64" -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=clang ../ 6 | cmake --build . 7 | cp imnodes.dylib ../../lib/imnodes.x86_64.dylib 8 | 9 | cd .. 10 | 11 | mkdir -p build_arm64 12 | cd build_arm64 13 | cmake -D CMAKE_C_FLAGS="" -D CMAKE_BUILD_TYPE=Release -D CMAKE_OSX_ARCHITECTURES="arm64" -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=clang ../ 14 | cmake --build . 15 | cp imnodes.dylib ../../lib/imnodes.arm64.dylib 16 | -------------------------------------------------------------------------------- /imnodes_dll/build_imnodes_windows.cmd: -------------------------------------------------------------------------------- 1 | :: 2 | :: For Windows + RubyInstaller2 with DevKit(MSYS2 gcc & make) + CMake users. 3 | :: - Use this script after "ridk enable"d. See https://github.com/oneclick/rubyinstaller2/wiki/The-ridk-tool for details. 4 | :: 5 | :: Usage 6 | :: > ridk enable 7 | :: > build_physac_windows.bat <- %PROGRAMFILES%\CMake\bin\cmake.exe will be used. 8 | :: > build_physac_windows.bat "D:\Program Files\CMake\bin\cmake.exe" <- You can give full path to 'cmake.exe'. 9 | 10 | @echo off 11 | setlocal enabledelayedexpansion 12 | set CMAKE_EXE=%1 13 | if "%CMAKE_EXE%"=="" ( 14 | set CMAKE_EXE="%PROGRAMFILES%\CMake\bin\cmake" 15 | ) 16 | 17 | pushd %~dp0 18 | if not exist build ( 19 | mkdir build 20 | ) 21 | cd build 22 | %CMAKE_EXE% -G "MSYS Makefiles" -D CMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=gcc ../ 23 | %CMAKE_EXE% --build . 24 | copy imnodes.dll ..\..\lib 25 | popd 26 | -------------------------------------------------------------------------------- /lib/imgui.aarch64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/lib/imgui.aarch64.so -------------------------------------------------------------------------------- /lib/imgui.arm64.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/lib/imgui.arm64.dylib -------------------------------------------------------------------------------- /lib/imgui.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/lib/imgui.dll -------------------------------------------------------------------------------- /lib/imgui.x86_64.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/lib/imgui.x86_64.dylib -------------------------------------------------------------------------------- /lib/imgui.x86_64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/lib/imgui.x86_64.so -------------------------------------------------------------------------------- /lib/imgui_impl_opengl2.rb: -------------------------------------------------------------------------------- 1 | require 'ffi' 2 | require 'opengl' 3 | 4 | require_relative 'imgui' 5 | 6 | module ImGui 7 | 8 | @@g_FontTexture = nil 9 | @@g_BackendRendererName = FFI::MemoryPointer.from_string("imgui_impl_opengl2") 10 | 11 | def self.ImplOpenGL2_Init() 12 | io = ImGuiIO.new(ImGui::GetIO()) 13 | io[:BackendRendererName] = @@g_BackendRendererName 14 | 15 | return true 16 | end 17 | 18 | def self.ImplOpenGL2_Shutdown() 19 | ImplOpenGL2_DestroyDeviceObjects() 20 | end 21 | 22 | def self.ImplOpenGL2_NewFrame() 23 | ImplOpenGL2_CreateDeviceObjects() if @@g_FontTexture == nil 24 | end 25 | 26 | def self.ImplOpenGL2_RenderDrawData(draw_data_raw) 27 | # Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) 28 | draw_data = ImDrawData.new(draw_data_raw) 29 | fb_width = (draw_data[:DisplaySize][:x] * draw_data[:FramebufferScale][:x]).to_i 30 | fb_height = (draw_data[:DisplaySize][:y] * draw_data[:FramebufferScale][:y]).to_i 31 | 32 | return if fb_width == 0 || fb_height == 0 33 | 34 | # Backup GL state 35 | last_texture = ' ' * 4 36 | GL.GetIntegerv(GL::TEXTURE_BINDING_2D, last_texture) 37 | last_polygon_mode = ' ' * 8 38 | GL.GetIntegerv(GL::POLYGON_MODE, last_polygon_mode) 39 | last_viewport = ' ' * 16 40 | GL.GetIntegerv(GL::VIEWPORT, last_viewport) 41 | last_scissor_box = ' ' * 16 42 | GL.GetIntegerv(GL::SCISSOR_BOX, last_scissor_box) 43 | GL.PushAttrib(GL::ENABLE_BIT | GL::COLOR_BUFFER_BIT | GL::TRANSFORM_BIT) 44 | last_shade_model = ' ' * 4 45 | GL.GetIntegerv(GL::SHADE_MODEL, last_shade_model) 46 | last_tex_env_mode = ' ' * 4 47 | GL.GetTexEnviv(GL::TEXTURE_ENV, GL::TEXTURE_ENV_MODE, last_tex_env_mode) 48 | 49 | # Setup desired GL state 50 | ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height) 51 | 52 | # Will project scissor/clipping rectangles into framebuffer space 53 | clip_off = draw_data[:DisplayPos] # (0,0) unless using multi-viewports 54 | clip_scale = draw_data[:FramebufferScale] # (1,1) unless using retina display which are often (2,2) 55 | 56 | # Render command lists 57 | draw_data[:CmdListsCount].times do |n| 58 | cmd_list = ImDrawList.new((draw_data[:CmdLists][:Data] + 8 * n).read_pointer) # 8 == const ImDrawList* 59 | vtx_buffer = ImDrawVert.new(cmd_list[:VtxBuffer][:Data]) # const ImDrawVert* 60 | idx_buffer = cmd_list[:IdxBuffer][:Data] # const ImDrawIdx* 61 | GL.VertexPointer(2, GL::FLOAT, ImDrawVert.size, Fiddle::Pointer.new((cmd_list[:VtxBuffer][:Data] + vtx_buffer.offset_of(:pos))) ) 62 | GL.TexCoordPointer(2, GL::FLOAT, ImDrawVert.size, Fiddle::Pointer.new((cmd_list[:VtxBuffer][:Data] + vtx_buffer.offset_of(:uv))) ) 63 | GL.ColorPointer(4, GL::UNSIGNED_BYTE, ImDrawVert.size, Fiddle::Pointer.new((cmd_list[:VtxBuffer][:Data] + vtx_buffer.offset_of(:col))) ) 64 | 65 | cmd_list[:CmdBuffer][:Size].times do |cmd_i| 66 | pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i) # const ImDrawCmd* 67 | if pcmd[:UserCallback] != nil 68 | # [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks ) 69 | 70 | # User callback, registered via ImDrawList::AddCallback() 71 | # (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) 72 | # if pcmd[:UserCallback] == :ImDrawCallback_ResetRenderState 73 | ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height) 74 | # else 75 | # pcmd[:UserCallback](cmd_list, pcmd) 76 | # end 77 | else 78 | # Project scissor/clipping rectangles into framebuffer space 79 | clip_rect = ImVec4.new 80 | clip_rect[:x] = (pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x] 81 | clip_rect[:y] = (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y] 82 | clip_rect[:z] = (pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x] 83 | clip_rect[:w] = (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y] 84 | 85 | if (clip_rect[:x] < fb_width && clip_rect[:y] < fb_height && clip_rect[:z] >= 0.0 && clip_rect[:w] >= 0.0) 86 | # Apply scissor/clipping rectangle 87 | GL.Scissor(clip_rect[:x].to_i, (fb_height - clip_rect[:w]).to_i, (clip_rect[:z] - clip_rect[:x]).to_i, (clip_rect[:w] - clip_rect[:y]).to_i) 88 | 89 | # Bind texture, Draw 90 | GL.BindTexture(GL::TEXTURE_2D, pcmd.GetTexID()) 91 | GL.DrawElements(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(idx_buffer.address)) 92 | end 93 | 94 | end 95 | idx_buffer += pcmd[:ElemCount] * 2 # 2 == ImDrawIdx(:ushort).size 96 | end 97 | end 98 | 99 | # Restore modified GL state 100 | GL.DisableClientState(GL::COLOR_ARRAY) 101 | GL.DisableClientState(GL::TEXTURE_COORD_ARRAY) 102 | GL.DisableClientState(GL::VERTEX_ARRAY) 103 | GL.BindTexture(GL::TEXTURE_2D, last_texture.unpack1('L')) 104 | GL.MatrixMode(GL::MODELVIEW) 105 | GL.PopMatrix() 106 | GL.MatrixMode(GL::PROJECTION) 107 | GL.PopMatrix() 108 | GL.PopAttrib() 109 | last_polygon_mode = last_polygon_mode.unpack('L2') 110 | GL.PolygonMode(GL::FRONT, last_polygon_mode[0]) 111 | GL.PolygonMode(GL::BACK, last_polygon_mode[1]) 112 | last_viewport = last_viewport.unpack('L4') 113 | GL.Viewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3]) 114 | last_scissor_box = last_scissor_box.unpack('L4') 115 | GL.Scissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3]) 116 | GL.ShadeModel(last_shade_model.unpack1('L')) 117 | GL.TexEnvi(GL::TEXTURE_ENV, GL::TEXTURE_ENV_MODE, last_tex_env_mode.unpack1('L')) 118 | end 119 | 120 | # private 121 | 122 | def self.ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height) 123 | # Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. 124 | GL.Enable(GL::BLEND) 125 | GL.BlendFunc(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA) 126 | # GL.BlendFuncSeparate(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA, GL::ONE, GL::ONE_MINUS_SRC_ALPHA) # In order to composite our output buffer we need to preserve alpha 127 | GL.Disable(GL::CULL_FACE) 128 | GL.Disable(GL::STENCIL_TEST) 129 | GL.Disable(GL::DEPTH_TEST) 130 | GL.Disable(GL::LIGHTING) 131 | GL.Disable(GL::COLOR_MATERIAL) 132 | GL.Enable(GL::SCISSOR_TEST) 133 | GL.EnableClientState(GL::VERTEX_ARRAY) 134 | GL.EnableClientState(GL::TEXTURE_COORD_ARRAY) 135 | GL.EnableClientState(GL::COLOR_ARRAY) 136 | GL.DisableClientState(GL::NORMAL_ARRAY) 137 | GL.Enable(GL::TEXTURE_2D) 138 | GL.PolygonMode(GL::FRONT_AND_BACK, GL::FILL) 139 | GL.ShadeModel(GL::SMOOTH) 140 | GL.TexEnvi(GL::TEXTURE_ENV, GL::TEXTURE_ENV_MODE, GL::MODULATE) 141 | 142 | # If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!), 143 | # you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below. 144 | # (DO NOT MODIFY THIS FILE! Add the code in your calling function) 145 | # GLint last_program; 146 | # glGetIntegerv(GL::CURRENT_PROGRAM, &last_program); 147 | # glUseProgram(0); 148 | # ImGui_ImplOpenGL2_RenderDrawData(...); 149 | # glUseProgram(last_program) 150 | # There are potentially many more states you could need to clear/setup that we can't access from default headers. 151 | # e.g. glBindBuffer(GL::ARRAY_BUFFER, 0), glDisable(GL::TEXTURE_CUBE_MAP). 152 | 153 | # Setup viewport, orthographic projection matrix 154 | # Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. 155 | GL.Viewport(0, 0, fb_width, fb_height) 156 | GL.MatrixMode(GL::PROJECTION) 157 | GL.PushMatrix() 158 | GL.LoadIdentity() 159 | GL.Ortho(draw_data[:DisplayPos][:x], draw_data[:DisplayPos][:x] + draw_data[:DisplaySize][:x], draw_data[:DisplayPos][:y] + draw_data[:DisplaySize][:y], draw_data[:DisplayPos][:y], -1.0, +1.0) 160 | GL.MatrixMode(GL::MODELVIEW) 161 | GL.PushMatrix() 162 | GL.LoadIdentity() 163 | end 164 | 165 | def self.ImplOpenGL2_CreateFontsTexture() 166 | # Build texture atlas 167 | io = ImGuiIO.new(ImGui::GetIO()) 168 | pixels = FFI::MemoryPointer.new :pointer 169 | width = FFI::MemoryPointer.new :int 170 | height = FFI::MemoryPointer.new :int 171 | io[:Fonts].GetTexDataAsRGBA32(pixels, width, height, nil) # Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. 172 | 173 | # Upload texture to graphics system 174 | last_texture = ' ' * 4 175 | @@g_FontTexture = ' ' * 4 176 | GL.GetIntegerv(GL::TEXTURE_BINDING_2D, last_texture) 177 | GL.GenTextures(1, @@g_FontTexture) 178 | GL.BindTexture(GL::TEXTURE_2D, @@g_FontTexture.unpack1('L')) 179 | GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, GL::LINEAR) 180 | GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER, GL::LINEAR) 181 | GL.PixelStorei(GL::UNPACK_ROW_LENGTH, 0) 182 | # Ruby/FFI <-> Fiddle pointer exchange 183 | pixels_ptr = Fiddle::Pointer.new(pixels.read_pointer.address) 184 | GL.TexImage2D(GL::TEXTURE_2D, 0, GL::RGBA, width.read_uint, height.read_uint, 0, GL::RGBA, GL::UNSIGNED_BYTE, pixels_ptr) 185 | 186 | # Store our identifier 187 | io[:Fonts][:TexID] = @@g_FontTexture.unpack1('L') 188 | 189 | # Restore state 190 | GL.BindTexture(GL::TEXTURE_2D, last_texture.unpack1('L')) 191 | 192 | return true 193 | end 194 | 195 | def self.ImplOpenGL2_DestroyFontsTexture() 196 | if @@g_FontTexture != 0 197 | GL.DeleteTextures(1, @@g_FontTexture) 198 | io = ImGuiIO.new(ImGui::GetIO()) 199 | io[:Fonts][:TexID] = 0 200 | @@g_FontTexture = 0 201 | end 202 | end 203 | 204 | def self.ImplOpenGL2_CreateDeviceObjects() 205 | return ImplOpenGL2_CreateFontsTexture() 206 | end 207 | 208 | def self.ImplOpenGL2_DestroyDeviceObjects() 209 | ImplOpenGL2_DestroyFontsTexture() 210 | end 211 | 212 | end 213 | -------------------------------------------------------------------------------- /lib/imgui_impl_raylib.rb: -------------------------------------------------------------------------------- 1 | require 'ffi' 2 | require 'raylib' 3 | 4 | require_relative 'imgui' 5 | 6 | module ImGui 7 | 8 | @@g_BackendPlatformName = FFI::MemoryPointer.from_string("imgui_impl_raylib") 9 | 10 | # ImGui::GetCurrentContext().address => ImGui_ImplRaylib_Data 11 | @@g_BackendData = Hash.new 12 | 13 | # [INTERNAL] 14 | class ImGui_ImplRaylib_Data 15 | attr_accessor :time 16 | 17 | def initialize 18 | @time = 0.0 19 | end 20 | end 21 | 22 | # [INTERNAL] 23 | def self.ImGui_ImplRaylib_GetBackendData() 24 | if ImGui::GetCurrentContext() != nil 25 | @@g_BackendData[ImGui::GetCurrentContext().address] 26 | else 27 | nil 28 | end 29 | end 30 | 31 | # [TODO] Support ClipboardText 32 | # g_ClipboardTextData 33 | # ImplRaylib_GetClipboardText 34 | # ImplRaylib_SetClipboardText 35 | 36 | KEY_IDS = [ 37 | # Alphanumeric keys 38 | Raylib::KEY_APOSTROPHE, # Key: ' 39 | Raylib::KEY_COMMA, # Key: , 40 | Raylib::KEY_MINUS, # Key: - 41 | Raylib::KEY_PERIOD, # Key: . 42 | Raylib::KEY_SLASH, # Key: / 43 | Raylib::KEY_ZERO, # Key: 0 44 | Raylib::KEY_ONE, # Key: 1 45 | Raylib::KEY_TWO, # Key: 2 46 | Raylib::KEY_THREE, # Key: 3 47 | Raylib::KEY_FOUR, # Key: 4 48 | Raylib::KEY_FIVE, # Key: 5 49 | Raylib::KEY_SIX, # Key: 6 50 | Raylib::KEY_SEVEN, # Key: 7 51 | Raylib::KEY_EIGHT, # Key: 8 52 | Raylib::KEY_NINE, # Key: 9 53 | Raylib::KEY_SEMICOLON, # Key: ; 54 | Raylib::KEY_EQUAL, # Key: = 55 | Raylib::KEY_A, # Key: A | a 56 | Raylib::KEY_B, # Key: B | b 57 | Raylib::KEY_C, # Key: C | c 58 | Raylib::KEY_D, # Key: D | d 59 | Raylib::KEY_E, # Key: E | e 60 | Raylib::KEY_F, # Key: F | f 61 | Raylib::KEY_G, # Key: G | g 62 | Raylib::KEY_H, # Key: H | h 63 | Raylib::KEY_I, # Key: I | i 64 | Raylib::KEY_J, # Key: J | j 65 | Raylib::KEY_K, # Key: K | k 66 | Raylib::KEY_L, # Key: L | l 67 | Raylib::KEY_M, # Key: M | m 68 | Raylib::KEY_N, # Key: N | n 69 | Raylib::KEY_O, # Key: O | o 70 | Raylib::KEY_P, # Key: P | p 71 | Raylib::KEY_Q, # Key: Q | q 72 | Raylib::KEY_R, # Key: R | r 73 | Raylib::KEY_S, # Key: S | s 74 | Raylib::KEY_T, # Key: T | t 75 | Raylib::KEY_U, # Key: U | u 76 | Raylib::KEY_V, # Key: V | v 77 | Raylib::KEY_W, # Key: W | w 78 | Raylib::KEY_X, # Key: X | x 79 | Raylib::KEY_Y, # Key: Y | y 80 | Raylib::KEY_Z, # Key: Z | z 81 | Raylib::KEY_LEFT_BRACKET, # Key: [ 82 | Raylib::KEY_BACKSLASH, # Key: '\' 83 | Raylib::KEY_RIGHT_BRACKET, # Key: ] 84 | Raylib::KEY_GRAVE, # Key: ` 85 | # Function keys 86 | Raylib::KEY_SPACE, # Key: Space 87 | Raylib::KEY_ESCAPE, # Key: Esc 88 | Raylib::KEY_ENTER, # Key: Enter 89 | Raylib::KEY_TAB, # Key: Tab 90 | Raylib::KEY_BACKSPACE, # Key: Backspace 91 | Raylib::KEY_INSERT, # Key: Ins 92 | Raylib::KEY_DELETE, # Key: Del 93 | Raylib::KEY_RIGHT, # Key: Cursor right 94 | Raylib::KEY_LEFT, # Key: Cursor left 95 | Raylib::KEY_DOWN, # Key: Cursor down 96 | Raylib::KEY_UP, # Key: Cursor up 97 | Raylib::KEY_PAGE_UP, # Key: Page up 98 | Raylib::KEY_PAGE_DOWN, # Key: Page down 99 | Raylib::KEY_HOME, # Key: Home 100 | Raylib::KEY_END, # Key: End 101 | Raylib::KEY_CAPS_LOCK, # Key: Caps lock 102 | Raylib::KEY_SCROLL_LOCK, # Key: Scroll down 103 | Raylib::KEY_NUM_LOCK, # Key: Num lock 104 | Raylib::KEY_PRINT_SCREEN, # Key: Print screen 105 | Raylib::KEY_PAUSE, # Key: Pause 106 | Raylib::KEY_F1, # Key: F1 107 | Raylib::KEY_F2, # Key: F2 108 | Raylib::KEY_F3, # Key: F3 109 | Raylib::KEY_F4, # Key: F4 110 | Raylib::KEY_F5, # Key: F5 111 | Raylib::KEY_F6, # Key: F6 112 | Raylib::KEY_F7, # Key: F7 113 | Raylib::KEY_F8, # Key: F8 114 | Raylib::KEY_F9, # Key: F9 115 | Raylib::KEY_F10, # Key: F10 116 | Raylib::KEY_F11, # Key: F11 117 | Raylib::KEY_F12, # Key: F12 118 | Raylib::KEY_LEFT_SHIFT, # Key: Shift left 119 | Raylib::KEY_LEFT_CONTROL, # Key: Control left 120 | Raylib::KEY_LEFT_ALT, # Key: Alt left 121 | Raylib::KEY_LEFT_SUPER, # Key: Super left 122 | Raylib::KEY_RIGHT_SHIFT, # Key: Shift right 123 | Raylib::KEY_RIGHT_CONTROL, # Key: Control right 124 | Raylib::KEY_RIGHT_ALT, # Key: Alt right 125 | Raylib::KEY_RIGHT_SUPER, # Key: Super right 126 | Raylib::KEY_KB_MENU, # Key: KB menu 127 | # Keypad keys 128 | Raylib::KEY_KP_0, # Key: Keypad 0 129 | Raylib::KEY_KP_1, # Key: Keypad 1 130 | Raylib::KEY_KP_2, # Key: Keypad 2 131 | Raylib::KEY_KP_3, # Key: Keypad 3 132 | Raylib::KEY_KP_4, # Key: Keypad 4 133 | Raylib::KEY_KP_5, # Key: Keypad 5 134 | Raylib::KEY_KP_6, # Key: Keypad 6 135 | Raylib::KEY_KP_7, # Key: Keypad 7 136 | Raylib::KEY_KP_8, # Key: Keypad 8 137 | Raylib::KEY_KP_9, # Key: Keypad 9 138 | Raylib::KEY_KP_DECIMAL, # Key: Keypad . 139 | Raylib::KEY_KP_DIVIDE, # Key: Keypad / 140 | Raylib::KEY_KP_MULTIPLY, # Key: Keypad * 141 | Raylib::KEY_KP_SUBTRACT, # Key: Keypad - 142 | Raylib::KEY_KP_ADD, # Key: Keypad + 143 | Raylib::KEY_KP_ENTER, # Key: Keypad Enter 144 | Raylib::KEY_KP_EQUAL, # Key: Keypad = 145 | ] 146 | 147 | # [INTERNAL] 148 | def self.ImGui_ImplRaylib_KeyToImGuiKey(key) 149 | case key 150 | when Raylib::KEY_TAB then ImGuiKey_Tab 151 | when Raylib::KEY_LEFT then ImGuiKey_LeftArrow 152 | when Raylib::KEY_RIGHT then ImGuiKey_RightArrow 153 | when Raylib::KEY_UP then ImGuiKey_UpArrow 154 | when Raylib::KEY_DOWN then ImGuiKey_DownArrow 155 | when Raylib::KEY_PAGE_UP then ImGuiKey_PageUp 156 | when Raylib::KEY_PAGE_DOWN then ImGuiKey_PageDown 157 | when Raylib::KEY_HOME then ImGuiKey_Home 158 | when Raylib::KEY_END then ImGuiKey_End 159 | when Raylib::KEY_INSERT then ImGuiKey_Insert 160 | when Raylib::KEY_DELETE then ImGuiKey_Delete 161 | when Raylib::KEY_BACKSPACE then ImGuiKey_Backspace 162 | when Raylib::KEY_SPACE then ImGuiKey_Space 163 | when Raylib::KEY_ENTER then ImGuiKey_Enter 164 | when Raylib::KEY_ESCAPE then ImGuiKey_Escape 165 | when Raylib::KEY_APOSTROPHE then ImGuiKey_Apostrophe 166 | when Raylib::KEY_COMMA then ImGuiKey_Comma 167 | when Raylib::KEY_MINUS then ImGuiKey_Minus 168 | when Raylib::KEY_PERIOD then ImGuiKey_Period 169 | when Raylib::KEY_SLASH then ImGuiKey_Slash 170 | when Raylib::KEY_SEMICOLON then ImGuiKey_Semicolon 171 | when Raylib::KEY_EQUAL then ImGuiKey_Equal 172 | when Raylib::KEY_LEFT_BRACKET then ImGuiKey_LeftBracket 173 | when Raylib::KEY_BACKSLASH then ImGuiKey_Backslash 174 | when Raylib::KEY_RIGHT_BRACKET then ImGuiKey_RightBracket 175 | when Raylib::KEY_GRAVE then ImGuiKey_GraveAccent 176 | when Raylib::KEY_CAPS_LOCK then ImGuiKey_CapsLock 177 | when Raylib::KEY_SCROLL_LOCK then ImGuiKey_ScrollLock 178 | when Raylib::KEY_NUM_LOCK then ImGuiKey_NumLock 179 | when Raylib::KEY_PRINT_SCREEN then ImGuiKey_PrintScreen 180 | when Raylib::KEY_PAUSE then ImGuiKey_Pause 181 | when Raylib::KEY_KP_0 then ImGuiKey_Keypad0 182 | when Raylib::KEY_KP_1 then ImGuiKey_Keypad1 183 | when Raylib::KEY_KP_2 then ImGuiKey_Keypad2 184 | when Raylib::KEY_KP_3 then ImGuiKey_Keypad3 185 | when Raylib::KEY_KP_4 then ImGuiKey_Keypad4 186 | when Raylib::KEY_KP_5 then ImGuiKey_Keypad5 187 | when Raylib::KEY_KP_6 then ImGuiKey_Keypad6 188 | when Raylib::KEY_KP_7 then ImGuiKey_Keypad7 189 | when Raylib::KEY_KP_8 then ImGuiKey_Keypad8 190 | when Raylib::KEY_KP_9 then ImGuiKey_Keypad9 191 | when Raylib::KEY_KP_DECIMAL then ImGuiKey_KeypadDecimal 192 | when Raylib::KEY_KP_DIVIDE then ImGuiKey_KeypadDivide 193 | when Raylib::KEY_KP_MULTIPLY then ImGuiKey_KeypadMultiply 194 | when Raylib::KEY_KP_SUBTRACT then ImGuiKey_KeypadSubtract 195 | when Raylib::KEY_KP_ADD then ImGuiKey_KeypadAdd 196 | when Raylib::KEY_KP_ENTER then ImGuiKey_KeypadEnter 197 | when Raylib::KEY_KP_EQUAL then ImGuiKey_KeypadEqual 198 | when Raylib::KEY_LEFT_CONTROL then ImGuiKey_LeftCtrl 199 | when Raylib::KEY_LEFT_SHIFT then ImGuiKey_LeftShift 200 | when Raylib::KEY_LEFT_ALT then ImGuiKey_LeftAlt 201 | when Raylib::KEY_LEFT_SUPER then ImGuiKey_LeftSuper 202 | when Raylib::KEY_RIGHT_CONTROL then ImGuiKey_RightCtrl 203 | when Raylib::KEY_RIGHT_SHIFT then ImGuiKey_RightShift 204 | when Raylib::KEY_RIGHT_ALT then ImGuiKey_RightAlt 205 | when Raylib::KEY_RIGHT_SUPER then ImGuiKey_RightSuper 206 | when Raylib::KEY_MENU then ImGuiKey_Menu 207 | when Raylib::KEY_ZERO then ImGuiKey_0 208 | when Raylib::KEY_ONE then ImGuiKey_1 209 | when Raylib::KEY_TWO then ImGuiKey_2 210 | when Raylib::KEY_THREE then ImGuiKey_3 211 | when Raylib::KEY_FOUR then ImGuiKey_4 212 | when Raylib::KEY_FIVE then ImGuiKey_5 213 | when Raylib::KEY_SIX then ImGuiKey_6 214 | when Raylib::KEY_SEVEN then ImGuiKey_7 215 | when Raylib::KEY_EIGHT then ImGuiKey_8 216 | when Raylib::KEY_NINE then ImGuiKey_9 217 | when Raylib::KEY_A then ImGuiKey_A 218 | when Raylib::KEY_B then ImGuiKey_B 219 | when Raylib::KEY_C then ImGuiKey_C 220 | when Raylib::KEY_D then ImGuiKey_D 221 | when Raylib::KEY_E then ImGuiKey_E 222 | when Raylib::KEY_F then ImGuiKey_F 223 | when Raylib::KEY_G then ImGuiKey_G 224 | when Raylib::KEY_H then ImGuiKey_H 225 | when Raylib::KEY_I then ImGuiKey_I 226 | when Raylib::KEY_J then ImGuiKey_J 227 | when Raylib::KEY_K then ImGuiKey_K 228 | when Raylib::KEY_L then ImGuiKey_L 229 | when Raylib::KEY_M then ImGuiKey_M 230 | when Raylib::KEY_N then ImGuiKey_N 231 | when Raylib::KEY_O then ImGuiKey_O 232 | when Raylib::KEY_P then ImGuiKey_P 233 | when Raylib::KEY_Q then ImGuiKey_Q 234 | when Raylib::KEY_R then ImGuiKey_R 235 | when Raylib::KEY_S then ImGuiKey_S 236 | when Raylib::KEY_T then ImGuiKey_T 237 | when Raylib::KEY_U then ImGuiKey_U 238 | when Raylib::KEY_V then ImGuiKey_V 239 | when Raylib::KEY_W then ImGuiKey_W 240 | when Raylib::KEY_X then ImGuiKey_X 241 | when Raylib::KEY_Y then ImGuiKey_Y 242 | when Raylib::KEY_Z then ImGuiKey_Z 243 | when Raylib::KEY_F1 then ImGuiKey_F1 244 | when Raylib::KEY_F2 then ImGuiKey_F2 245 | when Raylib::KEY_F3 then ImGuiKey_F3 246 | when Raylib::KEY_F4 then ImGuiKey_F4 247 | when Raylib::KEY_F5 then ImGuiKey_F5 248 | when Raylib::KEY_F6 then ImGuiKey_F6 249 | when Raylib::KEY_F7 then ImGuiKey_F7 250 | when Raylib::KEY_F8 then ImGuiKey_F8 251 | when Raylib::KEY_F9 then ImGuiKey_F9 252 | when Raylib::KEY_F10 then ImGuiKey_F10 253 | when Raylib::KEY_F11 then ImGuiKey_F11 254 | when Raylib::KEY_F12 then ImGuiKey_F12 255 | else ImGuiKey_None 256 | end 257 | end 258 | 259 | # [INTERNAL] 260 | def self.ImGui_ImplRaylib_UpdateKeyModifiers() 261 | io = ImGuiIO.new(ImGui::GetIO()) 262 | io.AddKeyEvent(ImGuiMod_Ctrl, Raylib.IsKeyDown(Raylib::KEY_RIGHT_CONTROL) || Raylib.IsKeyDown(Raylib::KEY_LEFT_CONTROL)) 263 | io.AddKeyEvent(ImGuiMod_Shift, Raylib.IsKeyDown(Raylib::KEY_RIGHT_SHIFT) || Raylib.IsKeyDown(Raylib::KEY_LEFT_SHIFT)) 264 | io.AddKeyEvent(ImGuiMod_Alt, Raylib.IsKeyDown(Raylib::KEY_RIGHT_ALT) || Raylib.IsKeyDown(Raylib::KEY_LEFT_ALT)) 265 | io.AddKeyEvent(ImGuiMod_Super, Raylib.IsKeyDown(Raylib::KEY_RIGHT_SUPER) || Raylib.IsKeyDown(Raylib::KEY_LEFT_SUPER)) 266 | end 267 | 268 | def self.ImplRaylib_ProcessKeyboard() 269 | io = ImGuiIO.new(ImGui::GetIO()) 270 | 271 | ImGui_ImplRaylib_UpdateKeyModifiers() 272 | 273 | KEY_IDS.each do |raylib_key| 274 | if Raylib.IsKeyPressed(raylib_key) 275 | key = ImGui_ImplRaylib_KeyToImGuiKey(raylib_key) 276 | io.AddKeyEvent(key, true) 277 | elsif Raylib.IsKeyReleased(raylib_key) 278 | key = ImGui_ImplRaylib_KeyToImGuiKey(raylib_key) 279 | io.AddKeyEvent(key, false) 280 | end 281 | end 282 | 283 | while (charPressed = Raylib.GetCharPressed()) != 0 284 | io.AddInputCharacter(charPressed) 285 | end 286 | 287 | return true 288 | end 289 | 290 | # [INTERNAL] 291 | def self.ImplRaylib_UpdateMouseData() 292 | bd = ImGui_ImplRaylib_GetBackendData() 293 | io = ImGuiIO.new(ImGui::GetIO()) 294 | 295 | # Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 296 | if io[:WantSetMousePos] 297 | Raylib.SetMousePosition(io[:MousePos][:x].to_i, io[:MousePos][:y].to_i) 298 | end 299 | 300 | wheel_move = Raylib.GetMouseWheelMove() 301 | wheel_y = if wheel_move > 0 302 | 1.0 303 | elsif wheel_move < 0 304 | -1.0 305 | else 306 | 0.0 307 | end 308 | io.AddMouseWheelEvent(0, wheel_y) # [TODO] Get wheel tilt from Raylib 309 | 310 | [Raylib::MOUSE_BUTTON_LEFT, Raylib::MOUSE_BUTTON_RIGHT, Raylib::MOUSE_BUTTON_MIDDLE].each_with_index do |button, mouse_button| 311 | pressed = Raylib.IsMouseButtonPressed(button) 312 | released = Raylib.IsMouseButtonReleased(button) 313 | if pressed || released 314 | io.AddMouseButtonEvent(mouse_button, pressed) 315 | end 316 | end 317 | 318 | mouse_pos = Raylib.GetMousePosition() 319 | io.AddMousePosEvent(mouse_pos[:x].to_f, mouse_pos[:y].to_f) 320 | end 321 | 322 | # [INTERNAL] 323 | def self.ImplRaylib_UpdateMouseCursor() 324 | io = ImGuiIO.new(ImGui::GetIO()) 325 | return if (io[:ConfigFlags] & ImGuiConfigFlags_NoMouseCursorChange) 326 | 327 | if io[:MouseDrawCursor] || ImGui::GetMouseCursor() == ImGuiMouseCursor_None 328 | Raylib.HideCursor() # Hide OS mouse cursor if imgui is drawing it or if it wants no cursor 329 | else 330 | Raylib.ShowCursor() # Show OS mouse cursor 331 | end 332 | end 333 | 334 | # 335 | # [TODO] Support ImplRaylib_UpdateGamepads 336 | # 337 | 338 | def self.ImplRaylib_Init() 339 | # Setup backend capabilities flags 340 | bd = ImGui_ImplRaylib_Data.new 341 | @@g_BackendData[ImGui::GetCurrentContext().address] = bd 342 | 343 | io = ImGuiIO.new(ImGui::GetIO()) 344 | 345 | io[:BackendPlatformUserData] = nil 346 | io[:BackendPlatformName] = @@g_BackendPlatformName 347 | io[:BackendFlags] |= ImGuiBackendFlags_HasMouseCursors # We can honor GetMouseCursor() values (optional) 348 | io[:BackendFlags] |= ImGuiBackendFlags_HasSetMousePos # We can honor io.WantSetMousePos requests (optional, rarely used) 349 | 350 | bd.time = 0.0 351 | 352 | return true 353 | end 354 | 355 | def self.ImplRaylib_Shutdown() 356 | io = ImGuiIO.new(ImGui::GetIO()) 357 | io[:BackendPlatformName] = nil 358 | io[:BackendPlatformUserData] = nil 359 | @@g_BackendData[ImGui::GetCurrentContext()] = nil 360 | end 361 | 362 | def self.ImplRaylib_NewFrame() 363 | bd = ImGui_ImplRaylib_GetBackendData() 364 | io = ImGuiIO.new(ImGui::GetIO()) 365 | 366 | # Setup display size (every frame to accommodate for window resizing) 367 | io[:DisplaySize][:x] = Raylib.GetScreenWidth() 368 | io[:DisplaySize][:y] = Raylib.GetScreenHeight() 369 | 370 | # Setup time step 371 | current_time = Raylib.GetTime() 372 | 373 | io[:DeltaTime] = bd.time > 0 ? (current_time - bd.time).to_f : 1.0 / 60.0 374 | bd.time = current_time 375 | 376 | ImplRaylib_ProcessKeyboard() 377 | ImplRaylib_UpdateMouseData() 378 | ImplRaylib_UpdateMouseCursor() 379 | 380 | # [TODO] update gamepads 381 | end 382 | 383 | # [INTERNAL] 384 | def self.set_vertex(xy, uv, color) 385 | Raylib.rlColor4ub(color[0], color[1], color[2], color[3]) 386 | Raylib.rlTexCoord2f(uv[0], uv[1]) 387 | Raylib.rlVertex2f(xy[0], xy[1]) 388 | end 389 | 390 | def self.ImplRaylib_RenderDrawData(draw_data_raw) 391 | draw_data = ImDrawData.new(draw_data_raw) 392 | Raylib.rlDisableBackfaceCulling() 393 | 394 | clip_offset = draw_data[:DisplayPos] 395 | draw_data[:CmdListsCount].times do |n| 396 | cmd_list = ImDrawList.new((draw_data[:CmdLists][:Data] + FFI.type_size(:pointer) * n).read_pointer) 397 | vtx_buffer = cmd_list[:VtxBuffer][:Data] # const ImDrawVert* 398 | idx_buffer = cmd_list[:IdxBuffer][:Data] # const ImDrawIdx* 399 | 400 | cmd_list[:CmdBuffer][:Size].times do |cmd_i| 401 | pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i) # const ImDrawCmd* 402 | if pcmd[:UserCallback] != nil 403 | # [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks ) 404 | else 405 | rect_min_x = (pcmd[:ClipRect][:x] - clip_offset[:x]) 406 | rect_min_y = (pcmd[:ClipRect][:y] - clip_offset[:y]) 407 | rect_max_x = (pcmd[:ClipRect][:z] - clip_offset[:x]) 408 | rect_max_y = (pcmd[:ClipRect][:w] - clip_offset[:y]) 409 | 410 | rect_w = rect_max_x - rect_min_x 411 | rect_h = rect_max_y - rect_min_y 412 | 413 | Raylib.BeginScissorMode(rect_min_x, rect_min_y, rect_w, rect_h) 414 | 415 | # Render triangles 416 | indices = idx_buffer + FFI.type_size(:ImDrawIdx) * pcmd[:IdxOffset] 417 | vertices = vtx_buffer + ImDrawVert.size * pcmd[:VtxOffset] 418 | 0.step(pcmd[:ElemCount] - 3, 3) do |i| 419 | Raylib.rlPushMatrix() 420 | Raylib.rlBegin(Raylib::RL_TRIANGLES) 421 | # Raylib.rlSetTexture(pcmd[:TextureId].read_uint32) 422 | Raylib.rlSetTexture(pcmd[:TextureId]) 423 | 424 | index = indices.get_array_of_uint16(i * FFI::type_size(:ImDrawIdx), 3) 425 | 426 | base_offset = ImDrawVert.size * index[0] 427 | xy = vertices + (base_offset + ImDrawVert.offset_of(:pos)) 428 | uv = vertices + (base_offset + ImDrawVert.offset_of(:uv)) 429 | color = vertices + (base_offset + ImDrawVert.offset_of(:col)) 430 | set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4)) 431 | 432 | base_offset = ImDrawVert.size * index[2] 433 | xy = vertices + (base_offset + ImDrawVert.offset_of(:pos)) 434 | uv = vertices + (base_offset + ImDrawVert.offset_of(:uv)) 435 | color = vertices + (base_offset + ImDrawVert.offset_of(:col)) 436 | set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4)) 437 | 438 | base_offset = ImDrawVert.size * index[1] 439 | xy = vertices + (base_offset + ImDrawVert.offset_of(:pos)) 440 | uv = vertices + (base_offset + ImDrawVert.offset_of(:uv)) 441 | color = vertices + (base_offset + ImDrawVert.offset_of(:col)) 442 | set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4)) 443 | 444 | Raylib.rlSetTexture(0) 445 | Raylib.rlEnd() 446 | Raylib.rlPopMatrix() 447 | end 448 | Raylib.EndScissorMode() 449 | end 450 | end 451 | end 452 | Raylib.rlEnableBackfaceCulling() 453 | end 454 | 455 | end 456 | -------------------------------------------------------------------------------- /lib/imgui_impl_sdl2.rb: -------------------------------------------------------------------------------- 1 | require 'ffi' 2 | require 'sdl2' 3 | require_relative 'imgui' 4 | 5 | module ImGui 6 | 7 | @@g_BackendPlatformName = FFI::MemoryPointer.from_string("imgui_impl_sdl") 8 | 9 | # ImGui::GetCurrentContext().address => ImGui_ImplSDL2_Data 10 | @@g_BackendData = Hash.new 11 | 12 | # [INTERNAL] 13 | class ImGui_ImplSDL2_Data 14 | attr_accessor :window, :renderer, :time, :mouseButtonsDown, :mouseCursors, :clipboardTextData, :mouseCanUseGlobalState 15 | 16 | def initialize 17 | @window = nil # SDL_Window* 18 | @renderer = nil # SDL_Renderer* 19 | @time = 0.0 # Uint64 20 | @mouseButtonsDown = 0 # int 21 | @mouseCursors = Array.new(ImGuiMouseCursor_COUNT) { 0 } # SDL_Cursor* 22 | @clipboardTextData = nil # char* 23 | @mouseCanUseGlobalState = false # bool 24 | end 25 | end 26 | 27 | # Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts 28 | # It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. 29 | # FIXME: multi-context support is not well tested and probably dysfunctional in this backend. 30 | # FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context. 31 | # [INTERNAL] 32 | def self.ImGui_ImplSDL2_GetBackendData() 33 | if ImGui::GetCurrentContext() != nil 34 | @@g_BackendData[ImGui::GetCurrentContext().address] 35 | else 36 | nil 37 | end 38 | end 39 | 40 | # [TODO] Support ClipboardText 41 | # g_ClipboardTextData 42 | # ImplSDL2_GetClipboardText 43 | # ImplSDL2_SetClipboardText 44 | 45 | # [INTERNAL] 46 | def self.ImGui_ImplSDL2_GetClipboardText(user_data) 47 | bd = ImGui_ImplSDL2_GetBackendData() 48 | SDL.free(bd.clipboardTextData) if bd.clipboardTextData 49 | bd.clipboardTextData = SDL.GetClipboardText() 50 | return bd.clipboardTextData 51 | end 52 | 53 | # [INTERNAL] 54 | def self.ImGui_ImplSDL2_SetClipboardText(user_data, text) 55 | SDL.SetClipboardText(text) 56 | end 57 | 58 | # [INTERNAL] 59 | def self.ImGui_ImplSDL2_KeyToImGuiKey(key) 60 | case key 61 | when SDL::SDLK_TAB then ImGuiKey_Tab 62 | when SDL::SDLK_LEFT then ImGuiKey_LeftArrow 63 | when SDL::SDLK_RIGHT then ImGuiKey_RightArrow 64 | when SDL::SDLK_UP then ImGuiKey_UpArrow 65 | when SDL::SDLK_DOWN then ImGuiKey_DownArrow 66 | when SDL::SDLK_PAGEUP then ImGuiKey_PageUp 67 | when SDL::SDLK_PAGEDOWN then ImGuiKey_PageDown 68 | when SDL::SDLK_HOME then ImGuiKey_Home 69 | when SDL::SDLK_END then ImGuiKey_End 70 | when SDL::SDLK_INSERT then ImGuiKey_Insert 71 | when SDL::SDLK_DELETE then ImGuiKey_Delete 72 | when SDL::SDLK_BACKSPACE then ImGuiKey_Backspace 73 | when SDL::SDLK_SPACE then ImGuiKey_Space 74 | when SDL::SDLK_RETURN then ImGuiKey_Enter 75 | when SDL::SDLK_ESCAPE then ImGuiKey_Escape 76 | when SDL::SDLK_QUOTE then ImGuiKey_Apostrophe 77 | when SDL::SDLK_COMMA then ImGuiKey_Comma 78 | when SDL::SDLK_MINUS then ImGuiKey_Minus 79 | when SDL::SDLK_PERIOD then ImGuiKey_Period 80 | when SDL::SDLK_SLASH then ImGuiKey_Slash 81 | when SDL::SDLK_SEMICOLON then ImGuiKey_Semicolon 82 | when SDL::SDLK_EQUALS then ImGuiKey_Equal 83 | when SDL::SDLK_LEFTBRACKET then ImGuiKey_LeftBracket 84 | when SDL::SDLK_BACKSLASH then ImGuiKey_Backslash 85 | when SDL::SDLK_RIGHTBRACKET then ImGuiKey_RightBracket 86 | when SDL::SDLK_BACKQUOTE then ImGuiKey_GraveAccent 87 | when SDL::SDLK_CAPSLOCK then ImGuiKey_CapsLock 88 | when SDL::SDLK_SCROLLLOCK then ImGuiKey_ScrollLock 89 | when SDL::SDLK_NUMLOCKCLEAR then ImGuiKey_NumLock 90 | when SDL::SDLK_PRINTSCREEN then ImGuiKey_PrintScreen 91 | when SDL::SDLK_PAUSE then ImGuiKey_Pause 92 | when SDL::SDLK_KP_0 then ImGuiKey_Keypad0 93 | when SDL::SDLK_KP_1 then ImGuiKey_Keypad1 94 | when SDL::SDLK_KP_2 then ImGuiKey_Keypad2 95 | when SDL::SDLK_KP_3 then ImGuiKey_Keypad3 96 | when SDL::SDLK_KP_4 then ImGuiKey_Keypad4 97 | when SDL::SDLK_KP_5 then ImGuiKey_Keypad5 98 | when SDL::SDLK_KP_6 then ImGuiKey_Keypad6 99 | when SDL::SDLK_KP_7 then ImGuiKey_Keypad7 100 | when SDL::SDLK_KP_8 then ImGuiKey_Keypad8 101 | when SDL::SDLK_KP_9 then ImGuiKey_Keypad9 102 | when SDL::SDLK_KP_PERIOD then ImGuiKey_KeypadDecimal 103 | when SDL::SDLK_KP_DIVIDE then ImGuiKey_KeypadDivide 104 | when SDL::SDLK_KP_MULTIPLY then ImGuiKey_KeypadMultiply 105 | when SDL::SDLK_KP_MINUS then ImGuiKey_KeypadSubtract 106 | when SDL::SDLK_KP_PLUS then ImGuiKey_KeypadAdd 107 | when SDL::SDLK_KP_ENTER then ImGuiKey_KeypadEnter 108 | when SDL::SDLK_KP_EQUALS then ImGuiKey_KeypadEqual 109 | when SDL::SDLK_LCTRL then ImGuiKey_LeftCtrl 110 | when SDL::SDLK_LSHIFT then ImGuiKey_LeftShift 111 | when SDL::SDLK_LALT then ImGuiKey_LeftAlt 112 | when SDL::SDLK_LGUI then ImGuiKey_LeftSuper 113 | when SDL::SDLK_RCTRL then ImGuiKey_RightCtrl 114 | when SDL::SDLK_RSHIFT then ImGuiKey_RightShift 115 | when SDL::SDLK_RALT then ImGuiKey_RightAlt 116 | when SDL::SDLK_RGUI then ImGuiKey_RightSuper 117 | when SDL::SDLK_APPLICATION then ImGuiKey_Menu 118 | when SDL::SDLK_0 then ImGuiKey_0 119 | when SDL::SDLK_1 then ImGuiKey_1 120 | when SDL::SDLK_2 then ImGuiKey_2 121 | when SDL::SDLK_3 then ImGuiKey_3 122 | when SDL::SDLK_4 then ImGuiKey_4 123 | when SDL::SDLK_5 then ImGuiKey_5 124 | when SDL::SDLK_6 then ImGuiKey_6 125 | when SDL::SDLK_7 then ImGuiKey_7 126 | when SDL::SDLK_8 then ImGuiKey_8 127 | when SDL::SDLK_9 then ImGuiKey_9 128 | when SDL::SDLK_a then ImGuiKey_A 129 | when SDL::SDLK_b then ImGuiKey_B 130 | when SDL::SDLK_c then ImGuiKey_C 131 | when SDL::SDLK_d then ImGuiKey_D 132 | when SDL::SDLK_e then ImGuiKey_E 133 | when SDL::SDLK_f then ImGuiKey_F 134 | when SDL::SDLK_g then ImGuiKey_G 135 | when SDL::SDLK_h then ImGuiKey_H 136 | when SDL::SDLK_i then ImGuiKey_I 137 | when SDL::SDLK_j then ImGuiKey_J 138 | when SDL::SDLK_k then ImGuiKey_K 139 | when SDL::SDLK_l then ImGuiKey_L 140 | when SDL::SDLK_m then ImGuiKey_M 141 | when SDL::SDLK_n then ImGuiKey_N 142 | when SDL::SDLK_o then ImGuiKey_O 143 | when SDL::SDLK_p then ImGuiKey_P 144 | when SDL::SDLK_q then ImGuiKey_Q 145 | when SDL::SDLK_r then ImGuiKey_R 146 | when SDL::SDLK_s then ImGuiKey_S 147 | when SDL::SDLK_t then ImGuiKey_T 148 | when SDL::SDLK_u then ImGuiKey_U 149 | when SDL::SDLK_v then ImGuiKey_V 150 | when SDL::SDLK_w then ImGuiKey_W 151 | when SDL::SDLK_x then ImGuiKey_X 152 | when SDL::SDLK_y then ImGuiKey_Y 153 | when SDL::SDLK_z then ImGuiKey_Z 154 | when SDL::SDLK_F1 then ImGuiKey_F1 155 | when SDL::SDLK_F2 then ImGuiKey_F2 156 | when SDL::SDLK_F3 then ImGuiKey_F3 157 | when SDL::SDLK_F4 then ImGuiKey_F4 158 | when SDL::SDLK_F5 then ImGuiKey_F5 159 | when SDL::SDLK_F6 then ImGuiKey_F6 160 | when SDL::SDLK_F7 then ImGuiKey_F7 161 | when SDL::SDLK_F8 then ImGuiKey_F8 162 | when SDL::SDLK_F9 then ImGuiKey_F9 163 | when SDL::SDLK_F10 then ImGuiKey_F10 164 | when SDL::SDLK_F11 then ImGuiKey_F11 165 | when SDL::SDLK_F12 then ImGuiKey_F12 166 | else ImGuiKey_None 167 | end 168 | end 169 | 170 | # [INTERNAL] 171 | def self.ImGui_ImplSDL2_UpdateKeyModifiers(sdl_key_mods) 172 | io = ImGuiIO.new(ImGui::GetIO()) 173 | io.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods & SDL::KMOD_CTRL) != 0) 174 | io.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods & SDL::KMOD_SHIFT) != 0) 175 | io.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods & SDL::KMOD_ALT) != 0) 176 | io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & SDL::KMOD_GUI) != 0) 177 | end 178 | 179 | # You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. 180 | # - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. 181 | # - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. 182 | # Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. 183 | # 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. 184 | def self.ImplSDL2_ProcessEvent(event) 185 | io = ImGuiIO.new(ImGui::GetIO()) 186 | bd = ImGui_ImplSDL2_GetBackendData() 187 | 188 | case event[:type] 189 | 190 | when SDL::MOUSEMOTION 191 | io.AddMousePosEvent(event[:motion][:x].to_f, event[:motion][:y].to_f) 192 | return true 193 | 194 | when SDL::MOUSEWHEEL 195 | wheel_x = (event[:wheel][:x] > 0) ? 1.0 : (event[:wheel][:x] < 0) ? -1.0 : 0.0 196 | wheel_y = (event[:wheel][:y] > 0) ? 1.0 : (event[:wheel][:y] < 0) ? -1.0 : 0.0 197 | io.AddMouseWheelEvent(wheel_x, wheel_y) 198 | return true 199 | 200 | when SDL::MOUSEBUTTONDOWN, SDL::MOUSEBUTTONUP 201 | mouse_button = -1 202 | mouse_button = 0 if event[:button][:button] == SDL::BUTTON_LEFT 203 | mouse_button = 1 if event[:button][:button] == SDL::BUTTON_RIGHT 204 | mouse_button = 2 if event[:button][:button] == SDL::BUTTON_MIDDLE 205 | if mouse_button != -1 206 | io.AddMouseButtonEvent(mouse_button, event[:type] == SDL::MOUSEBUTTONDOWN) 207 | bd.mouseButtonsDown = (event[:type] == SDL::MOUSEBUTTONDOWN) ? (bd.mouseButtonsDown | (1 << mouse_button)) : (bd.mouseButtonsDown & ~(1 << mouse_button)) 208 | return true 209 | end 210 | 211 | when SDL::TEXTINPUT 212 | io.AddInputCharactersUTF8(event[:text][:text]) 213 | return true 214 | 215 | when SDL::KEYDOWN, SDL::KEYUP 216 | ImGui_ImplSDL2_UpdateKeyModifiers(event[:key][:keysym][:mod]) 217 | key = ImGui_ImplSDL2_KeyToImGuiKey(event[:key][:keysym][:sym]) 218 | io.AddKeyEvent(key, (event[:type] == SDL::KEYDOWN)) 219 | io.SetKeyEventNativeData(key, event[:key][:keysym][:sym], event[:key][:keysym][:scancode], event[:key][:keysym][:scancode]) # To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. 220 | return true 221 | 222 | when SDL::WINDOWEVENT 223 | io.AddMousePosEvent(-Float::MAX, -Float::MAX) if event[:window][:event] == SDL::WINDOWEVENT_LEAVE 224 | 225 | if event[:window][:event] == SDL::WINDOWEVENT_FOCUS_GAINED 226 | io.AddFocusEvent(true) 227 | elsif event[:window][:event] == SDL::WINDOWEVENT_FOCUS_LOST 228 | io.AddFocusEvent(false) 229 | end 230 | return true 231 | 232 | end 233 | 234 | return false 235 | end 236 | 237 | def self.ImplSDL2_Init(window, renderer) 238 | 239 | # Check and store if we are on a SDL backend that supports global mouse position 240 | # ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) 241 | mouse_can_use_global_state = false 242 | sdl_backend = SDL.GetCurrentVideoDriver().read_string 243 | global_mouse_whitelist = ["windows", "cocoa", "x11", "DIVE", "VMAN"] 244 | global_mouse_whitelist.each do |platform| 245 | mouse_can_use_global_state = true if sdl_backend == platform 246 | end 247 | 248 | # Setup backend capabilities flags 249 | bd = ImGui_ImplSDL2_Data.new 250 | @@g_BackendData[ImGui::GetCurrentContext().address] = bd 251 | 252 | io = ImGuiIO.new(ImGui::GetIO()) 253 | io[:BackendPlatformName] = @@g_BackendPlatformName 254 | io[:BackendFlags] |= ImGuiBackendFlags_HasMouseCursors # We can honor GetMouseCursor() values (optional) 255 | io[:BackendFlags] |= ImGuiBackendFlags_HasSetMousePos # We can honor io.WantSetMousePos requests (optional, rarely used) 256 | 257 | bd.window = window 258 | bd.renderer = renderer 259 | bd.mouseCanUseGlobalState = mouse_can_use_global_state 260 | 261 | # [TODO] Support ClipboardText : pass callbacks as Proc or something 262 | # io[:SetClipboardTextFn] = ImGui_ImplSDL2_SetClipboardText 263 | # io[:GetClipboardTextFn] = ImGui_ImplSDL2_GetClipboardText 264 | io[:ClipboardUserData] = nil 265 | 266 | # Load mouse cursors 267 | bd.mouseCursors[ImGuiMouseCursor_Arrow] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_ARROW) 268 | bd.mouseCursors[ImGuiMouseCursor_TextInput] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_IBEAM) 269 | bd.mouseCursors[ImGuiMouseCursor_ResizeAll] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZEALL) 270 | bd.mouseCursors[ImGuiMouseCursor_ResizeNS] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZENS) 271 | bd.mouseCursors[ImGuiMouseCursor_ResizeEW] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZEWE) 272 | bd.mouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZENESW) 273 | bd.mouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_SIZENWSE) 274 | bd.mouseCursors[ImGuiMouseCursor_Hand] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_HAND) 275 | bd.mouseCursors[ImGuiMouseCursor_NotAllowed] = SDL.CreateSystemCursor(SDL::SYSTEM_CURSOR_NO) 276 | 277 | # Set platform dependent data in viewport 278 | case RbConfig::CONFIG['host_os'] 279 | when /mswin|msys|mingw|cygwin/ 280 | info = SDL::SysWMinfo_win.new 281 | SDL.GetVersion(info[:version]) 282 | if SDL.GetWindowWMInfo(window, info) == SDL::TRUE 283 | viewport = ImGuiViewport.new(ImGui::GetMainViewport()) 284 | viewport[:PlatformHandleRaw] = info[:info][:win][:window] 285 | end 286 | end 287 | 288 | # Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event. 289 | # Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered. 290 | # (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application. 291 | # It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click: 292 | # you can ignore SDL_MOUSEBUTTONDOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED) 293 | if defined?(SDL::HINT_MOUSE_FOCUS_CLICKTHROUGH) 294 | SDL.SetHint(SDL::HINT_MOUSE_FOCUS_CLICKTHROUGH, "1") 295 | end 296 | 297 | return true 298 | end 299 | 300 | def self.ImplSDL2_Shutdown() 301 | io = ImGuiIO.new(ImGui::GetIO()) 302 | bd = ImGui_ImplSDL2_GetBackendData() 303 | 304 | SDL.free(bd.clipboardTextData) if bd.clipboardTextData 305 | 306 | ImGuiMouseCursor_COUNT.times do |cursor_n| 307 | SDL.FreeCursor(bd.mouseCursors[cursor_n]) 308 | bd.mouseCursors[cursor_n] = nil 309 | end 310 | 311 | io[:BackendPlatformName] = nil 312 | io[:BackendPlatformUserData] = nil 313 | @@g_BackendData[ImGui::GetCurrentContext()] = nil 314 | end 315 | 316 | # [INTERNAL] 317 | def self.ImplSDL2_UpdateMouseData() 318 | bd = ImGui_ImplSDL2_GetBackendData() 319 | io = ImGuiIO.new(ImGui::GetIO()) 320 | 321 | SDL.CaptureMouse(bd.mouseButtonsDown != 0 ? SDL::TRUE : SDL::FALSE) 322 | focused_window = SDL.GetKeyboardFocus() 323 | is_app_focused = (bd.window == focused_window) 324 | if is_app_focused 325 | # (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 326 | if io[:WantSetMousePos] 327 | SDL.WarpMouseInWindow(bd.window, io[:MousePos][:x].to_i, io[:MousePos][:y].to_i) 328 | end 329 | 330 | # (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured) 331 | if bd.mouseCanUseGlobalState && bd.mouseButtonsDown == 0 332 | wx = FFI::MemoryPointer.new(:int) 333 | wy = FFI::MemoryPointer.new(:int) 334 | mx = FFI::MemoryPointer.new(:int) 335 | my = FFI::MemoryPointer.new(:int) 336 | SDL.GetGlobalMouseState(mx, my) 337 | SDL.GetWindowPosition(bd.window, wx, wy) 338 | io.AddMousePosEvent(mx.read(:int).to_f - wx.read(:int).to_f, my.read(:int).to_f - wy.read(:int).to_f) 339 | end 340 | end 341 | end 342 | 343 | # [INTERNAL] 344 | def self.ImplSDL2_UpdateMouseCursor() 345 | io = ImGuiIO.new(ImGui::GetIO()) 346 | return if (io[:ConfigFlags] & ImGuiConfigFlags_NoMouseCursorChange) 347 | bd = ImGui_ImplSDL2_GetBackendData() 348 | 349 | imgui_cursor = ImGui::GetMouseCursor() 350 | if io[:MouseDrawCursor] || imgui_cursor == ImGuiMouseCursor_None 351 | # Hide OS mouse cursor if imgui is drawing it or if it wants no cursor 352 | SDL.ShowCursor(SDL::FALSE) 353 | else 354 | # Show OS mouse cursor 355 | SDL.SetCursor(bd.mouseCursors[imgui_cursor] ? bd.mouseCursors[imgui_cursor] : bd.mouseCursors[ImGuiMouseCursor_Arrow]) 356 | SDL.ShowCursor(SDL::TRUE) 357 | end 358 | end 359 | 360 | # 361 | # [TODO] Support ImplSDL2_UpdateGamepads 362 | # 363 | 364 | def self.ImplSDL2_NewFrame() 365 | bd = ImGui_ImplSDL2_GetBackendData() 366 | io = ImGuiIO.new(ImGui::GetIO()) 367 | 368 | # Setup display size (every frame to accommodate for window resizing) 369 | w = ' ' * 4 370 | h = ' ' * 4 371 | display_w = ' ' * 4 372 | display_h = ' ' * 4 373 | SDL.GetWindowSize(bd.window, w, h) 374 | w = w.unpack1('L') 375 | h = h.unpack1('L') 376 | 377 | if (SDL.GetWindowFlags(bd.window) & SDL::WINDOW_MINIMIZED) != 0 378 | w = h = 0 379 | end 380 | if bd.renderer != nil 381 | SDL.GetRendererOutputSize(bd.renderer, display_w, display_h) 382 | else 383 | SDL.GL_GetDrawableSize(bd.window, display_w, display_h) 384 | end 385 | display_w = display_w.unpack1('L') 386 | display_h = display_h.unpack1('L') 387 | 388 | io[:DisplaySize] = ImVec2.create(w.to_f, h.to_f) 389 | 390 | if w > 0 && h > 0 391 | io[:DisplayFramebufferScale][:x] = display_w.to_f / w 392 | io[:DisplayFramebufferScale][:y] = display_h.to_f / h 393 | end 394 | 395 | # Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) 396 | frequency = SDL.GetPerformanceFrequency() 397 | current_time = SDL.GetPerformanceCounter() 398 | 399 | io[:DeltaTime] = bd.time > 0 ? ((current_time - bd.time).to_f / frequency) : (1.0/60.0) 400 | bd.time = current_time 401 | 402 | ImplSDL2_UpdateMouseData() 403 | ImplSDL2_UpdateMouseCursor() 404 | 405 | # [TODO] update gamepads 406 | # ImGui_ImplSDL2_UpdateGamepads() 407 | end 408 | 409 | end 410 | -------------------------------------------------------------------------------- /lib/imgui_impl_sdlrenderer.rb: -------------------------------------------------------------------------------- 1 | require 'ffi' 2 | require 'sdl2' 3 | require_relative 'imgui' 4 | 5 | module ImGui 6 | 7 | class ImGui_ImplSDLRenderer_Data < FFI::Struct 8 | layout( 9 | :SDLRenderer, :pointer, 10 | :FontTexture, :pointer 11 | ) 12 | end 13 | 14 | def self.ImGui_ImplSDLRenderer_GetBackendData() 15 | if ImGui::GetCurrentContext() != nil 16 | io = ImGuiIO.new(ImGui::GetIO()) 17 | instance = ImGui_ImplSDLRenderer_Data.new(io[:BackendRendererUserData]) 18 | return instance 19 | else 20 | return nil 21 | end 22 | end 23 | 24 | @@g_BackendRendererName = FFI::MemoryPointer.from_string("imgui_impl_sdlrenderer") 25 | @@g_BackendRendererUserData = nil 26 | 27 | def self.ImplSDLRenderer_Init(renderer) 28 | io = ImGuiIO.new(ImGui::GetIO()) 29 | 30 | # Setup backend capabilities flags 31 | 32 | io[:BackendRendererName] = @@g_BackendRendererName 33 | 34 | @@g_BackendRendererUserData = ImGui_ImplSDLRenderer_Data.new 35 | @@g_BackendRendererUserData[:SDLRenderer] = renderer 36 | @@g_BackendRendererUserData[:FontTexture] = nil 37 | io[:BackendRendererUserData] = @@g_BackendRendererUserData 38 | 39 | io[:BackendFlags] |= ImGuiBackendFlags_RendererHasVtxOffset # We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. 40 | 41 | return true 42 | end 43 | 44 | def self.ImplSDLRenderer_Shutdown() 45 | ImplSDLRenderer_DestroyDeviceObjects() 46 | io = ImGuiIO.new(ImGui::GetIO()) 47 | io[:BackendRendererName] = nil 48 | io[:BackendRendererUserData] = nil 49 | @@g_BackendRendererUserData = nil 50 | end 51 | 52 | # [Internal] 53 | def self.ImplSDLRenderer_SetupRenderState() 54 | bd = ImGui_ImplSDLRenderer_GetBackendData() 55 | 56 | # Clear out any viewports and cliprect set by the user 57 | # FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process. 58 | SDL.RenderSetViewport(bd[:SDLRenderer], nil) 59 | SDL.RenderSetClipRect(bd[:SDLRenderer], nil) 60 | end 61 | 62 | def self.ImplSDLRenderer_NewFrame() 63 | bd = ImGui_ImplSDLRenderer_GetBackendData() 64 | ImGui::ImplSDLRenderer_CreateDeviceObjects() if bd[:FontTexture] == nil 65 | end 66 | 67 | def self.ImplSDLRenderer_RenderDrawData(draw_data_raw) 68 | draw_data = ImDrawData.new(draw_data_raw) 69 | bd = ImGui_ImplSDLRenderer_GetBackendData() 70 | 71 | # If there's a scale factor set by the user, use that instead 72 | # If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass 73 | # to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here. 74 | rsx = FFI::MemoryPointer.new :float 75 | rsy = FFI::MemoryPointer.new :float 76 | SDL.RenderGetScale(bd[:SDLRenderer], rsx, rsy) 77 | render_scale = ImVec2.create(0, 0) 78 | render_scale[:x] = (rsx.read_float() == 1.0) ? draw_data[:FramebufferScale][:x] : 1.0 79 | render_scale[:y] = (rsy.read_float() == 1.0) ? draw_data[:FramebufferScale][:y] : 1.0 80 | 81 | # Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) 82 | fb_width = (draw_data[:DisplaySize][:x] * render_scale[:x]).to_i 83 | fb_height = (draw_data[:DisplaySize][:y] * render_scale[:y]).to_i 84 | return if fb_width == 0 || fb_height == 0 85 | 86 | # Backup SDL_Renderer state that will be modified to restore it afterwards 87 | oldViewport = SDL::Rect.new 88 | oldClipEnabled = FFI::MemoryPointer.new :bool 89 | oldClipRect = SDL::Rect.new 90 | 91 | oldClipEnabled = (SDL.RenderIsClipEnabled(bd[:SDLRenderer]) == SDL::TRUE) 92 | SDL.RenderGetViewport(bd[:SDLRenderer], oldViewport) 93 | SDL.RenderGetClipRect(bd[:SDLRenderer], oldClipRect) 94 | 95 | # Will project scissor/clipping rectangles into framebuffer space 96 | clip_off = draw_data[:DisplayPos] # (0,0) unless using multi-viewports 97 | clip_scale = render_scale 98 | 99 | # Render command lists 100 | ImplSDLRenderer_SetupRenderState() 101 | draw_data[:CmdListsCount].times do |n| 102 | cmd_list = ImDrawList.new((draw_data[:CmdLists][:Data] + FFI.type_size(:pointer) * n).read_pointer) 103 | vtx_buffer = cmd_list[:VtxBuffer][:Data] # const ImDrawVert* 104 | idx_buffer = cmd_list[:IdxBuffer][:Data] # const ImDrawIdx* 105 | 106 | cmd_list[:CmdBuffer][:Size].times do |cmd_i| 107 | pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i) # const ImDrawCmd* 108 | if pcmd[:UserCallback] != nil 109 | # [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks ) 110 | 111 | # User callback, registered via ImDrawList::AddCallback() 112 | # (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) 113 | # if pcmd[:UserCallback] == :ImDrawCallback_ResetRenderState 114 | ImGui_ImplSDLRenderer_SetupRenderState() 115 | # else 116 | # pcmd[:UserCallback](cmd_list, pcmd) 117 | # end 118 | else 119 | clip_min = ImVec2.create((pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x], (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y]) 120 | clip_max = ImVec2.create((pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x], (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y]) 121 | 122 | clip_min[:x] = 0.0 if clip_min[:x] < 0.0 123 | clip_min[:y] = 0.0 if clip_min[:y] < 0.0 124 | clip_max[:x] = fb_width.to_f if clip_max[:x] > fb_width 125 | clip_max[:y] = fb_height.to_f if clip_max[:y] > fb_height 126 | next if (clip_max[:x] <= clip_min[:x] || clip_max[:y] <= clip_min[:y]) 127 | 128 | r = SDL::Rect.new 129 | r[:x] = clip_min[:x].to_i 130 | r[:y] = clip_min[:y].to_i 131 | r[:w] = (clip_max[:x] - clip_min[:x]).to_i 132 | r[:h] = (clip_max[:y] - clip_min[:y]).to_i 133 | 134 | SDL.RenderSetClipRect(bd[:SDLRenderer], r.to_ptr) 135 | 136 | xy = vtx_buffer + (pcmd[:VtxOffset] + ImDrawVert.offset_of(:pos)) 137 | uv = vtx_buffer + (pcmd[:VtxOffset] + ImDrawVert.offset_of(:uv)) 138 | color = vtx_buffer + (pcmd[:VtxOffset] + ImDrawVert.offset_of(:col)) 139 | 140 | SDL.RenderGeometryRaw(bd[:SDLRenderer], pcmd[:TextureId], 141 | xy, ImDrawVert.size, 142 | color, ImDrawVert.size, 143 | uv, ImDrawVert.size, 144 | cmd_list[:VtxBuffer][:Size] - pcmd[:VtxOffset], 145 | idx_buffer + FFI.type_size(:ImDrawIdx) * pcmd[:IdxOffset], pcmd[:ElemCount], FFI.type_size(:ImDrawIdx)) # FFI.type_size(:ImDrawIdx) == FFI::Type::UINT16.size 146 | 147 | # Restore modified SDL_Renderer state 148 | SDL.RenderSetViewport(bd[:SDLRenderer], oldViewport) 149 | SDL.RenderSetClipRect(bd[:SDLRenderer], oldClipEnabled ? oldClipRect : nil) 150 | end 151 | end 152 | end 153 | end 154 | 155 | # Called by Init/NewFrame/Shutdown 156 | def self.ImplSDLRenderer_CreateFontsTexture() 157 | io = ImGuiIO.new(ImGui::GetIO()) 158 | bd = ImGui_ImplSDLRenderer_GetBackendData() 159 | 160 | # Build texture atlas 161 | pixels = FFI::MemoryPointer.new :pointer 162 | width = FFI::MemoryPointer.new :int 163 | height = FFI::MemoryPointer.new :int 164 | io[:Fonts].GetTexDataAsRGBA32(pixels, width, height, nil) # Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. 165 | 166 | # Upload texture to graphics system 167 | bd[:FontTexture] = SDL.CreateTexture(bd[:SDLRenderer], SDL::PIXELFORMAT_ABGR8888, SDL::TEXTUREACCESS_STATIC, width.read_int, height.read_int) 168 | if bd[:FontTexture] == nil 169 | SDL.Log("error creating texture") 170 | return false 171 | end 172 | 173 | SDL.UpdateTexture(bd[:FontTexture], nil, pixels.read_pointer, 4 * width.read_int) 174 | SDL.SetTextureBlendMode(bd[:FontTexture], SDL::BLENDMODE_BLEND) 175 | 176 | # Store our identifier 177 | io[:Fonts].SetTexID(bd[:FontTexture]) 178 | 179 | return true 180 | end 181 | 182 | def self.ImplSDLRenderer_DestroyFontsTexture() 183 | io = ImGuiIO.new(ImGui::GetIO()) 184 | bd = ImGui_ImplSDLRenderer_GetBackendData() 185 | if bd[:FontTexture] != nil 186 | io[:Fonts].SetTexID(nil) 187 | SDL.DestroyTexture(bd[:FontTexture]) 188 | bd[:FontTexture] = nil 189 | end 190 | end 191 | 192 | def self.ImplSDLRenderer_CreateDeviceObjects() 193 | return ImGui::ImplSDLRenderer_CreateFontsTexture() 194 | end 195 | 196 | def self.ImplSDLRenderer_DestroyDeviceObjects() 197 | ImGui::ImplSDLRenderer_DestroyFontsTexture() 198 | end 199 | 200 | end 201 | -------------------------------------------------------------------------------- /lib/imgui_internal.rb: -------------------------------------------------------------------------------- 1 | # imgui-bindings : Yet another ImGui wrapper for Ruby 2 | # 3 | # * https://github.com/vaiorabbit/ruby-imgui 4 | 5 | require 'ffi' 6 | 7 | module ImGui 8 | 9 | extend FFI::Library 10 | 11 | @@imgui_import_internal_done = false 12 | 13 | def self.import_internal_symbols(output_error = false) 14 | 15 | symbols = [ 16 | :igFocusWindow, 17 | :igGetCurrentWindow, 18 | ] 19 | 20 | args = { 21 | :igFocusWindow => [:pointer], 22 | :igGetCurrentWindow => [], 23 | } 24 | 25 | retvals = { 26 | :igFocusWindow => :void, 27 | :igGetCurrentWindow => :pointer, 28 | } 29 | 30 | symbols.each do |sym| 31 | begin 32 | attach_function sym, args[sym], retvals[sym] 33 | rescue FFI::NotFoundError 34 | $stderr.puts("[Warning] Failed to import #{sym}.\n") if output_error 35 | end 36 | end 37 | 38 | @@imgui_import_internal_done = true 39 | end # self.import_internal_symbols 40 | 41 | def self.GetCurrentWindow() 42 | igGetCurrentWindow() 43 | end 44 | 45 | def self.FocusWindow(window) 46 | igFocusWindow(window) 47 | end 48 | 49 | end # module ImGui 50 | -------------------------------------------------------------------------------- /lib/imnodes.aarch64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/lib/imnodes.aarch64.so -------------------------------------------------------------------------------- /lib/imnodes.arm64.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/lib/imnodes.arm64.dylib -------------------------------------------------------------------------------- /lib/imnodes.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/lib/imnodes.dll -------------------------------------------------------------------------------- /lib/imnodes.rb: -------------------------------------------------------------------------------- 1 | # imgui-bindings : Yet another ImGui wrapper for Ruby 2 | # 3 | # * https://github.com/vaiorabbit/ruby-imgui 4 | 5 | require 'ffi' 6 | 7 | # ImNodes::StyleColor 8 | ImNodesStyleColor_ColCanvasLines = 0 9 | ImNodesStyleColor_ColNodeBg = 1 10 | ImNodesStyleColor_ColNodeActiveBg = 2 11 | ImNodesStyleColor_ColNodeBorder = 3 12 | ImNodesStyleColor_ColConnection = 4 13 | ImNodesStyleColor_ColConnectionActive = 5 14 | ImNodesStyleColor_ColSelectBg = 6 15 | ImNodesStyleColor_ColSelectBorder = 7 16 | ImNodesStyleColor_ColMax = 8 17 | 18 | # ImNodesStyleVar 19 | ImNodesStyleVar_GridSpacing = 0 # float 20 | ImNodesStyleVar_CurveThickness = 1 # float 21 | ImNodesStyleVar_CurveStrength = 2 # float 22 | ImNodesStyleVar_SlotRadius = 3 # float 23 | ImNodesStyleVar_NodeRounding = 4 # float 24 | ImNodesStyleVar_NodeSpacing = 5 # ImVec2 25 | ImNodesStyleVar_ItemSpacing = 6 # ImVec2 26 | ImNodesStyleVar_COUNT = 7 27 | 28 | # ImNodesStyleCol 29 | ImNodesStyleCol_GridLines = 0 30 | ImNodesStyleCol_NodeBodyBg = 1 31 | ImNodesStyleCol_NodeBodyBgHovered = 2 32 | ImNodesStyleCol_NodeBodyBgActive = 3 33 | ImNodesStyleCol_NodeBorder = 4 34 | ImNodesStyleCol_Connection = 5 35 | ImNodesStyleCol_ConnectionActive = 6 36 | ImNodesStyleCol_SelectBg = 7 37 | ImNodesStyleCol_SelectBorder = 8 38 | ImNodesStyleCol_NodeTitleBarBg = 9 39 | ImNodesStyleCol_NodeTitleBarBgHovered = 10 40 | ImNodesStyleCol_NodeTitleBarBgActive = 11 41 | ImNodesStyleCol_COUNT = 12 42 | 43 | module ImNodes 44 | 45 | extend FFI::Library 46 | 47 | @@imnodes_import_done = false 48 | 49 | class CanvasStyle < FFI::Struct 50 | layout( 51 | # Thickness of curves that connect slots together. 52 | :CurveThickness, :float, 53 | # Indent connection into slot widget a little. Useful when slot content covers connection end with some kind 54 | # of icon (like a circle) and then no seam between icon and connection end is visible. 55 | :ConnectionIndent, :float, 56 | :GridSpacing, :float, 57 | :CurveStrength, :float, 58 | :NodeRounding, :float, 59 | :NodeSpacing, ImVec2.by_value 60 | ) 61 | end 62 | 63 | class CanvasState < FFI::Struct 64 | layout( 65 | # Current zoom of canvas. 66 | :Zoom, :float, 67 | # Current scroll offset of canvas. 68 | :Offset, ImVec2.by_value, 69 | # Colors used to style elements of this canvas. 70 | :Colors, [ImColor.by_value, ImNodesStyleColor_ColMax], 71 | # Style parameters 72 | :Style, CanvasStyle.by_value, 73 | # Implementation detail. 74 | :_Impl, :pointer 75 | ) 76 | 77 | def self.create() 78 | return CanvasState.new(ImNodesCanvasStateCtor()) 79 | end 80 | 81 | def destroy() 82 | ImNodesCanvasStateDtor(self) 83 | end 84 | end 85 | 86 | class SlotInfo < FFI::Struct 87 | layout( 88 | :title, :pointer, 89 | :kind, :int 90 | ) 91 | 92 | def self.create(title, kind) 93 | instance = SlotInfo.new 94 | instance[:title] = FFI::MemoryPointer.from_string(title) 95 | instance[:kind] = kind 96 | return instance 97 | end 98 | end 99 | 100 | def self.load_lib(libpath = './imnodes.dylib', output_error = false) 101 | ffi_lib_flags :now, :global 102 | ffi_lib libpath 103 | import_symbols(output_error) unless @@imnodes_import_done 104 | end 105 | 106 | def self.import_symbols(output_error = false) 107 | 108 | symbols = [ 109 | # name, func, args, returns 110 | [:CanvasStateCtor, :ImNodesCanvasStateCtor, [], :pointer], 111 | [:CanvasStateDtor, :ImNodesCanvasStateDtor, [:pointer], :void], 112 | [:BeginCanvas, :ImNodesBeginCanvas, [:pointer], :void], 113 | [:EndCanvas, :ImNodesEndCanvas, [], :void], 114 | [:BeginNode, :ImNodesBeginNode, [:pointer, :pointer, :pointer], :bool], 115 | [:EndNode, :ImNodesEndNode, [], :void], 116 | [:IsNodeHovered, :ImNodesIsNodeHovered, [], :bool], 117 | [:AutoPositionNode, :ImNodesAutoPositionNode, [:pointer], :void], 118 | [:GetNewConnection, :ImNodesGetNewConnection, [:pointer, :pointer, :pointer, :pointer], :bool], 119 | [:GetPendingConnection, :ImNodesGetPendingConnection, [:pointer, :pointer, :pointer], :bool], 120 | [:Connection, :ImNodesConnection, [:pointer, :pointer, :pointer, :pointer], :bool], 121 | [:GetCurrentCanvas, :ImNodesGetCurrentCanvas, [], :pointer], 122 | [:InputSlotKind, :ImNodesInputSlotKind, [:int], :int], 123 | [:OutputSlotKind, :ImNodesOutputSlotKind, [:int], :int], 124 | [:IsInputSlotKind, :ImNodesIsInputSlotKind, [:int], :bool], 125 | [:IsOutputSlotKind, :ImNodesIsOutputSlotKind, [:int], :bool], 126 | [:BeginSlot, :ImNodesBeginSlot, [:pointer, :int], :bool], 127 | [:BeginInputSlot, :ImNodesBeginInputSlot, [:pointer, :int], :bool], 128 | [:BeginOutputSlot, :ImNodesBeginOutputSlot, [:pointer, :int], :bool], 129 | [:EndSlot, :ImNodesEndSlot, [], :void], 130 | [:IsSlotCurveHovered, :ImNodesIsSlotCurveHovered, [], :bool], 131 | [:IsConnectingCompatibleSlot, :ImNodesIsConnectingCompatibleSlot, [], :bool], 132 | [:EzCreateContext, :ImNodesEzCreateContext, [], :pointer], 133 | [:EzFreeContext, :ImNodesEzFreeContext, [:pointer], :void], 134 | [:EzSetContext, :ImNodesEzSetContext, [:pointer], :void], 135 | [:EzGetState, :ImNodesEzGetState, [], :pointer], 136 | [:EzBeginCanvas, :ImNodesEzBeginCanvas, [], :void], 137 | [:EzEndCanvas, :ImNodesEzEndCanvas, [], :void], 138 | [:EzBeginNode, :ImNodesEzBeginNode, [:pointer, :pointer, :pointer, :pointer], :bool], 139 | [:EzEndNode, :ImNodesEzEndNode, [], :void], 140 | [:EzInputSlots, :ImNodesEzInputSlots, [:pointer, :int], :void], 141 | [:EzOutputSlots, :ImNodesEzOutputSlots, [:pointer, :int], :void], 142 | [:EzConnection, :ImNodesEzConnection, [:pointer, :pointer, :pointer, :pointer], :bool], 143 | [:EzPushStyleVarFloat, :ImNodesEzPushStyleVarFloat, [:int, :float], :void], 144 | [:EzPushStyleVarVec2, :ImNodesEzPushStyleVarVec2, [:int, :pointer], :void], 145 | [:EzPopStyleVar, :ImNodesEzPopStyleVar, [:int], :void], 146 | [:EzPushStyleColorU32, :ImNodesEzPushStyleColorU32, [:int, :uint], :void], 147 | [:EzPushStyleColorVec4, :ImNodesEzPushStyleColorVec4, [:int, :pointer], :void], 148 | [:EzPopStyleColor, :ImNodesEzPopStyleColor, [:int], :void], 149 | ] 150 | 151 | symbols.each do |sym| 152 | begin 153 | attach_function *sym 154 | rescue FFI::NotFoundError 155 | $stderr.puts("[Warning] Failed to import #{sym}.\n") if output_error 156 | end 157 | end 158 | 159 | end # self.import_symbols 160 | 161 | end # module ImNodes 162 | -------------------------------------------------------------------------------- /lib/imnodes.x86_64.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/lib/imnodes.x86_64.dylib -------------------------------------------------------------------------------- /lib/imnodes.x86_64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaiorabbit/ruby-imgui/a31b871144b549c1f0a8ba1d4ef6c296fea80449/lib/imnodes.x86_64.so -------------------------------------------------------------------------------- /script/check_syntax.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | for /f %%f in ('dir /b ..\lib\*.rb') do ( 3 | ruby -c %~dp0\..\lib\%%f 4 | ) 5 | -------------------------------------------------------------------------------- /script/dearbindings_generate_schema.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | pushd ..\third_party\ 3 | set PYTHON_EXE=%1 4 | if "%PYTHON_EXE%"=="" ( 5 | set PYTHON_EXE=python 6 | ) 7 | %PYTHON_EXE% dear_bindings\dear_bindings.py -t .\dear_bindings\src\templates -o ..\generator\dearbindings ..\imgui_dll\cimgui\imgui\imgui.h 8 | del ..\generator\dearbindings.cpp 9 | del ..\generator\dearbindings.h 10 | popd 11 | -------------------------------------------------------------------------------- /script/dearbindings_generate_schema.sh: -------------------------------------------------------------------------------- 1 | pushd ../third_party/ 2 | python3.11 dear_bindings/dear_bindings.py -t ./dear_bindings/src/templates -o ../generator/dearbindings ../imgui_dll/cimgui/imgui/imgui.h 3 | rm ../generator/dearbindings.cpp ../generator/dearbindings.h 4 | popd 5 | -------------------------------------------------------------------------------- /script/gems_build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | pushd %CD% 3 | cd .. 4 | call gem.cmd build imgui-bindings.gemspec 5 | call gem.cmd build imgui-bindings.gemspec --platform arm64-darwin 6 | call gem.cmd build imgui-bindings.gemspec --platform x86_64-darwin 7 | call gem.cmd build imgui-bindings.gemspec --platform aarch64-linux 8 | call gem.cmd build imgui-bindings.gemspec --platform x86_64-linux 9 | call gem.cmd build imgui-bindings.gemspec --platform x64-mingw 10 | popd 11 | -------------------------------------------------------------------------------- /script/gems_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | pushd . 3 | cd .. 4 | gem build imgui-bindings.gemspec 5 | gem build imgui-bindings.gemspec --platform arm64-darwin 6 | gem build imgui-bindings.gemspec --platform x86_64-darwin 7 | gem build imgui-bindings.gemspec --platform aarch64-linux 8 | gem build imgui-bindings.gemspec --platform x86_64-linux 9 | gem build imgui-bindings.gemspec --platform x64-mingw 10 | popd 11 | -------------------------------------------------------------------------------- /script/gems_push.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | pushd %CD% 3 | cd .. 4 | for /f "delims=" %%f in ('dir ^*.gem /b ^| findstr .gem$') do ( 5 | echo gem push %%f 6 | ) 7 | popd 8 | -------------------------------------------------------------------------------- /script/gems_push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | pushd . 3 | cd .. 4 | for i in `ls imgui-bindings-*.gem`; do 5 | echo gem push $i 6 | done 7 | popd 8 | -------------------------------------------------------------------------------- /script/rebuild_libs_linux.sh: -------------------------------------------------------------------------------- 1 | pushd . 2 | cd ../imgui_dll 3 | rm -r -f build 4 | bash ./build_imgui_linux.sh 5 | popd 6 | 7 | pushd . 8 | cd ../imnodes_dll 9 | rm -r -f build 10 | bash ./build_imnodes_linux.sh 11 | popd 12 | -------------------------------------------------------------------------------- /script/rebuild_libs_linux_cross.sh: -------------------------------------------------------------------------------- 1 | pushd . 2 | cd ../imgui_dll 3 | rm -r -f build 4 | bash ./build_imgui_linux_cross.sh 5 | popd 6 | 7 | pushd . 8 | cd ../imnodes_dll 9 | rm -r -f build 10 | bash ./build_imnodes_linux_cross.sh 11 | popd 12 | -------------------------------------------------------------------------------- /script/rebuild_libs_macos.sh: -------------------------------------------------------------------------------- 1 | pushd . 2 | cd ../imgui_dll 3 | rm -r -f build 4 | bash ./build_imgui_macos.sh 5 | popd 6 | 7 | pushd . 8 | cd ../imnodes_dll 9 | rm -r -f build 10 | bash ./build_imnodes_macos.sh 11 | popd 12 | -------------------------------------------------------------------------------- /script/rebuild_libs_windows.cmd: -------------------------------------------------------------------------------- 1 | :: 2 | :: For Windows + RubyInstaller2 with DevKit(MSYS2 gcc & make) + CMake users. 3 | :: - Use this script after "ridk enable"d. See https://github.com/oneclick/rubyinstaller2/wiki/The-ridk-tool for details. 4 | :: 5 | :: Usage 6 | :: > ridk enable 7 | :: > rebuild_libs_windows.cmd <- %PROGRAMFILES%\CMake\bin\cmake.exe will be used. 8 | :: > rebuild_libs_windows.cmd "D:\Program Files\CMake\bin\cmake.exe" <- You can give full path to 'cmake.exe'. 9 | 10 | @echo off 11 | setlocal enabledelayedexpansion 12 | set CMAKE_EXE=%1 13 | if %CMAKE_EXE% == "" ( 14 | set CMAKE_EXE="%PROGRAMFILES%\CMake\bin\cmake" 15 | ) 16 | 17 | pushd %~dp0 18 | cd ..\imgui_dll 19 | if exist build ( 20 | rmdir /s /q build 21 | ) 22 | call build_imgui_windows.cmd %CMAKE_EXE% 23 | popd 24 | 25 | pushd %~dp0 26 | cd ..\physac_dll 27 | if exist build ( 28 | rmdir /s /q build 29 | ) 30 | call build_imnodes_windows.cmd %CMAKE_EXE% 31 | popd 32 | -------------------------------------------------------------------------------- /third_party/glfw_build.bat: -------------------------------------------------------------------------------- 1 | :: 2 | :: For Windows + RubyInstaller2 with DevKit(MSYS2 gcc & make) + CMake users. 3 | :: - Use this script after "ridk enable"d. See https://github.com/oneclick/rubyinstaller2/wiki/The-ridk-tool for details. 4 | :: 5 | git clone --depth=1 https://github.com/glfw/glfw.git glfw 6 | cd glfw/ 7 | mkdir build 8 | cd build 9 | "%PROGRAMFILES%"\CMake\bin\cmake -G "MSYS Makefiles" -D CMAKE_BUILD_TYPE=Release -D GLFW_NATIVE_API=1 -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=gcc ../ 10 | make 11 | cp -R src/glfw3.dll ../../../sample 12 | -------------------------------------------------------------------------------- /third_party/glfw_build.sh: -------------------------------------------------------------------------------- 1 | # 2 | # For Mac OS X + Xcode + CMake users. 3 | # 4 | # Ref.: https://github.com/malkia/ufo/blob/master/build/OSX/glfw.sh 5 | # 6 | git clone --depth=1 https://github.com/glfw/glfw.git glfw 7 | cd glfw/ 8 | mkdir build 9 | cd build 10 | export MACOSX_DEPLOYMENT_TARGET=10.14 11 | cmake -D CMAKE_BUILD_TYPE=Release -D GLFW_NATIVE_API=1 -D CMAKE_OSX_ARCHITECTURES="x86_64;arm64" -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=clang ../ 12 | make 13 | cp -R src/libglfw* ../../../sample 14 | -------------------------------------------------------------------------------- /third_party/glfw_build_linux.sh: -------------------------------------------------------------------------------- 1 | # 2 | # For Linux + CMake users. 3 | # 4 | # Ref.: https://github.com/malkia/ufo/blob/master/build/OSX/glfw.sh 5 | # 6 | git clone --depth=1 https://github.com/glfw/glfw.git glfw 7 | cd glfw/ 8 | mkdir build 9 | cd build 10 | cmake -D CMAKE_BUILD_TYPE=Release -D GLFW_NATIVE_API=1 -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=clang ../ 11 | make 12 | cp -R src/libglfw* ../../../sample 13 | -------------------------------------------------------------------------------- /third_party/sdl2_build_dll.cmd: -------------------------------------------------------------------------------- 1 | :: 2 | :: Usage : 3 | :: - Open "Developer Command Prompt for VS2019" from start menu 4 | :: - > sdl2_build_dll.cmd 5 | :: 6 | @echo off 7 | setlocal enabledelayedexpansion 8 | 9 | set SDL2_VERSION=2.0.18 10 | 11 | curl -O https://www.libsdl.org/release/SDL2-%SDL2_VERSION%.zip 12 | powershell -Command Expand-Archive -Force SDL2-%SDL2_VERSION%.zip 13 | cd SDL2-%SDL2_VERSION%\SDL2-%SDL2_VERSION% 14 | mkdir build 15 | cd build 16 | cmake -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=ON .. 17 | msbuild SDL2.sln /t:rebuild /p:Configuration=Release;Platform="x64" 18 | 19 | xcopy /y Release\SDL2.dll ..\..\..\..\sample\ 20 | cd ..\..\.. 21 | -------------------------------------------------------------------------------- /third_party/sdl2_build_dylib.sh: -------------------------------------------------------------------------------- 1 | # For macOS + Xcode + CMake users. 2 | curl -O https://www.libsdl.org/release/SDL2-2.0.18.zip 3 | unzip SDL2-2.0.18.zip 4 | cd SDL2-2.0.18/ 5 | mkdir build 6 | cd build 7 | export MACOSX_DEPLOYMENT_TARGET=10.14 8 | cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_OSX_ARCHITECTURES="x86_64;arm64" -D BUILD_SHARED_LIBS=ON -D CMAKE_C_COMPILER=clang ../ 9 | make 10 | 11 | ln -s libSDL2-2.0.dylib libSDL2.dylib 12 | cp -R libSDL2*.dylib ../../../sample 13 | --------------------------------------------------------------------------------