2024年08月24日

Lua言語:GUI: LuaJITでDear ImGuiを動かした時のメモ 2024/08

Lua言語:GUI: LuaJITでDear ImGuiを動かした時のメモ 2024/08

Lua言語:GUI: LuaJITでDear ImGuiを動かした時のメモ 2024/08

はじまり


Dear ImGui [1] の各種言語バインディング用C言語インターフェースCImGuiの作者である
Victor Bombi氏のリポジトリでanimaプロジェクトというのを発見した

animaとは魂、生命、精神という意味だけど、それらをイメージした音と映像を使ったart系の作品を作るためのライブラリ群のことと思われる

このanimaリポジトリには以下のライブラリ(*.dll, *.lua)と実行ファイル(LuaJIT.exe)が含まれている

  1. LuaJIT インタプリター (Lua言語を超高速JITコンパイル実行)
    Lua(+FFI)言語を使ってGUI(Dear ImGui)プログラムを作成後、実行するためのexeファイル
  2. オーディオ再生系ライブラリ
  3. 画像処理系ライブラリ (動画系もある?)
  4. 非同期処理系ライブラリ
  5. SDL2/SDL3[2], GLFW, GL ライブラリ
  6. ImGuiとアドオンライブラリ
    ImPlot, ImPlot3D ImNodes, ImGuizmo, その他多数
    LuaJITで使う時は CImGui, CImPlot, CImNodes, CImGuizmoを経由する
  7. 上記ライブラリを使うためのLuaで書かれた簡単なサンプルコード群

ポイント


  1. ユーザー側のLua GUI ソースコードはLuaJITインタプリタで実行されるので
    Luaソースコードのコンパイルが不要でお手軽に即GUIアプリが実行できる

  2. 外部依存ライブラリなし
    LuaJITを含め必要な多数のライブラリが含まれている

  3. WindowsOS, Linux用プロジェクト可能
    このブログではWindowsOS用にコンパイルした物を使います

  4. オリジナル(animaプロジェクト)のコンパイル済みのバイナリ配布は2021/04が最後(今は2024/08)
    https://github.com/sonoro1234/anima/releases (ImGui部分は v1.82)

  5. なので自分でコンパイルしてみた
    今ここ

  6. オリジナルとの違い

    • コンパイルオプションに以下を加えています

      1. 日本語入力IMEの入力候補位置正常化対応 [3]
        "-DIMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS"
      2. ImPlot
        "-DImDrawIdx=unsigned int"
    • animaプロジェクト付属のexampleプログラムが簡単に実行できるように*.batファイル群を追加

    • Dear ImGui / CImGuiのサンプルをベースに各種exampleプログラムを追加
      (ImGuinImGuinZプロジェクトと同じ)

    • GUIの背景に表示されるコンソール画面を消すことも可能(後述)

Dear ImGuiのバージョン


GUIプログラムの概略


ここと同じなので省略
Zig言語:GUI: Zig言語でDear ImGui/ImPlotを使ってみたメモ 2024/07

Examples


implot3d_sample.lua

ImPlot3Dのデモ
This sample is attached by anima project. You can execute this sample using
implot3d_sample.bat
in bin/examples/LuaJIT-ImGui/examples folder.

alt

glfw_opengl3_simple

