From d2876aece66876f757cdf353f3ea6240109e394b Mon Sep 17 00:00:00 2001 From: dpethes Date: Thu, 4 May 2017 01:07:18 +0200 Subject: [PATCH] update imgui bindings --- model_viewer/hob_mesh.pas | 8 +- model_viewer/imgui/{imgui.pas => fpimgui.pas} | 103 ++++++++++++++---- ...mpl_sdlgl2.pas => fpimgui_impl_sdlgl2.pas} | 6 +- model_viewer/model_viewer.lpi | 4 +- model_viewer/model_viewer.pas | 9 +- 5 files changed, 97 insertions(+), 33 deletions(-) rename model_viewer/imgui/{imgui.pas => fpimgui.pas} (90%) rename model_viewer/imgui/{imgui_impl_sdlgl2.pas => fpimgui_impl_sdlgl2.pas} (96%) diff --git a/model_viewer/hob_mesh.pas b/model_viewer/hob_mesh.pas index 29cb884..2e34f97 100644 --- a/model_viewer/hob_mesh.pas +++ b/model_viewer/hob_mesh.pas @@ -4,7 +4,7 @@ unit hob_mesh; interface uses - Classes, SysUtils, gl, GLext, math, gvector, imgui, + Classes, SysUtils, gl, GLext, math, gvector, fpimgui, hob_parser, hmt_parser; type @@ -339,9 +339,9 @@ begin if opts.wireframe then glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - igBegin('Mesh'); - ImguiText(Format('triangles: %d (vertices: %d)', [triangle_count, _vertices.Size])); - igEnd; + ImGui.Begin_('Mesh'); + ImGui.Text('triangles: %d (vertices: %d)', [triangle_count, _vertices.Size]); + ImGui.End_; end; diff --git a/model_viewer/imgui/imgui.pas b/model_viewer/imgui/fpimgui.pas similarity index 90% rename from model_viewer/imgui/imgui.pas rename to model_viewer/imgui/fpimgui.pas index f696148..5b5fd59 100644 --- a/model_viewer/imgui/imgui.pas +++ b/model_viewer/imgui/fpimgui.pas @@ -1,15 +1,17 @@ { Bindings for dear imgui (AKA ImGui) - a bloat-free graphical user interface library for C++ Based on cimgui+ImGui 1.49/1.50 +Not all functions were tested. } -unit imgui; +unit fpimgui; +{$mode objfpc}{$H+} interface -{$IFDEF FPC} +uses {$PACKRECORDS C} -uses dynlibs; -{$ENDIF} +dynlibs, //for SharedSuffix +sysutils; //for Format() const ImguiLibName = 'cimgui.' + SharedSuffix; @@ -61,6 +63,8 @@ type ImGuiInputTextFlags = longint; ImGuiSelectableFlags = longint; + { Enums } + ImGuiTreeNodeFlags = ( Selected = 1 shl 0, Framed = 1 shl 1, @@ -144,8 +148,7 @@ type //ImGuiCol_COUNT - unnecessary ); - - { structs } + { Structs } ImGuiStyle = record Alpha : single; WindowPadding : ImVec2; @@ -299,7 +302,7 @@ procedure igShowMetricsWindow(opened: Pbool); cdecl; external ImguiLibName; { Window } function igBegin(Name: PChar; p_open: Pbool = nil; flags: ImGuiWindowFlags = 0): bool; cdecl; external ImguiLibName; -function igBegin2(Name: PChar; p_open: Pbool; size_on_first_use: ImVec2; bg_alpha: single; flags: ImGuiWindowFlags): bool; cdecl; external ImguiLibName; + // OBSOLETE function igBegin2(Name: PChar; p_open: Pbool; size_on_first_use: ImVec2; bg_alpha: single; flags: ImGuiWindowFlags): bool; cdecl; external ImguiLibName; procedure igEnd; cdecl; external ImguiLibName; function igBeginChild(str_id: PChar; size: ImVec2; border: bool; extra_flags: ImGuiWindowFlags): bool; cdecl; external ImguiLibName; function igBeginChildEx(id: ImGuiID; size: ImVec2; border: bool; extra_flags: ImGuiWindowFlags): bool; cdecl; external ImguiLibName; @@ -397,7 +400,7 @@ function igGetTextLineHeight: single; cdecl; external ImguiLibName; function igGetTextLineHeightWithSpacing: single; cdecl; external ImguiLibName; function igGetItemsLineHeightWithSpacing: single; cdecl; external ImguiLibName; -{Columns } +{ Columns } procedure igColumns(Count: longint; id: PChar; border: bool); cdecl; external ImguiLibName; procedure igNextColumn; cdecl; external ImguiLibName; function igGetColumnIndex: longint; cdecl; external ImguiLibName; @@ -431,7 +434,7 @@ procedure igTextDisabled(fmt: PChar); cdecl; external ImguiLibName; procedure igTextWrapped(fmt: PChar; args: array of const); cdecl; external ImguiLibName; procedure igTextWrapped(fmt: PChar); cdecl; external ImguiLibName; //procedure igTextWrappedV(fmt:Pchar; args:va_list);cdecl;external ImguiLibName; -procedure igTextUnformatted(Text: PChar; text_end: PChar); cdecl; external ImguiLibName; +procedure igTextUnformatted(text: PChar; text_end: PChar); cdecl; external ImguiLibName; procedure igLabelText(_label: PChar; fmt: PChar; args: array of const); cdecl; external ImguiLibName; procedure igLabelText(_label: PChar; fmt: PChar); cdecl; external ImguiLibName; //procedure igLabelTextV(_label:Pchar; fmt:Pchar; args:va_list);cdecl;external ImguiLibName; @@ -775,8 +778,47 @@ procedure ImDrawList_UpdateTextureID(list: PImDrawList); cdecl; external ImguiLi //binding helpers function ImVec2Init(const x, y: single): Imvec2; inline; -procedure ImguiText(const s: string); inline; -function ImguiSelectable(const s: string; const selected: boolean): boolean; inline; +{ Static ImGui class, wraps external igSomething calls + Used for: + - having original's C++ styled API + - adding default parameters + - using native strings + Things to consider: + - perhaps the methods could be inlined to prevent calling overhead + - use var parameters instead of pointers where possible +} +type + ImGui = class + public + class function GetIO(): PImGuiIO; + class function GetStyle(): PImGuiStyle; + class function GetDrawData(): PImDrawData; + class procedure NewFrame; + class procedure Render; + class procedure Shutdown; + class procedure ShowUserGuide; + class procedure ShowStyleEditor(ref: PImGuiStyle); + class procedure ShowTestWindow(p_open: Pbool = nil); + class procedure ShowMetricsWindow(p_open: Pbool = nil); + + { Window } + class function Begin_(name: string; p_open: Pbool = nil; flags: ImGuiWindowFlags = 0): Boolean; + class procedure End_; + + { Widgets } + { Text() just wraps TextUnformatted, while it originally takes C-style string with formatting params. + The overloaded version with variable params uses native Format() from sysutils } + class procedure Text(const text_: string); + class procedure Text(const Fmt: string; const Args: array of Const); + class procedure TextUnformatted(const _text: string); + class procedure TextUnformatted(const _text: PChar; const text_end: PChar = nil); + class function Button(_label: string; size: ImVec2): bool; + class function Button(_label: string): bool; //overload for default size (0,0) + + { Widgets: Selectable / Lists } + class function Selectable(_label: string; selected: bool; flags: ImGuiSelectableFlags; size: ImVec2): bool; + class function Selectable(_label: string; selected: bool; flags: ImGuiSelectableFlags = 0): bool; //overload for default size (0,0) + end; implementation @@ -786,14 +828,37 @@ begin result.y := y; end; -procedure ImguiText(const s: string); -begin - igText(pchar(s)); -end; +{ ImGui + keep functions short, they're mostly just wrappers. Inlining begin ... end is ok +} + +class function ImGui.GetIO: PImGuiIO; begin result := igGetIO end; +class function ImGui.GetStyle: PImGuiStyle; begin result := igGetStyle end; +class function ImGui.GetDrawData: PImDrawData; begin result := igGetDrawData end; +class procedure ImGui.NewFrame; begin igNewFrame end; +class procedure ImGui.Render; begin igRender end; +class procedure ImGui.Shutdown; begin igShutdown end; +class procedure ImGui.ShowUserGuide; begin igShowUserGuide end; +class procedure ImGui.ShowStyleEditor(ref: PImGuiStyle); begin igShowStyleEditor(ref) end; +class procedure ImGui.ShowTestWindow(p_open: Pbool); begin igShowTestWindow(p_open) end; +class procedure ImGui.ShowMetricsWindow(p_open: Pbool); begin ShowMetricsWindow(p_open) end; + +class function ImGui.Begin_(name: string; p_open: Pbool; flags: ImGuiWindowFlags): Boolean; +begin result := igBegin(pchar(name), p_open, flags); end; +class procedure ImGui.End_; begin igEnd end; + +class procedure ImGui.Text(const text_: string); begin TextUnformatted(text_) end; +class procedure ImGui.Text(const Fmt: string; const Args: array of const); begin TextUnformatted(Format(fmt, args)) end; +class procedure ImGui.TextUnformatted(const _text: string); begin igTextUnformatted(pchar(_text), nil) end; +class procedure ImGui.TextUnformatted(const _text: PChar; const text_end: PChar); begin igTextUnformatted(_text, text_end) end; + +class function ImGui.Button(_label: string; size: ImVec2): bool; begin result := igButton(pchar(_label), size) end; +class function ImGui.Button(_label: string): bool; begin result := Button(_label, ImVec2Init(0,0)) end; + +class function ImGui.Selectable(_label: string; selected: bool; flags: ImGuiSelectableFlags; size: ImVec2): bool; +begin result := igSelectable(pchar(_label), selected, flags, size) end; +class function ImGui.Selectable(_label: string; selected: bool; flags: ImGuiSelectableFlags): bool; +begin result := Selectable(_label, selected, flags, ImVec2Init(0,0)); end; -function ImguiSelectable(const s: string; const selected: boolean): boolean; -begin - result := igSelectable(pchar(s), selected, 0, ImVec2Init(0,0)); -end; end. diff --git a/model_viewer/imgui/imgui_impl_sdlgl2.pas b/model_viewer/imgui/fpimgui_impl_sdlgl2.pas similarity index 96% rename from model_viewer/imgui/imgui_impl_sdlgl2.pas rename to model_viewer/imgui/fpimgui_impl_sdlgl2.pas index c262862..853dbab 100644 --- a/model_viewer/imgui/imgui_impl_sdlgl2.pas +++ b/model_viewer/imgui/fpimgui_impl_sdlgl2.pas @@ -9,14 +9,14 @@ If you are new to ImGui, see examples/README.txt and documentation at the top of https://github.com/ocornut/imgui } -unit imgui_impl_sdlgl2; +unit fpimgui_impl_sdlgl2; {$mode objfpc}{$H+} interface uses sdl2, gl, glu, GLext, - imgui; + fpimgui; procedure ImGui_ImplSdlGL2_Init(); procedure ImGui_ImplSdlGL2_Shutdown(); @@ -139,7 +139,7 @@ begin io^.KeyMap[ImGuiKey_Y] := SDLK_y; io^.KeyMap[ImGuiKey_Z] := SDLK_z; - io^.RenderDrawListsFn := @Imgui_ImplSdlGL2_RenderDrawLists; //todo assign + io^.RenderDrawListsFn := @Imgui_ImplSdlGL2_RenderDrawLists; io^.SetClipboardTextFn := nil; io^.GetClipboardTextFn := nil; io^.ClipboardUserData := nil; diff --git a/model_viewer/model_viewer.lpi b/model_viewer/model_viewer.lpi index 250025c..a315cc1 100644 --- a/model_viewer/model_viewer.lpi +++ b/model_viewer/model_viewer.lpi @@ -60,11 +60,11 @@ - + - + diff --git a/model_viewer/model_viewer.pas b/model_viewer/model_viewer.pas index 4f7b9d9..46579b1 100644 --- a/model_viewer/model_viewer.pas +++ b/model_viewer/model_viewer.pas @@ -20,7 +20,7 @@ program model_viewer; uses sysutils, classes, math, strutils, gvector, - gl, glu, glext, sdl2, imgui, imgui_impl_sdlgl2, + gl, glu, glext, sdl2, fpimgui, fpimgui_impl_sdlgl2, rs_dat, hob_mesh; const @@ -392,7 +392,6 @@ begin hmt.Free; end; - procedure DrawGui; var style: PImGuiStyle; @@ -408,9 +407,9 @@ begin igBegin('Mesh'); if not g_model_loading_failed then begin - ImguiText(g_model_name); + Imgui.Text(g_model_name); end else - ImguiText('mesh loading failed :('); + Imgui.Text('mesh loading failed :('); igEnd; igBegin('Rendering options'); @@ -428,7 +427,7 @@ begin //todo filter for file_item in g_filelist do begin fitem_selected := file_item.name = g_model_name; - if ImguiSelectable(file_item.name, fitem_selected) then begin + if Imgui.Selectable(file_item.name, fitem_selected) then begin selected_mesh_name := file_item.name; selected_item := file_item; end;