├── .gitattributes
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ ├── msbuild_vs2022_dev.yml
│ └── msbuild_vs2022_main.yml
├── .gitignore
├── Build
├── GenerateCompatibilityTest.bat
├── Sharpmake
│ ├── Basic.Reference.Assemblies.Net50.dll
│ ├── Microsoft.CodeAnalysis.CSharp.dll
│ ├── Microsoft.CodeAnalysis.dll
│ ├── Microsoft.VisualStudio.Setup.Configuration.Interop.dll
│ ├── Sharpmake.Application
│ ├── Sharpmake.Application.deps.json
│ ├── Sharpmake.Application.dll
│ ├── Sharpmake.Application.dll.config
│ ├── Sharpmake.Application.exe
│ ├── Sharpmake.Application.runtimeconfig.dev.json
│ ├── Sharpmake.Application.runtimeconfig.json
│ ├── Sharpmake.CommonPlatforms.deps.json
│ ├── Sharpmake.CommonPlatforms.dll
│ ├── Sharpmake.CommonPlatforms.xml
│ ├── Sharpmake.Generators.deps.json
│ ├── Sharpmake.Generators.dll
│ ├── Sharpmake.Generators.xml
│ ├── Sharpmake.deps.json
│ ├── Sharpmake.dll
│ └── Sharpmake.xml
├── compatibility.sharpmake.cs.1
├── compatibility.sharpmake.cs.2
├── compatibility.sharpmake.cs.3
├── netImgui.sharpmake.cs
├── nocompatibility.sharpmake.cs
├── readme.txt
├── shared.sharpmake.cs
└── shared.sharpmake_mac.cs
├── Clean.bat
├── Code
├── Client
│ ├── NetImgui_Api.h
│ ├── NetImgui_Config.h
│ └── Private
│ │ ├── NetImgui_Api.cpp
│ │ ├── NetImgui_Client.cpp
│ │ ├── NetImgui_Client.h
│ │ ├── NetImgui_Client.inl
│ │ ├── NetImgui_CmdPackets.h
│ │ ├── NetImgui_CmdPackets.inl
│ │ ├── NetImgui_CmdPackets_DrawFrame.cpp
│ │ ├── NetImgui_CmdPackets_DrawFrame.h
│ │ ├── NetImgui_Network.h
│ │ ├── NetImgui_NetworkPosix.cpp
│ │ ├── NetImgui_NetworkUE4.cpp
│ │ ├── NetImgui_NetworkWin32.cpp
│ │ ├── NetImgui_Shared.h
│ │ ├── NetImgui_Shared.inl
│ │ ├── NetImgui_WarningDisable.h
│ │ ├── NetImgui_WarningDisableImgui.h
│ │ ├── NetImgui_WarningDisableStd.h
│ │ └── NetImgui_WarningReenable.h
├── Sample
│ ├── Common
│ │ ├── Sample.cpp
│ │ ├── Sample.h
│ │ └── main.cpp
│ ├── SampleBackground
│ │ └── SampleBackground.cpp
│ ├── SampleBasic
│ │ └── SampleBasic.cpp
│ ├── SampleCompression
│ │ ├── SampleCompression.cpp
│ │ └── SampleNetworkWin32.cpp
│ ├── SampleDisabled
│ │ └── SampleDisabled.cpp
│ ├── SampleDualUI
│ │ └── SampleDualUI.cpp
│ ├── SampleFontDPI
│ │ └── SampleFontDPI.cpp
│ ├── SampleIndex
│ │ └── SampleIndex.cpp
│ ├── SampleNewFrame
│ │ └── SampleNewFrame.cpp
│ ├── SampleNoBackend
│ │ └── SampleNoBackend.cpp
│ ├── SampleSingleInclude
│ │ └── SampleSingleInclude.cpp
│ └── SampleTextures
│ │ └── SampleTextures.cpp
├── ServerApp
│ ├── Background.png
│ ├── Source
│ │ ├── Custom
│ │ │ └── NetImguiServer_App_Custom.cpp
│ │ ├── Fonts
│ │ │ └── Roboto_Medium.cpp
│ │ ├── GlfwGL3
│ │ │ ├── NetImguiServer_App_GlfwGL3.cpp
│ │ │ ├── NetImguiServer_HAL_GL3.cpp
│ │ │ └── NetImguiServer_HAL_Glfw.cpp
│ │ ├── NetImguiServer_App.cpp
│ │ ├── NetImguiServer_App.h
│ │ ├── NetImguiServer_Config.cpp
│ │ ├── NetImguiServer_Config.h
│ │ ├── NetImguiServer_Network.cpp
│ │ ├── NetImguiServer_Network.h
│ │ ├── NetImguiServer_RemoteClient.cpp
│ │ ├── NetImguiServer_RemoteClient.h
│ │ ├── NetImguiServer_UI.cpp
│ │ ├── NetImguiServer_UI.h
│ │ ├── Sokol
│ │ │ ├── NetImguiServer_App_Sokol.cpp
│ │ │ ├── NetImguiServer_HAL_SokolApp.cpp
│ │ │ ├── NetImguiServer_HAL_SokolGfx.cpp
│ │ │ └── sokol
│ │ │ │ ├── sokol_app.h
│ │ │ │ ├── sokol_gfx.h
│ │ │ │ ├── sokol_glue.h
│ │ │ │ ├── sokol_log.h
│ │ │ │ └── util
│ │ │ │ └── sokol_imgui.h
│ │ └── Win32DX11
│ │ │ ├── NetImguiServer_App_win32dx11.cpp
│ │ │ ├── NetImguiServer_HAL_dx11.cpp
│ │ │ └── NetImguiServer_HAL_win32.cpp
│ ├── info.plist
│ ├── netImguiApp.ico
│ ├── netImguiApp.rc
│ ├── resource.h
│ ├── small.ico
│ └── targetver.h
└── ThirdParty
│ ├── DearImgui
│ ├── .editorconfig
│ ├── .gitattributes
│ ├── .gitignore
│ ├── LICENSE.txt
│ ├── backends
│ │ ├── imgui_impl_dx11.cpp
│ │ ├── imgui_impl_dx11.h
│ │ ├── imgui_impl_glfw.cpp
│ │ ├── imgui_impl_glfw.h
│ │ ├── imgui_impl_opengl3.cpp
│ │ ├── imgui_impl_opengl3.h
│ │ ├── imgui_impl_opengl3_loader.h
│ │ ├── imgui_impl_win32.cpp
│ │ └── imgui_impl_win32.h
│ ├── imconfig.h
│ ├── imgui.cpp
│ ├── imgui.h
│ ├── imgui_demo.cpp
│ ├── imgui_draw.cpp
│ ├── imgui_internal.h
│ ├── imgui_tables.cpp
│ ├── imgui_widgets.cpp
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ └── imstb_truetype.h
│ ├── glfw
│ ├── COPYING.txt
│ ├── include
│ │ └── GLFW
│ │ │ ├── glfw3.h
│ │ │ └── glfw3native.h
│ ├── lib-macos-universal
│ │ ├── libglfw.3.dylib
│ │ └── libglfw3.a
│ ├── lib-vc2017-64
│ │ └── glfw3_mt.lib
│ ├── lib-vc2019-32
│ │ ├── glfw3_mt.lib
│ │ └── glfw3_mtd.lib
│ ├── lib-vc2019-64
│ │ ├── glfw3_mt.lib
│ │ └── glfw3_mtd.lib
│ ├── lib-vc2022-32
│ │ ├── glfw3_mt.lib
│ │ └── glfw3_mtd.lib
│ └── lib-vc2022-64
│ │ ├── glfw3_mt.lib
│ │ └── glfw3_mtd.lib
│ ├── nlohmann_json
│ └── json.hpp
│ ├── quicklz.cpp
│ ├── quicklz.h
│ └── stb_image.h
├── GenerateProject.bat
├── GenerateProject.sh
├── LICENSE.txt
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/msbuild_vs2022_dev.yml:
--------------------------------------------------------------------------------
1 | # Using 2 similars yml files, to get unique name displayed in build tag
2 | # (Can't seem to use variable object to retrieve branch name when setting action name)
3 | name: (Build VS2022 Dev)
4 |
5 | on:
6 | push:
7 | branches: [ "dev" ]
8 | pull_request:
9 | branches: [ "dev" ]
10 |
11 | env:
12 | # Path to the solution file relative to the root of the project.
13 | SOLUTION_FILE_PATH: ./_projects/vs2022_netImgui_All.sln
14 |
15 | # Configuration type to build.
16 | # You can convert this to a build matrix if you need coverage of multiple configuration types.
17 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
18 | BUILD_CONFIGURATION: MSBuild_Release
19 |
20 | permissions:
21 | contents: read
22 |
23 | jobs:
24 | build:
25 | runs-on: windows-latest
26 |
27 | steps:
28 | - uses: actions/checkout@v3
29 |
30 | - name: Add MSBuild to PATH
31 | uses: microsoft/setup-msbuild@v1.1
32 |
33 | - name: Setup dotnet
34 | uses: actions/setup-dotnet@v1
35 | with:
36 | dotnet-version: '5.0.408'
37 |
38 | - name: Generate Solutions
39 | working-directory: ${{env.GITHUB_WORKSPACE}}
40 | run: ./GenerateProject.bat 1
41 |
42 | - name: Restore NuGet packages
43 | working-directory: ${{env.GITHUB_WORKSPACE}}
44 | run: nuget restore ${{env.SOLUTION_FILE_PATH}}
45 |
46 | - name: Build
47 | working-directory: ${{env.GITHUB_WORKSPACE}}
48 | # Add additional options to the MSBuild command line here (like platform or verbosity level).
49 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
50 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}
51 |
--------------------------------------------------------------------------------
/.github/workflows/msbuild_vs2022_main.yml:
--------------------------------------------------------------------------------
1 | # Using 2 similars yml files, to get unique name displayed in build tag
2 | # (Can't seem to use variable object to retrieve branch name when setting action name)
3 | name: (Build VS2022 Main)
4 |
5 | on:
6 | push:
7 | branches: [ "master" ]
8 | pull_request:
9 | branches: [ "master" ]
10 |
11 | env:
12 | # Path to the solution file relative to the root of the project.
13 | SOLUTION_FILE_PATH: ./_projects/vs2022_netImgui_All.sln
14 |
15 | # Configuration type to build.
16 | # You can convert this to a build matrix if you need coverage of multiple configuration types.
17 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
18 | BUILD_CONFIGURATION: MSBuild_Release
19 |
20 | permissions:
21 | contents: read
22 |
23 | jobs:
24 | build:
25 | runs-on: windows-latest
26 |
27 | steps:
28 | - uses: actions/checkout@v3
29 |
30 | - name: Add MSBuild to PATH
31 | uses: microsoft/setup-msbuild@v1.1
32 |
33 | - name: Setup dotnet
34 | uses: actions/setup-dotnet@v1
35 | with:
36 | dotnet-version: '5.0.408' # Check for latest at link at .NET 5 download page
37 |
38 | - name: Generate Solutions
39 | working-directory: ${{env.GITHUB_WORKSPACE}}
40 | run: ./GenerateProject.bat 1
41 |
42 | - name: Restore NuGet packages
43 | working-directory: ${{env.GITHUB_WORKSPACE}}
44 | run: nuget restore ${{env.SOLUTION_FILE_PATH}}
45 |
46 | - name: Build
47 | working-directory: ${{env.GITHUB_WORKSPACE}}
48 | # Add additional options to the MSBuild command line here (like platform or verbosity level).
49 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
50 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 | _*/
25 |
26 | # Visual Studio 2015 cache/options directory
27 | .vs/
28 | # Uncomment if you have tasks that create the project's static files in wwwroot
29 | #wwwroot/
30 |
31 | # MSTest test Results
32 | [Tt]est[Rr]esult*/
33 | [Bb]uild[Ll]og.*
34 |
35 | # NUNIT
36 | *.VisualState.xml
37 | TestResult.xml
38 |
39 | # Build Results of an ATL Project
40 | [Dd]ebugPS/
41 | [Rr]eleasePS/
42 | dlldata.c
43 |
44 | # DNX
45 | project.lock.json
46 | project.fragment.lock.json
47 | artifacts/
48 |
49 | *_i.c
50 | *_p.c
51 | *_i.h
52 | *.ilk
53 | *.meta
54 | *.obj
55 | *.pch
56 | *.pdb
57 | *.pgc
58 | *.pgd
59 | *.rsp
60 | *.sbr
61 | *.tlb
62 | *.tli
63 | *.tlh
64 | *.tmp
65 | *.tmp_proj
66 | *.log
67 | *.vspscc
68 | *.vssscc
69 | .builds
70 | *.pidb
71 | *.svclog
72 | *.scc
73 |
74 | # Chutzpah Test files
75 | _Chutzpah*
76 |
77 | # Visual C++ cache files
78 | ipch/
79 | *.aps
80 | *.ncb
81 | *.opendb
82 | *.opensdf
83 | *.sdf
84 | *.cachefile
85 | *.VC.db
86 | *.VC.VC.opendb
87 |
88 | # Visual Studio profiler
89 | *.psess
90 | *.vsp
91 | *.vspx
92 | *.sap
93 |
94 | # TFS 2012 Local Workspace
95 | $tf/
96 |
97 | # Guidance Automation Toolkit
98 | *.gpState
99 |
100 | # ReSharper is a .NET coding add-in
101 | _ReSharper*/
102 | *.[Rr]e[Ss]harper
103 | *.DotSettings.user
104 |
105 | # JustCode is a .NET coding add-in
106 | .JustCode
107 |
108 | # TeamCity is a build add-in
109 | _TeamCity*
110 |
111 | # DotCover is a Code Coverage Tool
112 | *.dotCover
113 |
114 | # NCrunch
115 | _NCrunch_*
116 | .*crunch*.local.xml
117 | nCrunchTemp_*
118 |
119 | # MightyMoose
120 | *.mm.*
121 | AutoTest.Net/
122 |
123 | # Web workbench (sass)
124 | .sass-cache/
125 |
126 | # Installshield output folder
127 | [Ee]xpress/
128 |
129 | # DocProject is a documentation generator add-in
130 | DocProject/buildhelp/
131 | DocProject/Help/*.HxT
132 | DocProject/Help/*.HxC
133 | DocProject/Help/*.hhc
134 | DocProject/Help/*.hhk
135 | DocProject/Help/*.hhp
136 | DocProject/Help/Html2
137 | DocProject/Help/html
138 |
139 | # Click-Once directory
140 | publish/
141 |
142 | # Publish Web Output
143 | *.[Pp]ublish.xml
144 | *.azurePubxml
145 | # TODO: Comment the next line if you want to checkin your web deploy settings
146 | # but database connection strings (with potential passwords) will be unencrypted
147 | #*.pubxml
148 | *.publishproj
149 |
150 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
151 | # checkin your Azure Web App publish settings, but sensitive information contained
152 | # in these scripts will be unencrypted
153 | PublishScripts/
154 |
155 | # NuGet Packages
156 | *.nupkg
157 | # The packages folder can be ignored because of Package Restore
158 | **/packages/*
159 | # except build/, which is used as an MSBuild target.
160 | !**/packages/build/
161 | # Uncomment if necessary however generally it will be regenerated when needed
162 | #!**/packages/repositories.config
163 | # NuGet v3's project.json files produces more ignoreable files
164 | *.nuget.props
165 | *.nuget.targets
166 |
167 | # Microsoft Azure Build Output
168 | csx/
169 | *.build.csdef
170 |
171 | # Microsoft Azure Emulator
172 | ecf/
173 | rcf/
174 |
175 | # Windows Store app package directories and files
176 | AppPackages/
177 | BundleArtifacts/
178 | Package.StoreAssociation.xml
179 | _pkginfo.txt
180 |
181 | # Visual Studio cache files
182 | # files ending in .cache can be ignored
183 | *.[Cc]ache
184 | # but keep track of directories ending in .cache
185 | !*.[Cc]ache/
186 |
187 | # Others
188 | ClientBin/
189 | ~$*
190 | *~
191 | *.dbmdl
192 | *.dbproj.schemaview
193 | *.jfm
194 | *.pfx
195 | *.publishsettings
196 | node_modules/
197 | orleans.codegen.cs
198 |
199 | # Since there are multiple workflows, uncomment next line to ignore bower_components
200 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
201 | #bower_components/
202 |
203 | # RIA/Silverlight projects
204 | Generated_Code/
205 |
206 | # Backup & report files from converting an old project file
207 | # to a newer Visual Studio version. Backup files are not needed,
208 | # because we have git ;-)
209 | _UpgradeReport_Files/
210 | Backup*/
211 | UpgradeLog*.XML
212 | UpgradeLog*.htm
213 |
214 | # SQL Server files
215 | *.mdf
216 | *.ldf
217 |
218 | # Business Intelligence projects
219 | *.rdl.data
220 | *.bim.layout
221 | *.bim_*.settings
222 |
223 | # Microsoft Fakes
224 | FakesAssemblies/
225 |
226 | # GhostDoc plugin setting file
227 | *.GhostDoc.xml
228 |
229 | # Node.js Tools for Visual Studio
230 | .ntvs_analysis.dat
231 |
232 | # Visual Studio 6 build log
233 | *.plg
234 |
235 | # Visual Studio 6 workspace options file
236 | *.opt
237 |
238 | # Visual Studio LightSwitch build output
239 | **/*.HTMLClient/GeneratedArtifacts
240 | **/*.DesktopClient/GeneratedArtifacts
241 | **/*.DesktopClient/ModelManifest.xml
242 | **/*.Server/GeneratedArtifacts
243 | **/*.Server/ModelManifest.xml
244 | _Pvt_Extensions
245 |
246 | # Paket dependency manager
247 | .paket/paket.exe
248 | paket-files/
249 |
250 | # FAKE - F# Make
251 | .fake/
252 |
253 | # JetBrains Rider
254 | .idea/
255 | *.sln.iml
256 |
257 | # CodeRush
258 | .cr/
259 |
260 | # Python Tools for Visual Studio (PTVS)
261 | __pycache__/
262 | *.pyc
263 | Web/raw/InputWithNetImgui.xcf
264 | Web/raw/HowItWorks.svg
265 | Web/raw/AppWithoutNetImgui.xcf
266 | Web/raw/AppWithNetImgui.xcf
267 |
--------------------------------------------------------------------------------
/Build/GenerateCompatibilityTest.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | setlocal enabledelayedexpansion
3 | cls
4 | pushd %~dp0
5 |
6 | ::-----------------------------------------------------------------------------------
7 | :: SETTINGS
8 | ::-----------------------------------------------------------------------------------
9 | :: List of offical Dear ImGui (from official depot)
10 | set VERSIONS=(v1.71 v1.72 v1.73 v1.74 v1.75 v1.76 v1.77 v1.78 v1.79, v1.80, v1.81, v1.82, v1.83, v1.84, v1.85, v1.86, v1.87, v1.88, v1.89.1, v1.89.2, v1.89.3, v1.89.4, v1.89.5, v1.89.6, v1.89.7, v1.89.7-docking, v1.89.8, v1.89.8-docking, v1.89.9, v1.89.9-docking, v1.90, v1.90-docking, v1.90.1, v1.90.2, v1.90.3, v1.90.4, v1.90.5, v1.90.6, v1.90.6-docking, v1.90.7, v1.90.8, v1.90.9, v1.91.0, v1.91.0-docking, v1.91.1, v1.91.2, v1.91.3, v1.91.4, v1.91.5, v1.91.5-docking)
11 |
12 | :: List of custom Dear ImGui releases (from own depot)
13 | set EXTRA_VERSIONS=(dock-1-76, dock-1-80, dock-1-89)
14 |
15 | :: Output directory
16 | set IMGUI_DIR=%~dp0..\_generated\imgui
17 |
18 | :: Destination of Compatibility project config file
19 | set COMPAT_FILE=%IMGUI_DIR%\compatibility.sharpmake.cs
20 |
21 | :: goto SkipDownload
22 |
23 | :GetAllImgui
24 | echo ================================================================================
25 | echo Download multiple versions of Dear Imgui.
26 | echo Unpack them and generates netImgui projects for each.
27 | echo Used to test compatibility against multiple version of Dear ImGui
28 | echo ================================================================================
29 | echo.
30 |
31 | :: Only download new release
32 |
33 | :: if not exist %IMGUI_DIR% goto SkipDelete
34 | :: echo.
35 | :: echo --------------------------------------------------------------------------------
36 | :: echo Clearing Releases
37 | :: echo --------------------------------------------------------------------------------
38 | :: echo Removing: %IMGUI_DIR%
39 | :: rmdir /s /q %IMGUI_DIR%
40 |
41 |
42 | :SkipDelete
43 | if not exist %IMGUI_DIR% (
44 | mkdir %IMGUI_DIR%
45 | )
46 |
47 | echo.
48 | echo --------------------------------------------------------------------------------
49 | echo Downloading and extracting Dear ImGui Releases
50 | echo --------------------------------------------------------------------------------
51 | pushd %IMGUI_DIR%
52 |
53 | for %%v in %VERSIONS% do (
54 | echo Extracting: %%v
55 | set IMGUI_FILE=%%v.tar.gz
56 | set IMGUI_FILEPATH="https://github.com/ocornut/imgui/archive/!IMGUI_FILE!"
57 | if not exist !IMGUI_FILE! curl -LJ !IMGUI_FILEPATH! --output !IMGUI_FILE!
58 | tar -xzf !IMGUI_FILE!
59 | )
60 |
61 | for %%v in %EXTRA_VERSIONS% do (
62 | echo Extracting: %%v
63 | set IMGUI_FILE=%%v.zip
64 | set IMGUI_FILEPATH="https://raw.githubusercontent.com/wiki/sammyfreg/netImgui/ImguiVersions/!IMGUI_FILE!"
65 | if not exist !IMGUI_FILE! curl -LJ !IMGUI_FILEPATH! --output !IMGUI_FILE!
66 | tar -xzf !IMGUI_FILE!
67 | )
68 | popd
69 |
70 | :SkipDownload
71 | echo.
72 | echo --------------------------------------------------------------------------------
73 | echo Generating Sharpmake config for compatibility projects
74 | echo --------------------------------------------------------------------------------
75 | type compatibility.sharpmake.cs.1 > %COMPAT_FILE%
76 | :: Declare each compatibility project (1 per Imgui version)
77 | for /D %%d IN (%IMGUI_DIR%\*) DO (
78 | call :GenerateProjectName %%d
79 | echo [Sharpmake.Generate] public class !NetImguiName! : ProjectNoBackend { public !NetImguiName!^(^): base^("!NetImguiName!", @"%%d"^){} } >> %COMPAT_FILE%
80 | )
81 |
82 | type compatibility.sharpmake.cs.2 >> %COMPAT_FILE%
83 | :: Create function adding each project
84 | for /D %%d IN (%IMGUI_DIR%\*) DO (
85 | call :GenerateProjectName %%d
86 | echo conf.AddProject^^(target, false, SolutionFolder^); >> %COMPAT_FILE%
87 | echo !NetImguiName! added
88 | )
89 | type compatibility.sharpmake.cs.3 >> %COMPAT_FILE%
90 |
91 | echo.
92 | echo --------------------------------------------------------------------------------
93 | echo Dear ImGui Older versions fetched
94 | echo Please regenerate the projects to have them included in compiling tests
95 | echo --------------------------------------------------------------------------------
96 | pause
97 |
98 | popd
99 | exit /b %errorlevel%
100 |
101 | :: Take a Imgui install path, and make it into a NetImgui project name
102 | :: By keeping only the last directory name and removing '-' and '.'
103 | :GenerateProjectName
104 | set NetImguiName=%~nx1
105 | set NetImguiName=%NetImguiName:-=_%
106 | set NetImguiName=%NetImguiName:.=_%
107 | set NetImguiName=ProjectCompatibility_%NetImguiName%
108 | exit /b 0
109 |
110 |
111 |
--------------------------------------------------------------------------------
/Build/Sharpmake/Basic.Reference.Assemblies.Net50.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Build/Sharpmake/Basic.Reference.Assemblies.Net50.dll
--------------------------------------------------------------------------------
/Build/Sharpmake/Microsoft.CodeAnalysis.CSharp.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Build/Sharpmake/Microsoft.CodeAnalysis.CSharp.dll
--------------------------------------------------------------------------------
/Build/Sharpmake/Microsoft.CodeAnalysis.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Build/Sharpmake/Microsoft.CodeAnalysis.dll
--------------------------------------------------------------------------------
/Build/Sharpmake/Microsoft.VisualStudio.Setup.Configuration.Interop.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Build/Sharpmake/Microsoft.VisualStudio.Setup.Configuration.Interop.dll
--------------------------------------------------------------------------------
/Build/Sharpmake/Sharpmake.Application:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Build/Sharpmake/Sharpmake.Application
--------------------------------------------------------------------------------
/Build/Sharpmake/Sharpmake.Application.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Build/Sharpmake/Sharpmake.Application.dll
--------------------------------------------------------------------------------
/Build/Sharpmake/Sharpmake.Application.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Build/Sharpmake/Sharpmake.Application.exe
--------------------------------------------------------------------------------
/Build/Sharpmake/Sharpmake.Application.runtimeconfig.dev.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeOptions": {
3 | "additionalProbingPaths": [
4 | "C:\\Users\\runneradmin\\.dotnet\\store\\|arch|\\|tfm|",
5 | "C:\\Users\\runneradmin\\.nuget\\packages",
6 | "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages",
7 | "C:\\Program Files (x86)\\Microsoft\\Xamarin\\NuGet",
8 | "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
9 | ]
10 | }
11 | }
--------------------------------------------------------------------------------
/Build/Sharpmake/Sharpmake.Application.runtimeconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeOptions": {
3 | "tfm": "net5.0",
4 | "framework": {
5 | "name": "Microsoft.NETCore.App",
6 | "version": "5.0.0"
7 | },
8 | "configProperties": {
9 | "System.Globalization.Invariant": true
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/Build/Sharpmake/Sharpmake.CommonPlatforms.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Build/Sharpmake/Sharpmake.CommonPlatforms.dll
--------------------------------------------------------------------------------
/Build/Sharpmake/Sharpmake.CommonPlatforms.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Sharpmake.CommonPlatforms
5 |
6 |
7 |
8 |
9 | Android SDK path
10 |
11 |
12 |
13 |
14 | Android NDK path
15 |
16 |
17 |
18 |
19 | Java SE Development Kit path
20 |
21 |
22 |
23 |
24 | Apache Ant path
25 |
26 |
27 |
28 |
29 | Allows setting a custom provider for system paths
30 |
31 |
32 |
33 |
34 | Generates position-independent code, suitable for shared libraries.
35 |
36 |
37 | The corresponding clang flags is -fPIC.
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Build/Sharpmake/Sharpmake.Generators.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Build/Sharpmake/Sharpmake.Generators.dll
--------------------------------------------------------------------------------
/Build/Sharpmake/Sharpmake.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Build/Sharpmake/Sharpmake.dll
--------------------------------------------------------------------------------
/Build/compatibility.sharpmake.cs.1:
--------------------------------------------------------------------------------
1 | // Note:
2 | // The files 'Build\compatibility.sharpmake.cs.1 [2,3]'
3 | // are used by 'Build\GenerateCompatibilityTest.bat'
4 | // while generating '_generated\imgui\compatibility.sharpmake.cs'
5 |
6 | namespace NetImgui
7 | {
8 |
--------------------------------------------------------------------------------
/Build/compatibility.sharpmake.cs.2:
--------------------------------------------------------------------------------
1 |
2 | public class Utility
3 | {
4 | public static void AddCompatibilityProjects(Sharpmake.Solution.Configuration conf, NetImguiTarget target)
5 | {
6 | string SolutionFolder = "CompatibilityTest";
7 |
--------------------------------------------------------------------------------
/Build/compatibility.sharpmake.cs.3:
--------------------------------------------------------------------------------
1 | }
2 | }
3 | }
4 |
--------------------------------------------------------------------------------
/Build/nocompatibility.sharpmake.cs:
--------------------------------------------------------------------------------
1 | namespace NetImgui
2 | {
3 | public class Utility
4 | {
5 | public static void AddCompatibilityProjects(Sharpmake.Solution.Configuration conf, NetImguiTarget target)
6 | {
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Build/readme.txt:
--------------------------------------------------------------------------------
1 | This folder contains files needed to generate the various NetImgui projects.
2 |
3 | User can safely ignore its content; only "GenerateProject.bat" needs calling, or "GenerateProject.sh" on macOS.
4 |
5 | Optionally, "GenerateCompatibilityTest.bat" can be called to get older versions of Dear ImGui and test compatibility of NetImgui against all of them.
6 |
--------------------------------------------------------------------------------
/Clean.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | FOR /d %%d IN ("_*") DO @IF EXIST "%%d" rd /s /q "%%d"
3 |
--------------------------------------------------------------------------------
/Code/Client/NetImgui_Config.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | //=================================================================================================
4 | // Enable code compilation for this library
5 | // Note: Useful to disable 'netImgui' on unsupported builds while keeping functions declared
6 | //=================================================================================================
7 | #ifndef NETIMGUI_ENABLED
8 | #define NETIMGUI_ENABLED 1
9 | #endif
10 |
11 | #if NETIMGUI_ENABLED
12 |
13 | #include
14 |
15 | #ifdef NETIMGUI_INTERNAL_INCLUDE
16 | #include "Private/NetImgui_WarningDisableImgui.h" // Disable some extra warning generated by imgui_internal in '-Wall'
17 | #include // Only needed when compiling NetImgui, not when using the NetImgui Api
18 | #include "Private/NetImgui_WarningReenable.h"
19 | #endif
20 |
21 | #endif // NETIMGUI_ENABLED
22 |
23 | //=================================================================================================
24 | // Default Ports used to reach the Server or the Client (listen port for incoming connection)
25 | //=================================================================================================
26 | namespace NetImgui
27 | {
28 | enum Constants{
29 | kDefaultServerPort = 8888, //!< Default port Server waits for a connection
30 | kDefaultClientPort = 8889 //!< Default port Client waits for a connection
31 | };
32 | }
33 |
34 | //=================================================================================================
35 | // Enable default Win32/Posix networking code
36 | // Note: By default, netImgui uses Winsock on Windows and Posix sockets on other platforms
37 | //
38 | // The use your own code, turn off both NETIMGUI_WINSOCKET_ENABLED,
39 | // NETIMGUI_POSIX_SOCKETS_ENABLED and provide your own implementation of the functions
40 | // declared in 'NetImgui_Network.h'.
41 | //
42 | // As an example, 'SampleCompression' disable default com implementation and use its own
43 | //=================================================================================================
44 | #if !defined(NETIMGUI_WINSOCKET_ENABLED) && !defined(__UNREAL__)
45 | #ifdef _WIN32
46 | #define NETIMGUI_WINSOCKET_ENABLED 1 // Project needs 'ws2_32.lib' added to input libraries
47 | #else
48 | #define NETIMGUI_WINSOCKET_ENABLED 0
49 | #endif
50 | #endif
51 |
52 | #if !defined(NETIMGUI_POSIX_SOCKETS_ENABLED) && !defined(__UNREAL__)
53 | #define NETIMGUI_POSIX_SOCKETS_ENABLED !(NETIMGUI_WINSOCKET_ENABLED)
54 | #endif
55 |
56 | //=================================================================================================
57 | // Various build settings define
58 | // Note: for more information, please look in 'NetImgui_Api.h' for description and default values
59 | //=================================================================================================
60 | //#define NETIMGUI_IMGUI_CALLBACK_ENABLED (IMGUI_VERSION_NUM >= 18100) // Not supported pre Dear ImGui 1.81
61 | //#define NETIMGUI_FORCE_TCP_LISTEN_BINDING 0 // Doesn't seem to be needed on Window/Linux
62 | //#define NETIMGUI_API IMGUI_API // Use same value as defined by Dear ImGui by default
63 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_Client.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "NetImgui_Shared.h"
4 | #include "NetImgui_CmdPackets.h"
5 |
6 | //=============================================================================
7 | // Forward Declares
8 | //=============================================================================
9 | namespace NetImgui { namespace Internal { namespace Network { struct SocketInfo; } } }
10 |
11 | namespace NetImgui { namespace Internal { namespace Client
12 | {
13 |
14 | //=============================================================================
15 | // Keep a list of textures used by Imgui, needed by server
16 | //=============================================================================
17 | struct ClientTexture
18 | {
19 | inline void Set( CmdTexture* pCmdTexture );
20 | inline bool IsValid()const;
21 | CmdTexture* mpCmdTexture= nullptr;
22 | bool mbSent = false;
23 | uint8_t mPadding[7] = {};
24 | };
25 |
26 | //=============================================================================
27 | // Keeps a list of ImGui context values NetImgui overrides (to restore)
28 | //=============================================================================
29 | struct SavedImguiContext
30 | {
31 | void Save(ImGuiContext* copyFrom);
32 | void Restore(ImGuiContext* copyTo);
33 | const char* mBackendPlatformName = nullptr;
34 | const char* mBackendRendererName = nullptr;
35 | void* mImeWindowHandle = nullptr;
36 | float mFontGlobalScale = 1.f;
37 | float mFontGeneratedSize = 0.f;
38 | ImGuiBackendFlags mBackendFlags = 0;
39 | ImGuiConfigFlags mConfigFlags = 0;
40 | bool mDrawMouse = false;
41 | bool mSavedContext = false;
42 | char mPadding1[2] = {};
43 | void* mClipboardUserData = nullptr;
44 | #if IMGUI_VERSION_NUM < 19110
45 | const char* (*mGetClipboardTextFn)(void*) = nullptr;
46 | void (*mSetClipboardTextFn)(void*, const char*) = nullptr;
47 | #else
48 | const char* (*mGetClipboardTextFn)(ImGuiContext*) = nullptr;
49 | void (*mSetClipboardTextFn)(ImGuiContext*, const char*) = nullptr;
50 | #endif
51 | #if IMGUI_VERSION_NUM < 18700
52 | int mKeyMap[ImGuiKey_COUNT] = {};
53 | char mPadding2[8 - (sizeof(mKeyMap) % 8)] = {};
54 | #endif
55 | };
56 |
57 | //=============================================================================
58 | // Keep all Client infos needed for communication with server
59 | //=============================================================================
60 | struct ClientInfo
61 | {
62 | using VecTexture = ImVector;
63 | using BufferKeys = Ringbuffer;
64 | using TimePoint = std::chrono::time_point;
65 |
66 | struct InputState
67 | {
68 | uint64_t mInputDownMask[(CmdInput::ImGuiKey_COUNT+63)/64] = {};
69 | float mInputAnalog[CmdInput::kAnalog_Count] = {};
70 | uint64_t mMouseDownMask = 0;
71 | float mMouseWheelVertPrev = 0.f;
72 | float mMouseWheelHorizPrev = 0.f;
73 | };
74 | ClientInfo();
75 | ~ClientInfo();
76 | void ContextInitialize();
77 | void ContextOverride();
78 | void ContextRestore();
79 | void ContextRemoveHooks();
80 | inline bool IsContextOverriden()const;
81 |
82 | std::atomic mpSocketPending; // Hold socket info until communication is established
83 | std::atomic mpSocketComs; // Socket used for communications with server
84 | std::atomic mpSocketListen; // Socket used to wait for communication request from server
85 | std::atomic_bool mbDisconnectPending; // Terminate Client/Server coms
86 | std::atomic_bool mbDisconnectListen; // Terminate waiting connection from Server
87 | uint32_t mSocketListenPort = 0; // Socket Port number used to wait for communication request from server
88 | VecTexture mTextures; // List if textures created by this client (used un main thread)
89 | char mName[64] = {};
90 | uint64_t mFrameIndex = 0; // Incremented everytime we send a DrawFrame Command
91 | CmdTexture* mTexturesPending[16] = {};
92 | ExchangePtr mPendingFrameOut;
93 | ExchangePtr mPendingBackgroundOut;
94 | ExchangePtr mPendingInputIn;
95 | ExchangePtr mPendingClipboardIn; // Clipboard content received from Server and waiting to be taken by client
96 | ExchangePtr mPendingClipboardOut; // Clipboard content copied on Client and waiting to be sent to Server
97 | ImGuiContext* mpContext = nullptr; // Context that the remote drawing should use (either the one active when connection request happened, or a clone)
98 | PendingCom mPendingRcv; // Data being currently received from Server
99 | PendingCom mPendingSend; // Data being currently sent to Server
100 | uint32_t mPendingSendNext = 0; // Type of Cmd to next attempt sending, when channel is available
101 | CmdPendingRead mCmdPendingRead; // Used to get info on the next incoming command from Server
102 | CmdInput* mpCmdInputPending = nullptr; // Last Input Command from server, waiting to be processed by client
103 | CmdClipboard* mpCmdClipboard = nullptr; // Last received clipboad command
104 | CmdDrawFrame* mpCmdDrawLast = nullptr; // Last sent Draw Command. Used by data compression, to generate delta between previous and current frame
105 | CmdBackground mBGSetting; // Current value assigned to background appearance by user
106 | CmdBackground mBGSettingSent; // Last sent value to remote server
107 | BufferKeys mPendingKeyIn; // Keys pressed received. Results of 2 CmdInputs are concatenated if received before being processed
108 | TimePoint mLastOutgoingDrawCheckTime; // When we last checked if we have a pending draw command to send
109 | TimePoint mLastOutgoingDrawTime; // When we last sent an updated draw command to the server
110 | ImVec2 mSavedDisplaySize = {0, 0}; // Save original display size on 'NewFrame' and restore it on 'EndFrame' (making sure size is still valid after a disconnect)
111 | const void* mpFontTextureData = nullptr; // Last font texture data send to server (used to detect if font was changed)
112 | ImTextureID mFontTextureID;
113 | SavedImguiContext mSavedContextValues;
114 | std::atomic_uint32_t mTexturesPendingSent;
115 | std::atomic_uint32_t mTexturesPendingCreated;
116 |
117 | std::atomic_bool mbClientThreadActive; // True when connected and communicating with Server
118 | std::atomic_bool mbListenThreadActive; // True when listening from connection request from Server
119 | std::atomic_bool mbComInitActive; // True when attempting to initialize a new connection
120 | bool mbHasTextureUpdate = false;
121 | bool mbIsDrawing = false; // We are inside a 'NetImgui::NewFrame' / 'NetImgui::EndFrame' (even if not for a remote draw)
122 | bool mbIsRemoteDrawing = false; // True if the rendering it meant for the remote netImgui server
123 | bool mbRestorePending = false; // Original context has had some settings overridden, original values stored in mRestoreXXX
124 | bool mbFontUploaded = false; // Auto detect if font was sent to server
125 | bool mbInsideHook = false; // Currently inside ImGui hook callback
126 | bool mbInsideNewEnd = false; // Currently inside NetImgui::NewFrame() or NetImgui::EndFrame() (prevents recusrive hook call)
127 | bool mbValidDrawFrame = false; // If we should forward the drawdata to the server at the end of ImGui::Render()
128 | uint8_t mClientCompressionMode = eCompressionMode::kUseServerSetting;
129 | bool mServerCompressionEnabled = false; // If Server would like compression to be enabled (mClientCompressionMode value can override this value)
130 | bool mServerCompressionSkip = false; // Force ignore compression setting for 1 frame
131 | bool mServerForceConnectEnabled = true; // If another NetImguiServer can take connection away from the one currently active
132 | ThreadFunctPtr mThreadFunction = nullptr; // Function to use when laucnhing new threads
133 | FontCreateFuncPtr mFontCreationFunction = nullptr; // Method to call to generate the remote ImGui font. By default, re-use the local font, but this doesn't handle native DPI scaling on remote server
134 | float mFontCreationScaling = 1.f; // Last font scaling used when generating the NetImgui font
135 | float mDesiredFps = 30.f; // How often we should update the remote drawing. Received from server
136 | InputState mPreviousInputState; // Keeping track of last keyboard/mouse state
137 | ImGuiID mhImguiHookNewframe = 0;
138 | ImGuiID mhImguiHookEndframe = 0;
139 |
140 | void ProcessDrawData(const ImDrawData* pDearImguiData, ImGuiMouseCursor mouseCursor);
141 | void ProcessTexturePending();
142 | inline bool IsConnected()const;
143 | inline bool IsConnectPending()const;
144 | inline bool IsActive()const;
145 |
146 | // Prevent warnings about implicitly created copy
147 | protected:
148 | ClientInfo(const ClientInfo&)=delete;
149 | ClientInfo(const ClientInfo&&)=delete;
150 | void operator=(const ClientInfo&)=delete;
151 | };
152 |
153 | //=============================================================================
154 | // Main communication loop threads that are run in separate threads
155 | //=============================================================================
156 | void CommunicationsConnect(void* pClientVoid);
157 | void CommunicationsHost(void* pClientVoid);
158 |
159 | }}} //namespace NetImgui::Internal::Client
160 |
161 | #include "NetImgui_Client.inl"
162 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_Client.inl:
--------------------------------------------------------------------------------
1 |
2 | #include "NetImgui_Network.h"
3 |
4 | namespace NetImgui { namespace Internal { namespace Client {
5 |
6 | void ClientTexture::Set( CmdTexture* pCmdTexture )
7 | {
8 | netImguiDeleteSafe(mpCmdTexture);
9 | mpCmdTexture = pCmdTexture;
10 | mbSent = pCmdTexture == nullptr;
11 | }
12 |
13 | bool ClientTexture::IsValid()const
14 | {
15 | return mpCmdTexture != nullptr;
16 | }
17 |
18 | bool ClientInfo::IsConnected()const
19 | {
20 | return mpSocketComs.load() != nullptr;
21 | }
22 |
23 | bool ClientInfo::IsConnectPending()const
24 | {
25 | return mbComInitActive || mpSocketPending.load() != nullptr || mpSocketListen.load() != nullptr;
26 | }
27 |
28 | bool ClientInfo::IsActive()const
29 | {
30 | return mbClientThreadActive || mbListenThreadActive;
31 | }
32 |
33 | bool ClientInfo::IsContextOverriden()const
34 | {
35 | return mSavedContextValues.mSavedContext;
36 | }
37 |
38 | }}} // namespace NetImgui::Internal::Client
39 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_CmdPackets.inl:
--------------------------------------------------------------------------------
1 | #include "NetImgui_CmdPackets.h"
2 |
3 | namespace NetImgui { namespace Internal
4 | {
5 |
6 | void CmdDrawFrame::ToPointers()
7 | {
8 | if( !mpDrawGroups.IsPointer() )
9 | {
10 | mpDrawGroups.ToPointer();
11 | for (uint32_t i(0); i < mDrawGroupCount; ++i) {
12 | mpDrawGroups[i].ToPointers();
13 | }
14 | }
15 | }
16 |
17 | void CmdDrawFrame::ToOffsets()
18 | {
19 | if( !mpDrawGroups.IsOffset() )
20 | {
21 | for (uint32_t i(0); i < mDrawGroupCount; ++i) {
22 | mpDrawGroups[i].ToOffsets();
23 | }
24 | mpDrawGroups.ToOffset();
25 | }
26 | }
27 |
28 | void ImguiDrawGroup::ToPointers()
29 | {
30 | if( !mpIndices.IsPointer() ) //Safer to test the first element after CmdHeader
31 | {
32 | mpIndices.ToPointer();
33 | mpVertices.ToPointer();
34 | mpDraws.ToPointer();
35 | }
36 | }
37 |
38 | void ImguiDrawGroup::ToOffsets()
39 | {
40 | if( !mpIndices.IsOffset() ) //Safer to test the first element after CmdHeader
41 | {
42 | mpIndices.ToOffset();
43 | mpVertices.ToOffset();
44 | mpDraws.ToOffset();
45 | }
46 | }
47 |
48 | bool CmdInput::IsKeyDown( CmdInput::NetImguiKeys netimguiKey) const
49 | {
50 | uint32_t valIndex = netimguiKey/64;
51 | uint64_t valMask = 0x0000000000000001ull << (netimguiKey%64);
52 | return mInputDownMask[valIndex] & valMask;
53 | }
54 |
55 | bool CmdBackground::operator==(const CmdBackground& cmp)const
56 | {
57 | bool sameValue(true);
58 | for(size_t i(0); i(this)[i] == reinterpret_cast(&cmp)[i];
60 | }
61 | return sameValue;
62 | }
63 |
64 | bool CmdBackground::operator!=(const CmdBackground& cmp)const
65 | {
66 | return (*this == cmp) == false;
67 | }
68 |
69 |
70 | void CmdClipboard::ToPointers()
71 | {
72 | if( !mContentUTF8.IsPointer() ){
73 | mContentUTF8.ToPointer();
74 | }
75 | }
76 |
77 | void CmdClipboard::ToOffsets()
78 | {
79 | if( !mContentUTF8.IsOffset() ){
80 | mContentUTF8.ToOffset();
81 | }
82 | }
83 |
84 | CmdClipboard* CmdClipboard::Create(const char* clipboard)
85 | {
86 | if( clipboard )
87 | {
88 | size_t clipboardByteSize(0);
89 | while(clipboard[clipboardByteSize++] != 0);
90 | size_t totalDataCount = sizeof(CmdClipboard) + DivUp(clipboardByteSize, ComDataSize);
91 | auto pNewClipboard = NetImgui::Internal::netImguiSizedNew(totalDataCount*ComDataSize);
92 | pNewClipboard->mSize = static_cast(totalDataCount*ComDataSize);
93 | pNewClipboard->mByteSize = clipboardByteSize;
94 | pNewClipboard->mContentUTF8.SetPtr(reinterpret_cast(&pNewClipboard[1]));
95 | memcpy(pNewClipboard->mContentUTF8.Get(), clipboard, clipboardByteSize);
96 | return pNewClipboard;
97 | }
98 | return nullptr;
99 | }
100 |
101 | }} // namespace NetImgui::Internal
102 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_CmdPackets_DrawFrame.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "NetImgui_Shared.h"
4 |
5 | namespace NetImgui { namespace Internal
6 | {
7 |
8 | struct ImguiVert
9 | {
10 | //Note: If updating this, increase 'CmdVersion::eVersion'
11 | enum Constants{ kUvRange_Min=0, kUvRange_Max=1, kPosRange_Min=-8192, kPosRange_Max=8192};
12 | uint16_t mPos[2];
13 | uint16_t mUV[2];
14 | uint32_t mColor;
15 | };
16 |
17 | struct ImguiDraw
18 | {
19 | uint64_t mTextureId;
20 | uint32_t mIdxCount; // Drawcall number of indices (3 indices per triangles)
21 | uint32_t mVtxOffset; // Drawcall start position in vertices buffer (considered index 0)
22 | uint32_t mIdxOffset; // Drawcall start position in indices buffer
23 | float mClipRect[4];
24 | uint8_t PADDING[4]={};
25 | };
26 |
27 | // Each DearImgui window has its own vertex/index buffers with multiple drawcalls
28 | struct alignas(8) ImguiDrawGroup
29 | {
30 | static constexpr uint32_t kInvalidDrawGroup = 0xFFFFFFFF;
31 | uint64_t mGroupID = 0; // Unique ID to recognize DrawGroup between 2 frames
32 | uint32_t mVerticeCount = 0;
33 | uint32_t mIndiceCount = 0;
34 | uint32_t mDrawCount = 0;
35 | uint32_t mDrawGroupIdxPrev = kInvalidDrawGroup;// Group index in previous DrawFrame (kInvalidDrawGroup when not using delta compression)
36 | uint8_t mBytePerIndex = 2; // 2, 4 bytes
37 | uint8_t PADDING[7] = {};
38 | float mReferenceCoord[2] = {}; // Reference position for the encoded vertices offsets (1st vertice top/left position)
39 | OffsetPointer mpIndices;
40 | OffsetPointer mpVertices;
41 | OffsetPointer mpDraws;
42 | inline void ToPointers();
43 | inline void ToOffsets();
44 | };
45 |
46 | struct CmdDrawFrame* ConvertToCmdDrawFrame(const ImDrawData* pDearImguiData, ImGuiMouseCursor cursor);
47 | struct CmdDrawFrame* CompressCmdDrawFrame(const CmdDrawFrame* pDrawFramePrev, const CmdDrawFrame* pDrawFrameNew);
48 | struct CmdDrawFrame* DecompressCmdDrawFrame(const CmdDrawFrame* pDrawFramePrev, const CmdDrawFrame* pDrawFramePacked);
49 |
50 | }} // namespace NetImgui::Internal
51 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_Network.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace NetImgui { namespace Internal { struct PendingCom; }}
4 |
5 | namespace NetImgui { namespace Internal { namespace Network
6 | {
7 |
8 | struct SocketInfo;
9 |
10 | bool Startup (void);
11 | void Shutdown (void);
12 |
13 | SocketInfo* Connect (const char* ServerHost, uint32_t ServerPort); // Communication Socket expected to be blocking
14 | SocketInfo* ListenConnect (SocketInfo* ListenSocket); // Communication Socket expected to be blocking
15 | SocketInfo* ListenStart (uint32_t ListenPort); // Listening Socket expected to be non blocking
16 | void Disconnect (SocketInfo* pClientSocket);
17 |
18 | bool DataReceivePending (SocketInfo* pClientSocket); // True if some new data if waiting to be processed from remote connection
19 | void DataReceive (SocketInfo* pClientSocket, PendingCom& PendingComRcv); // Try reading X amount of bytes from remote connection, but can fall short.
20 | void DataSend (SocketInfo* pClientSocket, PendingCom& PendingComSend); // Try sending X amount of bytes to remote connection, but can fall short.
21 |
22 | }}} //namespace NetImgui::Internal::Network
23 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_NetworkUE4.cpp:
--------------------------------------------------------------------------------
1 | #include "NetImgui_Shared.h"
2 |
3 | // Tested with Unreal Engine 4.27, 5.3, 5.4, 5.5
4 |
5 | #if NETIMGUI_ENABLED && defined(__UNREAL__)
6 |
7 | #include "CoreMinimal.h"
8 | #include "Runtime/Launch/Resources/Version.h"
9 | #include "Misc/OutputDeviceRedirector.h"
10 | #include "SocketSubsystem.h"
11 | #include "Sockets.h"
12 | #include "HAL/PlatformProcess.h"
13 | #if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 2
14 | #include "IPAddressAsyncResolve.h"
15 | #endif
16 |
17 | namespace NetImgui { namespace Internal { namespace Network
18 | {
19 |
20 | //=================================================================================================
21 | // Wrapper around native socket object and init some socket options
22 | //=================================================================================================
23 | struct SocketInfo
24 | {
25 | SocketInfo(FSocket* pSocket)
26 | : mpSocket(pSocket)
27 | {
28 | if( mpSocket )
29 | {
30 | mpSocket->SetNonBlocking(true);
31 | mpSocket->SetNoDelay(true);
32 |
33 | int32 NewSize(0);
34 | while( !mpSocket->SetSendBufferSize(2*mSendSize, NewSize) ){
35 | mSendSize /= 2;
36 | }
37 | mSendSize = NewSize/2;
38 | }
39 | }
40 |
41 | ~SocketInfo()
42 | {
43 | Close();
44 | }
45 |
46 | void Close()
47 | {
48 | if(mpSocket )
49 | {
50 | mpSocket->Close();
51 | ISocketSubsystem::Get()->DestroySocket(mpSocket);
52 | mpSocket = nullptr;
53 | }
54 | }
55 | FSocket* mpSocket = nullptr;
56 | int32 mSendSize = 1024*1024; // Limit tx data to avoid socket error on large amount (texture)
57 | };
58 |
59 | bool Startup()
60 | {
61 | return true;
62 | }
63 |
64 | void Shutdown()
65 | {
66 | }
67 |
68 | //=================================================================================================
69 | // Try establishing a connection to a remote client at given address
70 | //=================================================================================================
71 | SocketInfo* Connect(const char* ServerHost, uint32_t ServerPort)
72 | {
73 | SocketInfo* pSocketInfo = nullptr;
74 | ISocketSubsystem* SocketSubSystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM);
75 | TSharedPtr IpAddressFind = SocketSubSystem->GetAddressFromString((TCHAR*)StringCast(static_cast(ServerHost)).Get());
76 | if(IpAddressFind)
77 | {
78 | TSharedRef IpAddress = IpAddressFind->Clone();
79 | IpAddress->SetPort(ServerPort);
80 | if (IpAddress->IsValid())
81 | {
82 | FSocket* pNewSocket = SocketSubSystem->CreateSocket(NAME_Stream, "NetImgui", IpAddress->GetProtocolType());
83 | if (pNewSocket)
84 | {
85 | pNewSocket->SetNonBlocking(true);
86 | if (pNewSocket->Connect(*IpAddress))
87 | {
88 | bool bConnectionReady = false;
89 | pNewSocket->WaitForPendingConnection(bConnectionReady, FTimespan::FromSeconds(1.0f));
90 | if( bConnectionReady )
91 | {
92 | pSocketInfo = netImguiNew(pNewSocket);
93 | return pSocketInfo;
94 | }
95 | }
96 | }
97 | }
98 | }
99 | netImguiDelete(pSocketInfo);
100 | return nullptr;
101 | }
102 |
103 | //=================================================================================================
104 | // Start waiting for connection request on this socket
105 | //=================================================================================================
106 | SocketInfo* ListenStart(uint32_t ListenPort)
107 | {
108 | ISocketSubsystem* PlatformSocketSub = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM);
109 | TSharedPtr IpAddress = PlatformSocketSub->GetLocalBindAddr(*GLog);
110 | IpAddress->SetPort(ListenPort);
111 |
112 | FSocket* pNewListenSocket = PlatformSocketSub->CreateSocket(NAME_Stream, "NetImguiListen", IpAddress->GetProtocolType());
113 | if( pNewListenSocket )
114 | {
115 | SocketInfo* pListenSocketInfo = netImguiNew(pNewListenSocket);
116 | #if NETIMGUI_FORCE_TCP_LISTEN_BINDING
117 | pNewListenSocket->SetReuseAddr();
118 | #endif
119 | pNewListenSocket->SetNonBlocking(false);
120 | pNewListenSocket->SetRecvErr();
121 | if (pNewListenSocket->Bind(*IpAddress))
122 | {
123 | if (pNewListenSocket->Listen(1))
124 | {
125 | return pListenSocketInfo;
126 | }
127 | }
128 | netImguiDelete(pListenSocketInfo);
129 | }
130 | return nullptr;
131 | }
132 |
133 | //=================================================================================================
134 | // Establish a new connection to a remote request
135 | //=================================================================================================
136 | SocketInfo* ListenConnect(SocketInfo* pListenSocket)
137 | {
138 | if (pListenSocket)
139 | {
140 | FSocket* pNewSocket = pListenSocket->mpSocket->Accept(FString("NetImgui"));
141 | if( pNewSocket )
142 | {
143 | SocketInfo* pSocketInfo = netImguiNew(pNewSocket);
144 | return pSocketInfo;
145 | }
146 | }
147 | return nullptr;
148 | }
149 |
150 | //=================================================================================================
151 | // Close a connection and free allocated object
152 | //=================================================================================================
153 | void Disconnect(SocketInfo* pClientSocket)
154 | {
155 | netImguiDelete(pClientSocket);
156 | }
157 |
158 | //=================================================================================================
159 | // Return true if data has been received, or there's a connection error
160 | //=================================================================================================
161 | bool DataReceivePending(SocketInfo* pClientSocket)
162 | {
163 | // Note: return true on a connection error, to exit code looping on the data wait. Will handle error after DataReceive()
164 | uint32 PendingDataSize;
165 | return !pClientSocket || pClientSocket->mpSocket->HasPendingData(PendingDataSize) || (pClientSocket->mpSocket->GetConnectionState() != ESocketConnectionState::SCS_Connected);
166 | }
167 |
168 | //=================================================================================================
169 | // Receive as much as possible a command and keep track of transfer status
170 | //=================================================================================================
171 | void DataReceive(SocketInfo* pClientSocket, NetImgui::Internal::PendingCom& PendingComRcv)
172 | {
173 | // Invalid command
174 | if( !pClientSocket || !PendingComRcv.pCommand || !pClientSocket->mpSocket || (pClientSocket->mpSocket->GetConnectionState() != ESocketConnectionState::SCS_Connected)){
175 | PendingComRcv.bError = true;
176 | return;
177 | }
178 |
179 | int32 sizeRcv(0);
180 | if( pClientSocket->mpSocket->Recv( &reinterpret_cast(PendingComRcv.pCommand)[PendingComRcv.SizeCurrent],
181 | static_cast(PendingComRcv.pCommand->mSize-PendingComRcv.SizeCurrent),
182 | sizeRcv,
183 | ESocketReceiveFlags::None) )
184 | {
185 | PendingComRcv.SizeCurrent += static_cast(sizeRcv);
186 | PendingComRcv.bError |= sizeRcv <= 0; // Error if no data read since DataReceivePending() said there was some available
187 | }
188 | else
189 | {
190 | // Connection error, abort transmission
191 | const ESocketErrors SocketError = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->GetLastErrorCode();
192 | PendingComRcv.bError = SocketError != SE_NO_ERROR && SocketError != ESocketErrors::SE_EWOULDBLOCK;
193 | }
194 | }
195 |
196 | //=================================================================================================
197 | // Receive as much as possible a command and keep track of transfer status
198 | //=================================================================================================
199 | void DataSend(SocketInfo* pClientSocket, NetImgui::Internal::PendingCom& PendingComSend)
200 | {
201 | // Invalid command
202 | if( !pClientSocket || !PendingComSend.pCommand || !pClientSocket->mpSocket || (pClientSocket->mpSocket->GetConnectionState() != ESocketConnectionState::SCS_Connected) ){
203 | PendingComSend.bError = true;
204 | return;
205 | }
206 |
207 | int32 sizeSent = 0;
208 | int32 sizeToSend = PendingComSend.pCommand->mSize-PendingComSend.SizeCurrent;
209 | sizeToSend = sizeToSend > pClientSocket->mSendSize ? pClientSocket->mSendSize : sizeToSend;
210 |
211 | if( pClientSocket->mpSocket->Send( &reinterpret_cast(PendingComSend.pCommand)[PendingComSend.SizeCurrent],
212 | static_cast(sizeToSend),
213 | sizeSent) )
214 | {
215 | PendingComSend.SizeCurrent += static_cast(sizeSent);
216 | }
217 | else
218 | {
219 | // Connection error, abort transmission
220 | const ESocketErrors SocketError = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->GetLastErrorCode();
221 | PendingComSend.bError = SocketError != SE_NO_ERROR && SocketError != ESocketErrors::SE_EWOULDBLOCK;
222 | }
223 | }
224 |
225 | }}} // namespace NetImgui::Internal::Network
226 |
227 | #else
228 |
229 | // Prevents Linker warning LNK4221 in Visual Studio (This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library)
230 | extern int sSuppresstLNK4221_NetImgui_NetworkUE4;
231 | int sSuppresstLNK4221_NetImgui_NetworkUE4(0);
232 |
233 | #endif // #if NETIMGUI_ENABLED && defined(__UNREAL__)
234 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_Shared.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | //=================================================================================================
4 | // Include NetImgui_Api.h with almost no warning suppression.
5 | // this is to make sure library user does not need to suppress any
6 | #if defined(_MSC_VER)
7 | #pragma warning (disable: 4464) // warning C4464: relative include path contains '..'
8 | #endif
9 |
10 | #ifndef NETIMGUI_INTERNAL_INCLUDE
11 | #define NETIMGUI_INTERNAL_INCLUDE 1
12 | #include "NetImgui_Api.h"
13 | #undef NETIMGUI_INTERNAL_INCLUDE
14 | #else
15 | #include "NetImgui_Api.h"
16 | #endif
17 |
18 | #if NETIMGUI_ENABLED
19 |
20 | //=================================================================================================
21 | // Include a few standard c++ header, with additional warning suppression
22 | #include "NetImgui_WarningDisableStd.h"
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include "NetImgui_WarningReenable.h"
28 | //=================================================================================================
29 |
30 |
31 | //=================================================================================================
32 | #include "NetImgui_WarningDisable.h"
33 | namespace NetImgui { namespace Internal
34 | {
35 |
36 | using ComDataType = uint64_t;
37 | constexpr size_t ComDataSize = sizeof(ComDataType);
38 |
39 | //=============================================================================
40 | // All allocations made by netImgui goes through here.
41 | // Relies in ImGui allocator
42 | //=============================================================================
43 | template TType* netImguiNew(Args... args);
44 | template TType* netImguiSizedNew(size_t placementSize);
45 | template void netImguiDelete(TType* pData);
46 | template void netImguiDeleteSafe(TType*& pData);
47 |
48 | class ScopedImguiContext
49 | {
50 | public:
51 | ScopedImguiContext(ImGuiContext* pNewContext) : mpSavedContext(ImGui::GetCurrentContext()){ ImGui::SetCurrentContext(pNewContext); }
52 | ~ScopedImguiContext() { ImGui::SetCurrentContext(mpSavedContext); }
53 |
54 | protected:
55 | ImGuiContext* mpSavedContext;
56 | };
57 |
58 | template
59 | class ScopedValue
60 | {
61 | public:
62 | ScopedValue(TType& ValueRef, TType Value)
63 | : mValueRef(ValueRef)
64 | , mValueRestore(ValueRef)
65 | {
66 | mValueRef = Value;
67 | }
68 | ~ScopedValue()
69 | {
70 | mValueRef = mValueRestore;
71 | }
72 | protected:
73 | TType& mValueRef;
74 | TType mValueRestore;
75 | uint8_t mPadding[sizeof(void*)-(sizeof(TType)%8)]={};
76 |
77 | // Prevents warning about implicitly delete functions
78 | ScopedValue(const ScopedValue&) = delete;
79 | ScopedValue(const ScopedValue&&) = delete;
80 | void operator=(const ScopedValue&) = delete;
81 | };
82 |
83 | using ScopedBool = ScopedValue;
84 |
85 | //=============================================================================
86 | // Class to safely exchange a pointer between two threads
87 | //=============================================================================
88 | template
89 | class ExchangePtr
90 | {
91 | public:
92 | ExchangePtr():mpData(nullptr){}
93 | ~ExchangePtr();
94 | inline TType* Release();
95 | inline void Assign(TType*& pNewData);
96 | inline void Free();
97 | inline bool IsNull()const { return mpData.load() == nullptr; }
98 | private:
99 | std::atomic mpData;
100 |
101 | // Prevents warning about implicitly delete functions
102 | private:
103 | ExchangePtr(const ExchangePtr&) = delete;
104 | ExchangePtr(const ExchangePtr&&) = delete;
105 | void operator=(const ExchangePtr&) = delete;
106 | };
107 |
108 | //=============================================================================
109 | // Make data serialization easier
110 | //=============================================================================
111 | template
112 | struct OffsetPointer
113 | {
114 | inline OffsetPointer();
115 | inline explicit OffsetPointer(TType* pPointer);
116 | inline explicit OffsetPointer(uint64_t offset);
117 |
118 | inline bool IsPointer()const;
119 | inline bool IsOffset()const;
120 |
121 | inline TType* ToPointer();
122 | inline uint64_t ToOffset();
123 | inline TType* operator->();
124 | inline const TType* operator->()const;
125 | inline TType& operator[](size_t index);
126 | inline const TType& operator[](size_t index)const;
127 |
128 | inline TType* Get();
129 | inline const TType* Get()const;
130 | inline const ComDataType* GetComData()const;
131 | inline uint64_t GetOff()const;
132 | inline void SetPtr(TType* pPointer);
133 | inline void SetComDataPtr(ComDataType* pPointer);
134 | inline void SetOff(uint64_t offset);
135 |
136 | private:
137 | union
138 | {
139 | uint64_t mOffset;
140 | TType* mPointer;
141 | };
142 | };
143 |
144 | //=============================================================================
145 | //=============================================================================
146 | template
147 | class Ringbuffer
148 | {
149 | public:
150 | Ringbuffer():mPosCur(0),mPosLast(0){}
151 | void AddData(const TType* pData, size_t& count);
152 | bool ReadData(TType* pData);
153 | private:
154 | TType mBuffer[TCount] = {0};
155 | std::atomic_uint64_t mPosCur;
156 | std::atomic_uint64_t mPosLast;
157 |
158 | // Prevents warning about implicitly delete functions
159 | private:
160 | Ringbuffer(const Ringbuffer&) = delete;
161 | Ringbuffer(const Ringbuffer&&) = delete;
162 | void operator=(const Ringbuffer&) = delete;
163 | };
164 |
165 | template
166 | constexpr std::size_t ArrayCount(T const (&)[N]) noexcept
167 | {
168 | return N;
169 | }
170 |
171 | //=============================================================================
172 | //=============================================================================
173 | template
174 | inline void StringCopy(char (&output)[charCount], const char* pSrc, size_t srcCharCount=0xFFFFFFFE);
175 |
176 | template
177 | int StringFormat(char(&output)[charCount], char const* const format, ...);
178 |
179 | //=============================================================================
180 | // Get the (value / Denominator) rounded up to the next int value big enough
181 | //=============================================================================
182 | template
183 | IntType DivUp(IntType Value, IntType Denominator);
184 |
185 | //=============================================================================
186 | // Get the rounded up value
187 | //=============================================================================
188 | template
189 | IntType RoundUp(IntType Value, IntType Round);
190 |
191 | inline uint64_t TextureCastFromID(ImTextureID textureID);
192 | inline ImTextureID TextureCastFromPtr(void* pTexture);
193 | inline ImTextureID TextureCastFromUInt(uint64_t textureID);
194 |
195 | }} //namespace NetImgui::Internal
196 |
197 | #include "NetImgui_Shared.inl"
198 | #include "NetImgui_WarningReenable.h"
199 |
200 | #endif //NETIMGUI_ENABLED
201 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_Shared.inl:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | namespace NetImgui { namespace Internal
7 | {
8 |
9 | template
10 | TType* netImguiNew(Args... args)
11 | {
12 | return new( ImGui::MemAlloc(sizeof(TType)) ) TType(args...);
13 | }
14 |
15 | template
16 | TType* netImguiSizedNew(size_t placementSize)
17 | {
18 | return new( ImGui::MemAlloc(placementSize > sizeof(TType) ? placementSize : sizeof(TType)) ) TType();
19 | }
20 |
21 | template
22 | void netImguiDelete(TType* pData)
23 | {
24 | if( pData )
25 | {
26 | pData->~TType();
27 | ImGui::MemFree(pData);
28 | }
29 | }
30 |
31 | template
32 | void netImguiDeleteSafe(TType*& pData)
33 | {
34 | netImguiDelete(pData);
35 | pData = nullptr;
36 | }
37 |
38 | //=============================================================================
39 | // Acquire ownership of the resource
40 | //=============================================================================
41 | template
42 | TType* ExchangePtr::Release()
43 | {
44 | return mpData.exchange(nullptr);
45 | }
46 |
47 | //-----------------------------------------------------------------------------
48 | // Take ownership of the provided data.
49 | // If there's a previous unclaimed pointer to some data, release it
50 | //-----------------------------------------------------------------------------
51 | template
52 | void ExchangePtr::Assign(TType*& pNewData)
53 | {
54 | netImguiDelete( mpData.exchange(pNewData) );
55 | pNewData = nullptr;
56 | }
57 |
58 | template
59 | void ExchangePtr::Free()
60 | {
61 | TType* pNull(nullptr);
62 | Assign(pNull);
63 | }
64 |
65 | template
66 | ExchangePtr::~ExchangePtr()
67 | {
68 | Free();
69 | }
70 |
71 | //=============================================================================
72 | //
73 | //=============================================================================
74 | template
75 | OffsetPointer::OffsetPointer()
76 | : mOffset(0)
77 | {
78 | SetOff(0);
79 | }
80 |
81 | template
82 | OffsetPointer::OffsetPointer(TType* pPointer)
83 | {
84 | SetPtr(pPointer);
85 | }
86 |
87 | template
88 | OffsetPointer::OffsetPointer(uint64_t offset)
89 | {
90 | SetOff(offset);
91 | }
92 |
93 | template
94 | void OffsetPointer::SetPtr(TType* pPointer)
95 | {
96 | mOffset = 0; // Remove 'offset flag' that can be left active on non 64bits pointer
97 | mPointer = pPointer;
98 | }
99 |
100 | template
101 | void OffsetPointer::SetComDataPtr(ComDataType* pPointer)
102 | {
103 | SetPtr(reinterpret_cast(pPointer));
104 | }
105 |
106 | template
107 | void OffsetPointer::SetOff(uint64_t offset)
108 | {
109 | mOffset = offset | 0x0000000000000001u;
110 | }
111 |
112 | template
113 | uint64_t OffsetPointer::GetOff()const
114 | {
115 | return mOffset & ~0x0000000000000001u;
116 | }
117 |
118 | template
119 | bool OffsetPointer::IsOffset()const
120 | {
121 | return (mOffset & 0x0000000000000001u) != 0;
122 | }
123 |
124 | template
125 | bool OffsetPointer::IsPointer()const
126 | {
127 | return !IsOffset();
128 | }
129 |
130 | template
131 | TType* OffsetPointer::ToPointer()
132 | {
133 | assert(IsOffset());
134 | SetPtr( reinterpret_cast( reinterpret_cast(&mPointer) + GetOff() ) );
135 | return mPointer;
136 | }
137 |
138 | template
139 | uint64_t OffsetPointer::ToOffset()
140 | {
141 | assert(IsPointer());
142 | SetOff( reinterpret_cast(mPointer) - reinterpret_cast(&mPointer) );
143 | return mOffset;
144 | }
145 |
146 | template
147 | TType* OffsetPointer::operator->()
148 | {
149 | assert(IsPointer());
150 | return mPointer;
151 | }
152 |
153 | template
154 | const TType* OffsetPointer::operator->()const
155 | {
156 | assert(IsPointer());
157 | return mPointer;
158 | }
159 |
160 | template
161 | TType* OffsetPointer::Get()
162 | {
163 | assert(IsPointer());
164 | return mPointer;
165 | }
166 |
167 | template
168 | const TType* OffsetPointer::Get()const
169 | {
170 | assert(IsPointer());
171 | return mPointer;
172 | }
173 |
174 | template
175 | const ComDataType* OffsetPointer::GetComData()const
176 | {
177 | return reinterpret_cast(Get());
178 | }
179 |
180 | template
181 | TType& OffsetPointer::operator[](size_t index)
182 | {
183 | assert(IsPointer());
184 | return mPointer[index];
185 | }
186 |
187 | template
188 | const TType& OffsetPointer::operator[](size_t index)const
189 | {
190 | assert(IsPointer());
191 | return mPointer[index];
192 | }
193 |
194 | //=============================================================================
195 | template
196 | void Ringbuffer::AddData(const TType* pData, size_t& count)
197 | //=============================================================================
198 | {
199 | size_t i(0);
200 | while (i < count && (mPosLast - mPosCur < TCount)) {
201 | mBuffer[mPosLast % TCount] = pData[i];
202 | mPosLast++;
203 | i++;
204 | }
205 | count = i;
206 | }
207 |
208 | //=============================================================================
209 | template
210 | bool Ringbuffer::ReadData(TType* pData)
211 | //=============================================================================
212 | {
213 | if (mPosCur < mPosLast)
214 | {
215 | *pData = mBuffer[mPosCur % TCount];
216 | mPosCur++;
217 | return true;
218 | }
219 | return false;
220 | }
221 |
222 |
223 | //=============================================================================
224 | // The _s string functions are a mess. There's really no way to do this right
225 | // in a cross-platform way. Best solution I've found is to set just use
226 | // strncpy, infer the buffer length, and null terminate. Still need to suppress
227 | // the warning on Windows.
228 | // See https://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/
229 | // and many other discussions online on the topic.
230 | //=============================================================================
231 | template
232 | void StringCopy(char (&output)[charCount], const char* pSrc, size_t srcCharCount)
233 | {
234 | #if defined(__clang__)
235 | #pragma clang diagnostic push
236 | #pragma clang diagnostic ignored "-Wdeprecated-declarations"
237 | #elif defined(_MSC_VER)
238 | #pragma warning (push)
239 | #pragma warning (disable: 4996) // warning C4996: 'strncpy': This function or variable may be unsafe.
240 | #endif
241 |
242 | size_t charToCopyCount = charCount < srcCharCount + 1 ? charCount : srcCharCount + 1;
243 | strncpy(output, pSrc, charToCopyCount - 1);
244 | output[charCount - 1] = 0;
245 |
246 | #if defined(_MSC_VER) && defined(__clang__)
247 | #pragma clang diagnostic pop
248 | #elif defined(_MSC_VER)
249 | #pragma warning (pop)
250 | #endif
251 | }
252 |
253 | template
254 | int StringFormat(char(&output)[charCount], char const* const format, ...)
255 | {
256 | #if defined(__clang__)
257 | #pragma clang diagnostic push
258 | #pragma clang diagnostic ignored "-Wformat-nonliteral"
259 | #endif
260 |
261 | va_list args;
262 | va_start(args, format);
263 | int w = vsnprintf(output, charCount, format, args);
264 | va_end(args);
265 | output[charCount - 1] = 0;
266 | return w;
267 |
268 | #if defined(__clang__)
269 | #pragma clang diagnostic pop
270 | #endif
271 | }
272 |
273 | //=============================================================================
274 | //=============================================================================
275 | template
276 | IntType DivUp(IntType Value, IntType Denominator)
277 | {
278 | return (Value + Denominator - 1) / Denominator;
279 | }
280 |
281 | template
282 | IntType RoundUp(IntType Value, IntType Round)
283 | {
284 | return DivUp(Value, Round) * Round;
285 | }
286 |
287 | union TextureCastHelperUnion
288 | {
289 | ImTextureID TextureID;
290 | uint64_t TextureUint;
291 | const void* TexturePtr;
292 | };
293 |
294 | uint64_t TextureCastFromID(ImTextureID textureID)
295 | {
296 | TextureCastHelperUnion textureUnion;
297 | textureUnion.TextureUint = 0;
298 | textureUnion.TextureID = textureID;
299 | return textureUnion.TextureUint;
300 | }
301 |
302 | ImTextureID TextureCastFromPtr(void* pTexture)
303 | {
304 | TextureCastHelperUnion textureUnion;
305 | textureUnion.TextureUint = 0;
306 | textureUnion.TexturePtr = pTexture;
307 | return textureUnion.TextureID;
308 | }
309 |
310 | #ifndef IS_NETIMGUISERVER
311 | ImTextureID TextureCastFromUInt(uint64_t textureID)
312 | {
313 | TextureCastHelperUnion textureUnion;
314 | textureUnion.TextureUint = textureID;
315 | return textureUnion.TextureID;
316 | }
317 | #endif
318 |
319 | }} //namespace NetImgui::Internal
320 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_WarningDisable.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | //
3 | // Deactivate a few warnings to allow internal netImgui code to compile
4 | // with 'Warning as error' and '-Wall' compile actions enabled
5 | //
6 |
7 | //=================================================================================================
8 | // Clang
9 | //=================================================================================================
10 | #if defined (__clang__)
11 | #pragma clang diagnostic push
12 | #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
13 | #pragma clang diagnostic ignored "-Wmissing-prototypes"
14 |
15 | //=================================================================================================
16 | // Visual Studio warnings
17 | //=================================================================================================
18 | #elif defined(_MSC_VER)
19 | #pragma warning (disable: 5032) // detected #pragma warning(push) with no corresponding #pragma warning(pop)
20 |
21 | #pragma warning (push)
22 | #pragma warning (disable: 4365) // conversion from 'long' to 'unsigned int', signed/unsigned mismatch for
23 | #pragma warning (disable: 4464) // relative include path contains '..'
24 | #pragma warning (disable: 4514) // unreferenced inline function has been removed
25 | #pragma warning (disable: 4577) // 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify
26 | #pragma warning (disable: 4710) // 'xxx': function not inlined
27 | #pragma warning (disable: 4711) // function 'xxx' selected for automatic inline expansion
28 | #pragma warning (disable: 4826) // Conversion from 'TType *' to 'uint64_t' is sign-extended. This may cause unexpected runtime behavior.
29 | #pragma warning (disable: 5031) // #pragma warning(pop): likely mismatch, popping warning state pushed in different file
30 | #pragma warning (disable: 5045) // Compiler will insert Spectre mitigation for memory load if / Qspectre switch specified
31 | #pragma warning (disable: 5264) // 'xxx': 'const' variable is not used
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_WarningDisableImgui.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | //
3 | // Deactivate a few warnings to allow Imgui header includes,
4 | // without generating warnings in '-Wall' compile actions enabled
5 | //
6 |
7 | //=================================================================================================
8 | // Clang
9 | //=================================================================================================
10 | #if defined (__clang__)
11 | #pragma clang diagnostic push
12 | #pragma clang diagnostic ignored "-Wunknown-warning-option"
13 | #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
14 | #pragma clang diagnostic ignored "-Wnonportable-include-path" // Sharpmake convert include path to lowercase, avoid warning
15 | #pragma clang diagnostic ignored "-Wreserved-identifier" // Enuma values using '__' or member starting with '_' in imgui.h
16 |
17 | //=================================================================================================
18 | // Visual Studio warnings
19 | //=================================================================================================
20 | #elif defined(_MSC_VER)
21 | #pragma warning (push)
22 | #pragma warning (disable: 4514) // 'xxx': unreferenced inline function has been removed
23 | #pragma warning (disable: 4365) // '=': conversion from 'ImGuiTabItemFlags' to 'ImGuiID', signed/unsigned mismatch
24 | #pragma warning (disable: 4710) // 'xxx': function not inlined
25 | #pragma warning (disable: 4820) // 'xxx': 'yyy' bytes padding added after data member 'zzz'
26 | #pragma warning (disable: 5031) // #pragma warning(pop): likely mismatch, popping warning state pushed in different file
27 | #pragma warning (disable: 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
28 | #if _MSC_VER >= 1920
29 | #pragma warning (disable: 5219) // implicit conversion from 'int' to 'float', possible loss of data
30 | #endif
31 | #pragma warning (disable: 26495) // Code Analysis warning : Variable 'ImGuiStorage::ImGuiStoragePair::::val_p' is uninitialized. Always initialize a member variable (type.6).
32 | #endif
33 |
34 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_WarningDisableStd.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | //
3 | // Deactivate a few more warnings to allow standard header includes,
4 | // without generating warnings in '-Wall' compile actions enabled
5 | //
6 |
7 | #include "NetImgui_WarningDisable.h"
8 |
9 | //=================================================================================================
10 | // Clang
11 | //=================================================================================================
12 | #if defined (__clang__)
13 |
14 |
15 | //=================================================================================================
16 | // Visual Studio warnings
17 | //=================================================================================================
18 | #elif defined(_MSC_VER)
19 | #pragma warning (disable: 4061) // enumerator xxx in switch of enum yyy is not explicitly handled by a case label (d3d11.h)
20 | #pragma warning (disable: 4548) // expression before comma has no effect; expected expression with side - effect (malloc.h VS2017)
21 | #pragma warning (disable: 4668) // xxx is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' (winsock2.h)
22 | #pragma warning (disable: 4574) // xxx is defined to be '0': did you mean to use yyy (winsock2.h VS2017)
23 | #pragma warning (disable: 4820) // xxx : yyy bytes padding added after data member zzz
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/Code/Client/Private/NetImgui_WarningReenable.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | //=================================================================================================
5 | // Clang
6 | //=================================================================================================
7 | #if defined(__clang__)
8 | #pragma clang diagnostic pop
9 |
10 |
11 | //=================================================================================================
12 | // Visual Studio warnings
13 | //=================================================================================================
14 | #elif defined(_MSC_VER)
15 | #pragma warning(pop)
16 | #endif
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Code/Sample/Common/Sample.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | // Forward declares when NetImgui is not enabled
6 | #if !NETIMGUI_ENABLED
7 | struct ImGuiContext;
8 | struct ImDrawData;
9 | namespace NetImgui
10 | {
11 | using ThreadFunctPtr = void*;
12 | using FontCreateFuncPtr = void*;
13 | }
14 | #endif
15 |
16 | namespace Sample
17 | {
18 |
19 | class Base
20 | {
21 | public:
22 | Base(const char* sampleName); //!< Constructor receiving pointer to constant string that must remains valid
23 | virtual bool Startup(); //!< Called once when starting
24 | virtual void Shutdown(); //!< Called once when exiting
25 | virtual bool UpdateFont(float fontScaleDPI, bool isLocal); //!< Receive command to create/update the Font Atlas and its texture data
26 | virtual ImDrawData* Draw() = 0; //!< Each sample should have their Dear ImGui drawing routines in this overloaded method
27 |
28 | protected:
29 | void Draw_Connect(); //!< Display UI for initiating a connection to the remote NetImgui server application
30 | const char* mSampleName = nullptr; //!< Name displayed in the Main Menu bar (must receive string pointer in constructor that remains valid)
31 | ImGuiContext* mpContextMain = nullptr; //!< Pointer to main context created in main.cpp (used to detect when to update font texture)
32 | ImGuiContext* mpContextLocal = nullptr; //!< Pointer to context used for local draw. Most sample leave it to the same as mpContextMain (used to detect when to update font texture)
33 | NetImgui::ThreadFunctPtr mCallback_ThreadLaunch = nullptr; //!< [Optional] Thread launcher callback assigned on NetImgui connection. Used to start a new thread for coms with NetImgui server
34 | NetImgui::FontCreateFuncPtr mCallback_FontGenerate = nullptr; //!< [Optional] Font generation callback assigned on NetImgui connection. Used to adjust the font data to remote server DPI
35 | float mGeneratedFontScaleDPI = 0.f; //!< Current generated font texture DPI
36 | bool mbShowDemoWindow = false; //!< If we should show the Dear ImGui demo window
37 | char mConnect_HostnameServer[128] = {"localhost"}; //!< IP/Hostname used to send a connection request when when trying to reach the server
38 | int mConnect_PortServer = 0; //!< Port used to send a connection request when when trying to reach the server
39 | int mConnect_PortClient = 0; //!< Port opened when waiting for a server connection request
40 | };
41 |
42 | //=============================================================================
43 | // The _s string functions are a mess. There's really no way to do this right
44 | // in a cross-platform way. Best solution I've found is to just use strncpy,
45 | // infer the buffer length, and null terminate. Still need to suppress
46 | // the warning on Windows.
47 | // See https://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/
48 | // and many other discussions online on the topic.
49 | //=============================================================================
50 | template
51 | inline void StringCopy(char (&output)[charCount], const char* pSrc, size_t srcCharCount=0xFFFFFFFE)
52 | {
53 | #if defined(__clang__)
54 | #pragma clang diagnostic push
55 | #pragma clang diagnostic ignored "-Wdeprecated-declarations"
56 | #elif defined(_MSC_VER)
57 | #pragma warning (push)
58 | #pragma warning (disable: 4996) // warning C4996: 'strncpy': This function or variable may be unsafe.
59 | #endif
60 |
61 | size_t charToCopyCount = charCount < srcCharCount + 1 ? charCount : srcCharCount + 1;
62 | strncpy(output, pSrc, charToCopyCount - 1);
63 | output[charCount - 1] = 0;
64 |
65 | #if defined(_MSC_VER) && defined(__clang__)
66 | #pragma clang diagnostic pop
67 | #elif defined(_MSC_VER)
68 | #pragma warning (pop)
69 | #endif
70 | }
71 |
72 | #if NETIMGUI_ENABLED
73 |
74 | union TextureCastHelperUnion
75 | {
76 | ImTextureID TextureID;
77 | uint64_t TextureUint;
78 | const void* TexturePtr;
79 | };
80 |
81 | inline uint64_t TextureCastFromID(ImTextureID textureID)
82 | {
83 | TextureCastHelperUnion textureUnion;
84 | textureUnion.TextureUint = 0;
85 | textureUnion.TextureID = textureID;
86 | return textureUnion.TextureUint;
87 | }
88 |
89 | inline ImTextureID TextureCastFromPtr(void* pTexture)
90 | {
91 | TextureCastHelperUnion textureUnion;
92 | textureUnion.TextureUint = 0;
93 | textureUnion.TexturePtr = pTexture;
94 | return textureUnion.TextureID;
95 | }
96 |
97 | inline ImTextureID TextureCastFromUInt(uint64_t textureID)
98 | {
99 | TextureCastHelperUnion textureUnion;
100 | textureUnion.TextureUint = textureID;
101 | return textureUnion.TextureID;
102 | }
103 | #endif // NETIMGUI_ENABLED
104 |
105 | }; // namespace Sample
106 |
107 | Sample::Base& GetSample(); // Each Sample must implement this function and return a valid sample object
108 |
109 | #include
110 |
--------------------------------------------------------------------------------
/Code/Sample/SampleBackground/SampleBackground.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // SAMPLE BACKGROUND
3 | //-------------------------------------------------------------------------------------------------
4 | // Example of using the NetImgui 'Background' setting
5 | //=================================================================================================
6 |
7 | #include
8 | #include
9 | #include
10 | #include "../Common/Sample.h"
11 |
12 | // Methods declared in main.cpp, extern declare to avoid having to include 'd3d11.h' here
13 | extern void TextureCreate(const uint8_t* pPixelData, uint32_t width, uint32_t height, void*& pTextureViewOut);
14 | extern void TextureDestroy(void*& pTextureView);
15 |
16 | //=================================================================================================
17 | // SAMPLE CLASS
18 | //=================================================================================================
19 | class SampleBackground : public Sample::Base
20 | {
21 | public:
22 | SampleBackground() : Base("SampleBackground") {}
23 | virtual bool Startup() override;
24 | virtual void Shutdown() override;
25 | virtual ImDrawData* Draw() override;
26 | protected:
27 | void* mTextureView = nullptr;
28 | };
29 |
30 | //=================================================================================================
31 | // GET SAMPLE
32 | // Each project must return a valid sample object
33 | //=================================================================================================
34 | Sample::Base& GetSample()
35 | {
36 | static SampleBackground sample;
37 | return sample;
38 | };
39 |
40 | //=================================================================================================
41 | // STARTUP
42 | //=================================================================================================
43 | bool SampleBackground::Startup()
44 | {
45 | if (!Base::Startup())
46 | return false;
47 |
48 | constexpr uint16_t kSize = 256;
49 | constexpr float kFadeSize = 16.f;
50 | uint32_t pixels[kSize][kSize];
51 | for (uint32_t y(0); y < kSize; ++y) {
52 | for (uint32_t x(0); x < kSize; ++x)
53 | {
54 | float offsetX = static_cast(x) - static_cast(kSize/2);
55 | float offsetY = static_cast(y) - static_cast(kSize/2);
56 | float radius = static_cast(sqrt(offsetX*offsetX+offsetY*offsetY));
57 | float alpha = 1.f - std::min(1.f, std::max(0.f, (radius - (static_cast(kSize/2)-kFadeSize))) / kFadeSize);
58 | pixels[y][x] = ImColor( static_cast(x), static_cast(y), (x+y) <= 255 ? 0 : 255-(x+y), static_cast(255.f*alpha));
59 | }
60 | }
61 | TextureCreate(reinterpret_cast(pixels), kSize, kSize, mTextureView); // For local display
62 | NetImgui::SendDataTexture(Sample::TextureCastFromPtr(mTextureView), pixels, kSize, kSize, NetImgui::eTexFormat::kTexFmtRGBA8); // For remote display
63 | return true;
64 | }
65 |
66 | //=================================================================================================
67 | // SHUTDOWN
68 | //=================================================================================================
69 | void SampleBackground::Shutdown()
70 | {
71 | TextureDestroy(mTextureView);
72 | NetImgui::Shutdown();
73 | }
74 |
75 | //=================================================================================================
76 | // DRAW
77 | //=================================================================================================
78 | ImDrawData* SampleBackground::Draw()
79 | {
80 | //---------------------------------------------------------------------------------------------
81 | // (1) Start a new Frame
82 | //---------------------------------------------------------------------------------------------
83 | if (NetImgui::NewFrame(true))
84 | {
85 | //-----------------------------------------------------------------------------------------
86 | // (2) Draw ImGui Content
87 | //-----------------------------------------------------------------------------------------
88 | Base::Draw_Connect(); //Note: Connection to remote server done in there
89 |
90 | ImGui::SetNextWindowPos(ImVec2(32, 48), ImGuiCond_Once);
91 | ImGui::SetNextWindowSize(ImVec2(400, 400), ImGuiCond_Once);
92 | if (ImGui::Begin("Sample Background", nullptr))
93 | {
94 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Demonstration of NetImgui's Background settings.");
95 | static ImVec4 sBgColor(0.2f,0.2f,0.2f,1.f);
96 | static ImVec4 sTextureTint(1,1,1,0.5f);
97 | static bool sUseTextureOverride(false);
98 |
99 | ImGui::ColorEdit4("Background", reinterpret_cast(&sBgColor), ImGuiColorEditFlags_Float | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_PickerHueWheel);
100 | ImGui::ColorEdit4("Logo Tint", reinterpret_cast(&sTextureTint), ImGuiColorEditFlags_Float | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_PickerHueWheel);
101 | ImGui::Checkbox("Replace Background Texture", &sUseTextureOverride);
102 | ImGui::Image(ImTextureID(mTextureView), ImVec2(64,64));
103 | ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.5f, 0.5f, 1.f));
104 | ImGui::TextWrapped("(Note: Custom background settings only applied on remote server)");
105 | ImGui::PopStyleColor();
106 | if( sUseTextureOverride )
107 | {
108 | NetImgui::SetBackground(sBgColor, sTextureTint, Sample::TextureCastFromPtr(mTextureView));
109 | }
110 | else
111 | {
112 | NetImgui::SetBackground(sBgColor, sTextureTint);
113 | }
114 | }
115 | ImGui::End();
116 |
117 | //-----------------------------------------------------------------------------------------
118 | // (3) Finish the frame, preparing the drawing data and...
119 | // (3a) Send the data to the netImGui server when connected
120 | //-----------------------------------------------------------------------------------------
121 | NetImgui::EndFrame();
122 | }
123 |
124 | //---------------------------------------------------------------------------------------------
125 | // (4b) Render nothing locally (when connected)
126 | //---------------------------------------------------------------------------------------------
127 | return !NetImgui::IsConnected() ? ImGui::GetDrawData() : nullptr;
128 | }
129 |
130 |
--------------------------------------------------------------------------------
/Code/Sample/SampleBasic/SampleBasic.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // SAMPLE BASIC
3 | //-------------------------------------------------------------------------------------------------
4 | // Barebone example of adding NetImgui to a code base. This demonstrate how little changes
5 | // are needed to be up and running.
6 | //=================================================================================================
7 |
8 | #include
9 | #include "../Common/Sample.h"
10 |
11 | //=================================================================================================
12 | // SAMPLE CLASS
13 | //=================================================================================================
14 | class SampleBasic : public Sample::Base
15 | {
16 | public:
17 | SampleBasic() : Base("SampleBasic") {}
18 | virtual ImDrawData* Draw() override;
19 | };
20 |
21 | //=================================================================================================
22 | // GET SAMPLE
23 | // Each project must return a valid sample object
24 | //=================================================================================================
25 | Sample::Base& GetSample()
26 | {
27 | static SampleBasic sample;
28 | return sample;
29 | }
30 |
31 | //=================================================================================================
32 | // DRAW
33 | //=================================================================================================
34 | ImDrawData* SampleBasic::Draw()
35 | {
36 | //---------------------------------------------------------------------------------------------
37 | // (1) Start a new Frame.
38 | // Note: With ImGui 1.81+ NetImgui can automatically intercept Imgui::NewFrame/Render. This
39 | // sample does this. For older Imgui releases, please look at 'Client_Draw_ModeAlways'
40 | // in 'SampleNewFrame' on how to tell NetImgui directly about NewFrame/EndFrame.
41 | // Other samples also avoid the auto intercept to allow drawing only when needed.
42 | //---------------------------------------------------------------------------------------------
43 | ImGui::NewFrame();
44 |
45 | //-----------------------------------------------------------------------------------------
46 | // (2) Draw ImGui Content
47 | //-----------------------------------------------------------------------------------------
48 | Base::Draw_Connect(); //Note: Connection to remote server done in there
49 |
50 | //Note: Some dummy text content
51 | ImGui::SetNextWindowPos(ImVec2(32,48), ImGuiCond_Once);
52 | ImGui::SetNextWindowSize(ImVec2(400,400), ImGuiCond_Once);
53 | if( ImGui::Begin("Sample Basic", nullptr) )
54 | {
55 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Basic demonstration of NetImgui code integration.");
56 | ImGui::TextWrapped("Create a basic Window with some text.");
57 | ImGui::NewLine();
58 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Where are we drawing: ");
59 | ImGui::SameLine();
60 | ImGui::TextUnformatted(NetImgui::IsDrawingRemote() ? "Remote Draw" : "Local Draw");
61 | ImGui::NewLine();
62 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Filler content");
63 | ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
64 | }
65 | ImGui::End();
66 |
67 | //---------------------------------------------------------------------------------------------
68 | // (3) Finish the frame
69 | // Note: Same note as in (1)
70 | //---------------------------------------------------------------------------------------------
71 | ImGui::Render();
72 |
73 | //---------------------------------------------------------------------------------------------
74 | // (4) Return content to draw by local renderer. Stop drawing locally when remote connected
75 | //---------------------------------------------------------------------------------------------
76 | return !NetImgui::IsConnected() ? ImGui::GetDrawData() : nullptr;
77 | }
78 |
--------------------------------------------------------------------------------
/Code/Sample/SampleDisabled/SampleDisabled.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // SAMPLE DISABLED
3 | //-------------------------------------------------------------------------------------------------
4 | // This sample demonstrate compiling your code with netImgui disabled but ImGui still active.
5 | // It relies on the Define 'NETIMGUI_ENABLED' assigned in the project properties to compile
6 | // with NetImfui inactive.
7 | //=================================================================================================
8 |
9 | #include
10 | // Since NetImgui is disabled in this sample, NetImgui_Api.h will not include this header,
11 | // so must include it manually
12 | #include "imgui.h"
13 |
14 | #include "../Common/Sample.h"
15 |
16 | //=================================================================================================
17 | // SAMPLE CLASS
18 | //=================================================================================================
19 | class SampleDisabled : public Sample::Base
20 | {
21 | public:
22 | SampleDisabled() : Base("SampleDisabled") {}
23 | virtual ImDrawData* Draw() override;
24 | };
25 |
26 | //=================================================================================================
27 | // GET SAMPLE
28 | // Each project must return a valid sample object
29 | //=================================================================================================
30 | Sample::Base& GetSample()
31 | {
32 | static SampleDisabled sample;
33 | return sample;
34 | }
35 |
36 | //=================================================================================================
37 | // DRAW
38 | //=================================================================================================
39 | ImDrawData* SampleDisabled::Draw()
40 | {
41 | //---------------------------------------------------------------------------------------------
42 | // (1) Start a new Frame
43 | //---------------------------------------------------------------------------------------------
44 | ImGui::NewFrame();
45 |
46 | //-----------------------------------------------------------------------------------------
47 | // (2) Draw ImGui Content
48 | //-----------------------------------------------------------------------------------------
49 | Base::Draw_Connect(); //Note: Connection to remote server done in there
50 |
51 | ImGui::SetNextWindowPos(ImVec2(32,48), ImGuiCond_Once);
52 | ImGui::SetNextWindowSize(ImVec2(400,400), ImGuiCond_Once);
53 | if( ImGui::Begin("Sample Disabled", nullptr) )
54 | {
55 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Compiling with netImgui Disabled.");
56 | ImGui::TextWrapped( "This shows being able to continue using ImGui normally, while netImgui code has been disabled. "
57 | "No connection with the remote netImgui will be possible since the client code is entirely ifdef out ");
58 | ImGui::NewLine();
59 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Filler content");
60 | ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
61 | }
62 | ImGui::End();
63 |
64 | //---------------------------------------------------------------------------------------------
65 | // (3) Finish the frame, preparing the drawing data and...
66 | //---------------------------------------------------------------------------------------------
67 | ImGui::Render();
68 |
69 | //---------------------------------------------------------------------------------------------
70 | // (4) Forward to drawing data our local renderer when not remotely drawing
71 | //---------------------------------------------------------------------------------------------
72 | return ImGui::GetDrawData();
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/Code/Sample/SampleIndex/SampleIndex.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // SAMPLE INDEX 16/32Bits
3 | //-------------------------------------------------------------------------------------------------
4 | // Sample testing render of large amount of shapes, pushing the vertices count past the 65k
5 | // limit of 16bits indices.
6 | //
7 | // Note: This source file is compiled under 2 samples projects, one with Dear ImGui using
8 | // 16bits indices and the other one using 32 bits indices.
9 | //
10 | // Note: This sample is meant as a UnitTest ensuring large draws amount is handled properly on
11 | // NetImgui Server application
12 | //=================================================================================================
13 |
14 | #include
15 | #include
16 | #include "../Common/Sample.h"
17 |
18 | //=================================================================================================
19 | // SAMPLE CLASS
20 | //=================================================================================================
21 | class SampleIndex : public Sample::Base
22 | {
23 | public:
24 | SampleIndex() : Base(sizeof(ImDrawIdx) == 2 ? "SampleIndex16Bits" : "SampleIndex32Bits") {}
25 | virtual ImDrawData* Draw() override;
26 | };
27 |
28 | //=================================================================================================
29 | // GET SAMPLE
30 | // Each project must return a valid sample object
31 | //=================================================================================================
32 | Sample::Base& GetSample()
33 | {
34 | static SampleIndex sample;
35 | return sample;
36 | }
37 |
38 | //=================================================================================================
39 | // Function used by the sample, to draw all ImGui Content
40 | //=================================================================================================
41 | ImDrawData* SampleIndex::Draw()
42 | {
43 | //---------------------------------------------------------------------------------------------
44 | // (1) Start a new Frame
45 | //---------------------------------------------------------------------------------------------
46 | if (NetImgui::NewFrame(true))
47 | {
48 | //-----------------------------------------------------------------------------------------
49 | // (2) Draw ImGui Content
50 | //-----------------------------------------------------------------------------------------
51 | Base::Draw_Connect(); //Note: Connection to remote server done in there
52 |
53 | ImGui::SetNextWindowPos(ImVec2(32, 48), ImGuiCond_Once);
54 | ImGui::SetNextWindowSize(ImVec2(525, 820), ImGuiCond_Once);
55 | if (ImGui::Begin("Sample Index", nullptr))
56 | {
57 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Large amount of mesh drawing.");
58 | ImGui::TextWrapped("This sample is meant as a UnitTest ensuring large draws amount is handled properly on NetImgui Server application");
59 | ImGui::NewLine();
60 |
61 | static size_t sIndexSize = sizeof(ImDrawIdx); // Using a static value to prevent VS warning :/ (C4127: Conditional Expression is Constant)
62 | if( sIndexSize == 2 ){
63 | ImGui::TextWrapped("Note: This sample uses Dear ImGui compiled with 16bits indices. Meaning that each draw will be splitted in multiple drawcalls of less than 65k vertices each.");
64 | }
65 | else {
66 | ImGui::TextWrapped("Note: This sample uses Dear ImGui compiled with 32bits indices. Meaning that each draw can be sent as a single drawcall, even when having more than 65k vertices.");
67 | }
68 |
69 | ImGui::NewLine();
70 |
71 | ImDrawList* draw_list = ImGui::GetWindowDrawList();
72 | const ImVec2 winPos = ImGui::GetCursorScreenPos();
73 | constexpr float th = 3.f;//(n == 0) ? 1.0f : thickness;
74 | constexpr int segments = 64;
75 | constexpr float size = 16.f;
76 | constexpr float spacing = 4.f;
77 | for (float y(0); y < 25.f; y++) {
78 | for (float x(0); x < 25.f; x++) {
79 | float posX = winPos.x + (x + 0.5f)*(size + spacing);
80 | float posY = winPos.y + (y + 0.5f)*(size + spacing);
81 | draw_list->AddCircle(ImVec2(posX, posY), size*0.5f, ImColor(1.f,1.f,1.f,1.f), segments, th);
82 | }
83 | }
84 | }
85 | ImGui::End();
86 |
87 |
88 | //-----------------------------------------------------------------------------------------
89 | // (3) Finish the frame, preparing the drawing data and...
90 | // (3a) Send the data to the netImGui server when connected
91 | //-----------------------------------------------------------------------------------------
92 | NetImgui::EndFrame();
93 | }
94 |
95 | //---------------------------------------------------------------------------------------------
96 | // (4b) Render nothing locally (when connected)
97 | //---------------------------------------------------------------------------------------------
98 | return !NetImgui::IsConnected() ? ImGui::GetDrawData() : nullptr;
99 | }
100 |
--------------------------------------------------------------------------------
/Code/Sample/SampleNewFrame/SampleNewFrame.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // SAMPLE NEW FRAME
3 | //-------------------------------------------------------------------------------------------------
4 | // Example of handling frame skipping.
5 | // When connected to NetImgui Server, we don't need to refresh the ImGui content every frame.
6 | // If your program can handle skipping drawing, saves CPU cycles when no refresh is expected.
7 | //=================================================================================================
8 |
9 | #include
10 | #include "../Common/Sample.h"
11 |
12 | //=================================================================================================
13 | // SAMPLE CLASS
14 | //=================================================================================================
15 | class SampleNewFrame : public Sample::Base
16 | {
17 | public:
18 | SampleNewFrame() : Base("SampleNewFrame") {}
19 | virtual ImDrawData* Draw() override;
20 |
21 | protected:
22 | enum class eDrawUpdateMode : int { Always, OnDemand };
23 | void Draw_Content();
24 | ImDrawData* Draw_ModeOnDemand();
25 | ImDrawData* Draw_ModeAlways();
26 |
27 | eDrawUpdateMode mFrameRefreshMode = eDrawUpdateMode::Always;
28 | uint32_t mFrameDrawnCount = 0;
29 | uint32_t mFrameSkippedCount = 0;
30 | };
31 |
32 | //=================================================================================================
33 | // GET SAMPLE
34 | // Each project must return a valid sample object
35 | //=================================================================================================
36 | Sample::Base& GetSample()
37 | {
38 | static SampleNewFrame sample;
39 | return sample;
40 | }
41 |
42 | //=================================================================================================
43 | // Imgui content
44 | //=================================================================================================
45 | void SampleNewFrame::Draw_Content()
46 | {
47 | bool bModeChanged(false);
48 |
49 | Base::Draw_Connect(); //Note: Connection to remote server done in there
50 |
51 | ImGui::SetNextWindowPos(ImVec2(32,48), ImGuiCond_Once);
52 | ImGui::SetNextWindowSize(ImVec2(700,450), ImGuiCond_Once);
53 | if (ImGui::Begin("Sample NewFrame", nullptr))
54 | {
55 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Demonstration of frame skip handling.");
56 | ImGui::TextWrapped( "Demonstrate how to reduce CPU usage by only redrawing ImGui content when needed. "
57 | "The netImgui remote server does not expect a UI refresh every frame, we can skip some redraw. "
58 | "When a codebase does not support skipping a frame, internally we just assign a placeholder "
59 | "ImGui context and discard the result.");
60 |
61 | ImGui::NewLine();
62 | ImGui::AlignTextToFramePadding();
63 | ImGui::TextUnformatted("Frame Refresh Mode :");
64 | ImGui::SameLine(); bModeChanged |= ImGui::RadioButton("Always", reinterpret_cast(&mFrameRefreshMode), static_cast(eDrawUpdateMode::Always));
65 | ImGui::SameLine(); bModeChanged |= ImGui::RadioButton("On Demand", reinterpret_cast(&mFrameRefreshMode), static_cast(eDrawUpdateMode::OnDemand));
66 | if( bModeChanged )
67 | mFrameDrawnCount = mFrameSkippedCount = 0;
68 |
69 | ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f,0.75f,0.75f,1.f));
70 | ImGui::TextWrapped( NetImgui::IsDrawingRemote() ? "Note: The ratio of frames skipped depends on the 'Refresh Rate' configured in the Server's settings."
71 | : "Note: Frame skipping only happen when drawing for remote connection.");
72 | ImGui::PopStyleColor();
73 |
74 | ImGui::NewLine();
75 | ImGui::Text("Draw Count: %i", mFrameDrawnCount);
76 | ImGui::Text("Skip Count: %i", mFrameSkippedCount);
77 | ImGui::Text("Time Saved: %i%%", mFrameSkippedCount ? mFrameSkippedCount * 100 / (mFrameDrawnCount+mFrameSkippedCount) : 0);
78 | }
79 | ImGui::End();
80 | }
81 |
82 | //=================================================================================================
83 | // Without Frame skip support. User redraw content every frame, even when netImgui doesn't
84 | // require a new drawframe
85 | //=================================================================================================
86 | ImDrawData* SampleNewFrame::Draw_ModeAlways()
87 | {
88 | //---------------------------------------------------------------------------------------------
89 | // (1) Start a new Frame
90 | // If your codebase doesn't handle skipping drawing the menu for some frame
91 | // (either by not calling your Imgui
92 | //---------------------------------------------------------------------------------------------
93 | NetImgui::NewFrame(false);
94 |
95 | //-----------------------------------------------------------------------------------------
96 | // (2) Draw ImGui Content
97 | //-----------------------------------------------------------------------------------------
98 | Draw_Content();
99 |
100 | //---------------------------------------------------------------------------------------------
101 | // (3) Finish the frame, preparing the drawing data and...
102 | // (3a) Send the data to the netImGui server when connected
103 | //---------------------------------------------------------------------------------------------
104 | NetImgui::EndFrame();
105 | mFrameDrawnCount++;
106 |
107 | //---------------------------------------------------------------------------------------------
108 | // (4) Forward to drawing data our local renderer when not connected or
109 | // connected and wanting to mirror the remote content.
110 | //---------------------------------------------------------------------------------------------
111 | return !NetImgui::IsConnected() ? ImGui::GetDrawData() : nullptr;
112 | }
113 |
114 | //=============================================================================================
115 | // With Frame skip support
116 | // This code path handle not rendering a frame when not needed. netImgui doesn't require
117 | // redrawing every frame.
118 | //=============================================================================================
119 | ImDrawData* SampleNewFrame::Draw_ModeOnDemand()
120 | {
121 | //---------------------------------------------------------------------------------------------
122 | // (1) Start a new Frame
123 | // When 'NewFrame' returns false, we should skip drawing this frame
124 | // Note 1 : Key point is using the 'NewFrame()' return value to decide when to skip drawing
125 | // Note 2 : Instead of relying on 'NewFrame()' return value, 'IsDrawing()' can be queried
126 | // Note 3 : Frame skipping only happens when remote drawing
127 | // Note 4 : To enable this, we explicitly call NetImgui::NewFrame/EndFrame() instead of
128 | // relying on ImGui::NewFrame/Render interception by NetImgui.
129 | //---------------------------------------------------------------------------------------------
130 | if (NetImgui::NewFrame(true))
131 | {
132 | //-----------------------------------------------------------------------------------------
133 | // (2) Draw ImGui Content
134 | //-----------------------------------------------------------------------------------------
135 | Draw_Content();
136 |
137 | //---------------------------------------------------------------------------------------------
138 | // (3) Finish the frame, preparing the drawing data and...
139 | // (3a) Send the data to the netImGui server when connected
140 | //---------------------------------------------------------------------------------------------
141 | NetImgui::EndFrame();
142 |
143 | //---------------------------------------------------------------------------------------------
144 | // (4) Forward to drawing data our local renderer when not connected or
145 | // connected and wanting to mirror the remote content.
146 | //---------------------------------------------------------------------------------------------
147 | mFrameDrawnCount++;
148 | return !NetImgui::IsConnected() ? ImGui::GetDrawData() : nullptr;
149 | }
150 |
151 | mFrameSkippedCount++;
152 | return nullptr;
153 | }
154 |
155 |
156 | //=================================================================================================
157 | // Function used by the sample, to draw all ImGui Content
158 | //=================================================================================================
159 | ImDrawData* SampleNewFrame::Draw()
160 | {
161 | switch( mFrameRefreshMode )
162 | {
163 | case eDrawUpdateMode::Always: return Draw_ModeAlways();
164 | case eDrawUpdateMode::OnDemand: return Draw_ModeOnDemand();
165 | }
166 | return nullptr;
167 | }
168 |
169 |
--------------------------------------------------------------------------------
/Code/Sample/SampleNoBackend/SampleNoBackend.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // SAMPLE NO BACKEND
3 | //-------------------------------------------------------------------------------------------------
4 | // Demonstration of using Dear ImGui without any Backend support.
5 | // This way, user can use DearImgui without any code needed for drawing / input management,
6 | // since it is all handled by the NetImgui remote server instead. Useful when this code
7 | // is running on hardward without any display and/or convenient input.
8 | //
9 | // Because we are not using any Backend code, this Sample is a little bit different from
10 | // the others. All of its code is included in this file (except for Dear ImGui sources)
11 | // and does not rely on some shared sample source file.
12 | //
13 | // This sample compile both 'Dear Imgui' and 'NetImgui' sources directly
14 | // (not using their project version in the solution)
15 | //
16 | // NOTE: This sample is also use in backward compatibility test with older Dear ImGui versions,
17 | // making it easier to compile Dear Imgui without any OS specific code (Backends)
18 | //
19 | // NOTE: This is also an excellent example of own little is needed to add NetImgui support
20 | // to a project. It doesn't handle Font DPI regeneration, keeping things simple.
21 | //=================================================================================================
22 |
23 | #include
24 |
25 | // By defining 'NETIMGUI_IMPLEMENTATION' before '#include ', you can tell the
26 | // library to pull all source files needed to compile NetImgui here.
27 | //
28 | // It should only be done in 1 source file (to avoid duplicate symbol at link time).
29 | //
30 | // Other location can still include 'NetImgui_Api.h', but without using the define
31 | //
32 | // Note: Another (more conventional) way of compiling 'NetImgui' with your code,
33 | // is to includes its sources file directly in your project. This single header include
34 | // approach was added for potential convenience, minimizing changes to a project, but
35 | // can prevent code change detection in these included files, when compiling.
36 | #define NETIMGUI_IMPLEMENTATION
37 | #include
38 |
39 | #include
40 |
41 | namespace SampleNoBackend
42 | {
43 |
44 | enum eSampleState : uint8_t {
45 | Start,
46 | Disconnected,
47 | Connected,
48 | };
49 |
50 | //=================================================================================================
51 | // Initialize the Dear Imgui Context and the NetImgui library
52 | //=================================================================================================
53 | bool Client_Startup()
54 | {
55 | IMGUI_CHECKVERSION();
56 | ImGui::CreateContext();
57 | ImGuiIO& io = ImGui::GetIO();
58 | io.Fonts->AddFontDefault();
59 | io.Fonts->Build();
60 | io.Fonts->SetTexID(0);
61 | io.DisplaySize = ImVec2(8,8);
62 | io.BackendFlags |= ImGuiBackendFlags_HasGamepad; // Enable NetImgui Gamepad support
63 | ImGui::StyleColorsDark();
64 |
65 | if( !NetImgui::Startup() )
66 | return false;
67 |
68 | return true;
69 | }
70 |
71 | //=================================================================================================
72 | // Release resources
73 | //=================================================================================================
74 | void Client_Shutdown()
75 | {
76 | NetImgui::Shutdown();
77 | ImGui::DestroyContext(ImGui::GetCurrentContext());
78 | }
79 |
80 | //=================================================================================================
81 | // Manage connection to NetImguiServer
82 | //=================================================================================================
83 | void Client_Connect(eSampleState& sampleState)
84 | {
85 | constexpr char zClientName[] = "SampleNoBackend (ImGui " IMGUI_VERSION ")";
86 | if( sampleState == eSampleState::Start )
87 | {
88 | printf("- Connecting to NetImguiServer to (127.0.0.1:%i)... ", NetImgui::kDefaultServerPort);
89 | NetImgui::ConnectToApp(zClientName, "localhost");
90 | while( NetImgui::IsConnectionPending() );
91 | bool bSuccess = NetImgui::IsConnected();
92 | sampleState = bSuccess ? eSampleState::Connected : eSampleState::Disconnected;
93 | printf(bSuccess ? "Success\n" : "Failed\n");
94 | if (!bSuccess) {
95 | printf("- Waiting for a connection from NetImguiServer on port %i... ", NetImgui::kDefaultClientPort);
96 | NetImgui::ConnectFromApp(zClientName);
97 |
98 | }
99 | }
100 | else if (sampleState == eSampleState::Disconnected && NetImgui::IsConnected())
101 | {
102 | sampleState = eSampleState::Connected;
103 | printf("CONNECTED\n");
104 | }
105 | else if (sampleState == eSampleState::Connected && !NetImgui::IsConnected())
106 | {
107 | sampleState = eSampleState::Disconnected;
108 | printf("DISCONNECTED\n");
109 | printf("- Waiting for a connection from NetImguiServer on port %i... ", NetImgui::kDefaultClientPort);
110 | NetImgui::ConnectFromApp(zClientName);
111 | }
112 | }
113 |
114 | //=================================================================================================
115 | // Render all of our Dear ImGui Content (when appropriate)
116 | //=================================================================================================
117 | void Client_Draw(bool& bQuit)
118 | {
119 | if( NetImgui::IsConnected() && NetImgui::NewFrame(true) ){
120 |
121 | ImGui::ShowDemoWindow();
122 |
123 | ImGui::SetNextWindowPos(ImVec2(32,48), ImGuiCond_Once);
124 | ImGui::SetNextWindowSize(ImVec2(400,400), ImGuiCond_Once);
125 | if( ImGui::Begin("Sample No Backend", nullptr) )
126 | {
127 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Client:");
128 | ImGui::TextUnformatted(" DearImgui Version: " IMGUI_VERSION);
129 | ImGui::TextUnformatted(" NetImgui Version: " NETIMGUI_VERSION);
130 | ImGui::TextUnformatted(""); ImGui::SameLine();
131 | bQuit = ImGui::Button(" Quit ");
132 | if( ImGui::IsItemHovered() )
133 | ImGui::SetTooltip("Terminate this sample.");
134 | ImGui::NewLine();
135 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Description:");
136 | ImGui::TextWrapped( "This sample demonstate the ability to use Dear ImGui without any Backend. "
137 | "Rely instead on NetImgui to remotely handle drawing and inputs. This avoids the need for rendering/input/window management code on the client itself.");
138 | }
139 | ImGui::End();
140 |
141 | NetImgui::EndFrame();
142 | }
143 | }
144 |
145 | } // namespace SampleNoBackend
146 |
147 | int main(int, char**)
148 | {
149 | printf("================================================================================\n");
150 | printf(" NetImgui Sample: No Backend\n");
151 | printf("================================================================================\n");
152 | printf(" Demonstrate 'Dear ImGui' + 'NetImgui' for a UI displayed on a remote server.\n");
153 | printf(" Dear ImGui : " IMGUI_VERSION "\n");
154 | printf(" NetImgui : " NETIMGUI_VERSION "\n");
155 | printf(" ['Ctrl + C' to quit]\n");
156 | printf("--------------------------------------------------------------------------------\n");
157 | if ( !SampleNoBackend::Client_Startup() ) {
158 | printf("Failed initializing NetImgui.");
159 | SampleNoBackend::Client_Shutdown();
160 | return -1;
161 | }
162 |
163 | // Main loop
164 | bool bQuit = false;
165 | SampleNoBackend::eSampleState sampleState = SampleNoBackend::eSampleState::Start;
166 | while (!bQuit)
167 | {
168 | // Avoids high CPU/GPU usage by releasing this thread until enough time has passed
169 | static auto sLastTime = std::chrono::steady_clock::now();
170 | std::chrono::duration elapsedSec = std::chrono::steady_clock::now() - sLastTime;
171 | if( elapsedSec.count() < 1.f/120.f ){
172 | std::this_thread::sleep_for(std::chrono::microseconds(250));
173 | continue;
174 | }
175 | sLastTime = std::chrono::steady_clock::now();
176 |
177 | // Sample Update
178 | SampleNoBackend::Client_Connect(sampleState);
179 | SampleNoBackend::Client_Draw(bQuit);
180 | }
181 |
182 | // Cleanup
183 | SampleNoBackend::Client_Shutdown();
184 | return 0;
185 | }
186 |
--------------------------------------------------------------------------------
/Code/Sample/SampleSingleInclude/SampleSingleInclude.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // SAMPLE Single Include
3 | //-------------------------------------------------------------------------------------------------
4 | // Identical to 'SampleBasic' except for how the NetImgui code is integrated to the project.
5 | //
6 | // Other samples use the 'NetImgui_Api.h' and link against a pre compiled 'NetImgui' library.
7 | //
8 | // By defining 'NETIMGUI_IMPLEMENTATION' before '#include ', you can tell the
9 | // library to pull all source files needed to compile NetImgui here.
10 | //
11 | // It should only be done in 1 source file (to avoid duplicate symbol at link time).
12 | //
13 | // Other location can still include 'NetImgui_Api.h', but without using the define
14 | //
15 | // Note: Another (more conventional) way of compiling 'NetImgui' with your code,
16 | // is to includes its sources file directly in your project. This single header include
17 | // approach was added for potential convenience, minimizing changes to a project, but
18 | // can prevent code change detection in these included files, when compiling.
19 | //=================================================================================================
20 | #define NETIMGUI_IMPLEMENTATION
21 | #include
22 | #include "../Common/Sample.h"
23 |
24 | //=================================================================================================
25 | // SAMPLE CLASS
26 | //=================================================================================================
27 | class SampleSingleInclude : public Sample::Base
28 | {
29 | public:
30 | SampleSingleInclude() : Base("SampleSingleInclude") {}
31 | virtual ImDrawData* Draw() override;
32 | };
33 |
34 | //=================================================================================================
35 | // GET SAMPLE
36 | // Each project must return a valid sample object
37 | //=================================================================================================
38 | Sample::Base& GetSample()
39 | {
40 | static SampleSingleInclude sample;
41 | return sample;
42 | }
43 |
44 | //=================================================================================================
45 | // Function used by the sample, to draw all ImGui Content
46 | //=================================================================================================
47 | ImDrawData* SampleSingleInclude::Draw()
48 | {
49 | //---------------------------------------------------------------------------------------------
50 | // (1) Start a new Frame.
51 | //---------------------------------------------------------------------------------------------
52 | ImGui::NewFrame();
53 |
54 | //-----------------------------------------------------------------------------------------
55 | // (2) Draw ImGui Content
56 | //-----------------------------------------------------------------------------------------
57 | Base::Draw_Connect(); //Note: Connection to remote server done in there
58 |
59 | ImGui::SetNextWindowPos(ImVec2(32,48), ImGuiCond_Once);
60 | ImGui::SetNextWindowSize(ImVec2(600,500), ImGuiCond_Once);
61 | if( ImGui::Begin("Sample Single Include", nullptr) )
62 | {
63 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Basic demonstration of NetImgui code integration.");
64 | ImGui::TextWrapped("Create a basic Window with some text.");
65 | ImGui::NewLine();
66 | ImGui::TextWrapped("Identical to SampleBasic, the only difference is how the client code was included in the project.");
67 | ImGui::NewLine();
68 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Where are we drawing: ");
69 | ImGui::SameLine();
70 | ImGui::TextUnformatted(NetImgui::IsDrawingRemote() ? "Remote Draw" : "Local Draw");
71 | ImGui::NewLine();
72 | ImGui::TextColored(ImVec4(0.1, 1, 0.1, 1), "Filler content");
73 | ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
74 | }
75 | ImGui::End();
76 |
77 | //---------------------------------------------------------------------------------------------
78 | // (3) Finish the frame
79 | //---------------------------------------------------------------------------------------------
80 | ImGui::Render();
81 |
82 | //---------------------------------------------------------------------------------------------
83 | // (4) Return content to draw by local renderer. Stop drawing locally when remote connected
84 | //---------------------------------------------------------------------------------------------
85 | return !NetImgui::IsConnected() ? ImGui::GetDrawData() : nullptr;
86 | }
87 |
--------------------------------------------------------------------------------
/Code/ServerApp/Background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ServerApp/Background.png
--------------------------------------------------------------------------------
/Code/ServerApp/Source/Custom/NetImguiServer_App_Custom.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // This file is meant to be edited by Library user, to add extra functionalities to
3 | // the NetImguiServer application. It allows to isolate custom user code without interferring
4 | // with NetImgui code updates.
5 | //
6 | // For now, it is used to handle user defined custom texture formats.
7 | //=================================================================================================
8 |
9 | #include "NetImguiServer_App.h"
10 | #include "NetImguiServer_RemoteClient.h"
11 |
12 | // Enable handling of a Custom Texture Format samples.
13 | // Only meant as an example, users are free to replace it with their own handling of
14 | // custom texture formats. Look for this define for implementation details.
15 | #define TEXTURE_CUSTOM_SAMPLE 1
16 |
17 | #if TEXTURE_CUSTOM_SAMPLE
18 |
19 | //=================================================================================================
20 | // This is our Custom texture data format, it must match when the NetImgui Client code send
21 | // It can be customized to anything needed, as long as Client/Server use the same content
22 | // For this sample, we rely on the struct size and a starting stamp to identify the custom data
23 | struct customTextureData1{
24 | static constexpr uint64_t kStamp = 0x0123456789000001;
25 | uint64_t m_Stamp = kStamp;
26 | uint32_t m_ColorStart = 0;
27 | uint32_t m_ColorEnd = 0;
28 | };
29 |
30 | struct customTextureData2{
31 | static constexpr uint64_t kStamp = 0x0123456789000002;
32 | uint64_t m_Stamp = kStamp;
33 | uint64_t m_TimeUS = 0;
34 | };
35 | //=================================================================================================
36 | #endif
37 |
38 | namespace NetImguiServer { namespace App
39 | {
40 |
41 | //=================================================================================================
42 | // This contains a sample of letting User create their own texture format, handling it on both
43 | // the NetImgui Client and the NetImgui Server side
44 | //
45 | // User are entirely free to manage custom texture content as they wish as long as it generates
46 | // a valid 'ServerTexture.mpHAL_Texture' GPU texture object for the Imgui Backend
47 | //
48 | // Sample was kept simple by reusing HAL_CreateTexture / HAL_DestroyTexture when updating
49 | // the texture, but User is free to create valid texture without these functions
50 | //
51 | //-------------------------------------------------------------------------------------------------
52 | // Return true if the command was handled
53 | //=================================================================================================
54 | bool CreateTexture_Custom( ServerTexture& serverTexture, const NetImgui::Internal::CmdTexture& cmdTexture, uint32_t customDataSize )
55 | {
56 | IM_UNUSED(serverTexture);
57 | IM_UNUSED(cmdTexture);
58 | IM_UNUSED(customDataSize);
59 | #if TEXTURE_CUSTOM_SAMPLE
60 | auto eTexFmt = static_cast(cmdTexture.mFormat);
61 | if( eTexFmt == NetImgui::eTexFormat::kTexFmtCustom ){
62 |
63 | // Process Custom Texture Type 1
64 | // This sample custom texture interpolate between 2 colors over the x axis
65 | const customTextureData1* pCustomData1 = reinterpret_cast(cmdTexture.mpTextureData.Get());
66 | if( customDataSize == sizeof(customTextureData1) && pCustomData1->m_Stamp == customTextureData1::kStamp )
67 | {
68 | ImColor colorStart = pCustomData1->m_ColorStart;
69 | ImColor colorEnd = pCustomData1->m_ColorEnd;
70 | uint32_t* pTempData = static_cast(malloc((size_t)cmdTexture.mWidth*(size_t)cmdTexture.mHeight*sizeof(uint32_t)));
71 | for(uint32_t x=0; pTempData && x(x) / static_cast(cmdTexture.mWidth);
73 | ImColor colorCurrent = ImColor( colorStart.Value.x * ratio + colorEnd.Value.x * (1.f - ratio),
74 | colorStart.Value.y * ratio + colorEnd.Value.y * (1.f - ratio),
75 | colorStart.Value.z * ratio + colorEnd.Value.z * (1.f - ratio),
76 | colorStart.Value.w * ratio + colorEnd.Value.w * (1.f - ratio));
77 | for(uint32_t y=0; y(pTempData), serverTexture);
82 | free(pTempData);
83 |
84 | // Assign a custom texture information to the Server Texture
85 | // Here, it's just a stamp, but could be some user specific data, like allocated memory for extra info
86 | serverTexture.mCustomData = customTextureData1::kStamp;
87 | return true;
88 | }
89 |
90 | // Process Custom Texture Type 2
91 | // This sample custom texture display a moving sin wave
92 | const customTextureData2* pCustomData2 = reinterpret_cast(cmdTexture.mpTextureData.Get());
93 | if( customDataSize == sizeof(customTextureData2) && pCustomData2->m_Stamp == customTextureData2::kStamp )
94 | {
95 | uint32_t* pTempData = static_cast(malloc((size_t)cmdTexture.mWidth*(size_t)cmdTexture.mHeight*sizeof(uint32_t)));
96 | for(uint32_t x=0; pTempData && x(x) / static_cast(cmdTexture.mWidth);
100 | uint64_t timeRatio = pCustomData2->m_TimeUS % kLoopTimeUS;
101 | float sinRatio = (static_cast(timeRatio) / static_cast(kLoopTimeUS) + ratioX) * 3.1415f * 2.0f;
102 | float sinVal = static_cast(sin(sinRatio));
103 | for(uint32_t y=0; y(y) / static_cast(cmdTexture.mHeight) * 2.f - 1.f;
105 | float dist = sinVal - ratioY;
106 | float r = dist > 0.f ? 1.f - dist/2.f : 0.f;
107 | float b = dist < 0.f ? 1.f + dist/2.f : 0.f;
108 | ImColor colorCurrent = ImColor(r, 0.f, b, 1.f);
109 | pTempData[y*static_cast(cmdTexture.mWidth)+x] = (ImU32)colorCurrent;
110 | }
111 | }
112 | NetImguiServer::App::HAL_CreateTexture(cmdTexture.mWidth, cmdTexture.mHeight, NetImgui::eTexFormat::kTexFmtRGBA8, reinterpret_cast(pTempData), serverTexture);
113 | free(pTempData);
114 | // Assign a custom texture information to the Server Texture
115 | // Here, it's just a stamp, but could be some user specific data, like allocated memory for extra info
116 | serverTexture.mCustomData = customTextureData2::kStamp;
117 | return true;
118 | }
119 | }
120 | #endif
121 | return false;
122 | }
123 |
124 | //=================================================================================================
125 | // Return true if the command was handled
126 | bool DestroyTexture_Custom( ServerTexture& serverTexture, const NetImgui::Internal::CmdTexture& cmdTexture, uint32_t customDataSize )
127 | //=================================================================================================
128 | {
129 | IM_UNUSED(serverTexture);
130 | IM_UNUSED(cmdTexture);
131 | IM_UNUSED(customDataSize);
132 |
133 | #if TEXTURE_CUSTOM_SAMPLE
134 | if( serverTexture.mpHAL_Texture && serverTexture.mFormat == NetImgui::eTexFormat::kTexFmtCustom ){
135 | if( serverTexture.mCustomData == customTextureData1::kStamp ||
136 | serverTexture.mCustomData == customTextureData2::kStamp )
137 | {
138 | // Could decide to only update the texture instead of recreating it
139 | // But this sample just delete it (like default behavior)
140 | if ( serverTexture.mFormat == cmdTexture.mFormat &&
141 | serverTexture.mSize[0] == cmdTexture.mWidth &&
142 | serverTexture.mSize[1] == cmdTexture.mHeight )
143 | {
144 | NetImguiServer::App::EnqueueHALTextureDestroy(serverTexture);
145 | return true;
146 | }
147 | // Texture format changed or requested to be deleted
148 | else
149 | {
150 | NetImguiServer::App::EnqueueHALTextureDestroy(serverTexture);
151 | return true;
152 | }
153 | }
154 | }
155 | #endif
156 | return false;
157 | }
158 |
159 | } } //namespace NetImguiServer { namespace App
160 |
--------------------------------------------------------------------------------
/Code/ServerApp/Source/GlfwGL3/NetImguiServer_HAL_GL3.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // Source file handling renderer specific commands needed by NetImgui server.
3 | // It complement the rendering backend with a few more functionalities.
4 | //
5 | // @note: Thank you to github user A3Wypiok, for a lot of the OpenGL found in this file
6 | //=================================================================================================
7 | #include "NetImguiServer_App.h"
8 |
9 | #if HAL_API_PLATFORM_GLFW_GL3
10 |
11 | #include "NetImguiServer_RemoteClient.h"
12 | #include
13 | #include
14 |
15 | namespace NetImguiServer { namespace App
16 | {
17 | //=================================================================================================
18 | // HAL RENDER DRAW DATA
19 | // The drawing of remote clients is handled normally by the standard rendering backend,
20 | // but output is redirected to an allocated client texture instead default swapchain
21 | //=================================================================================================
22 | void HAL_RenderDrawData(RemoteClient::Client& client, ImDrawData* pDrawData)
23 | {
24 | if( client.mpHAL_AreaRT )
25 | {
26 | glBindFramebuffer(GL_FRAMEBUFFER, static_cast(reinterpret_cast(client.mpHAL_AreaRT)));
27 | glClearColor(client.mBGSettings.mClearColor[0], client.mBGSettings.mClearColor[1], client.mBGSettings.mClearColor[2], client.mBGSettings.mClearColor[3]);
28 | glClear(GL_COLOR_BUFFER_BIT);
29 | {
30 | void* mainBackend = ImGui::GetIO().BackendRendererUserData;
31 | NetImgui::Internal::ScopedImguiContext scopedCtx(client.mpBGContext);
32 | ImGui::GetIO().BackendRendererUserData = mainBackend; // Re-appropriate the existing renderer backend, for this client rendeering
33 | ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
34 | }
35 | if (pDrawData)
36 | {
37 | ImGui_ImplOpenGL3_RenderDrawData(pDrawData);
38 | }
39 | glBindFramebuffer(GL_FRAMEBUFFER, 0);
40 | }
41 | }
42 |
43 | //=================================================================================================
44 | // HAL CREATE RENDER TARGET
45 | // Allocate RenderTargetView / TextureView for each connected remote client.
46 | // The drawing of their menu content will be outputed in it, then displayed normally
47 | // inside our own 'NetImGui application' Imgui drawing
48 | //=================================================================================================
49 | bool HAL_CreateRenderTarget(uint16_t Width, uint16_t Height, void*& pOutRT, void*& pOutTexture)
50 | {
51 | HAL_DestroyRenderTarget(pOutRT, pOutTexture);
52 |
53 | GLuint pTextureView = 0u;
54 | glGenTextures(1, &pTextureView);
55 | glBindTexture(GL_TEXTURE_2D, pTextureView);
56 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
57 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
58 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
59 |
60 | GLuint pRenderTargetView = 0u;
61 | glGenFramebuffers(1, &pRenderTargetView);
62 | glBindFramebuffer(GL_FRAMEBUFFER, pRenderTargetView);
63 |
64 | //Attach 2D texture to this FBO
65 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pTextureView, 0);
66 |
67 | GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
68 | bool bSuccess = status == GL_FRAMEBUFFER_COMPLETE;
69 |
70 | // Unbind resources
71 | glBindTexture(GL_TEXTURE_2D, 0);
72 | glBindFramebuffer(GL_FRAMEBUFFER, 0);
73 |
74 | if( bSuccess ){
75 | pOutRT = reinterpret_cast(static_cast(pRenderTargetView));
76 | pOutTexture = reinterpret_cast(static_cast(pTextureView));
77 | return true;
78 | }
79 | return false;
80 | }
81 |
82 | //=================================================================================================
83 | // HAL DESTROY RENDER TARGET
84 | // Free up allocated resources tried to a RenderTarget
85 | //=================================================================================================
86 | void HAL_DestroyRenderTarget(void*& pOutRT, void*& pOutTexture)
87 | {
88 | if(pOutRT)
89 | {
90 | GLuint pRT = static_cast(reinterpret_cast(pOutRT));
91 | pOutRT = nullptr;
92 | glDeleteFramebuffers(1, &pRT);
93 | }
94 | if(pOutTexture)
95 | {
96 | GLuint pTexture = static_cast(reinterpret_cast(pOutTexture));
97 | pOutTexture = nullptr;
98 | glDeleteTextures(1, &pTexture);
99 | }
100 | }
101 |
102 | //=================================================================================================
103 | // HAL CREATE TEXTURE
104 | // Receive info on a Texture to allocate. At the moment, 'Dear ImGui' default rendering backend
105 | // only support RGBA8 format, so first convert any input format to a RGBA8 that we can use
106 | //=================================================================================================
107 | bool HAL_CreateTexture(uint16_t Width, uint16_t Height, NetImgui::eTexFormat Format, const uint8_t* pPixelData, ServerTexture& OutTexture)
108 | {
109 | NetImguiServer::App::EnqueueHALTextureDestroy(OutTexture);
110 |
111 | // Convert all incoming textures data to RGBA8
112 | uint32_t* pPixelDataAlloc = NetImgui::Internal::netImguiSizedNew(Width*Height*4);
113 | if(Format == NetImgui::eTexFormat::kTexFmtA8)
114 | {
115 | for (int i = 0; i < Width * Height; ++i){
116 | pPixelDataAlloc[i] = 0x00FFFFFF | (static_cast(pPixelData[i])<<24);
117 | }
118 | pPixelData = reinterpret_cast(pPixelDataAlloc);
119 | }
120 | else if (Format == NetImgui::eTexFormat::kTexFmtRGBA8)
121 | {
122 | }
123 | else
124 | {
125 | // Unsupported format
126 | return false;
127 | }
128 |
129 | GLint last_texture;
130 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); // Save state
131 |
132 | // Create new texture
133 | GLuint texture = 0u;
134 | glGenTextures(1, &texture);
135 |
136 | //GLenum error = glGetError(); (void)error;
137 | if( texture != 0 ){
138 | glBindTexture(GL_TEXTURE_2D, texture);
139 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
140 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
141 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixelData);
142 | OutTexture.mpHAL_Texture = reinterpret_cast(static_cast(texture));
143 | glBindTexture(GL_TEXTURE_2D, last_texture); // Restore state
144 | }
145 | NetImgui::Internal::netImguiDeleteSafe(pPixelDataAlloc);
146 | return texture != 0;
147 | }
148 |
149 | //=================================================================================================
150 | // HAL DESTROY TEXTURE
151 | // Free up allocated resources tried to a Texture
152 | //=================================================================================================
153 | void HAL_DestroyTexture(ServerTexture& OutTexture)
154 | {
155 | GLuint pTexture = static_cast(reinterpret_cast(OutTexture.mpHAL_Texture));
156 | glDeleteTextures(1, &pTexture);
157 | memset(&OutTexture, 0, sizeof(OutTexture));
158 | }
159 |
160 | }} //namespace NetImguiServer { namespace App
161 |
162 | #endif // HAL_API_PLATFORM_GLFW_GL3
163 |
--------------------------------------------------------------------------------
/Code/ServerApp/Source/GlfwGL3/NetImguiServer_HAL_Glfw.cpp:
--------------------------------------------------------------------------------
1 | #include "NetImguiServer_App.h"
2 |
3 | #if HAL_API_PLATFORM_GLFW_GL3
4 |
5 | #include
6 |
7 | //=================================================================================================
8 | // WINDOWS GLFW
9 | // Note: This file currently only has support for Windows application
10 | #ifdef _WIN32
11 | extern int main(int, char**);
12 | #ifndef WIN32_LEAN_AND_MEAN
13 | #define WIN32_LEAN_AND_MEAN
14 | #endif
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include "../resource.h"
22 |
23 | // WIN MAIN
24 | // Main window method expected as as Win32 Application.
25 | // Original 'main' method used by Dear ImGui sample is intended for a console Application, so we
26 | // need to provided expected entry point and manually call main.
27 | int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
28 | {
29 | IM_UNUSED(hInstance);
30 | IM_UNUSED(hPrevInstance);
31 | IM_UNUSED(lpCmdLine);
32 | IM_UNUSED(nCmdShow);
33 | return main(0, nullptr);
34 | }
35 | #endif // _WIN32
36 | //=================================================================================================
37 |
38 |
39 | namespace NetImguiServer { namespace App
40 | {
41 |
42 | //=================================================================================================
43 | // HAL STARTUP
44 | // Additional initialisation that are platform specific
45 | //=================================================================================================
46 | bool HAL_Startup(const char* CmdLine)
47 | {
48 | IM_UNUSED(CmdLine);
49 |
50 | #ifdef _WIN32
51 | // Change the icon for hwnd's window class.
52 | HICON appIconBig = LoadIcon(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_NETIMGUIAPP));
53 | HICON appIconSmall = LoadIcon(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_SMALL));
54 | ImGuiViewport* main_viewport = ImGui::GetMainViewport();
55 | HWND hwnd = reinterpret_cast(main_viewport->PlatformHandleRaw);
56 | SendMessage(hwnd, WM_SETICON, ICON_BIG, reinterpret_cast(appIconBig));
57 | SendMessage(hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast(appIconSmall));
58 | #endif
59 | return true;
60 | }
61 |
62 | //=================================================================================================
63 | // HAL SHUTDOWN
64 | // Prepare for shutdown of application, with platform specific code
65 | //=================================================================================================
66 | void HAL_Shutdown()
67 | {
68 |
69 | }
70 |
71 | //=================================================================================================
72 | // HAL GET SOCKET INFO
73 | // Take a platform specific socket (based on the NetImguiNetworkXXX.cpp implementation) and
74 | // fetch informations about the client IP connected
75 | //=================================================================================================
76 | bool HAL_GetSocketInfo(NetImgui::Internal::Network::SocketInfo* pClientSocket, char* pOutHostname, size_t HostNameLen, int& outPort)
77 | {
78 | #ifdef _WIN32
79 | sockaddr socketAdr;
80 | int sizeSocket(sizeof(sockaddr));
81 | SOCKET* pClientSocketWin = reinterpret_cast(pClientSocket);
82 | if( getsockname(*pClientSocketWin, &socketAdr, &sizeSocket) == 0 )
83 | {
84 | char zPortBuffer[32];
85 | if( getnameinfo(&socketAdr, sizeSocket, pOutHostname, static_cast(HostNameLen), zPortBuffer, sizeof(zPortBuffer), NI_NUMERICSERV) == 0 )
86 | {
87 | outPort = atoi(zPortBuffer);
88 | return true;
89 | }
90 | }
91 | #endif
92 | return false;
93 | }
94 |
95 | //=================================================================================================
96 | // HAL GET USER SETTING FOLDER
97 | // Request the directory where to the 'shared config' clients should be saved
98 | // Return 'nullptr' to disable this feature
99 | //=================================================================================================
100 | const char* HAL_GetUserSettingFolder()
101 | {
102 | #ifdef _WIN32
103 | static char sUserSettingFolder[1024]={};
104 | if(sUserSettingFolder[0] == 0)
105 | {
106 | WCHAR* UserPath;
107 | HRESULT Ret = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &UserPath);
108 | if( SUCCEEDED(Ret) ){
109 | sprintf_s(sUserSettingFolder, "%ws\\NetImgui", UserPath); // convert from wchar to char
110 | DWORD ftyp = GetFileAttributesA(sUserSettingFolder);
111 | if (ftyp != INVALID_FILE_ATTRIBUTES && (ftyp & FILE_ATTRIBUTE_DIRECTORY) ){
112 | return sUserSettingFolder;
113 | }
114 | else if (ftyp == INVALID_FILE_ATTRIBUTES && CreateDirectoryA(sUserSettingFolder, nullptr) ){
115 | return sUserSettingFolder;
116 | }
117 | }
118 | sUserSettingFolder[0] = 0;
119 | return nullptr;
120 | }
121 | return sUserSettingFolder;
122 | #else
123 | return nullptr;
124 | #endif
125 | }
126 |
127 | //=================================================================================================
128 | // HAL GET CLIPBOARD UPDATED
129 | // Detect when clipboard had a content change and we should refetch it on the Server and
130 | // forward it to the Clients
131 | //
132 | // Note: We rely on Dear ImGui for Clipboard Get/Set but want to avoid constantly reading then
133 | // converting it to a UTF8 text. If the Server platform doesn't support tracking change,
134 | // return true. If the Server platform doesn't support any clipboard, return false;
135 | //=================================================================================================
136 | bool HAL_GetClipboardUpdated()
137 | {
138 | #ifdef _WIN32
139 | static DWORD sClipboardSequence(0);
140 | DWORD clipboardSequence = GetClipboardSequenceNumber();
141 | if (sClipboardSequence != clipboardSequence){
142 | sClipboardSequence = clipboardSequence;
143 | return true;
144 | }
145 | #else
146 | // Update Clipboard content every second
147 | static std::chrono::steady_clock::time_point sLastCheck = std::chrono::steady_clock::now();
148 | std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
149 | if( (now - sLastCheck) > std::chrono::seconds(1) )
150 | {
151 | sLastCheck = now;
152 | return true;
153 | }
154 | #endif
155 | return false;
156 | }
157 |
158 | }} // namespace NetImguiServer { namespace App
159 |
160 | #endif // HAL_API_PLATFORM_WIN32DX11
--------------------------------------------------------------------------------
/Code/ServerApp/Source/NetImguiServer_App.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | //=============================================================================================
7 | // SELECT RENDERING/OS API HERE
8 | //=============================================================================================
9 | #define HAL_API_PLATFORM_WIN32_DX11 1
10 | #define HAL_API_PLATFORM_GLFW_GL3 0 // Currently only compiles in release (library include compatibility)
11 | #define HAL_API_PLATFORM_SOKOL 0
12 | #define HAL_API_RENDERTARGET_INVERT_Y (HAL_API_PLATFORM_GLFW_GL3 || HAL_API_PLATFORM_SOKOL) // Invert client render target Y axis (since OpenGL start texture UV from BottomLeft instead of DirectX TopLeft)
13 | //=============================================================================================
14 |
15 | // Forward declare
16 | namespace NetImguiServer { namespace RemoteClient { struct Client; } }
17 | namespace NetImgui { namespace Internal { struct CmdTexture; } }
18 |
19 | namespace NetImguiServer { namespace App
20 | {
21 | //=============================================================================================
22 | // Code specific to 'NetImgui Server' application and needed inside platform specific code
23 | //=============================================================================================
24 | // Additional initialisation needed by 'NetImGui Server' and not part of default ImGui sample code
25 | bool Startup(const char* CmdLine);
26 | // Prepare for shutdown of application
27 | void Shutdown();
28 | // Receive rendering request of each Remote client and output it to their own RenderTarget
29 | void UpdateRemoteContent();
30 | // Add a new remote client config to our list (to attempt connexion)
31 | bool AddTransientClientConfigFromString(const char* string);
32 | // Check for monitor DPI update and regenerate font when needed
33 | // (return true when font texture needs to be created)
34 | bool UpdateFont();
35 | // Descriptor of each textures by Server. Format always RGBA8
36 | // @sammyfreg todo: make this safer with smart pointer instead of manually deleting the HALTexture
37 | struct ServerTexture
38 | {
39 | inline bool IsValid(){ return mpHAL_Texture != nullptr; }
40 | void* mpHAL_Texture = nullptr;
41 | ServerTexture* mpDeleteNext = nullptr; // Used to insert in a list of textures to be deleted next frame
42 | uint64_t mImguiId = 0u; // Associated ImGui TextureId in Imgui commandlist
43 | uint64_t mCustomData = 0u; // Memory available to custom command
44 | uint16_t mSize[2] = {0,0};
45 | uint8_t mFormat = 0;
46 | uint8_t mPadding[3] = {};
47 | };
48 |
49 | //=============================================================================================
50 | // Handling of texture data
51 | //=============================================================================================
52 | bool CreateTexture(ServerTexture& serverTexture, const NetImgui::Internal::CmdTexture& cmdTexture, uint32_t customDataSize);
53 | void DestroyTexture(ServerTexture& serverTexture, const NetImgui::Internal::CmdTexture& cmdTexture, uint32_t customDataSize);
54 |
55 | // Library users can implement their own texture format (on client/server). Useful for vidoe streaming, new format, etc.
56 | bool CreateTexture_Custom(ServerTexture& serverTexture, const NetImgui::Internal::CmdTexture& cmdTexture, uint32_t customDataSize);
57 | bool DestroyTexture_Custom(ServerTexture& serverTexture, const NetImgui::Internal::CmdTexture& cmdTexture, uint32_t customDataSize);
58 |
59 | // Texture destruction is postponed until the end of the frame update to avoid rendering issues
60 | void EnqueueHALTextureDestroy(ServerTexture& serverTexture);
61 | void CompleteHALTextureDestroy();
62 |
63 | //=============================================================================================
64 | // Note (H)ardware (A)bstraction (L)ayer
65 | // When porting the 'NetImgui Server' application to other platform,
66 | // theses are the few functions needed to be supported by each specific API that
67 | // are not already supported by de 'Dear ImGui' provided backends
68 | //=============================================================================================
69 | // Additional initialisation that are platform specific
70 | bool HAL_Startup(const char* CmdLine);
71 | // Prepare for shutdown of application, with platform specific code
72 | void HAL_Shutdown();
73 | // Receive a platform specific socket, and return us with info on the connection
74 | bool HAL_GetSocketInfo(NetImgui::Internal::Network::SocketInfo* pClientSocket, char* pOutHostname, size_t HostNameLen, int& outPort);
75 | // Provide the current user setting folder (used to save the shared config file)
76 | const char* HAL_GetUserSettingFolder();
77 | // Return true when new content should be retrieved from Clipboard (avoid constantly reading/converting content)
78 | bool HAL_GetClipboardUpdated();
79 | // Receive a ImDrawData drawlist and request Dear ImGui's backend to output it into a texture
80 | void HAL_RenderDrawData(RemoteClient::Client& client, ImDrawData* pDrawData);
81 | // Allocate a texture resource
82 | bool HAL_CreateTexture(uint16_t Width, uint16_t Height, NetImgui::eTexFormat Format, const uint8_t* pPixelData, ServerTexture& OutTexture);
83 | // Free a Texture resource
84 | void HAL_DestroyTexture( ServerTexture& OutTexture );
85 | // Allocate a RenderTarget that each client will use to output their ImGui drawing into.
86 | bool HAL_CreateRenderTarget(uint16_t Width, uint16_t Height, void*& pOutRT, void*& pOutTexture );
87 | // Free a RenderTarget resource
88 | void HAL_DestroyRenderTarget(void*& pOutRT, void*& pOutTexture );
89 |
90 | }}
91 |
--------------------------------------------------------------------------------
/Code/ServerApp/Source/NetImguiServer_Config.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | namespace NetImguiServer { namespace Config
6 | {
7 |
8 | //=================================================================================================
9 | // Client Configs are used by this server to reach remote netImgui Clients.
10 | //
11 | // Note:For multihreading safety, we are always working with copies of the original data.
12 | //
13 | // Note:It is also possible for a remote netImgui client to connect to Server directly,
14 | // in which case they don't need to have an associated config.
15 | //=================================================================================================
16 | class Client
17 | {
18 | public:
19 | using RuntimeID = uint32_t;
20 | using TimeStamp = std::chrono::steady_clock::time_point;
21 | static constexpr RuntimeID kInvalidRuntimeID = static_cast(0);
22 |
23 | enum class eVersion : uint32_t {
24 | Initial = 1, // First version save file deployed
25 | Refresh = 2, // Added refresh rate support
26 | DPIScale = 3, // Added DPI scaling
27 | BlockTakeOver = 4, // Added Takeover Block
28 | _Count,
29 | _Latest = _Count-1
30 | };
31 | enum class eConfigType : uint8_t
32 | {
33 | Pending, // New config, will try saving it in the local config
34 | Local, // Config fetched from local config file, in the current working directory
35 | Local2nd, // Config fetched from a second local config file, in the current working directory. Used when 'Local' file is read only
36 | Shared, // Config fetched from the shared user folder
37 | Transient, // Config created from connection request (command line, OS pipes), cannot be saved
38 | };
39 | enum class eStatus : uint8_t
40 | {
41 | Disconnected, // No connection detected on client
42 | Connecting, // This server is connecting to client
43 | Connected, // This server is connect to client
44 | Available, // Client already taken, but this server can take over
45 | ErrorBusy, // Client already taken
46 | ErrorVer, // Server/Client network api mismatch
47 | };
48 |
49 | // Config settings
50 | char mClientName[128]; //!< Client display name
51 | char mHostName[128]; //!< Client IP or remote host address to attempt connection at
52 | uint32_t mHostPort; //!< Client Port to attempt connection at
53 | RuntimeID mRuntimeID; //!< Unique RuntimeID used to find this Config
54 | eConfigType mConfigType; //!< Type of the configuration
55 | bool mDPIScaleEnabled; //!< Enable support of Font DPI scaling requests by Server
56 | bool mBlockTakeover; //!< If another NetImguiServer is allowed to forcefully disconnect this client to connect to it
57 | bool mReadOnly; //!< Config comes from read only file, can't be modified
58 | bool mConnectAuto; //!< Try automatically connecting to client
59 |
60 | // Transient values used while running
61 | mutable bool mConnectRequest; //!< Attempt connecting to Client, after user request
62 | mutable bool mConnectForce; //!< Attempt connecting to Client, after user request, even if already connected
63 | mutable eStatus mConnectStatus; //!< Connection status of associated client
64 | mutable TimeStamp mConnectLastTime; //!< Last connection attempt time (avoid quickly retrying same client)
65 |
66 | // Access methods
67 | public:
68 | Client();
69 | Client(const Client& Copy) = default;
70 |
71 | inline bool IsReadOnly()const { return mReadOnly; };
72 | inline bool IsTransient()const { return mConfigType == eConfigType::Transient; };
73 | inline bool IsConnected()const { return mConnectStatus == eStatus::Connected; }
74 | inline bool IsConnecting()const { return mConnectStatus == eStatus::Connecting || mConnectRequest || mConnectForce; }
75 | inline bool IsConnectReady()const {
76 | bool bAvailable = mConnectStatus != eStatus::Connected && mConnectStatus != eStatus::Connecting;
77 | return bAvailable && (mConnectRequest || mConnectForce);
78 | }
79 | inline bool IsAutoConnectReady()const {
80 | bool bAvailable = mConnectStatus != eStatus::Connected && mConnectStatus != eStatus::Connecting;
81 | auto elapsedTime = std::chrono::steady_clock::now() - mConnectLastTime;
82 | int durationSec = static_cast(std::chrono::duration_cast(elapsedTime).count());
83 | bool elapseOk = durationSec > (mConnectStatus == eStatus::Disconnected ? 5 : 30);
84 | return bAvailable && mConnectAuto && elapseOk;
85 | }
86 |
87 | // Add/Edit/Remove config
88 | static void SetConfig(const Client& config); //!< Add or replace a client configuration info
89 | static void DelConfig(uint32_t configID); //!< Remove a client configuration
90 | static bool GetConfigByID(uint32_t configID, Client& outConfig); //!< Find client configuration with this id (return true if found)
91 | static bool GetConfigByIndex(uint32_t index, Client& outConfig); //!< Find client configuration at the x position
92 | static uint32_t GetConfigCount();
93 |
94 | // Set property value directly (without having to copy entire structure)
95 | static bool GetProperty_BlockTakeover(uint32_t configID);
96 | static void SetProperty_Status(uint32_t configID, eStatus Status);
97 | static void SetProperty_ConnectAuto(uint32_t configID, bool value);
98 | static void SetProperty_ConnectRequest(uint32_t configID, bool value, bool force);
99 |
100 | // Client Config list management
101 | static void SaveAll();
102 | static void LoadAll();
103 | static void Clear();
104 |
105 | protected:
106 | static void SaveConfigFile(eConfigType fileConfigType, bool writeServerSettings);
107 | static void LoadConfigFile(eConfigType fileConfigType);
108 | inline bool ShouldSave(eConfigType fileConfigType) const;
109 | };
110 |
111 | struct Server
112 | {
113 | static uint32_t sPort; //!< Port that Server should use for connection. (Note: not really a 'Client' setting, but easier to just bundle the value here for the moment)
114 | static float sRefreshFPSActive; //!< Refresh rate of active Window
115 | static float sRefreshFPSInactive; //!< Refresh rate of inactive Window
116 | static float sDPIScaleRatio; //!< Ratio of DPI scale applied to Font size (helps with high resolution monitor, default 1.0)
117 | static bool sCompressionEnable; //!< Ask the clients to compress their data before transmission
118 | };
119 |
120 | }} // namespace NetImguiServer { namespace Config
121 |
--------------------------------------------------------------------------------
/Code/ServerApp/Source/NetImguiServer_Network.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 |
4 | namespace NetImguiServer { namespace Network
5 | {
6 | // Initialize application's networking
7 | bool Startup();
8 |
9 | // Shutdown application's networking
10 | void Shutdown();
11 |
12 | // True if this application is actively waiting for clients to reach it
13 | // Note: False when unable to open listen socket (probably because port number alreay in use)
14 | bool IsWaitingForConnection();
15 |
16 | // Total amount of data sent to clients since start
17 | uint64_t GetStatsDataSent();
18 |
19 | // Total amount of data received from clients since start
20 | uint64_t GetStatsDataRcvd();
21 |
22 | }}
23 |
--------------------------------------------------------------------------------
/Code/ServerApp/Source/NetImguiServer_RemoteClient.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include "NetImguiServer_App.h"
8 |
9 | namespace NetImguiServer { namespace RemoteClient
10 | {
11 |
12 | //=================================================================================================
13 | // ImDrawData wrapper
14 | //
15 | // Allocate a single ImDrawList and assign it to itself.
16 | //
17 | // This child class leave the original ImDrawData behavior intact, but add the proper
18 | // memory freeing of the ImDrawList member.
19 | //=================================================================================================
20 | struct NetImguiImDrawData : ImDrawData
21 | {
22 | NetImguiImDrawData();
23 | ImDrawList mCommandList;
24 | };
25 |
26 | //=================================================================================================
27 | // All info needed by the server to communicate with a remote client, and render its content
28 | //=================================================================================================
29 | struct Client
30 | {
31 | static constexpr uint32_t kInvalidClient = static_cast(-1);
32 | using ExchPtrInput = NetImgui::Internal::ExchangePtr;
33 | using ExchPtrClipboard = NetImgui::Internal::ExchangePtr;
34 | using ExchPtrBackground = NetImgui::Internal::ExchangePtr;
35 | using ExchPtrImguiDraw = NetImgui::Internal::ExchangePtr;
36 | using TextureTable = std::unordered_map;
37 |
38 | Client();
39 | ~Client();
40 | Client(const Client&) = delete;
41 | Client(const Client&&) = delete;
42 | void operator=(const Client&) = delete;
43 | void Initialize();
44 | void Uninitialize();
45 | void Release();
46 | bool IsValid()const;
47 |
48 | void ReceiveTexture(NetImgui::Internal::CmdTexture*);
49 | void ReceiveDrawFrame(NetImgui::Internal::CmdDrawFrame*);
50 | NetImguiImDrawData* ConvertToImguiDrawData(const NetImgui::Internal::CmdDrawFrame* pCmdDrawFrame);
51 | NetImguiImDrawData* GetImguiDrawData(void* pEmtpyTextureHAL); // Get current active Imgui draw data
52 |
53 | void CaptureImguiInput();
54 | NetImgui::Internal::CmdInput* TakePendingInput();
55 | NetImgui::Internal::CmdClipboard* TakePendingClipboard();
56 | void ProcessPendingTextures();
57 |
58 | static bool Startup(uint32_t clientCountMax);
59 | static void Shutdown();
60 | static uint32_t GetCountMax();
61 | static uint32_t GetFreeIndex();
62 | static Client& Get(uint32_t index);
63 |
64 | void* mpHAL_AreaRT = nullptr;
65 | void* mpHAL_AreaTexture = nullptr;
66 | uint16_t mAreaRTSizeX = 0; //!< Currently allocated RenderTarget size
67 | uint16_t mAreaRTSizeY = 0; //!< Currently allocated RenderTarget size
68 | uint16_t mAreaSizeX = 0; //!< Available area size available to remote client
69 | uint16_t mAreaSizeY = 0; //!< Available area size available to remote client
70 | char mInfoName[128] = {};
71 | char mWindowID[128+16] = {};
72 | char mInfoImguiVerName[16] = {};
73 | char mInfoNetImguiVerName[16]= {};
74 | uint32_t mInfoImguiVerID = 0;
75 | uint32_t mInfoNetImguiVerID = 0;
76 | char mConnectHost[64] = {}; //!< Connected Hostname of this remote client
77 | int mConnectPort = 0; //!< Connected Port of this remote client
78 |
79 | NetImguiImDrawData* mpImguiDrawData = nullptr; //!< Current Imgui Data that this client is the owner of
80 | NetImgui::Internal::CmdDrawFrame* mpFrameDrawPrev = nullptr; //!< Last valid DrawDrame (used by com thread, to uncompress data)
81 | TextureTable mTextureTable; //!< Table of textures received and used by the client
82 | ExchPtrImguiDraw mPendingImguiDrawDataIn; //!< Pending received Imgui DrawData, waiting to be taken ownership of
83 | ExchPtrBackground mPendingBackgroundIn; //!< Background settings received and waiting to update client setting
84 | ExchPtrClipboard mPendingClipboardIn; //!< Clipboard received from Client and waiting to be processed on Server
85 | ExchPtrInput mPendingInputOut; //!< Input command waiting to be sent out to client
86 | ExchPtrClipboard mPendingClipboardOut; //!< Clipboard command waiting to be sent out to client
87 | std::vector mPendingInputChars; //!< Captured Imgui characters input waiting to be added to new InputCmd
88 | NetImgui::Internal::CmdTexture* mpPendingTextures[64] = {}; //!< Textures commands waiting to be processed in main update loop
89 | std::atomic_uint64_t mPendingTextureReadIndex;
90 | std::atomic_uint64_t mPendingTextureWriteIndex;
91 | bool mbIsVisible = false; //!< If currently shown
92 | bool mbIsActive = false; //!< Is the current active window (will receive input, only one is true at a time)
93 | bool mbIsReleased = false; //!< If released in com thread and main thread should delete resources
94 | bool mbIsConnected = false; //!< If connected to a remote client. Set to false in Unitialize, after mIsRelease is set to unload resources
95 | std::atomic_bool mbIsFree; //!< If available to use for a new connected client
96 | std::atomic_bool mbCompressionSkipOncePending; //!< When we detect invalid previous DrawFrame command, cancel compression for 1 frame, to get good data
97 | std::atomic_bool mbDisconnectPending; //!< Terminate Client/Server coms
98 | std::chrono::steady_clock::time_point mConnectedTime; //!< When the connection was established with this remote client
99 | std::chrono::steady_clock::time_point mLastUpdateTime; //!< When the client last send a content refresh request
100 | std::chrono::steady_clock::time_point mLastDrawFrame; //!< When we last receive a new drawframe commant
101 | std::chrono::steady_clock::time_point mLastIncomingComTime; //!< When we last received a valid command from client (to detect timeout)
102 | uint32_t mClientConfigID = 0; //!< ID of ClientConfig that connected (if connection came from our list of ClientConfigs)
103 | uint32_t mClientIndex = 0; //!< Entry idx into table of connected clients
104 | uint64_t mStatsDataRcvd = 0; //!< Current amount of Bytes received since connected
105 | uint64_t mStatsDataSent = 0; //!< Current amount of Bytes sent to client since connected
106 | uint64_t mStatsDataRcvdPrev = 0; //!< Last amount of Bytes received since connected
107 | uint64_t mStatsDataSentPrev = 0; //!< Last amount of Bytes sent to client since connected
108 | std::chrono::steady_clock::time_point mStatsTime; //!< Time when info was collected (with history of last x values)
109 | uint32_t mStatsRcvdBps = 0; //!< Average Bytes received per second
110 | uint32_t mStatsSentBps = 0; //!< Average Bytes sent per second
111 | float mStatsDrawElapsedMs = 0.f; //!< Average milliseconds between 2 draw requests
112 | uint32_t mStatsIndex = 0;
113 | float mMousePos[2] = {0,0};
114 | float mMouseWheelPos[2] = {0,0};
115 | ImGuiMouseCursor mMouseCursor = ImGuiMouseCursor_None; // Last mosue cursor remote client requested
116 | ImGuiContext* mpBGContext = nullptr; // Special Imgui Context used to render the background (only updated when needed)
117 | bool mBGNeedUpdate = true; // Let engine know that we should regenerate the background draw commands
118 | NetImgui::Internal::Network::SocketInfo* mpSocket = nullptr; //!< Socket used for communications
119 | NetImgui::Internal::CmdBackground mBGSettings; //!< Settings for client background drawing settings
120 | NetImgui::Internal::CmdPendingRead mCmdPendingRead; //!< Used to get info on the next incoming command from Client
121 | NetImgui::Internal::PendingCom mPendingRcv; //!< Data being currently received from Client
122 | NetImgui::Internal::PendingCom mPendingSend; //!< Data being currently sent to Client
123 | };
124 |
125 | }} // namespace NetImguiServer { namespace Client
--------------------------------------------------------------------------------
/Code/ServerApp/Source/NetImguiServer_UI.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace NetImguiServer { namespace App { struct ServerTexture; } } // Forward Declare
4 |
5 | namespace NetImguiServer { namespace UI
6 | {
7 | constexpr uint32_t kWindowDPIDefault = 96;
8 | bool Startup();
9 | void Shutdown();
10 | ImVec4 DrawImguiContent();
11 | void DrawCenteredBackground( const App::ServerTexture& Texture, const ImVec4& tint=ImVec4(1.f,1.f,1.f,1.f));
12 | float GetDisplayFPS();
13 | const App::ServerTexture& GetBackgroundTexture();
14 | void SetWindowDPI(uint32_t dpi);
15 | float GetFontDPIScale();
16 | }} //namespace NetImguiServer { namespace UI
--------------------------------------------------------------------------------
/Code/ServerApp/Source/Sokol/NetImguiServer_App_Sokol.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // @SAMPLE_EDIT
3 | // Note: This file a duplicate of 'Dear ImGui Sample' : "examples\example_glfw_opengl3\main.cpp"
4 | // With a few editions added to customize it for our NetImGui server needs.
5 | // These fews edits will be found in a few location, using the tag '@SAMPLE_EDIT'
6 | #include "NetImguiServer_App.h"
7 |
8 | #if HAL_API_PLATFORM_SOKOL
9 |
10 | #include
11 | #include
12 | #include "NetImguiServer_UI.h"
13 |
14 | #define SOKOL_IMPL
15 | #define SOKOL_NO_ENTRY
16 | #ifdef __EMSCRIPTEN__
17 | #define SOKOL_GLES3
18 | #else
19 | #define SOKOL_GLCORE33
20 | #endif
21 | #include "sokol/sokol_app.h"
22 | #include "sokol/sokol_gfx.h"
23 | #include "sokol/sokol_glue.h"
24 | #include "sokol/sokol_log.h"
25 | #include "imgui.h"
26 | #include "sokol/util/sokol_imgui.h"
27 |
28 | sg_pass_action pass_action{};
29 | ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
30 | std::string cmdArgs;
31 |
32 | void init() {
33 | sg_desc desc = {};
34 | sg_context_desc context_desc = sapp_sgcontext();
35 | context_desc.depth_format = SG_PIXELFORMAT_NONE;
36 | desc.context = context_desc;
37 | desc.logger.func = slog_func;
38 | desc.disable_validation = true;
39 | sg_setup(&desc);
40 |
41 | simgui_desc_t simgui_desc = {};
42 | simgui_desc.no_default_font = true;
43 | simgui_desc.depth_format = SG_PIXELFORMAT_NONE;
44 | simgui_setup(&simgui_desc);
45 |
46 | pass_action.colors[0].load_action = SG_LOADACTION_CLEAR;
47 |
48 | // Setup Dear ImGui context
49 | IMGUI_CHECKVERSION();
50 | ImGui::CreateContext();
51 | ImGuiIO& io = ImGui::GetIO(); (void)io;
52 | io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
53 | //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
54 | io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
55 | io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
56 | //io.ConfigViewportsNoAutoMerge = true;
57 | //io.ConfigViewportsNoTaskBarIcon = true;
58 |
59 | // Setup Dear ImGui style
60 | ImGui::StyleColorsDark();
61 | //ImGui::StyleColorsClassic();
62 |
63 | // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
64 | ImGuiStyle& style = ImGui::GetStyle();
65 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
66 | {
67 | style.WindowRounding = 0.0f;
68 | style.Colors[ImGuiCol_WindowBg].w = 1.0f;
69 | }
70 |
71 | bool ok = NetImguiServer::App::Startup(cmdArgs.c_str());
72 | IM_ASSERT(ok);
73 | (void)ok;
74 |
75 | // IMGUI Font texture init
76 | {
77 | // Build texture atlas
78 | unsigned char* pixels;
79 | int width, height;
80 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (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.
81 |
82 | sg_image_desc img_desc{};
83 | img_desc.width = width;
84 | img_desc.height = height;
85 | img_desc.label = "font-texture";
86 | img_desc.wrap_u = SG_WRAP_CLAMP_TO_EDGE;
87 | img_desc.wrap_v = SG_WRAP_CLAMP_TO_EDGE;
88 | img_desc.min_filter = SG_FILTER_LINEAR;
89 | img_desc.mag_filter = SG_FILTER_LINEAR;
90 | img_desc.data.subimage[0][0].ptr = pixels;
91 | img_desc.data.subimage[0][0].size = (width * height) * sizeof(uint32_t);
92 |
93 | sg_image img = sg_make_image(&img_desc);
94 |
95 | io.Fonts->TexID = (ImTextureID)(uintptr_t)img.id;
96 | }
97 | }
98 |
99 | void frame() {
100 | const int width = sapp_width();
101 | const int height = sapp_height();
102 |
103 | // sg_begin_default_pass(&pass_action, width, height);
104 |
105 | simgui_new_frame({ width, height, sapp_frame_duration(), sapp_dpi_scale() });
106 | NetImguiServer::App::UpdateRemoteContent(); // @SAMPLE_EDIT (Request each client to update their drawing content )
107 | clear_color = NetImguiServer::UI::DrawImguiContent();
108 | pass_action.colors[0].clear_value.r = clear_color.x;
109 | pass_action.colors[0].clear_value.g = clear_color.y;
110 | pass_action.colors[0].clear_value.b = clear_color.z;
111 | pass_action.colors[0].clear_value.a = clear_color.w;
112 |
113 | sg_begin_default_pass(&pass_action, width, height);
114 | simgui_render();
115 | sg_end_pass();
116 |
117 | sg_commit();
118 | }
119 |
120 | void cleanup() {
121 | simgui_shutdown();
122 | sg_shutdown();
123 | }
124 |
125 | void input(const sapp_event* event) {
126 | simgui_handle_event(event);
127 | }
128 |
129 | int main(int argc, const char* argv[]) {
130 | for (size_t i = 0; i < size_t(argc); ++i) {
131 | std::string arg(argv[i]);
132 | cmdArgs += arg + " ";
133 | }
134 |
135 | if (!cmdArgs.empty()) {
136 | cmdArgs.pop_back();
137 | }
138 |
139 |
140 | sapp_desc desc = {};
141 | desc.init_cb = init;
142 | desc.frame_cb = frame;
143 | desc.cleanup_cb = cleanup,
144 | desc.event_cb = input,
145 | desc.width = 1280,
146 | desc.height = 720,
147 | desc.window_title = "NetImgui Server",
148 | desc.icon.sokol_default = true,
149 | desc.logger.func = slog_func;
150 | sapp_run(desc);
151 |
152 | return EXIT_SUCCESS;
153 | }
154 |
155 | #endif // @SAMPLE_EDIT HAL_API_PLATFORM_SOKOL
156 |
--------------------------------------------------------------------------------
/Code/ServerApp/Source/Sokol/NetImguiServer_HAL_SokolApp.cpp:
--------------------------------------------------------------------------------
1 | #include "NetImguiServer_App.h"
2 |
3 | #if HAL_API_PLATFORM_SOKOL
4 | #include
5 |
6 |
7 | namespace NetImguiServer { namespace App
8 | {
9 |
10 | //=================================================================================================
11 | // HAL STARTUP
12 | // Additional initialisation that are platform specific
13 | //=================================================================================================
14 | bool HAL_Startup(const char* CmdLine)
15 | {
16 | IM_UNUSED(CmdLine);
17 | return true;
18 | }
19 |
20 | //=================================================================================================
21 | // HAL SHUTDOWN
22 | // Prepare for shutdown of application, with platform specific code
23 | //=================================================================================================
24 | void HAL_Shutdown()
25 | {
26 |
27 | }
28 |
29 | //=================================================================================================
30 | // HAL GET SOCKET INFO
31 | // Take a platform specific socket (based on the NetImguiNetworkXXX.cpp implementation) and
32 | // fetch informations about the client IP connected
33 | //=================================================================================================
34 | bool HAL_GetSocketInfo(NetImgui::Internal::Network::SocketInfo* , char* , size_t , int& )
35 | {
36 | return false;
37 | }
38 |
39 | //=================================================================================================
40 | // HAL GET USER SETTING FOLDER
41 | // Request the directory where to the 'shared config' clients should be saved
42 | // Return 'nullptr' to disable this feature
43 | //=================================================================================================
44 | const char* HAL_GetUserSettingFolder()
45 | {
46 | return nullptr;
47 | }
48 |
49 | //=================================================================================================
50 | // HAL GET CLIPBOARD UPDATED
51 | // Detect when clipboard had a content change and we should refetch it on the Server and
52 | // forward it to the Clients
53 | //
54 | // Note: We rely on Dear ImGui for Clipboard Get/Set but want to avoid constantly reading then
55 | // converting it to a UTF8 text. If the Server platform doesn't support tracking change,
56 | // return true. If the Server platform doesn't support any clipboard, return false;
57 | //=================================================================================================
58 | bool HAL_GetClipboardUpdated()
59 | {
60 | // Update Clipboard content every second
61 | static std::chrono::steady_clock::time_point sLastCheck = std::chrono::steady_clock::now();
62 | std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
63 | if( (now - sLastCheck) > std::chrono::seconds(1) )
64 | {
65 | sLastCheck = now;
66 | return true;
67 | }
68 | return false;
69 | }
70 | }} // namespace NetImguiServer { namespace App
71 |
72 | #endif // HAL_API_PLATFORM_SOKOL
--------------------------------------------------------------------------------
/Code/ServerApp/Source/Sokol/NetImguiServer_HAL_SokolGfx.cpp:
--------------------------------------------------------------------------------
1 | //=================================================================================================
2 | // Source file handling renderer specific commands needed by NetImgui server.
3 | // It complement the rendering backend with a few more functionalities.
4 | //
5 | // @note: Thank you to github user A3Wypiok, for a lot of the OpenGL found in this file
6 | //=================================================================================================
7 | #include "NetImguiServer_App.h"
8 |
9 | #if HAL_API_PLATFORM_SOKOL
10 |
11 | #include "NetImguiServer_RemoteClient.h"
12 | #include "sokol/sokol_app.h"
13 | #include "sokol/sokol_gfx.h"
14 | #include "sokol/util/sokol_imgui.h"
15 |
16 | namespace NetImguiServer { namespace App
17 | {
18 | //=================================================================================================
19 | // HAL RENDER DRAW DATA
20 | // The drawing of remote clients is handled normally by the standard rendering backend,
21 | // but output is redirected to an allocated client texture instead default swapchain
22 | //=================================================================================================
23 | void HAL_RenderDrawData(RemoteClient::Client& client, ImDrawData* pDrawData)
24 | {
25 | if (client.mpHAL_AreaRT)
26 | {
27 | sg_pass_action pass_action{};
28 | sg_pass_desc pass_desc{};
29 |
30 | pass_desc.color_attachments[0].image.id = static_cast(reinterpret_cast(client.mpHAL_AreaRT));
31 | pass_desc.depth_stencil_attachment.image.id = SG_INVALID_ID;
32 | pass_desc.label = "mpHAL_AreaRT";
33 |
34 | pass_action.colors[0].load_action = SG_LOADACTION_CLEAR;
35 | pass_action.colors[0].clear_value.r = client.mBGSettings.mClearColor[0];
36 | pass_action.colors[0].clear_value.g = client.mBGSettings.mClearColor[1];
37 | pass_action.colors[0].clear_value.b = client.mBGSettings.mClearColor[2];
38 | pass_action.colors[0].clear_value.a = client.mBGSettings.mClearColor[3];
39 |
40 | sg_pass pass = sg_make_pass(&pass_desc);
41 |
42 | sg_begin_pass(pass, &pass_action);
43 | {
44 | {
45 | void* mainBackend = ImGui::GetIO().BackendRendererUserData;
46 | NetImgui::Internal::ScopedImguiContext scopedCtx(client.mpBGContext);
47 | ImGui::GetIO().BackendRendererUserData = mainBackend; // Re-appropriate the existing renderer backend, for this client rendeering
48 | simgui_render_draw_data(ImGui::GetDrawData());
49 | }
50 | if (pDrawData)
51 | {
52 | simgui_render_draw_data(pDrawData);
53 | }
54 | }
55 | sg_end_pass();
56 |
57 | sg_destroy_pass(pass);
58 | }
59 | }
60 |
61 | //=================================================================================================
62 | // HAL CREATE RENDER TARGET
63 | // Allocate RenderTargetView / TextureView for each connected remote client.
64 | // The drawing of their menu content will be outputed in it, then displayed normally
65 | // inside our own 'NetImGui application' Imgui drawing
66 | //=================================================================================================
67 | bool HAL_CreateRenderTarget(uint16_t Width, uint16_t Height, void*& pOutRT, void*& pOutTexture)
68 | {
69 | HAL_DestroyRenderTarget(pOutRT, pOutTexture);
70 |
71 | sg_image_desc img_desc{};
72 | img_desc.render_target = true;
73 | img_desc.width = Width;
74 | img_desc.height = Height;
75 | img_desc.pixel_format = SG_PIXELFORMAT_RGBA8;
76 | img_desc.min_filter = SG_FILTER_LINEAR;
77 | img_desc.mag_filter = SG_FILTER_LINEAR;
78 |
79 | sg_image img = sg_make_image(&img_desc);
80 |
81 | bool bSuccess = img.id != SG_INVALID_ID;
82 | if( bSuccess ){
83 | pOutRT = reinterpret_cast(static_cast(img.id));
84 | pOutTexture = reinterpret_cast(static_cast(img.id));
85 | return true;
86 | }
87 |
88 | return false;
89 | }
90 |
91 | //=================================================================================================
92 | // HAL DESTROY RENDER TARGET
93 | // Free up allocated resources tried to a RenderTarget
94 | //=================================================================================================
95 | void HAL_DestroyRenderTarget(void*& pOutRT, void*& pOutTexture)
96 | {
97 | if(pOutRT)
98 | {
99 | sg_image pRT{};
100 | pRT.id = static_cast(reinterpret_cast(pOutRT));
101 | pOutRT = nullptr;
102 | sg_destroy_image(pRT);
103 | }
104 | if(pOutTexture)
105 | {
106 | sg_image pTexture{};
107 | pTexture.id = static_cast(reinterpret_cast(pOutTexture));
108 | pOutTexture = nullptr;
109 | sg_destroy_image(pTexture);
110 | }
111 | }
112 |
113 | //=================================================================================================
114 | // HAL CREATE TEXTURE
115 | // Receive info on a Texture to allocate. At the moment, 'Dear ImGui' default rendering backend
116 | // only support RGBA8 format, so first convert any input format to a RGBA8 that we can use
117 | //=================================================================================================
118 | bool HAL_CreateTexture(uint16_t Width, uint16_t Height, NetImgui::eTexFormat Format, const uint8_t* pPixelData, ServerTexture& OutTexture)
119 | {
120 | NetImguiServer::App::EnqueueHALTextureDestroy(OutTexture);
121 |
122 | // Convert all incoming textures data to RGBA8
123 | uint32_t* pPixelDataAlloc = NetImgui::Internal::netImguiSizedNew(Width*Height*4);
124 | if(Format == NetImgui::eTexFormat::kTexFmtA8)
125 | {
126 | for (int i = 0; i < Width * Height; ++i){
127 | pPixelDataAlloc[i] = 0x00FFFFFF | (static_cast(pPixelData[i])<<24);
128 | }
129 | pPixelData = reinterpret_cast(pPixelDataAlloc);
130 | }
131 | else if (Format == NetImgui::eTexFormat::kTexFmtRGBA8)
132 | {
133 | }
134 | else
135 | {
136 | // Unsupported format
137 | return false;
138 | }
139 |
140 | sg_image_desc img_desc{};
141 | img_desc.width = Width;
142 | img_desc.height = Height;
143 | img_desc.pixel_format = SG_PIXELFORMAT_RGBA8;
144 | img_desc.usage = SG_USAGE_STREAM;
145 |
146 | sg_image img = sg_make_image(&img_desc);
147 |
148 | if (img.id != SG_INVALID_ID)
149 | {
150 | sg_image_data img_data{};
151 | img_data.subimage[0][0].ptr = pPixelData;
152 | img_data.subimage[0][0].size = Width * Height * sizeof(uint32_t);
153 | sg_update_image(img, img_data);
154 |
155 | OutTexture.mSize[0] = Width;
156 | OutTexture.mSize[1] = Height;
157 | OutTexture.mpHAL_Texture = reinterpret_cast(static_cast(img.id));
158 | }
159 |
160 | NetImgui::Internal::netImguiDeleteSafe(pPixelDataAlloc);
161 | return img.id != SG_INVALID_ID;
162 | }
163 |
164 | //=================================================================================================
165 | // HAL DESTROY TEXTURE
166 | // Free up allocated resources tried to a Texture
167 | //=================================================================================================
168 | void HAL_DestroyTexture(ServerTexture& OutTexture)
169 | {
170 | if(OutTexture.mpHAL_Texture)
171 | {
172 | sg_image image{};
173 | image.id = static_cast(reinterpret_cast(OutTexture.mpHAL_Texture));
174 | sg_destroy_image(image);
175 | OutTexture.mpHAL_Texture = nullptr;
176 | }
177 | }
178 |
179 | }} //namespace NetImguiServer { namespace App
180 |
181 | #endif // HAL_API_PLATFORM_SOKOL
182 |
--------------------------------------------------------------------------------
/Code/ServerApp/Source/Sokol/sokol/sokol_glue.h:
--------------------------------------------------------------------------------
1 | #if defined(SOKOL_IMPL) && !defined(SOKOL_GLUE_IMPL)
2 | #define SOKOL_GLUE_IMPL
3 | #endif
4 | #ifndef SOKOL_GLUE_INCLUDED
5 | /*
6 | sokol_glue.h -- glue helper functions for sokol headers
7 |
8 | Project URL: https://github.com/floooh/sokol
9 |
10 | Do this:
11 | #define SOKOL_IMPL or
12 | #define SOKOL_GLUE_IMPL
13 | before you include this file in *one* C or C++ file to create the
14 | implementation.
15 |
16 | ...optionally provide the following macros to override defaults:
17 |
18 | SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
19 | SOKOL_GLUE_API_DECL - public function declaration prefix (default: extern)
20 | SOKOL_API_DECL - same as SOKOL_GLUE_API_DECL
21 | SOKOL_API_IMPL - public function implementation prefix (default: -)
22 |
23 | If sokol_glue.h is compiled as a DLL, define the following before
24 | including the declaration or implementation:
25 |
26 | SOKOL_DLL
27 |
28 | On Windows, SOKOL_DLL will define SOKOL_GLUE_API_DECL as __declspec(dllexport)
29 | or __declspec(dllimport) as needed.
30 |
31 | OVERVIEW
32 | ========
33 | The sokol core headers should not depend on each other, but sometimes
34 | it's useful to have a set of helper functions as "glue" between
35 | two or more sokol headers.
36 |
37 | This is what sokol_glue.h is for. Simply include the header after other
38 | sokol headers (both for the implementation and declaration), and
39 | depending on what headers have been included before, sokol_glue.h
40 | will make available "glue functions".
41 |
42 | PROVIDED FUNCTIONS
43 | ==================
44 |
45 | - if sokol_app.h and sokol_gfx.h is included:
46 |
47 | sg_context_desc sapp_sgcontext(void):
48 |
49 | Returns an initialized sg_context_desc function initialized
50 | by calling sokol_app.h functions.
51 |
52 | LICENSE
53 | =======
54 | zlib/libpng license
55 |
56 | Copyright (c) 2018 Andre Weissflog
57 |
58 | This software is provided 'as-is', without any express or implied warranty.
59 | In no event will the authors be held liable for any damages arising from the
60 | use of this software.
61 |
62 | Permission is granted to anyone to use this software for any purpose,
63 | including commercial applications, and to alter it and redistribute it
64 | freely, subject to the following restrictions:
65 |
66 | 1. The origin of this software must not be misrepresented; you must not
67 | claim that you wrote the original software. If you use this software in a
68 | product, an acknowledgment in the product documentation would be
69 | appreciated but is not required.
70 |
71 | 2. Altered source versions must be plainly marked as such, and must not
72 | be misrepresented as being the original software.
73 |
74 | 3. This notice may not be removed or altered from any source
75 | distribution.
76 | */
77 | #define SOKOL_GLUE_INCLUDED
78 |
79 | #if defined(SOKOL_API_DECL) && !defined(SOKOL_GLUE_API_DECL)
80 | #define SOKOL_GLUE_API_DECL SOKOL_API_DECL
81 | #endif
82 | #ifndef SOKOL_GLUE_API_DECL
83 | #if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_GLUE_IMPL)
84 | #define SOKOL_GLUE_API_DECL __declspec(dllexport)
85 | #elif defined(_WIN32) && defined(SOKOL_DLL)
86 | #define SOKOL_GLUE_API_DECL __declspec(dllimport)
87 | #else
88 | #define SOKOL_GLUE_API_DECL extern
89 | #endif
90 | #endif
91 |
92 | #ifdef __cplusplus
93 | extern "C" {
94 | #endif
95 |
96 | #if defined(SOKOL_GFX_INCLUDED) && defined(SOKOL_APP_INCLUDED)
97 | SOKOL_GLUE_API_DECL sg_context_desc sapp_sgcontext(void);
98 | #endif
99 |
100 | #ifdef __cplusplus
101 | } /* extern "C" */
102 | #endif
103 | #endif /* SOKOL_GLUE_INCLUDED */
104 |
105 | /*-- IMPLEMENTATION ----------------------------------------------------------*/
106 | #ifdef SOKOL_GLUE_IMPL
107 | #define SOKOL_GLUE_IMPL_INCLUDED (1)
108 | #include /* memset */
109 |
110 | #ifndef SOKOL_API_IMPL
111 | #define SOKOL_API_IMPL
112 | #endif
113 |
114 | #if defined(SOKOL_GFX_INCLUDED) && defined(SOKOL_APP_INCLUDED)
115 | SOKOL_API_IMPL sg_context_desc sapp_sgcontext(void) {
116 | sg_context_desc desc;
117 | memset(&desc, 0, sizeof(desc));
118 | desc.color_format = (sg_pixel_format) sapp_color_format();
119 | desc.depth_format = (sg_pixel_format) sapp_depth_format();
120 | desc.sample_count = sapp_sample_count();
121 | desc.metal.device = sapp_metal_get_device();
122 | desc.metal.renderpass_descriptor_cb = sapp_metal_get_renderpass_descriptor;
123 | desc.metal.drawable_cb = sapp_metal_get_drawable;
124 | desc.d3d11.device = sapp_d3d11_get_device();
125 | desc.d3d11.device_context = sapp_d3d11_get_device_context();
126 | desc.d3d11.render_target_view_cb = sapp_d3d11_get_render_target_view;
127 | desc.d3d11.depth_stencil_view_cb = sapp_d3d11_get_depth_stencil_view;
128 | desc.wgpu.device = sapp_wgpu_get_device();
129 | desc.wgpu.render_view_cb = sapp_wgpu_get_render_view;
130 | desc.wgpu.resolve_view_cb = sapp_wgpu_get_resolve_view;
131 | desc.wgpu.depth_stencil_view_cb = sapp_wgpu_get_depth_stencil_view;
132 | return desc;
133 | }
134 | #endif
135 |
136 | #endif /* SOKOL_GLUE_IMPL */
137 |
--------------------------------------------------------------------------------
/Code/ServerApp/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.yourcompany.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Code/ServerApp/netImguiApp.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ServerApp/netImguiApp.ico
--------------------------------------------------------------------------------
/Code/ServerApp/netImguiApp.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ServerApp/netImguiApp.rc
--------------------------------------------------------------------------------
/Code/ServerApp/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by netImguiApp.rc
4 | //
5 | #define IDC_MYICON 2
6 | #define IDD_REMOTEIMGUIAPP_DIALOG 102
7 | #define IDS_APP_TITLE 103
8 | #define IDM_ABOUT 104
9 | #define IDM_EXIT 105
10 | #define IDI_NETIMGUIAPP 107
11 | #define IDI_SMALL 108
12 | #define IDC_NETIMGUIAPP 109
13 | #define IDR_MAINFRAME 128
14 | #define IDC_SYSLINK2 1002
15 | #define IDC_COMMAND1 1004
16 | #define ID_FILE 32771
17 | #define IDC_STATIC -1
18 |
19 | // Next default values for new objects
20 | //
21 | #ifdef APSTUDIO_INVOKED
22 | #ifndef APSTUDIO_READONLY_SYMBOLS
23 | #define _APS_NO_MFC 1
24 | #define _APS_NEXT_RESOURCE_VALUE 129
25 | #define _APS_NEXT_COMMAND_VALUE 32772
26 | #define _APS_NEXT_CONTROL_VALUE 1005
27 | #define _APS_NEXT_SYMED_VALUE 110
28 | #endif
29 | #endif
30 |
--------------------------------------------------------------------------------
/Code/ServerApp/small.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ServerApp/small.ico
--------------------------------------------------------------------------------
/Code/ServerApp/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Including SDKDDKVer.h defines the highest available Windows platform.
4 |
5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7 |
8 | #include
9 |
--------------------------------------------------------------------------------
/Code/ThirdParty/DearImgui/.editorconfig:
--------------------------------------------------------------------------------
1 | # See http://editorconfig.org to read about the EditorConfig format.
2 | # - In theory automatically supported by VS2017+ and most common IDE or text editors.
3 | # - In practice VS2019-VS2022 stills don't trim trailing whitespaces correctly :(
4 | # - Suggest installing this to trim whitespaces:
5 | # GitHub https://github.com/madskristensen/TrailingWhitespace
6 | # VS2019 https://marketplace.visualstudio.com/items?itemName=MadsKristensen.TrailingWhitespaceVisualizer
7 | # VS2022 https://marketplace.visualstudio.com/items?itemName=MadsKristensen.TrailingWhitespace64
8 | # (in spite of its name doesn't only visualize but also trims)
9 | # - Alternative for older VS2010 to VS2015: https://marketplace.visualstudio.com/items?itemName=EditorConfigTeam.EditorConfig
10 |
11 | # top-most EditorConfig file
12 | root = true
13 |
14 | # Default settings:
15 | # Use 4 spaces as indentation
16 | [*]
17 | indent_style = space
18 | indent_size = 4
19 | insert_final_newline = true
20 | trim_trailing_whitespace = true
21 |
22 | [imstb_*]
23 | indent_size = 3
24 | trim_trailing_whitespace = false
25 |
26 | [Makefile]
27 | indent_style = tab
28 | indent_size = 4
29 |
--------------------------------------------------------------------------------
/Code/ThirdParty/DearImgui/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
3 | *.c text
4 | *.cpp text
5 | *.h text
6 | *.m text
7 | *.mm text
8 | *.md text
9 | *.txt text
10 | *.html text
11 | *.bat text
12 | *.frag text
13 | *.vert text
14 | *.mkb text
15 | *.icf text
16 |
17 | *.sln text eol=crlf
18 | *.vcxproj text eol=crlf
19 | *.vcxproj.filters text eol=crlf
20 | *.natvis text eol=crlf
21 |
22 | Makefile text eol=lf
23 | *.sh text eol=lf
24 | *.pbxproj text eol=lf
25 | *.storyboard text eol=lf
26 | *.plist text eol=lf
27 |
28 | *.png binary
29 | *.ttf binary
30 | *.lib binary
31 |
--------------------------------------------------------------------------------
/Code/ThirdParty/DearImgui/.gitignore:
--------------------------------------------------------------------------------
1 | ## OSX artifacts
2 | .DS_Store
3 |
4 | ## Dear ImGui artifacts
5 | imgui.ini
6 | imgui*.ini
7 |
8 | ## General build artifacts
9 | *.o
10 | *.obj
11 | *.exe
12 | examples/*/Debug/*
13 | examples/*/Release/*
14 | examples/*/x64/*
15 |
16 | ## Visual Studio artifacts
17 | .vs
18 | ipch
19 | *.opensdf
20 | *.log
21 | *.pdb
22 | *.ilk
23 | *.user
24 | *.sdf
25 | *.suo
26 | *.VC.db
27 | *.VC.VC.opendb
28 |
29 | ## Getting files created in JSON/Schemas/Catalog/ from a VS2022 update
30 | JSON/
31 |
32 | ## Commonly used CMake directories
33 | build*/
34 |
35 | ## Xcode artifacts
36 | project.xcworkspace
37 | xcuserdata
38 |
39 | ## Emscripten artifacts
40 | examples/*.o.tmp
41 | examples/*.out.js
42 | examples/*.out.wasm
43 | examples/example_glfw_opengl3/web/*
44 | examples/example_glfw_wgpu/web/*
45 | examples/example_glfw_wgpu/external/*
46 | examples/example_sdl2_opengl3/web/*
47 |
48 | ## JetBrains IDE artifacts
49 | .idea
50 | cmake-build-*
51 |
52 | ## Unix executables from our example Makefiles
53 | examples/example_glfw_metal/example_glfw_metal
54 | examples/example_glfw_opengl2/example_glfw_opengl2
55 | examples/example_glfw_opengl3/example_glfw_opengl3
56 | examples/example_glut_opengl2/example_glut_opengl2
57 | examples/example_null/example_null
58 | examples/example_sdl2_metal/example_sdl2_metal
59 | examples/example_sdl2_opengl2/example_sdl2_opengl2
60 | examples/example_sdl2_opengl3/example_sdl2_opengl3
61 | examples/example_sdl2_sdlrenderer/example_sdl2_sdlrenderer
62 |
--------------------------------------------------------------------------------
/Code/ThirdParty/DearImgui/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2024 Omar Cornut
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Code/ThirdParty/DearImgui/backends/imgui_impl_dx11.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Renderer Backend for DirectX11
2 | // This needs to be used along with a Platform Backend (e.g. Win32)
3 |
4 | // Implemented features:
5 | // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
6 | // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
7 | // [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
8 | // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
9 |
10 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
11 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
12 | // Learn about Dear ImGui:
13 | // - FAQ https://dearimgui.com/faq
14 | // - Getting Started https://dearimgui.com/getting-started
15 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
16 | // - Introduction, links and more at the top of imgui.cpp
17 |
18 | #pragma once
19 | #include "imgui.h" // IMGUI_IMPL_API
20 | #ifndef IMGUI_DISABLE
21 |
22 | struct ID3D11Device;
23 | struct ID3D11DeviceContext;
24 | struct ID3D11SamplerState;
25 |
26 | // Follow "Getting Started" link and check examples/ folder to learn about using backends!
27 | IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
28 | IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
29 | IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
30 | IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
31 |
32 | // Use if you want to reset your rendering device without losing Dear ImGui state.
33 | IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
34 | IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
35 |
36 | // [BETA] Selected render state data shared with callbacks.
37 | // This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX11_RenderDrawData() call.
38 | // (Please open an issue if you feel you need access to more data)
39 | struct ImGui_ImplDX11_RenderState
40 | {
41 | ID3D11Device* Device;
42 | ID3D11DeviceContext* DeviceContext;
43 | ID3D11SamplerState* SamplerDefault;
44 | };
45 |
46 | #endif // #ifndef IMGUI_DISABLE
47 |
--------------------------------------------------------------------------------
/Code/ThirdParty/DearImgui/backends/imgui_impl_glfw.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Platform Backend for GLFW
2 | // This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
3 | // (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
4 | // (Requires: GLFW 3.1+. Prefer GLFW 3.3+ for full feature support.)
5 |
6 | // Implemented features:
7 | // [X] Platform: Clipboard support.
8 | // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
9 | // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
10 | // [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
11 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
12 | // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
13 | // Issues:
14 | // [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
15 |
16 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
17 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
18 | // Learn about Dear ImGui:
19 | // - FAQ https://dearimgui.com/faq
20 | // - Getting Started https://dearimgui.com/getting-started
21 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
22 | // - Introduction, links and more at the top of imgui.cpp
23 |
24 | #pragma once
25 | #include "imgui.h" // IMGUI_IMPL_API
26 | #ifndef IMGUI_DISABLE
27 |
28 | struct GLFWwindow;
29 | struct GLFWmonitor;
30 |
31 | // Follow "Getting Started" link and check examples/ folder to learn about using backends!
32 | IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
33 | IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
34 | IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks);
35 | IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
36 | IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();
37 |
38 | // Emscripten related initialization phase methods (call after ImGui_ImplGlfw_InitForOpenGL)
39 | #ifdef __EMSCRIPTEN__
40 | IMGUI_IMPL_API void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow* window, const char* canvas_selector);
41 | //static inline void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector) { ImGui_ImplGlfw_InstallEmscriptenCallbacks(nullptr, canvas_selector); } } // Renamed in 1.91.0
42 | #endif
43 |
44 | // GLFW callbacks install
45 | // - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any.
46 | // - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks.
47 | IMGUI_IMPL_API void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window);
48 | IMGUI_IMPL_API void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window);
49 |
50 | // GFLW callbacks options:
51 | // - Set 'chain_for_all_windows=true' to enable chaining callbacks for all windows (including secondary viewports created by backends or by user)
52 | IMGUI_IMPL_API void ImGui_ImplGlfw_SetCallbacksChainForAllWindows(bool chain_for_all_windows);
53 |
54 | // GLFW callbacks (individual callbacks to call yourself if you didn't install callbacks)
55 | IMGUI_IMPL_API void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused); // Since 1.84
56 | IMGUI_IMPL_API void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered); // Since 1.84
57 | IMGUI_IMPL_API void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y); // Since 1.87
58 | IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
59 | IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
60 | IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
61 | IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c);
62 | IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event);
63 |
64 | // GLFW helpers
65 | IMGUI_IMPL_API void ImGui_ImplGlfw_Sleep(int milliseconds);
66 |
67 | #endif // #ifndef IMGUI_DISABLE
68 |
--------------------------------------------------------------------------------
/Code/ThirdParty/DearImgui/backends/imgui_impl_opengl3.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline
2 | // - Desktop GL: 2.x 3.x 4.x
3 | // - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
4 | // This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
5 |
6 | // Implemented features:
7 | // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
8 | // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
9 | // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
10 |
11 | // About WebGL/ES:
12 | // - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
13 | // - This is done automatically on iOS, Android and Emscripten targets.
14 | // - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
15 |
16 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
17 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
18 | // Learn about Dear ImGui:
19 | // - FAQ https://dearimgui.com/faq
20 | // - Getting Started https://dearimgui.com/getting-started
21 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
22 | // - Introduction, links and more at the top of imgui.cpp
23 |
24 | // About GLSL version:
25 | // The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string.
26 | // On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
27 | // Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
28 |
29 | #pragma once
30 | #include "imgui.h" // IMGUI_IMPL_API
31 | #ifndef IMGUI_DISABLE
32 |
33 | // Follow "Getting Started" link and check examples/ folder to learn about using backends!
34 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
35 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
36 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
37 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
38 |
39 | // (Optional) Called by Init/NewFrame/Shutdown
40 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
41 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
42 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
43 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
44 |
45 | // Configuration flags to add in your imconfig file:
46 | //#define IMGUI_IMPL_OPENGL_ES2 // Enable ES 2 (Auto-detected on Emscripten)
47 | //#define IMGUI_IMPL_OPENGL_ES3 // Enable ES 3 (Auto-detected on iOS/Android)
48 |
49 | // You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
50 | #if !defined(IMGUI_IMPL_OPENGL_ES2) \
51 | && !defined(IMGUI_IMPL_OPENGL_ES3)
52 |
53 | // Try to detect GLES on matching platforms
54 | #if defined(__APPLE__)
55 | #include
56 | #endif
57 | #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
58 | #define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
59 | #elif defined(__EMSCRIPTEN__) || defined(__amigaos4__)
60 | #define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
61 | #else
62 | // Otherwise imgui_impl_opengl3_loader.h will be used.
63 | #endif
64 |
65 | #endif
66 |
67 | #endif // #ifndef IMGUI_DISABLE
68 |
--------------------------------------------------------------------------------
/Code/ThirdParty/DearImgui/backends/imgui_impl_win32.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
3 |
4 | // Implemented features:
5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
6 | // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
7 | // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
9 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
10 | // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
11 |
12 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
13 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
14 | // Learn about Dear ImGui:
15 | // - FAQ https://dearimgui.com/faq
16 | // - Getting Started https://dearimgui.com/getting-started
17 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
18 | // - Introduction, links and more at the top of imgui.cpp
19 |
20 | #pragma once
21 | #include "imgui.h" // IMGUI_IMPL_API
22 | #ifndef IMGUI_DISABLE
23 |
24 | // Follow "Getting Started" link and check examples/ folder to learn about using backends!
25 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
26 | IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd);
27 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
28 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
29 |
30 | // Win32 message handler your application need to call.
31 | // - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper.
32 | // - You should COPY the line below into your .cpp code to forward declare the function and then you can call it.
33 | // - Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
34 |
35 | #if 0
36 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
37 | #endif
38 |
39 | // DPI-related helpers (optional)
40 | // - Use to enable DPI awareness without having to create an application manifest.
41 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
42 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
43 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
44 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
45 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness();
46 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd
47 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor
48 |
49 | // Transparency related helpers (optional) [experimental]
50 | // - Use to enable alpha compositing transparency with the desktop.
51 | // - Use together with e.g. clearing your framebuffer with zero-alpha.
52 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
53 |
54 | #endif // #ifndef IMGUI_DISABLE
55 |
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/COPYING.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2002-2006 Marcus Geelnard
2 | Copyright (c) 2006-2010 Camilla Berglund
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
15 | be appreciated but is not required.
16 |
17 | 2. Altered source versions must be plainly marked as such, and must not
18 | be misrepresented as being the original software.
19 |
20 | 3. This notice may not be removed or altered from any source
21 | distribution.
22 |
23 |
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-macos-universal/libglfw.3.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-macos-universal/libglfw.3.dylib
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-macos-universal/libglfw3.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-macos-universal/libglfw3.a
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-vc2017-64/glfw3_mt.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-vc2017-64/glfw3_mt.lib
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-vc2019-32/glfw3_mt.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-vc2019-32/glfw3_mt.lib
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-vc2019-32/glfw3_mtd.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-vc2019-32/glfw3_mtd.lib
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-vc2019-64/glfw3_mt.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-vc2019-64/glfw3_mt.lib
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-vc2019-64/glfw3_mtd.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-vc2019-64/glfw3_mtd.lib
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-vc2022-32/glfw3_mt.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-vc2022-32/glfw3_mt.lib
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-vc2022-32/glfw3_mtd.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-vc2022-32/glfw3_mtd.lib
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-vc2022-64/glfw3_mt.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-vc2022-64/glfw3_mt.lib
--------------------------------------------------------------------------------
/Code/ThirdParty/glfw/lib-vc2022-64/glfw3_mtd.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sammyfreg/netImgui/47e7bf9059a5d551521cbaff61ea6bab902f7fcb/Code/ThirdParty/glfw/lib-vc2022-64/glfw3_mtd.lib
--------------------------------------------------------------------------------
/Code/ThirdParty/quicklz.h:
--------------------------------------------------------------------------------
1 | #ifndef QLZ_HEADER
2 | #define QLZ_HEADER
3 |
4 | // Fast data compression library
5 | // Copyright (C) 2006-2011 Lasse Mikkel Reinhold
6 | // lar@quicklz.com
7 | //
8 | // QuickLZ can be used for free under the GPL 1, 2 or 3 license (where anything
9 | // released into public must be open source) or under a commercial license if such
10 | // has been acquired (see http://www.quicklz.com/order.html). The commercial license
11 | // does not cover derived or ported versions created by third parties under GPL.
12 |
13 | // You can edit following user settings. Data must be decompressed with the same
14 | // setting of QLZ_COMPRESSION_LEVEL and QLZ_STREAMING_BUFFER as it was compressed
15 | // (see manual). If QLZ_STREAMING_BUFFER > 0, scratch buffers must be initially
16 | // zeroed out (see manual). First #ifndef makes it possible to define settings from
17 | // the outside like the compiler command line.
18 |
19 | // 1.5.0 final
20 |
21 | #ifndef QLZ_COMPRESSION_LEVEL
22 |
23 | // 1 gives fastest compression speed. 3 gives fastest decompression speed and best
24 | // compression ratio.
25 | #define QLZ_COMPRESSION_LEVEL 1
26 | //#define QLZ_COMPRESSION_LEVEL 2
27 | //#define QLZ_COMPRESSION_LEVEL 3
28 |
29 | // If > 0, zero out both states prior to first call to qlz_compress() or qlz_decompress()
30 | // and decompress packets in the same order as they were compressed
31 | #define QLZ_STREAMING_BUFFER 0
32 | //#define QLZ_STREAMING_BUFFER 100000
33 | //#define QLZ_STREAMING_BUFFER 1000000
34 |
35 | // Guarantees that decompression of corrupted data cannot crash. Decreases decompression
36 | // speed 10-20%. Compression speed not affected.
37 | //#define QLZ_MEMORY_SAFE
38 | #endif
39 |
40 | #define QLZ_VERSION_MAJOR 1
41 | #define QLZ_VERSION_MINOR 5
42 | #define QLZ_VERSION_REVISION 0
43 |
44 | // Using size_t, memset() and memcpy()
45 | #include
46 |
47 | // Verify compression level
48 | #if QLZ_COMPRESSION_LEVEL != 1 && QLZ_COMPRESSION_LEVEL != 2 && QLZ_COMPRESSION_LEVEL != 3
49 | #error QLZ_COMPRESSION_LEVEL must be 1, 2 or 3
50 | #endif
51 |
52 | typedef unsigned int ui32;
53 | typedef unsigned short int ui16;
54 |
55 | // Decrease QLZ_POINTERS for level 3 to increase compression speed. Do not touch any other values!
56 | #if QLZ_COMPRESSION_LEVEL == 1
57 | #define QLZ_POINTERS 1
58 | #define QLZ_HASH_VALUES 4096
59 | #elif QLZ_COMPRESSION_LEVEL == 2
60 | #define QLZ_POINTERS 4
61 | #define QLZ_HASH_VALUES 2048
62 | #elif QLZ_COMPRESSION_LEVEL == 3
63 | #define QLZ_POINTERS 16
64 | #define QLZ_HASH_VALUES 4096
65 | #endif
66 |
67 | // Detect if pointer size is 64-bit. It's not fatal if some 64-bit target is not detected because this is only for adding an optional 64-bit optimization.
68 | #if defined _LP64 || defined __LP64__ || defined __64BIT__ || _ADDR64 || defined _WIN64 || defined __arch64__ || __WORDSIZE == 64 || (defined __sparc && defined __sparcv9) || defined __x86_64 || defined __amd64 || defined __x86_64__ || defined _M_X64 || defined _M_IA64 || defined __ia64 || defined __IA64__
69 | #define QLZ_PTR_64
70 | #endif
71 |
72 | // hash entry
73 | typedef struct
74 | {
75 | #if QLZ_COMPRESSION_LEVEL == 1
76 | ui32 cache;
77 | #if defined QLZ_PTR_64 && QLZ_STREAMING_BUFFER == 0
78 | unsigned int offset;
79 | #else
80 | const unsigned char *offset;
81 | #endif
82 | #else
83 | const unsigned char *offset[QLZ_POINTERS];
84 | #endif
85 |
86 | } qlz_hash_compress;
87 |
88 | typedef struct
89 | {
90 | #if QLZ_COMPRESSION_LEVEL == 1
91 | const unsigned char *offset;
92 | #else
93 | const unsigned char *offset[QLZ_POINTERS];
94 | #endif
95 | } qlz_hash_decompress;
96 |
97 |
98 | // states
99 | typedef struct
100 | {
101 | #if QLZ_STREAMING_BUFFER > 0
102 | unsigned char stream_buffer[QLZ_STREAMING_BUFFER];
103 | #endif
104 | size_t stream_counter;
105 | qlz_hash_compress hash[QLZ_HASH_VALUES];
106 | unsigned char hash_counter[QLZ_HASH_VALUES];
107 | } qlz_state_compress;
108 |
109 |
110 | #if QLZ_COMPRESSION_LEVEL == 1 || QLZ_COMPRESSION_LEVEL == 2
111 | typedef struct
112 | {
113 | #if QLZ_STREAMING_BUFFER > 0
114 | unsigned char stream_buffer[QLZ_STREAMING_BUFFER];
115 | #endif
116 | qlz_hash_decompress hash[QLZ_HASH_VALUES];
117 | unsigned char hash_counter[QLZ_HASH_VALUES];
118 | size_t stream_counter;
119 | } qlz_state_decompress;
120 | #elif QLZ_COMPRESSION_LEVEL == 3
121 | typedef struct
122 | {
123 | #if QLZ_STREAMING_BUFFER > 0
124 | unsigned char stream_buffer[QLZ_STREAMING_BUFFER];
125 | #endif
126 | #if QLZ_COMPRESSION_LEVEL <= 2
127 | qlz_hash_decompress hash[QLZ_HASH_VALUES];
128 | #endif
129 | size_t stream_counter;
130 | } qlz_state_decompress;
131 | #endif
132 |
133 |
134 | #if defined (__cplusplus)
135 | extern "C" {
136 | #endif
137 |
138 | // Public functions of QuickLZ
139 | size_t qlz_size_decompressed(const char *source);
140 | size_t qlz_size_compressed(const char *source);
141 | size_t qlz_compress(const void *source, char *destination, size_t size, qlz_state_compress *state);
142 | size_t qlz_decompress(const char *source, void *destination, qlz_state_decompress *state);
143 | int qlz_get_setting(int setting);
144 |
145 | #if defined (__cplusplus)
146 | }
147 | #endif
148 |
149 | #endif
150 |
151 |
--------------------------------------------------------------------------------
/GenerateProject.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | pushd %~dp0
3 |
4 | :: Detect if user has fetched previous version of DearImgui to also generate some compatibility compiling test
5 | set CompatibilityCS=@'Build/nocompatibility.sharpmake.cs'
6 | if exist "_generated\imgui\compatibility.sharpmake.cs" set CompatibilityCS=@'_generated/imgui/compatibility.sharpmake.cs'
7 |
8 | .\Build\Sharpmake\Sharpmake.Application.exe /sources(@'Build/shared.sharpmake.cs', %CompatibilityCS%, @'Build/netImgui.sharpmake.cs')
9 | popd
10 |
11 | IF "%1" == "1" GOTO end
12 | pause
13 |
14 | :end
--------------------------------------------------------------------------------
/GenerateProject.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd "$(dirname "$0")"
4 |
5 | # Detect if the compatibility.sharpmake.cs file exists, and set CompatibilityCS accordingly
6 | CompatibilityCS="Build/nocompatibility.sharpmake.cs"
7 | if [ -f "_generated/imgui/compatibility.sharpmake.cs" ]; then
8 | CompatibilityCS="_generated/imgui/compatibility.sharpmake.cs"
9 | fi
10 |
11 | ./Build/Sharpmake/Sharpmake.Application "/sources(@'Build/shared.sharpmake_mac.cs', @'$CompatibilityCS', @'Build/netImgui.sharpmake.cs') /verbose() "
12 |
13 | if [ "$1" = "1" ]; then
14 | exit 0
15 | fi
16 |
17 | read -p "Press any key to continue..."
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Sammy Fatnassi (Github: @Sammyfreg)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------