glfw_opengl3_simple.lua
アイコンフォントをふんだんに使ってみただけ (-:
glfw_opengl3_simple

IconFontViewer

アイコンフォントビューアを書いてみた
iconFontViewer.lua

alt

glfw_opengl3

glfw_opengl3.lua
画像の表示とWindow内の任意領域をキャプチャした画像を保存できるようにした
画像の部分拡大機能を追加 (2025/01)

glfw_opengl3

glfw_opengl3_implot / implot3D

glfw_opengl3_implot.lua
ImPlot / ImPlot3D 使用デモ
LuaJIT言語でデモを書き直してみた implotWindow.lua

glfw_opengl3_implot

animaプロジェクト付属の example: implot_sample.lua
alt

glfw_opengl3_jp

glfw_opengl3_jp.lua
日本語表示と日本語入力のデモ
画像の部分拡大機能を追加 (2025/01)

glfw_opengl3_jp

sdl2_opengl3

sdl2_opengl3.lua

SDL2のデモ
画像の部分拡大機能を追加 (2025/01)

sdl2_opengl3

ImGuizmo_sample.lua

ImGuizmo_sample.lua

ImGuizmoのデモ
左上の小さい物体をマウスでグリグリすると
右下の大きい物体も同期してグリグリされたりする
変形や回転移動もできたりする

ImGuizmo_sample

imnodes_graph_sample.lua

This sample is attached by anima project. You can execute this sample using
imnodes_graph_sample.bat
in bin/examples/LuaJIT-ImGui/examples folder.

imnodes_graph_sample

その他のexample


bin/examples内には他にもサンプルコードがあるけど全部は載せられないので一部を以下に載せます

julia.lua
luajitImGui-1.91.8.3/bin/examples/juliaSet/julia.bat

を実行するとLua + GLSLで書かれている3Dグリグリ系のデモが起動します

julia

delaunay_particles.lua

alt

bacteria.lua

alt

house.lua

alt

corazon.lua

alt

CTE_windows.lua

シンタックスハイライト付きのエディタプラグイン

alt

compute_shader.lua

alt

ダウンロードと実行 download


最新[4]Github リポジトリはここ luajitImGui

zipファイルを適当なフォルダに解凍します [5]

  • examplesを実行
    例えば Windowsのファイルエクスプローラで

    luajitImGui-1.91.8.3/examples/glfw_opengl3/glfw_opengl3.exe
    

    をダブルクリックで実行すればGUIが起動します
    (バージョン番号の部分はダウンロードしたファイル名に依存)
    又は

    # デバッグ用のコンソール画面が裏に表示されます
    luajitImGui-1.91.8.3/examples/glfw_opengl3/r.bat  
    

    一旦GUIを終了し、
    同じフォル内のglfw_opengl3.lua内の例えばigText()等の文字列等をテキトーに修正した後
    r.bat(又は*.exe)を実行すれば修正が反映したGUIが起動します (コンパイルの必要なし)

    以下のフォルダ内も同様に実行可能

    ...
    .../example/glfw_opengl3_implot
    .../example/glfw_opengl3_jp
    .../example/glfw_opengl3_simple
    .../example/sdl2_opengl3
    etc.
    
  • animaプロジェクトに付属のexampleプログラムを実行
    以下のフォルダ内に*.batファイルがあるのでそれぞれを
    Windowsのファイルエクスプローラでダブルクリック実行すればGUIが起動します

    luajitImGui-1.91.8.3/bin/examples/LuaJIT-ImGui/examples/
    

    bin/examples/LuaJIT-ImGui/examples

自前でビルドするメモ


以下は自分でバイナリファイル群(bin/ 以下の*.exe, *.dll)をビルドする時のメモ
上記zipファイルを使うだけなら不要な作業

  • 以下のツールズ(*.exeファイル)へ実行パスが設定されているとする

  • 必要なツール類: MSys2/MinGW ツールズとClangコンパイラ

  • CMake, make.exeも必要

    pacman -S mingw-w64-ucrt-x86_64-{cmake,gcc,clang,llvm-openmp} patch make
    
  • MSysコンソール上でトップフォルダのMakefileを実行

  • 現在はMinGW版のClangでコンパイルしている (GCCはバイナリが大きくなりすぎなので)

  • Makefile内の TC = clang
    TC = gcc で MinGW版GCC
    TC = msvc で Microsoft Visual Studio 2019 C/C++でコンパイル可能[6]

    • msvcでコンパイルする時は./buildフォルダ内に*.slnができるので
      Microsoft Visual Studio IDEでオープンして
      構成のところで自動インストールにチェックを入れた後ビルドする(これ重要)
  • OpenMPライブラリが必要だった記憶がある。MinGWで

    libopenmpt  
    libopenmpt-modplug  
    

    の二つがインストールされていた(プレフィックスは省略)
    本当に必要かどうかは未確認 (-: Clangの場合は必要

他にもMinGWで必要なライブラがあるかもですがCMakeのエラーを見ながら
テキトーに追加して下さい (-:

以下はClangでビルドする場合

git clone --recurse-submodules https://github.com/dinau/luajitImGui
cd luajitImGui
make clean
make

CMakeでコンパイルがはじまり正常終了すればOK
../binの中にバイナリとライブラリ(*.lua)がインストールされています

GUI背景のコンソール画面を消す


デフォルトのbin/luajit.exeバイナリでは必ずGUI背景のコンソール画面が表示されます
これを消すための方法はいくつかあるみたいで

  1. 例えば起動用のr.batファイルのショートカットを作ってそのプロバティ:実行時の大きさ(R)
    起動時に最小化させる方法: 【Windows11】バッチファイル実行時に黒い画面を出さない方法
    ショートカットは任意の名前に変更できる
    ショートカットのアイコン変更も可能
    ただしタスクバーに最小化されたコンソール画面が残っている

  2. luajit.exeをコンパイルする時に-mwindowsを付けてコンパイルする
    ここを参照してやってみました
    How to build windowless LuaJIT for Windows

    新規で任意のフォルダを作ってその中で

    git clone --recurse-submodules https://github.com/dinau/luajitImGui
    cd luajitImGui/anima/LuaJIT/LuaJIT
    

    ファイル src/luajit.c の最後の行に以下を追加して保存します[7]

    int __stdcall WinMain(void* hInstance, void* hPrevInstance, char* pCmdLine, int nShowCmd)
    { return main(__argc, __argv); }
    

コンパイルはMSysのコンソール画面内で行います(これ重要でした)

pwd 
LuaJIT
make TARGET_LDFLAGS="-mwindows" TARGET_CFLAGS="-O2 -DLUAJIT_ENABLE_LUA52COMPAT"

コンパイル後の

src/luajit.exe
src/lua51.dll

luajit.exeluajitw.exeにリネームしてlua51.dllとペアで使います

しかし 出来上がったluajitw.exeを使ってコンソール画面を消す方法がよく分からないので (オイ
ランチャーとなるEXEファイルを作って、それ経由でGUIアプリを起動させています
例えばそれぞれのフォルダ内の*.exeファイル

luajitImGui-1.91.8.3/examples/glfw_opengl3/glfw_opengl3.exe

がランチャーファイルになります
この場合glfw_opengl3.exeは自分と同じフォルダにある
glfw_opengl3.lua../../bin/luajitw.exe の引数にして実行します
例えば、
"glfw_opengl3.exemain.exeにリネームした場合、同じフォルダ内のmain.luaを実行します"
という動作をするランチャー です
ソースコードはこれ execLuaSource.c
ランチャーはEXEファイルなのでwindres.exeで任意のアイコンをくっつけることができます

未使用ファイルを削ってプロジェクトサイズを小さくする


./binフォルダ以下はzip解凍した状態で約30MB
アプリを作るときに未使用な*.dll, *.luaは削除可能
例えば
SDL2とaudio関連を未使用なら恐らくざっくり

 3.7M  cimgui_sdl.dll
 1.6M  SDL2.dll
 1.5M  libsamplerate-0.dll
 1.5M  samplerate.dll
 573K  sndfile.dll

合計 約9MB 減らせるのと関連する*.luaファイルも削除できる

その他の方法として

  1. コンパイラをmsvcにするともう少し小さくなるかも
  2. コンパイルオプションは-O2だけど-Osで良いなら劇的に減るかも

LuaJITのLuaモジュール・デフォルト検索フォルダ


LuaJITソースファイルLuaJIT/src/luaconf.hの上の方に以下の記述で
デフォルトの検索フォルダが決定されている
今回(普通は?)は以下の設定のままbin/luajit.exe,bin/luajitw.exeがビルドされている

...snip...
#if defined(_WIN32)
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
*/
#define LUA_LDIR	"!\\lua\\"
#define LUA_CDIR	"!\\"
#define LUA_PATH_DEFAULT \
  ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;"
#define LUA_CPATH_DEFAULT \
  ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
#else
...snip...
  • Luaモジュールとは*.luaファイルのこと

  • Cモジュールとは*.dllファイルのこと

  • !記号はluajit.exeがあるフォルダ名に置換される

  • #define LUA_LDIR "!\lua\"
    luajit.exeがあるフォルダ内のluaフォルダを表す

  • #define LUA_CDIR "!\"
    luajit.exeがあるフォルダを表す

  • #define LUA_PATH_DEFAULT
    LUA_PATHのデフォルト値を設定する
    「WinodwsOSの環境変数LUA_PATH」が未定義なら
    ここで設定された値がデフォルトのLuaモジュールパスとなる
    以下の3つが設定されている

    1. ユーザープログラムがあるフォルダ
    2. luajit.exeがあるフォルダ/lua
    3. luajit.exeがあるフォルダ/lua/init.lua

    上記i.と ii.に置かれた*.luaファイルはファイル名だけでrequireできる
    例えば luajit.exeがあるフォルダ/lua/mycode.luaというモジュールは
    ユーザーコード内で

    local mylib = require"mycode"
    

    という形で呼び出せる

    また luajit.exeがあるフォルダ/lua/pico/driver.lua という階層のモジュールは
    ユーザーコード内で

    local mypico = require"pico.driver"
    

    という形で呼び出せる
    iii.については
    もしその場所にinit.luaが存在すれば起動時にユーザープログラムの前に
    自動実行されるluaファイルとなる

  • #define LUA_CPATH_DEFAULT
    *.dllモジュール検索についての設定で

    1. ユーザープログラムがあるフォルダ
    2. luajit.exeがあるフォルダ
    3. luajit.exeがあるフォルダ/loadall.dll
      これは、もしその場所にlaodall.dllがあれば自動で読み込まれる
  • WindowsOS環境変数のLUA_PATH, LUA_CPATHを設定する場合
    上述の LUA_PATH_DEFAULT, LUA_CPATH_DEFAULTの設定は
    ;;という形で表される

    set LUA_PATH=";;..\mylib_dir;..\..\driver"
    set LUA_CPATH=";;..\bin;..\..\dlls"
    

    恐らく;;の記述位置を変えれば優先順位も変わる

  • 設定順序
    package.pathに上記の値が設定される順は

    1. 最初にLUA_PATH_DEFAULTの値が設定される
    2. WindowsOS環境変数LUA_PATHがあればその値で上書きされる
    3. ユーザープログラムで値を設定できる

ツール類のバージョン


  • Clang 20.1.0 (Current compiler)
    • Libraries: OpenMP
  • Gcc.exe (Rev1, Built by MSYS2 project) 14.2.0)
  • (Microsoft Visual Studio 2022 C/C++)
  • CMake version 3.31.6
  • Git version 2.46.0.windows.1
  • Make: GNU Make 4.4.1

メモ


最初の版は(2024/02)頃に"完"したけどブログ記載は半年後(2024/08)となった

旧版


WindowsOS 64bit 版

WindowsOS 32bit/64bit 共通版

  • LuaJITImGui: 1.91.0.2.zip (20MBくらい) (2024/10)

    • 変更点: 日本語表示ができないのを修正
  • LuaJITImGui: 1.91.0.1.zip (20MBくらい) (2024/08)

    • 変更点
      • glfw_opengl3.luaでSave window imageボタン押すと落ちるのを修正
      • LuaJITコンパイル時に-DLUAJIT_ENABLE_LUA52COMPATオプション追加
  • LuaJITImGui: 1.91.0.0.zip (20MBくらい) (2024/08)
    最初の版

類似 project


Language Project
Nim Compiler ImGuin, Nimgl_test, Nim_implot
Lua Script LuaJITImGui
Zig, C lang. Compiler Dear_Bindings_Build
Zig Compiler ImGuinZ
NeLua Compiler NeLuaImGui
Python Script DearPyGui for 32bit WindowsOS Binary

SDL Game tutorial Platfromer


ald

Language Project
Nim Compiler Nim-Platformer/ sdl3_nim
LuaJIT Script LuaJIT-Platformer
Nelua Compiler NeLua-Platformer
Zig Compiler Zig-Platformer

PythonでImGuiを使いたいときは
https://github.com/pthom/imgui_bundle
https://github.com/hoffstadt/DearPyGui かも

C++
https://github.com/pthom/hello_imgui

3D game engine with lua scripting
https://github.com/adriengivry/Overload


  1. 以下ImGuiと記すかも ↩︎

  2. SDL3は次のリリースで追加されるかも ↩︎

  3. SDL2は日本語入力に難ありです。日本語表示はok ↩︎

  4. Githubページのほうが最新版になってる可能性が高い。このページはあまり更新しない可能性あり ↩︎

  5. 日本語もスペースも含まないフォルダが良い ↩︎

  6. Microsoft Visual Studio 2022 C/C++はコンパイルできない orz ↩︎

  7. トップフォルダのMakefileに組み込んだので現在は自動適用される。(Patchコマンドが必要) ↩︎

posted by Copyright (C) audin All Rights Reserved. at 15:52| Comment(0) | Lua言語 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は90日以上新しい記事の投稿がないブログに表示されております。