コンテンツにスキップ

imgui制御#

imguiとは#

Direct3D、OpenGLなどグラフィックシステムで動作するように実装されたGUIフレームワークです。 詳細は、下記をご参照ください。

https://github.com/ocornut/imgui

オブジェクト#

IMGUIオブジェクトを使用します。IMGUIオブジェクトは、vrmapiに組み込まれている単一のオブジェクトです。

vrmapi.ImGui()

で指定します。関数は、このオブジェクトで呼び出します。

関数#

VRMNXに組み込まれているimguiをPythonから利用できるように最小構成の関数を提供しています。

imguiで使用できる機能の一部のみです。今後、適時追加予定です。

即時実行#

imguiは、Win32などの一般的なGUIとことなり、イベント駆動ではなく、関数を実行した瞬間の状態でデータを処理します。

具体的には、毎フレーム(frameイベント)、関数を実行、関数の結果でデータを変更します。データ入力関数の戻り値が、trueの場合は、データの変更が行われています。 ifで検出して、データを反映してください。

データ入力関数は、内部でデータを変更するため、データは、listで渡してください。listに設定するデータの型は、入力関数が要求する型にあわせてください。

タグ#

imguiのGUI部品は、ラベルで部品を識別します。ラベルだけでは、同じ名前のGUI部品を複数使用することができないため、ラベルに非表示文字列を設定します。

vrmapiは、タグ指定でこの非表示文字列を指定できます。

1
2
vrmapi.ImGui().InputInt("n1", "整数", nNum1)
vrmapi.ImGui().InputInt("n2", "整数", nNum2)

サンプルでは、タグに"n1","n2"を指定しています。同じラベル名でも、タグが異なるため、別のGUI部品になります。 ラベル名、タグが同一の場合は、imguiで部品が重複した状態になり、入力ができなくなります。

ラベル名に"#"は、使用しないでください。ラベル名の区切り記号になります。

実装上の注意#

imguiのルールから逸脱するコードは、imgui内部でクラッシュする場合があります。vrmnxシステム全体が停止するため、imgui関数の呼び出しを確認してください。

Begin() - End()の組み合わせ数がことなるなどが該当します。ある程度の防止コードをvrmnx側で用意していますが、完全ではありません。

実装サンプル#

imguiの実装サンプルです。

レイアウトのスクリプトに実装しています。initイベントで、frameイベントを登録、frameイベントでimguiを呼び出しています。 imguiは、frameイベント以外では使用できません。

Begin() - End()で、ウインドウ1枚を表示します。この区間に設定されているgui関数は、ウインドウ内部に表示されます。 指定しない場合は、特別なデバッグウィンドウが表示されます。

ヘッダー、ツリーは、ifでツリー内部に表示されるgui関数を記述します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#LAYOUT
import vrmapi

btn = 0
chk = [0]
nNum = [0]
fNum = [0.0]
radio0 = [0]

def vrmevent(obj,ev,param):
    if ev == 'init':
        obj.SetEventFrame()
    elif ev == 'broadcast':
        dummy = 1
    elif ev == 'timer':
        dummy = 1
    elif ev == 'time':
        dummy = 1
    elif ev == 'after':
        dummy = 1
    elif ev == 'frame':
        global btn
        global chk
        global nNum
        global fNum
        global radio0
        vrmapi.ImGui().Begin("win1","Sample Window")
        vrmapi.ImGui().Separator()
        vrmapi.ImGui().Text("ボタンテスト")
        vrmapi.ImGui().Text("btn =>"+str(btn))
        if vrmapi.ImGui().Button("b1", "ボタンその1"):
            btn = 1
        if btn == 1:
            vrmapi.ImGui().Text("ボタンをクリックした")
        vrmapi.ImGui().Separator()

        if vrmapi.ImGui().CollapsingHeader("head1", "Header"):
            vrmapi.ImGui().Text("チェックボックステスト")
            vrmapi.ImGui().Checkbox("chk1", "チェックA", chk)
            vrmapi.ImGui().Text("chk =>"+str(chk[0]))

        if vrmapi.ImGui().TreeNode("tree1", "Tree-A"):
            vrmapi.ImGui().PushItemWidth(160.0)
            vrmapi.ImGui().InputFloat("f1", "浮動小数点数", fNum)
            vrmapi.ImGui().InputInt("n1", "整数", nNum)
            vrmapi.ImGui().PopItemWidth()
            vrmapi.ImGui().TreePop()

        if vrmapi.ImGui().TreeNode("tree2", "Tree-B"):
            vrmapi.ImGui().RadioButton("r0", "ラジオボタンテスト0", radio0, 0)
            vrmapi.ImGui().RadioButton("r1", "ラジオボタンテスト1", radio0, 1)
            vrmapi.ImGui().RadioButton("r2", "ラジオボタンテスト2", radio0, 2)
            vrmapi.ImGui().RadioButton("r3", "ラジオボタンテスト3", radio0, 3)
            vrmapi.ImGui().RadioButton("r4", "ラジオボタンテスト4", radio0, 4)
            vrmapi.ImGui().TreePop()

        vrmapi.ImGui().End()
    elif ev == 'keydown':
        dummy = 1

実行結果