├── .gitignore ├── README.md ├── WT.sln ├── WT ├── ESP.cpp ├── ESP.h ├── MinHook │ ├── include │ │ └── MinHook.h │ └── lib │ │ └── libMinHook-x64-v140-mdd.lib ├── WT.vcxproj ├── WT.vcxproj.filters ├── coreNotGameSpecific.cpp ├── coreNotGameSpecific.h ├── d3d11hook.cpp ├── d3d11hook.h ├── d3dSpecific.cpp ├── d3dSpecific.h ├── dllmain.cpp ├── framework.h ├── imconfig.h ├── imgui.cpp ├── imgui.h ├── imgui_demo.cpp ├── imgui_draw.cpp ├── imgui_impl_dx11.cpp ├── imgui_impl_dx11.h ├── imgui_impl_win32.cpp ├── imgui_impl_win32.h ├── imgui_internal.h ├── imgui_tables.cpp ├── imgui_widgets.cpp ├── imstb_rectpack.h ├── imstb_textedit.h ├── imstb_truetype.h ├── mathStuff.h ├── offsets.h ├── rD3D11.cpp ├── rD3D11.h ├── stdafx.cpp ├── stdafx.h ├── structs.h ├── targetver.h ├── w2sAndUtils.cpp └── w2sAndUtils.h └── screenshots ├── 2021-01-23_2-52-57.png └── 2021-01-23_2-57-05.png /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Prediction marker for Arcade/Realistic/Sim Air Battle 2 | ## **EAC DETECTED**. 3 | ### Check EAC checkbox in game launcher 4 | ## *OUTDATED* 5 | 6 | Last Update: 23.01.2021 7 | 8 | War Thunder version: 3.51 9 | 10 | # How To Use 11 | 1. Compile using VS2019+; 12 | 2. Inject .dll by arbitrary injector (i.e. [GHInjector](https://guidedhacking.com/resources/guided-hacking-dll-injector.4/)); 13 | 3. Fix prediction marker scale using Num+/Num-. 14 | 15 | > To uninject use *Insert*. 16 | 17 | > Simple hide/unhide boxes/markers by *F9*. 18 | 19 | > Num+/Num- alse affect drawing distance. 20 | 21 | # How to update 22 | Update offsets in *offsets.h* file. 23 | 24 | # Screenshots 25 | Example 1 | Example 2 26 | :-------------------------:|:-------------------------: 27 | ![Alt text](screenshots//2021-01-23_2-52-57.png?raw=true "Title") | ![Alt text](screenshots//2021-01-23_2-57-05.png?raw=true "Title") 28 | 29 | 30 | # Requirements 31 | * MinHookLib (already included: *ROOT*/Libs) 32 | * DirectX SDK 33 | 34 | # Bugs 35 | * Fake boxes without players. Your client should get get info about players coordinates. I'll happen when someone of ally met an enemy. 36 | 37 | # See also 38 | * [D3D11Hook by Rebzzel](https://github.com/Rebzzel/Universal-D3D11-Hook/tree/master) 39 | * [MinHook](https://github.com/TsudaKageyu/minhook) 40 | -------------------------------------------------------------------------------- /WT.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30413.136 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WT", "WT\WT.vcxproj", "{64388E78-8323-42E0-B82B-1116AE2913F0}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {64388E78-8323-42E0-B82B-1116AE2913F0}.Debug|x64.ActiveCfg = Debug|x64 15 | {64388E78-8323-42E0-B82B-1116AE2913F0}.Debug|x64.Build.0 = Debug|x64 16 | {64388E78-8323-42E0-B82B-1116AE2913F0}.Release|x64.ActiveCfg = Release|x64 17 | {64388E78-8323-42E0-B82B-1116AE2913F0}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {83FF1685-3B5B-4325-88F7-20D3366A38A1} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /WT/ESP.cpp: -------------------------------------------------------------------------------- 1 | #include "ESP.h" 2 | #include "imgui.h" 3 | #include "imgui_internal.h" 4 | #include "offsets.h" 5 | #include "rD3D11.h" 6 | #include "mathStuff.h" 7 | 8 | #define alpha (color >> 24) & 0xff 9 | #define ImRed (color >> 16) & 0xff 10 | #define ImGreen (color >> 8) & 0xff 11 | #define ImBlue (color) & 0xff 12 | 13 | ESP esp; 14 | int rotateStringIter = 0; 15 | 16 | void RotateString(char* source, int size) { 17 | rotateStringIter++; 18 | 19 | if (rotateStringIter > 10) { 20 | rotateStringIter = 0; 21 | 22 | if (size < 3) 23 | return; 24 | char editedString[20]; 25 | 26 | char tempChar = source[size - 1]; 27 | strcpy_s(&editedString[1], size + 1, &source[0]); 28 | editedString[0] = tempChar; 29 | editedString[size] = '\0'; 30 | 31 | strcpy_s(source, 20, editedString); 32 | 33 | printf("%s\r\n", source); 34 | } 35 | } 36 | 37 | #define boxSizeDefault 4 38 | 39 | void ESP::draw3DBox(vec3 position, float* rotationMatrix, ImDrawList* draw, float distance ) { 40 | 41 | 42 | float boxSize = boxSizeDefault; 43 | /// 44 | /// bottom 45 | /// 46 | vec3 forwardDotLeftBottomForward = vec3{ boxSize, -boxSize, -boxSize }; 47 | vec3 forwardDotRightBottomForward = vec3{ boxSize, -boxSize, boxSize }; 48 | vec3 forwardDotLeftBottomBackward = vec3{ -boxSize, -boxSize, -boxSize }; 49 | vec3 forwardDotRightBottomBackward = vec3{ -boxSize, -boxSize, boxSize }; 50 | 51 | vec3 forwardDotLeftBottomForwardRotated, forwardDotRightBottomForwardRotated, forwardDotLeftBottomBackwardRotated, forwardDotRightBottomBackwardRotated; 52 | RotateDot(rotationMatrix, forwardDotLeftBottomForward, forwardDotLeftBottomForwardRotated); 53 | RotateDot(rotationMatrix, forwardDotRightBottomForward, forwardDotRightBottomForwardRotated); 54 | RotateDot(rotationMatrix, forwardDotLeftBottomBackward, forwardDotLeftBottomBackwardRotated); 55 | RotateDot(rotationMatrix, forwardDotRightBottomBackward, forwardDotRightBottomBackwardRotated); 56 | 57 | forwardDotLeftBottomForwardRotated += position; 58 | forwardDotRightBottomForwardRotated += position; 59 | forwardDotLeftBottomBackwardRotated += position; 60 | forwardDotRightBottomBackwardRotated += position; 61 | 62 | vec3 forwardDotLeftBottomForwardRotatedScreenPos, forwardDotRightBottomForwardRotatedScreenPos, forwardDotLeftBottomBackwardRotatedScreenPos, forwardDotRightBottomBackwardRotatedScreenPos; 63 | if (!DirectXWorldToScreen(forwardDotLeftBottomForwardRotated, forwardDotLeftBottomForwardRotatedScreenPos, (D3DX11Matricies*)esp.viewMatrix, esp.rect.right, esp.rect.bottom)) 64 | return; 65 | if (!DirectXWorldToScreen(forwardDotRightBottomForwardRotated, forwardDotRightBottomForwardRotatedScreenPos, (D3DX11Matricies*)esp.viewMatrix, esp.rect.right, esp.rect.bottom)) 66 | return; 67 | if (!DirectXWorldToScreen(forwardDotLeftBottomBackwardRotated, forwardDotLeftBottomBackwardRotatedScreenPos, (D3DX11Matricies*)esp.viewMatrix, esp.rect.right, esp.rect.bottom)) 68 | return; 69 | if (!DirectXWorldToScreen(forwardDotRightBottomBackwardRotated, forwardDotRightBottomBackwardRotatedScreenPos, (D3DX11Matricies*)esp.viewMatrix, esp.rect.right, esp.rect.bottom)) 70 | return; 71 | 72 | draw->AddLine(ImVec2(forwardDotLeftBottomForwardRotatedScreenPos.x, forwardDotLeftBottomForwardRotatedScreenPos.y), ImVec2(forwardDotRightBottomForwardRotatedScreenPos.x, forwardDotRightBottomForwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // prediction 73 | draw->AddLine(ImVec2(forwardDotRightBottomForwardRotatedScreenPos.x, forwardDotRightBottomForwardRotatedScreenPos.y), ImVec2(forwardDotRightBottomBackwardRotatedScreenPos.x, forwardDotRightBottomBackwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // prediction 74 | draw->AddLine(ImVec2(forwardDotRightBottomBackwardRotatedScreenPos.x, forwardDotRightBottomBackwardRotatedScreenPos.y), ImVec2(forwardDotLeftBottomBackwardRotatedScreenPos.x, forwardDotLeftBottomBackwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // prediction 75 | draw->AddLine(ImVec2(forwardDotLeftBottomBackwardRotatedScreenPos.x, forwardDotLeftBottomBackwardRotatedScreenPos.y), ImVec2(forwardDotLeftBottomForwardRotatedScreenPos.x, forwardDotLeftBottomForwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // prediction 76 | 77 | 78 | /// 79 | /// top 80 | /// 81 | vec3 forwardDotLeftTopForward = vec3{ boxSize, boxSize, -boxSize }; 82 | vec3 forwardDotRightTopForward = vec3{ boxSize, boxSize, boxSize }; 83 | vec3 forwardDotLeftTopBackward = vec3{ -boxSize, boxSize, -boxSize }; 84 | vec3 forwardDotRightTopBackward = vec3{ -boxSize, boxSize, boxSize }; 85 | 86 | vec3 forwardDotLeftTopForwardRotated, forwardDotRightTopForwardRotated, forwardDotLeftTopBackwardRotated, forwardDotRightTopBackwardRotated; 87 | RotateDot(rotationMatrix, forwardDotLeftTopForward, forwardDotLeftTopForwardRotated); 88 | RotateDot(rotationMatrix, forwardDotRightTopForward, forwardDotRightTopForwardRotated); 89 | RotateDot(rotationMatrix, forwardDotLeftTopBackward, forwardDotLeftTopBackwardRotated); 90 | RotateDot(rotationMatrix, forwardDotRightTopBackward, forwardDotRightTopBackwardRotated); 91 | 92 | forwardDotLeftTopForwardRotated += position; 93 | forwardDotRightTopForwardRotated += position; 94 | forwardDotLeftTopBackwardRotated += position; 95 | forwardDotRightTopBackwardRotated += position; 96 | 97 | 98 | vec3 forwardDotLeftTopForwardRotatedScreenPos, forwardDotRightTopForwardRotatedScreenPos, forwardDotLeftTopBackwardRotatedScreenPos, forwardDotRightTopBackwardRotatedScreenPos; 99 | if (!DirectXWorldToScreen(forwardDotLeftTopForwardRotated, forwardDotLeftTopForwardRotatedScreenPos, (D3DX11Matricies*)esp.viewMatrix, esp.rect.right, esp.rect.bottom)) 100 | return; 101 | if (!DirectXWorldToScreen(forwardDotRightTopForwardRotated, forwardDotRightTopForwardRotatedScreenPos, (D3DX11Matricies*)esp.viewMatrix, esp.rect.right, esp.rect.bottom)) 102 | return; 103 | if (!DirectXWorldToScreen(forwardDotLeftTopBackwardRotated, forwardDotLeftTopBackwardRotatedScreenPos, (D3DX11Matricies*)esp.viewMatrix, esp.rect.right, esp.rect.bottom)) 104 | return; 105 | if (!DirectXWorldToScreen(forwardDotRightTopBackwardRotated, forwardDotRightTopBackwardRotatedScreenPos, (D3DX11Matricies*)esp.viewMatrix, esp.rect.right, esp.rect.bottom)) 106 | return; 107 | 108 | draw->AddLine(ImVec2(forwardDotLeftTopForwardRotatedScreenPos.x, forwardDotLeftTopForwardRotatedScreenPos.y), ImVec2(forwardDotRightTopForwardRotatedScreenPos.x, forwardDotRightTopForwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // 109 | draw->AddLine(ImVec2(forwardDotRightTopForwardRotatedScreenPos.x, forwardDotRightTopForwardRotatedScreenPos.y), ImVec2(forwardDotRightTopBackwardRotatedScreenPos.x, forwardDotRightTopBackwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // 110 | draw->AddLine(ImVec2(forwardDotRightTopBackwardRotatedScreenPos.x, forwardDotRightTopBackwardRotatedScreenPos.y), ImVec2(forwardDotLeftTopBackwardRotatedScreenPos.x, forwardDotLeftTopBackwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // 111 | draw->AddLine(ImVec2(forwardDotLeftTopBackwardRotatedScreenPos.x, forwardDotLeftTopBackwardRotatedScreenPos.y), ImVec2(forwardDotLeftTopForwardRotatedScreenPos.x, forwardDotLeftTopForwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // 112 | 113 | /// 114 | /// concat top and bottom 115 | /// 116 | draw->AddLine(ImVec2(forwardDotLeftBottomForwardRotatedScreenPos.x, forwardDotLeftBottomForwardRotatedScreenPos.y), ImVec2(forwardDotLeftTopForwardRotatedScreenPos.x, forwardDotLeftTopForwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // 117 | draw->AddLine(ImVec2(forwardDotRightBottomForwardRotatedScreenPos.x, forwardDotRightBottomForwardRotatedScreenPos.y), ImVec2(forwardDotRightTopForwardRotatedScreenPos.x, forwardDotRightTopForwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // 118 | draw->AddLine(ImVec2(forwardDotRightBottomBackwardRotatedScreenPos.x, forwardDotRightBottomBackwardRotatedScreenPos.y), ImVec2(forwardDotRightTopBackwardRotatedScreenPos.x, forwardDotRightTopBackwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // 119 | draw->AddLine(ImVec2(forwardDotLeftBottomBackwardRotatedScreenPos.x, forwardDotLeftBottomBackwardRotatedScreenPos.y), ImVec2(forwardDotLeftTopBackwardRotatedScreenPos.x, forwardDotLeftTopBackwardRotatedScreenPos.y), IM_COL32_WHITE, 1.f); // 120 | 121 | 122 | } 123 | 124 | void ESP::update(){ 125 | 126 | strcpy_s((char*)(MC.exeBase + mainMenuLocalPlayerOffset), 20, "unknunknunkn"); 127 | 128 | if (!esp.gameInfo->isInFlightPositive || esp.gameInfo->isInFlightNegative) 129 | return; 130 | 131 | CBaseEntity* pPlayerInstance = *(CBaseEntity**)(MC.exeBase + mLocalPlayerOffset); 132 | //printf("%d\r\n", strlen(currentNickname)); 133 | //RotateString(pPlayerInstance->name, strlen(pPlayerInstance->name)); 134 | //printf("%s\r\n", currentNickname); 135 | 136 | strcpy_s(pPlayerInstance->name, 20, "unknunknunkn"); 137 | //RotateString(currentNickname, strlen(currentNickname)); 138 | //strcpy_s(pPlayerInstance->name, 20, currentNickname); 139 | 140 | // 141 | // determine mLocalPlayer 142 | // 143 | // 144 | esp.playerCount = *(int*)(MC.exeBase + playerCountOffset); 145 | esp.viewMatrix = (float*)(MC.exeBase + viewMatrixOffset); 146 | esp.instanceArray = *(uintptr_t*)(MC.exeBase + playerListOffset); 147 | //printf("%d: %d\r\n", esp.rect.left, esp.rect.bottom); 148 | 149 | for (int instanceIterator = 0; instanceIterator < playerCount; instanceIterator++) { 150 | CBaseEntity* pPlayerInstance = (CBaseEntity*)*(uintptr_t*)(instanceArray + instanceIterator * 8); 151 | 152 | //printf("[%d]: %s\n", instanceIterator, (char*) pPlayerInstance->name); 153 | if (!strncmp(pPlayerInstance->name, "unknunknunkn", 7)) { 154 | //printf("[%d] Gotten smyplayah\r\n", instanceIterator); 155 | //printf("%llx %llx\r\n", pPlayerInstance->unit, *pPlayerInstance->unit); 156 | mLocalPlayerUnit = pPlayerInstance->unit; 157 | mLocalPlayerTeamId = pPlayerInstance->teamId; 158 | //printf("tId: %d\r\n", mPlayerTeamId); 159 | *(&mLocalPlayerCoords) = *(vec3*)((char*)mLocalPlayerUnit + unitCoordsOffset); 160 | *(&mLocalPlayerVelocity) = *(vec3*)((char*)mLocalPlayerUnit + unitVelocityOffset); 161 | continue; 162 | } 163 | } 164 | 165 | return; 166 | }; 167 | 168 | void ESP::draw() { 169 | 170 | auto draw = ImGui::GetForegroundDrawList(); 171 | 172 | char textBuffer[30]; 173 | sprintf_s(textBuffer, "%s %.0f", "PredictionScaleCoeff =", esp.k); 174 | draw->AddText(ImGui::GetFont(), 16, ImVec2(30.0f, 30.f), ImColor(255, 255, 255, 255), textBuffer, 0, 0.0f, 0); 175 | 176 | if (!esp.gameInfo->isInFlightPositive || esp.gameInfo->isInFlightNegative) 177 | return; 178 | 179 | //printf("playerCount: %d\r\n", playerCount); 180 | for (int instanceIterator = 0; instanceIterator < playerCount; instanceIterator++) { 181 | CBaseEntity* pPlayerInstance = (CBaseEntity*)*(uintptr_t*)(instanceArray + instanceIterator * 8); 182 | 183 | //printf("%p\r\n", pPlayerInstance); 184 | 185 | if (pPlayerInstance->sign == entitySignature) { 186 | if (pPlayerInstance->teamId != mLocalPlayerTeamId && pPlayerInstance->state == 2 || 1) { 187 | // if enemy and IsAlive state (==2) 188 | Unit* pPlayersUnit = pPlayerInstance->unit; 189 | vec3 targetPlayerPos; 190 | vec3 targetPlayerVelocity; 191 | 192 | *(&targetPlayerPos) = (pPlayersUnit->position); 193 | *(&targetPlayerVelocity) = *(vec3*)((char*)pPlayersUnit + unitVelocityOffset); 194 | vec3 deltaPosVector = targetPlayerPos - mLocalPlayerCoords; 195 | float distanceToTarget = deltaPosVector.Length(); 196 | 197 | float projectileFlightTime = distanceToTarget / bulletMuzzleVelocity; 198 | vec3 predictionPosition = (targetPlayerVelocity * projectileFlightTime + targetPlayerPos); 199 | //float deltaZ = 4.9f * projectileFlightTime * projectileFlightTime; 200 | if (distanceToTarget < (28000.0f + 1000.0f * esp.k) ) { 201 | vec3 targetPlayerScreenPos; 202 | vec3 ScreenPosPrediction; 203 | if (DirectXWorldToScreen(targetPlayerPos, targetPlayerScreenPos, (D3DX11Matricies*)esp.viewMatrix, esp.rect.right, esp.rect.bottom)) { 204 | // if can be drawn trace, drawing trace 205 | // draw->AddLine(ImVec2(screenCenterX, screenCenterY), ImVec2(ScreenOriginPos.x, ScreenOriginPos.y), ImColor(255, 255, 255), 0.3f); // trace 206 | // 207 | float width = 25000 / distanceToTarget; 208 | //draw->AddRect(ImVec2(targetPlayerScreenPos.x - width, targetPlayerScreenPos.y - width), ImVec2(targetPlayerScreenPos.x + width, targetPlayerScreenPos.y + width), ImColor(255, 255, 255), 0, 0, 2); 209 | 210 | 211 | /// 212 | /// Rotation matrix specific 213 | /// 214 | esp.draw3DBox(targetPlayerPos, (float*)pPlayersUnit->rotationMatricies, draw, distanceToTarget); 215 | if (distanceToTarget > 4000.f) { 216 | sprintf_s(textBuffer, "%.0fk", distanceToTarget / 1000); 217 | draw->AddText(ImGui::GetFont(), 12, ImVec2(targetPlayerScreenPos.x + 5 + width, targetPlayerScreenPos.y - width - 5), ImColor(255, 0, 0, 255), textBuffer, 0, 0.0f, 0); 218 | } 219 | 220 | if (distanceToTarget < 1000.0f * esp.k) { 221 | // if enemy player near us, lets draw a prediction marker 222 | // 223 | if (DirectXWorldToScreen(predictionPosition, ScreenPosPrediction, (D3DX11Matricies*)esp.viewMatrix, esp.rect.right, esp.rect.bottom)) { 224 | float angle = deltaPosVector.calcAngle(deltaPosVector, targetPlayerVelocity); 225 | if (isnan(angle)) 226 | continue; 227 | 228 | float red; 229 | float green; 230 | if (angle <= M_PI / 2 ) { 231 | green = 1; 232 | red = 2 * angle / M_PI; 233 | } 234 | else { 235 | red = 1; 236 | green = 2 * (M_PI - angle) / M_PI; 237 | } 238 | 239 | draw->AddLine(ImVec2(targetPlayerScreenPos.x, targetPlayerScreenPos.y), ImVec2(ScreenPosPrediction.x, ScreenPosPrediction.y), ImColor(red, green, 0.0f), 1.f); // prediction 240 | /* 241 | float mLocalPlayerVelocityAbs = mLocalPlayerVelocity.Length(); 242 | float targetPlayerAbsVelocity = targetPlayerVelocity.Length(); 243 | float perpendicalarTargetPlayerVelocity = sin(M_PI - angle) * targetPlayerAbsVelocity; 244 | float parallelTargetPlayerVelocity = cos(M_PI - angle) * targetPlayerAbsVelocity; 245 | float imaginaryDistance = parallelTargetPlayerVelocity + distanceToTarget; 246 | float predictionDistance = sqrtf(imaginaryDistance * imaginaryDistance + perpendicalarTargetPlayerVelocity * perpendicalarTargetPlayerVelocity) / 750;*/ 247 | 248 | 249 | //printf("deltaVector: %f %f; targetPlayerVelocity: %f %f [angle: %f]\r\n", deltaVector.x, deltaVector.y, targetPlayerVelocity.x, targetPlayerVelocity.y, angle); 250 | //draw->AddCircleFilled(ImVec2(ScreenPosPrediction.x, ScreenPosPrediction.y), 4.0f, ImColor(230, 0, 0, 150), 12); 251 | } 252 | } 253 | 254 | } 255 | 256 | } 257 | } 258 | } 259 | else 260 | break; 261 | } 262 | return; 263 | } -------------------------------------------------------------------------------- /WT/ESP.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "structs.h" 4 | #include "w2sAndUtils.h" 5 | 6 | 7 | 8 | class ESP { 9 | private: 10 | int playerCount; 11 | CBaseEntity* playerInstance; 12 | 13 | uintptr_t instanceArray; 14 | 15 | public: 16 | GameInfo* gameInfo; 17 | uintptr_t exeBase; 18 | float* viewMatrix; 19 | RECT rect; 20 | int screenCenterX, screenCenterY; 21 | bool playingFlag = false; 22 | void update(); 23 | void draw(); 24 | void draw3DBox(vec3 position, float* rotationMatrix, ImDrawList* draw, float distance); 25 | float k = 4; // distance scale coeff 26 | int8_t mLocalPlayerTeamId = 1; 27 | Unit* mLocalPlayerUnit; 28 | vec3 mLocalPlayerCoords = { 1000, 1000, 1000 }; 29 | vec3 mLocalPlayerVelocity = { 0,0,0 }; 30 | bool drawTracers = false; 31 | }; 32 | 33 | 34 | extern ESP esp; -------------------------------------------------------------------------------- /WT/MinHook/include/MinHook.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2015 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #if !(defined _M_IX86) && !(defined _M_X64) 32 | #error MinHook supports only x86 and x64 systems. 33 | #endif 34 | 35 | #include 36 | 37 | // MinHook Error Codes. 38 | typedef enum MH_STATUS 39 | { 40 | // Unknown error. Should not be returned. 41 | MH_UNKNOWN = -1, 42 | 43 | // Successful. 44 | MH_OK = 0, 45 | 46 | // MinHook is already initialized. 47 | MH_ERROR_ALREADY_INITIALIZED, 48 | 49 | // MinHook is not initialized yet, or already uninitialized. 50 | MH_ERROR_NOT_INITIALIZED, 51 | 52 | // The hook for the specified target function is already created. 53 | MH_ERROR_ALREADY_CREATED, 54 | 55 | // The hook for the specified target function is not created yet. 56 | MH_ERROR_NOT_CREATED, 57 | 58 | // The hook for the specified target function is already enabled. 59 | MH_ERROR_ENABLED, 60 | 61 | // The hook for the specified target function is not enabled yet, or already 62 | // disabled. 63 | MH_ERROR_DISABLED, 64 | 65 | // The specified pointer is invalid. It points the address of non-allocated 66 | // and/or non-executable region. 67 | MH_ERROR_NOT_EXECUTABLE, 68 | 69 | // The specified target function cannot be hooked. 70 | MH_ERROR_UNSUPPORTED_FUNCTION, 71 | 72 | // Failed to allocate memory. 73 | MH_ERROR_MEMORY_ALLOC, 74 | 75 | // Failed to change the memory protection. 76 | MH_ERROR_MEMORY_PROTECT, 77 | 78 | // The specified module is not loaded. 79 | MH_ERROR_MODULE_NOT_FOUND, 80 | 81 | // The specified function is not found. 82 | MH_ERROR_FUNCTION_NOT_FOUND 83 | } 84 | MH_STATUS; 85 | 86 | // Can be passed as a parameter to MH_EnableHook, MH_DisableHook, 87 | // MH_QueueEnableHook or MH_QueueDisableHook. 88 | #define MH_ALL_HOOKS NULL 89 | 90 | #ifdef __cplusplus 91 | extern "C" { 92 | #endif 93 | 94 | // Initialize the MinHook library. You must call this function EXACTLY ONCE 95 | // at the beginning of your program. 96 | MH_STATUS WINAPI MH_Initialize(VOID); 97 | 98 | // Uninitialize the MinHook library. You must call this function EXACTLY 99 | // ONCE at the end of your program. 100 | MH_STATUS WINAPI MH_Uninitialize(VOID); 101 | 102 | // Creates a Hook for the specified target function, in disabled state. 103 | // Parameters: 104 | // pTarget [in] A pointer to the target function, which will be 105 | // overridden by the detour function. 106 | // pDetour [in] A pointer to the detour function, which will override 107 | // the target function. 108 | // ppOriginal [out] A pointer to the trampoline function, which will be 109 | // used to call the original target function. 110 | // This parameter can be NULL. 111 | MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); 112 | 113 | // Creates a Hook for the specified API function, in disabled state. 114 | // Parameters: 115 | // pszModule [in] A pointer to the loaded module name which contains the 116 | // target function. 117 | // pszTarget [in] A pointer to the target function name, which will be 118 | // overridden by the detour function. 119 | // pDetour [in] A pointer to the detour function, which will override 120 | // the target function. 121 | // ppOriginal [out] A pointer to the trampoline function, which will be 122 | // used to call the original target function. 123 | // This parameter can be NULL. 124 | MH_STATUS WINAPI MH_CreateHookApi( 125 | LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal); 126 | 127 | // Removes an already created hook. 128 | // Parameters: 129 | // pTarget [in] A pointer to the target function. 130 | MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); 131 | 132 | // Enables an already created hook. 133 | // Parameters: 134 | // pTarget [in] A pointer to the target function. 135 | // If this parameter is MH_ALL_HOOKS, all created hooks are 136 | // enabled in one go. 137 | MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget); 138 | 139 | // Disables an already created hook. 140 | // Parameters: 141 | // pTarget [in] A pointer to the target function. 142 | // If this parameter is MH_ALL_HOOKS, all created hooks are 143 | // disabled in one go. 144 | MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget); 145 | 146 | // Queues to enable an already created hook. 147 | // Parameters: 148 | // pTarget [in] A pointer to the target function. 149 | // If this parameter is MH_ALL_HOOKS, all created hooks are 150 | // queued to be enabled. 151 | MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget); 152 | 153 | // Queues to disable an already created hook. 154 | // Parameters: 155 | // pTarget [in] A pointer to the target function. 156 | // If this parameter is MH_ALL_HOOKS, all created hooks are 157 | // queued to be disabled. 158 | MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget); 159 | 160 | // Applies all queued changes in one go. 161 | MH_STATUS WINAPI MH_ApplyQueued(VOID); 162 | 163 | // Translates the MH_STATUS to its name as a string. 164 | const char * WINAPI MH_StatusToString(MH_STATUS status); 165 | 166 | #ifdef __cplusplus 167 | } 168 | #endif 169 | 170 | -------------------------------------------------------------------------------- /WT/MinHook/lib/libMinHook-x64-v140-mdd.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralFire/WarThunderHack/92eb7bd80b004954f75ccafc3d02efd38a891c07/WT/MinHook/lib/libMinHook-x64-v140-mdd.lib -------------------------------------------------------------------------------- /WT/WT.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 16.0 15 | Win32Proj 16 | {64388e78-8323-42e0-b82b-1116ae2913f0} 17 | WT 18 | 10.0 19 | 20 | 21 | 22 | DynamicLibrary 23 | true 24 | v142 25 | Unicode 26 | 27 | 28 | DynamicLibrary 29 | false 30 | v142 31 | true 32 | Unicode 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | true 48 | $(LibraryPath);$(ProjectDir)\MinHook\lib 49 | $(IncludePath);$(ProjectDir)MinHook\include 50 | WTD 51 | 52 | 53 | false 54 | $(ProjectDir)MinHook\lib;$(LibraryPath) 55 | $(ProjectDir)\ImGui;$(ProjectDir)MinHook\include;$(IncludePath) 56 | WT 57 | 58 | 59 | 60 | Level3 61 | true 62 | _DEBUG;WT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 63 | true 64 | NotUsing 65 | 66 | 67 | 26451 68 | 69 | 70 | Windows 71 | true 72 | false 73 | 74 | 75 | 76 | 77 | Level3 78 | true 79 | true 80 | true 81 | NDEBUG;WT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 82 | true 83 | NotUsing 84 | 85 | 86 | Full 87 | AnySuitable 88 | Speed 89 | 90 | 91 | Windows 92 | true 93 | true 94 | true 95 | false 96 | /ignore:4099 /NODEFAULTLIB:libcmt.lib %(AdditionalOptions) 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /WT/WT.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {32d5d4ed-875b-463f-9545-2b29f9453cdf} 14 | 15 | 16 | {a6c1b8a6-067e-4b7d-8e4c-351c6684d135} 17 | 18 | 19 | {7b3c9116-d843-4b90-8e65-fa9d8cd40823} 20 | 21 | 22 | {7269cba4-c5fb-4ecb-ab1c-19def7203754} 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | rD3D11 34 | 35 | 36 | w2sAndUtils 37 | 38 | 39 | Header Files 40 | 41 | 42 | ESP 43 | 44 | 45 | rD3D11 46 | 47 | 48 | ImGui 49 | 50 | 51 | ImGui 52 | 53 | 54 | ImGui 55 | 56 | 57 | ImGui 58 | 59 | 60 | ImGui 61 | 62 | 63 | ImGui 64 | 65 | 66 | ImGui 67 | 68 | 69 | 70 | 71 | rD3D11 72 | 73 | 74 | w2sAndUtils 75 | 76 | 77 | w2sAndUtils 78 | 79 | 80 | Header Files 81 | 82 | 83 | Header Files 84 | 85 | 86 | Header Files 87 | 88 | 89 | ESP 90 | 91 | 92 | ImGui 93 | 94 | 95 | ImGui 96 | 97 | 98 | ImGui 99 | 100 | 101 | ImGui 102 | 103 | 104 | ImGui 105 | 106 | 107 | ImGui 108 | 109 | 110 | ImGui 111 | 112 | 113 | Source Files 114 | 115 | 116 | Header Files 117 | 118 | 119 | -------------------------------------------------------------------------------- /WT/coreNotGameSpecific.cpp: -------------------------------------------------------------------------------- 1 | #include "coreNotGameSpecific.h" 2 | #include "stdio.h" 3 | #include "d3d11hook.h" 4 | #include "rD3D11.h" 5 | #include "ESP.h" 6 | 7 | void deattach(HMODULE dllHandle) { 8 | //printf("cleanupHook...\r\n"); 9 | //CleanupD3D(); 10 | printf("detaching...\r\n"); 11 | //HookDX11_Release(); 12 | FreeLibraryAndExitThread(dllHandle, 0); 13 | } 14 | 15 | void allocConsole() { 16 | 17 | GetClientRect(FindMainWindow(GetCurrentProcessId()), &esp.rect); 18 | esp.screenCenterX = esp.rect.right / 2; 19 | esp.screenCenterY = esp.rect.bottom / 2; 20 | FILE* f; 21 | AllocConsole(); 22 | freopen_s(&f, "CONOUT$", "w", stdout); 23 | printf("------\r\nConsoleAllocated: \r\n"); 24 | } -------------------------------------------------------------------------------- /WT/coreNotGameSpecific.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | typedef struct D3DXVECTOR3 { 6 | FLOAT x; 7 | FLOAT y; 8 | FLOAT z; 9 | } D3DXVECTOR3, * LPD3DXVECTOR3; 10 | 11 | void deattach(HMODULE dllHandle); 12 | void allocConsole(); 13 | 14 | -------------------------------------------------------------------------------- /WT/d3d11hook.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include "d3d11hook.h" 8 | #include "imgui.h" 9 | #include "imgui_impl_win32.h" 10 | #include "imgui_impl_dx11.h" 11 | #include "ESP.h" 12 | 13 | 14 | 15 | #pragma comment(lib, "d3d11.lib") 16 | 17 | // KeyBoard Options. 18 | const int OpenMenuKey = VK_F9; 19 | const int UninjectLibraryKey = VK_DELETE; 20 | 21 | 22 | typedef HRESULT(__stdcall *D3D11PresentHook) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags); 23 | typedef void(__stdcall *D3D11DrawIndexedHook) (ID3D11DeviceContext* pContext, UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation); 24 | typedef void(__stdcall *D3D11CreateQueryHook) (ID3D11Device* pDevice, const D3D11_QUERY_DESC *pQueryDesc, ID3D11Query **ppQuery); 25 | typedef void(__stdcall *D3D11PSSetShaderResourcesHook) (ID3D11DeviceContext* pContext, UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews); 26 | typedef void(__stdcall *D3D11ClearRenderTargetViewHook) (ID3D11DeviceContext* pContext, ID3D11RenderTargetView *pRenderTargetView, const FLOAT ColorRGBA[4]); 27 | 28 | static HWND g_hWnd = nullptr; 29 | static HMODULE g_hModule = nullptr; 30 | static ID3D11Device* g_pd3dDevice = nullptr; 31 | static ID3D11DeviceContext* g_pd3dContext = nullptr; 32 | static IDXGISwapChain* g_pSwapChain = nullptr; 33 | static std::once_flag g_isInitialized; 34 | 35 | D3D11PresentHook phookD3D11Present = nullptr; 36 | D3D11DrawIndexedHook phookD3D11DrawIndexed = nullptr; 37 | D3D11CreateQueryHook phookD3D11CreateQuery = nullptr; 38 | D3D11PSSetShaderResourcesHook phookD3D11PSSetShaderResources = nullptr; 39 | D3D11ClearRenderTargetViewHook phookD3D11ClearRenderTargetViewHook = nullptr; 40 | 41 | DWORD_PTR* pSwapChainVTable = nullptr; 42 | DWORD_PTR* pDeviceVTable = nullptr; 43 | DWORD_PTR* pDeviceContextVTable = nullptr; 44 | 45 | ID3D11DepthStencilState* m_DepthStencilState; 46 | BOOL g_bInitialised = false; 47 | bool g_PresentHooked = false; 48 | ID3D11RenderTargetView* mainRenderTargetView; 49 | static IDXGISwapChain* pSwapChain = NULL; 50 | static WNDPROC OriginalWndProcHandler = nullptr; 51 | HWND window = nullptr; 52 | 53 | 54 | HRESULT GetDeviceAndCtxFromSwapchain(IDXGISwapChain* pSwapChain, ID3D11Device** ppDevice, ID3D11DeviceContext** ppContext) 55 | { 56 | HRESULT ret = pSwapChain->GetDevice(__uuidof(ID3D11Device), (PVOID*)ppDevice); 57 | 58 | if (SUCCEEDED(ret)) 59 | (*ppDevice)->GetImmediateContext(ppContext); 60 | 61 | return ret; 62 | } 63 | 64 | HRESULT __stdcall PresentHook(IDXGISwapChain* pChain, UINT SyncInterval, UINT Flags) 65 | { 66 | if (!g_bInitialised) { 67 | g_PresentHooked = true; 68 | printf("[+] Present Hook called by first time\r\n"); 69 | if (FAILED(GetDeviceAndCtxFromSwapchain(pChain, &g_pd3dDevice, &g_pd3dContext))) 70 | return phookD3D11Present(pChain, SyncInterval, Flags); 71 | pSwapChain = pChain; 72 | DXGI_SWAP_CHAIN_DESC sd; 73 | pChain->GetDesc(&sd); 74 | ImGui::CreateContext(); 75 | window = sd.OutputWindow; 76 | 77 | 78 | // Disabling Z-Buffering 79 | D3D11_DEPTH_STENCIL_DESC depthStencilDesc; 80 | depthStencilDesc.DepthEnable = TRUE; 81 | depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; 82 | depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; 83 | depthStencilDesc.StencilEnable = FALSE; 84 | depthStencilDesc.StencilReadMask = 0xFF; 85 | depthStencilDesc.StencilWriteMask = 0xFF; 86 | 87 | // Stencil operations if pixel is front-facing 88 | depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; 89 | depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; 90 | depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 91 | depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; 92 | 93 | // Stencil operations if pixel is back-facing 94 | depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; 95 | depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; 96 | depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 97 | depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; 98 | 99 | 100 | g_pd3dDevice->CreateDepthStencilState(&depthStencilDesc, &m_DepthStencilState); 101 | 102 | ImGui_ImplWin32_Init(window); 103 | ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dContext); 104 | 105 | ID3D11Texture2D* pBackBuffer; 106 | 107 | pChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); 108 | g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &mainRenderTargetView); 109 | pBackBuffer->Release(); 110 | 111 | g_bInitialised = true; 112 | 113 | } 114 | 115 | ImGui_ImplWin32_NewFrame(); 116 | ImGui_ImplDX11_NewFrame(); 117 | 118 | ImGui::NewFrame(); 119 | //Menu is displayed when g_ShowMenu is TRUE 120 | esp.draw(); 121 | ImGui::EndFrame(); 122 | ImGui::Render(); 123 | 124 | g_pd3dContext->OMSetRenderTargets(1, &mainRenderTargetView, NULL); 125 | ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); 126 | 127 | return phookD3D11Present(pChain, SyncInterval, Flags); 128 | } 129 | 130 | void __stdcall DrawIndexedHook(ID3D11DeviceContext* pContext, UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation) 131 | { 132 | return phookD3D11DrawIndexed(pContext, IndexCount, StartIndexLocation, BaseVertexLocation); 133 | } 134 | 135 | void __stdcall hookD3D11CreateQuery(ID3D11Device* pDevice, const D3D11_QUERY_DESC *pQueryDesc, ID3D11Query **ppQuery) 136 | { 137 | if (pQueryDesc->Query == D3D11_QUERY_OCCLUSION) 138 | { 139 | D3D11_QUERY_DESC oqueryDesc = CD3D11_QUERY_DESC(); 140 | (&oqueryDesc)->MiscFlags = pQueryDesc->MiscFlags; 141 | (&oqueryDesc)->Query = D3D11_QUERY_TIMESTAMP; 142 | 143 | return phookD3D11CreateQuery(pDevice, &oqueryDesc, ppQuery); 144 | } 145 | 146 | return phookD3D11CreateQuery(pDevice, pQueryDesc, ppQuery); 147 | } 148 | 149 | UINT pssrStartSlot; 150 | D3D11_SHADER_RESOURCE_VIEW_DESC Descr; 151 | 152 | void __stdcall hookD3D11PSSetShaderResources(ID3D11DeviceContext* pContext, UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) 153 | { 154 | pssrStartSlot = StartSlot; 155 | 156 | for (UINT j = 0; j < NumViews; j++) 157 | { 158 | ID3D11ShaderResourceView* pShaderResView = ppShaderResourceViews[j]; 159 | if (pShaderResView) 160 | { 161 | pShaderResView->GetDesc(&Descr); 162 | 163 | if ((Descr.ViewDimension == D3D11_SRV_DIMENSION_BUFFER) || (Descr.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX)) 164 | { 165 | continue; //Skip buffer resources 166 | } 167 | } 168 | } 169 | 170 | return phookD3D11PSSetShaderResources(pContext, StartSlot, NumViews, ppShaderResourceViews); 171 | } 172 | 173 | void __stdcall ClearRenderTargetViewHook(ID3D11DeviceContext* pContext, ID3D11RenderTargetView *pRenderTargetView, const FLOAT ColorRGBA[4]) 174 | { 175 | return phookD3D11ClearRenderTargetViewHook(pContext, pRenderTargetView, ColorRGBA); 176 | } 177 | 178 | DWORD __stdcall HookDX11_Init() 179 | { 180 | printf("HookDX11_Init()\r\n"); 181 | D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 }; 182 | D3D_FEATURE_LEVEL obtainedLevel; 183 | DXGI_SWAP_CHAIN_DESC sd{ 0 }; 184 | sd.BufferCount = 1; 185 | sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 186 | sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 187 | sd.BufferDesc.Height = 800; 188 | sd.BufferDesc.Width = 600; 189 | sd.BufferDesc.RefreshRate = { 60, 1 }; 190 | sd.OutputWindow = GetForegroundWindow(); 191 | sd.Windowed = TRUE; 192 | sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 193 | sd.SampleDesc.Count = 1; 194 | sd.SampleDesc.Quality = 0; 195 | HRESULT hr = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &obtainedLevel, &g_pd3dContext); 196 | if (FAILED(hr)) { 197 | MessageBox(g_hWnd, L"Failed to create device and swapchain.", L"Fatal Error", MB_ICONERROR); 198 | return E_FAIL; 199 | } 200 | 201 | pSwapChainVTable = (DWORD_PTR*)(g_pSwapChain); 202 | pSwapChainVTable = (DWORD_PTR*)(pSwapChainVTable[0]); 203 | 204 | pDeviceVTable = (DWORD_PTR*)(g_pd3dDevice); 205 | pDeviceVTable = (DWORD_PTR*)pDeviceVTable[0]; 206 | 207 | pDeviceContextVTable = (DWORD_PTR*)(g_pd3dContext); 208 | pDeviceContextVTable = (DWORD_PTR*)(pDeviceContextVTable[0]); 209 | 210 | if (MH_Initialize() != MH_OK) { return 1; } 211 | if (MH_CreateHook((DWORD_PTR*)pSwapChainVTable[8], PresentHook, reinterpret_cast(&phookD3D11Present)) != MH_OK) { return 1; } 212 | if (MH_EnableHook((DWORD_PTR*)pSwapChainVTable[8]) != MH_OK) { return 1; } 213 | /*if (MH_CreateHook((DWORD_PTR*)pDeviceContextVTable[12], DrawIndexedHook, reinterpret_cast(&phookD3D11DrawIndexed)) != MH_OK) { return 1; } 214 | if (MH_EnableHook((DWORD_PTR*)pDeviceContextVTable[12]) != MH_OK) { return 1; } 215 | if (MH_CreateHook((DWORD_PTR*)pDeviceVTable[24], hookD3D11CreateQuery, reinterpret_cast(&phookD3D11CreateQuery)) != MH_OK) { return 1; } 216 | if (MH_EnableHook((DWORD_PTR*)pDeviceVTable[24]) != MH_OK) { return 1; } 217 | if (MH_CreateHook((DWORD_PTR*)pDeviceContextVTable[8], hookD3D11PSSetShaderResources, reinterpret_cast(&phookD3D11PSSetShaderResources)) != MH_OK) { return 1; } 218 | if (MH_EnableHook((DWORD_PTR*)pDeviceContextVTable[8]) != MH_OK) { return 1; } 219 | if (MH_CreateHook((DWORD_PTR*)pSwapChainVTable[50], ClearRenderTargetViewHook, reinterpret_cast(&phookD3D11ClearRenderTargetViewHook)) != MH_OK) { return 1; } 220 | if (MH_EnableHook((DWORD_PTR*)pSwapChainVTable[50]) != MH_OK) { return 1; }*/ 221 | 222 | DWORD old_protect; 223 | VirtualProtect(phookD3D11Present, 2, PAGE_EXECUTE_READWRITE, &old_protect); 224 | 225 | return S_OK; 226 | } 227 | 228 | void InitD3DHook(HMODULE hModule) { 229 | g_hModule = hModule; 230 | HookDX11_Init(); 231 | } 232 | 233 | D3D11_HOOK_API void mainDettach(HMODULE hModule) { 234 | 235 | printf("mainDettach()\r\n"); 236 | g_pd3dDevice->Release(); 237 | g_pd3dContext->Release(); 238 | g_pSwapChain->Release(); 239 | 240 | ImplHookDX11_Shutdown(); 241 | 242 | Beep(220, 300); 243 | 244 | Sleep(1000); 245 | printf("Calling FreseLibrary...\r\n"); 246 | FreeLibraryAndExitThread(hModule, 0); 247 | } 248 | 249 | D3D11_HOOK_API void ImplHookDX11_Init(HMODULE hModule, HWND hwnd) 250 | { 251 | 252 | g_hWnd = (HWND)hwnd; 253 | g_hModule = hModule; 254 | HookDX11_Init(); 255 | } 256 | 257 | D3D11_HOOK_API void ImplHookDX11_Shutdown() 258 | { 259 | printf("ImplHookDX11_Shutdown\r\n"); 260 | if (MH_DisableHook(MH_ALL_HOOKS)) { return; }; 261 | if (MH_Uninitialize()) { return; } 262 | } -------------------------------------------------------------------------------- /WT/d3d11hook.h: -------------------------------------------------------------------------------- 1 | /*** 2 | * _ ____ _ _ _ _ _ 3 | * __| |__ / __| / / | | |_ ___ ___| |__ 4 | * / _` ||_ \/ _` | | | | ' \/ _ \/ _ \ / / 5 | * \__,_|___/\__,_|_|_| |_||_\___/\___/_\_\ 6 | * 7 | * D3D11Hook by Rebzzel 8 | * Added ImGui + InputHook by Sh0ckFR - https://twitter.com/Sh0ckFR 9 | * For compile hook you need: 10 | * - DirectX SDK (https://www.microsoft.com/en-us/download/details.aspx?id=6812) 11 | * - Minhook (you can download in NuGet or github repository https://github.com/TsudaKageyu/minhook) 12 | * License: https://github.com/Rebzzel/Universal-D3D11-Hook#license 13 | */ 14 | 15 | 16 | #ifndef D3D11_HOOK_H_INCLUDED_ 17 | #define D3D11_HOOK_H_INCLUDED_ 18 | 19 | #define D3D11_HOOK_API 20 | 21 | struct ID3D11Device; // from d3d11.h 22 | struct ID3D11DeviceContext; // from d3d11.h 23 | struct IDXGISwapChain; // from d3d11.h 24 | 25 | // Use for rendering graphical user interfaces (for example: ImGui) or other. 26 | // Use for initialize hook. 27 | D3D11_HOOK_API void ImplHookDX11_Init(HMODULE hModule, HWND hwnd); 28 | 29 | // Use for untialize hook (ONLY AFTER INITIALIZE). 30 | D3D11_HOOK_API void ImplHookDX11_Shutdown(); 31 | 32 | D3D11_HOOK_API void mainDettach(HMODULE hmodule); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /WT/d3dSpecific.cpp: -------------------------------------------------------------------------------- 1 | #include "d3dSpecific.h" 2 | 3 | // d3d11 related object ptrs 4 | using namespace DirectX; 5 | 6 | ID3D11Device* pDevice = nullptr; 7 | IDXGISwapChain* pSwapchain = nullptr; 8 | ID3D11DeviceContext* pContext = nullptr; 9 | ID3D11RenderTargetView* pRenderTargetView = nullptr; 10 | ID3D11VertexShader* pVertexShader = nullptr; 11 | ID3D11InputLayout* pVertexLayout = nullptr; 12 | ID3D11PixelShader* pPixelShader = nullptr; 13 | ID3D11Buffer* pVertexBuffer = nullptr; 14 | ID3D11Buffer* pIndexBuffer = nullptr; 15 | ID3D11Buffer* pConstantBuffer = nullptr; 16 | 17 | // Changing this to an array of viewports 18 | #define MAINVP 0 19 | D3D11_VIEWPORT pViewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]{ 0 }; 20 | XMMATRIX mOrtho; 21 | 22 | struct ConstantBuffer { 23 | XMMATRIX mProjection; 24 | }; 25 | 26 | struct Vertex { 27 | XMFLOAT3 pos; 28 | XMFLOAT4 color; 29 | }; 30 | 31 | struct HandleData 32 | { 33 | DWORD pid; 34 | HWND hWnd; 35 | }; 36 | 37 | BOOL CALLBACK EnumWindowsCallback(HWND hWnd, LPARAM lParam) 38 | { 39 | HandleData& data = *(HandleData*)lParam; 40 | DWORD pid = 0; 41 | GetWindowThreadProcessId(hWnd, &pid); 42 | if (pid == data.pid && GetWindow(hWnd, GW_OWNER) == HWND(0) && IsWindowVisible(hWnd)) 43 | { 44 | data.hWnd = hWnd; 45 | return FALSE; 46 | } 47 | 48 | return TRUE; 49 | } 50 | 51 | HWND FindMainWindow(DWORD dwPID) 52 | { 53 | HandleData handleData{ 0 }; 54 | handleData.pid = dwPID; 55 | EnumWindows(EnumWindowsCallback, (LPARAM)&handleData); 56 | return handleData.hWnd; 57 | } 58 | 59 | bool Hook(void* pSrc, void* pDst, size_t size) { 60 | DWORD dwOld; 61 | uintptr_t src = (uintptr_t)pSrc; 62 | uintptr_t dst = (uintptr_t)pDst; 63 | 64 | if (!VirtualProtect(pSrc, size, PAGE_EXECUTE_READWRITE, &dwOld)) 65 | return false; 66 | 67 | *(char*)src = (char)0xE9; 68 | *(int*)(src + 1) = (int)(dst - src - 5); 69 | 70 | VirtualProtect(pSrc, size, dwOld, &dwOld); 71 | return true; 72 | } 73 | 74 | bool WriteMem(void* pDst, char* pBytes, size_t size) { 75 | DWORD dwOld; 76 | if (!VirtualProtect(pDst, size, PAGE_EXECUTE_READWRITE, &dwOld)) 77 | return false; 78 | 79 | memcpy(pDst, pBytes, PRESENT_STUB_SIZE); 80 | 81 | VirtualProtect(pDst, size, dwOld, &dwOld); 82 | return true; 83 | } 84 | 85 | bool CompileShader(const char* szShader, const char* szEntrypoint, const char* szTarget, ID3D10Blob** pBlob) 86 | { 87 | ID3D10Blob* pErrorBlob = nullptr; 88 | 89 | auto hr = D3DCompile(szShader, strlen(szShader), 0, nullptr, nullptr, szEntrypoint, szTarget, D3DCOMPILE_ENABLE_STRICTNESS, 0, pBlob, &pErrorBlob); 90 | if (FAILED(hr)) 91 | { 92 | if (pErrorBlob) 93 | { 94 | char szError[256]{ 0 }; 95 | memcpy(szError, pErrorBlob->GetBufferPointer(), pErrorBlob->GetBufferSize()); 96 | MessageBoxA(nullptr, szError, "Error", MB_OK); 97 | } 98 | return false; 99 | } 100 | return true; 101 | } 102 | 103 | HRESULT __stdcall hookedPresent(IDXGISwapChain* pThis, UINT SyncInterval, UINT Flags); 104 | using fnPresent = HRESULT(__stdcall*)(IDXGISwapChain* pThis, UINT SyncInterval, UINT Flags); 105 | void* originalPresentFcn; // Pointer to the original Present function 106 | fnPresent ogPresentTramp; // Function pointer that calls the Present stub in our trampoline 107 | void* pTrampoline = nullptr; // Pointer to jmp instruction in our trampoline that leads to hkPresent 108 | char originalPresentBytes[PRESENT_STUB_SIZE]; // Buffer to store original bytes from Present 109 | 110 | bool InitD3DHook(IDXGISwapChain* pSwapchain) 111 | { 112 | HRESULT hr = pSwapchain->GetDevice(__uuidof(ID3D11Device), (void**)&pDevice); 113 | if (FAILED(hr)) 114 | return false; 115 | 116 | pDevice->GetImmediateContext(&pContext); 117 | pContext->OMGetRenderTargets(1, &pRenderTargetView, nullptr); 118 | 119 | // If for some reason we fail to get a render target, create one. 120 | // This will probably never happen with a real game but maybe certain test environments... :P 121 | if (!pRenderTargetView) 122 | { 123 | // Get a pointer to the back buffer for the render target view 124 | ID3D11Texture2D* pBackbuffer = nullptr; 125 | hr = pSwapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast(&pBackbuffer)); 126 | if (FAILED(hr)) 127 | return false; 128 | 129 | // Create render target view 130 | hr = pDevice->CreateRenderTargetView(pBackbuffer, nullptr, &pRenderTargetView); 131 | pBackbuffer->Release(); 132 | if (FAILED(hr)) 133 | return false; 134 | 135 | // Make sure our render target is set. 136 | pContext->OMSetRenderTargets(1, &pRenderTargetView, nullptr); 137 | } 138 | 139 | // initialize shaders 140 | ID3D10Blob* pBlob = nullptr; 141 | 142 | // create vertex shader 143 | if (!CompileShader(szShadez, "VS", "vs_5_0", &pBlob)) 144 | return false; 145 | 146 | hr = pDevice->CreateVertexShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr, &pVertexShader); 147 | if (FAILED(hr)) 148 | return false; 149 | 150 | // Define/create the input layout for the vertex shader 151 | D3D11_INPUT_ELEMENT_DESC layout[2] = { 152 | {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, 153 | {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0} 154 | }; 155 | UINT numElements = ARRAYSIZE(layout); 156 | 157 | hr = pDevice->CreateInputLayout(layout, numElements, pBlob->GetBufferPointer(), pBlob->GetBufferSize(), &pVertexLayout); 158 | if (FAILED(hr)) 159 | return false; 160 | 161 | safe_release(pBlob); 162 | 163 | // create pixel shader 164 | if (!CompileShader(szShadez, "PS", "ps_5_0", &pBlob)) 165 | return false; 166 | 167 | hr = pDevice->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr, &pPixelShader); 168 | if (FAILED(hr)) 169 | return false; 170 | 171 | UINT numViewports = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; 172 | float fWidth = 0; 173 | float fHeight = 0; 174 | 175 | // Apparently this isn't universal. Works on some games 176 | pContext->RSGetViewports(&numViewports, pViewports); 177 | 178 | // 179 | if (!numViewports || !pViewports[MAINVP].Width) 180 | { 181 | // This should be retrieved dynamically 182 | //HWND hWnd0 = FindWindowA( "W2ViewportClass", nullptr ); 183 | HWND hWnd = FindMainWindow(GetCurrentProcessId()); 184 | RECT rc{ 0 }; 185 | if (!GetClientRect(hWnd, &rc)) 186 | return false; 187 | 188 | //fWidth = 1600.0f; 189 | //fHeight = 900.0f; 190 | fWidth = (float)rc.right; 191 | fHeight = (float)rc.bottom; 192 | 193 | // Setup viewport 194 | pViewports[MAINVP].Width = (float)fWidth; 195 | pViewports[MAINVP].Height = (float)fHeight; 196 | pViewports[MAINVP].MinDepth = 0.0f; 197 | pViewports[MAINVP].MaxDepth = 1.0f; 198 | 199 | // Set viewport to context 200 | pContext->RSSetViewports(1, pViewports); 201 | } 202 | else 203 | { 204 | fWidth = (float)pViewports[MAINVP].Width; 205 | fHeight = (float)pViewports[MAINVP].Height; 206 | } 207 | 208 | // Create the constant buffer 209 | D3D11_BUFFER_DESC bd{ 0 }; 210 | bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; 211 | bd.ByteWidth = sizeof(ConstantBuffer); 212 | bd.Usage = D3D11_USAGE_DEFAULT; 213 | 214 | // Setup orthographic projection 215 | mOrtho = XMMatrixOrthographicLH(fWidth, fHeight, 0.0f, 1.0f); 216 | ConstantBuffer cb; 217 | cb.mProjection = mOrtho; 218 | 219 | D3D11_SUBRESOURCE_DATA sr{ 0 }; 220 | sr.pSysMem = &cb; 221 | hr = pDevice->CreateBuffer(&bd, &sr, &pConstantBuffer); 222 | if (FAILED(hr)) 223 | return false; 224 | 225 | // Create a triangle to render 226 | // Create a vertex buffer, start by setting up a description. 227 | ZeroMemory(&bd, sizeof(bd)); 228 | bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; 229 | bd.Usage = D3D11_USAGE_DEFAULT; 230 | bd.ByteWidth = 3 * sizeof(Vertex); 231 | bd.StructureByteStride = sizeof(Vertex); 232 | 233 | // left and top edge of window 234 | float left = fWidth / -2; 235 | float top = fHeight / 2; 236 | 237 | // Width and height of triangle 238 | float w = 20; 239 | float h = 20; 240 | 241 | // Center position of triangle, this should center it in the screen. 242 | float fPosX = -1 * left; 243 | float fPosY = top; 244 | 245 | // Setup vertices of triangle 246 | Vertex pVerts[3] = { 247 | { XMFLOAT3(left + fPosX/10, top - fPosY/10 + h / 2, 1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }, 248 | { XMFLOAT3(left + fPosX/10 + w / 2, top - fPosY/10 - h / 2, 1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) }, 249 | { XMFLOAT3(left + fPosX/10 - w / 2, top - fPosY/10 - h / 2, 1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) }, 250 | }; 251 | 252 | // create the buffer. 253 | ZeroMemory(&sr, sizeof(sr)); 254 | sr.pSysMem = &pVerts; 255 | hr = pDevice->CreateBuffer(&bd, &sr, &pVertexBuffer); 256 | if (FAILED(hr)) 257 | return false; 258 | 259 | 260 | // Create an index buffer 261 | ZeroMemory(&bd, sizeof(bd)); 262 | ZeroMemory(&sr, sizeof(sr)); 263 | 264 | UINT pIndices[3] = { 0, 1, 2 }; 265 | bd.BindFlags = D3D11_BIND_INDEX_BUFFER; 266 | bd.Usage = D3D11_USAGE_DEFAULT; 267 | bd.ByteWidth = sizeof(UINT) * 3; 268 | bd.StructureByteStride = sizeof(UINT); 269 | 270 | sr.pSysMem = &pIndices; 271 | hr = pDevice->CreateBuffer(&bd, &sr, &pIndexBuffer); 272 | if (FAILED(hr)) 273 | return false; 274 | 275 | return true; 276 | } 277 | 278 | void Render() 279 | { 280 | // Make sure our render target is set. 281 | pContext->OMSetRenderTargets(1, &pRenderTargetView, nullptr); 282 | 283 | // Update view 284 | ConstantBuffer cb; 285 | cb.mProjection = XMMatrixTranspose(mOrtho); 286 | pContext->UpdateSubresource(pConstantBuffer, 0, nullptr, &cb, 0, 0); 287 | pContext->VSSetConstantBuffers(0, 1, &pConstantBuffer); 288 | 289 | // Make sure the input assembler knows how to process our verts/indices 290 | UINT stride = sizeof(Vertex); 291 | UINT offset = 0; 292 | pContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset); 293 | pContext->IASetInputLayout(pVertexLayout); 294 | pContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R32_UINT, 0); 295 | pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 296 | 297 | // Set the shaders we need to render our triangle 298 | pContext->VSSetShader(pVertexShader, nullptr, 0); 299 | pContext->PSSetShader(pPixelShader, nullptr, 0); 300 | 301 | // Set viewport to context 302 | pContext->RSSetViewports(1, pViewports); 303 | 304 | // Draw our triangle 305 | pContext->DrawIndexed(3, 0, 0); 306 | 307 | 308 | } 309 | 310 | bool installD3DHook() { 311 | printf("hookD3d()...\r\n"); 312 | 313 | while (!GetModuleHandle("dxgi") || !GetModuleHandle("D3D11.dll")) 314 | Sleep(500); 315 | 316 | // Create a dummy device, get swapchain vmt, hook present. 317 | D3D_FEATURE_LEVEL featLevel; 318 | DXGI_SWAP_CHAIN_DESC sd{ 0 }; 319 | sd.BufferCount = 1; 320 | sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 321 | sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 322 | sd.BufferDesc.Height = 800; 323 | sd.BufferDesc.Width = 600; 324 | sd.BufferDesc.RefreshRate = { 60, 1 }; 325 | sd.OutputWindow = GetForegroundWindow(); 326 | sd.Windowed = TRUE; 327 | sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 328 | sd.SampleDesc.Count = 1; 329 | sd.SampleDesc.Quality = 0; 330 | HRESULT hr = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &sd, &pSwapchain, &pDevice, &featLevel, nullptr); 331 | if (FAILED(hr)) { 332 | printf("D3D11CreateDeviceAndSwapChain failed\r\n"); 333 | return 0; 334 | } 335 | 336 | printf("D3D11CreateDeviceAndSwapChain success\r\n"); 337 | // Get swapchain vmt 338 | void** pVMT = *(void***)pSwapchain; 339 | 340 | // Get Present's address out of vmt 341 | originalPresentFcn = (fnPresent)(pVMT[VMT_PRESENT]); 342 | 343 | // got what we need, we can release device and swapchain now 344 | // we'll be stealing the game's. 345 | safe_release(pSwapchain); 346 | safe_release(pDevice); 347 | 348 | // Create a code cave to trampoline to our hook 349 | // We'll try to do this close to present to make sure we'll be able to use a 5 byte jmp (important for x64) 350 | void* pLoc = (void*)((uintptr_t)originalPresentFcn - 0x2000); 351 | void* pTrampLoc = nullptr; 352 | while (!pTrampLoc) { 353 | //pTrampLoc = VirtualAlloc(pLoc, 1, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 354 | pTrampLoc = VirtualAlloc(pLoc, 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 355 | pLoc = (void*)((uintptr_t)pLoc + 0x200); 356 | } 357 | ogPresentTramp = (fnPresent)pTrampLoc; 358 | 359 | // write original bytes to trampoline 360 | // write jmp to hook 361 | memcpy(originalPresentBytes, originalPresentFcn, PRESENT_STUB_SIZE); 362 | memcpy(pTrampLoc, originalPresentBytes, PRESENT_STUB_SIZE); 363 | 364 | pTrampLoc = (void*)((uintptr_t)pTrampLoc + PRESENT_STUB_SIZE); 365 | 366 | // write the jmp back into present 367 | *(char*)pTrampLoc = (char)0xE9; 368 | pTrampLoc = (void*)((uintptr_t)pTrampLoc + 1); 369 | uintptr_t ogPresRet = (uintptr_t)originalPresentFcn + 5; 370 | *(int*)pTrampLoc = (int)(ogPresRet - (uintptr_t)pTrampLoc - 4); 371 | 372 | // write the jmp to our hook 373 | pTrampoline = pTrampLoc = (void*)((uintptr_t)pTrampLoc + 4); 374 | 375 | // if x64, gazzillion byte absolute jmp 376 | unsigned char pJmp[] = { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 }; 377 | WriteMem(pTrampLoc, (char*)pJmp, ARRAYSIZE(pJmp)); 378 | pTrampLoc = (void*)((uintptr_t)pTrampLoc + ARRAYSIZE(pJmp)); 379 | *(uintptr_t*)pTrampLoc = (uintptr_t)hookedPresent; 380 | 381 | // hook present, place a normal mid-function at the beginning of the Present function 382 | return Hook(originalPresentFcn, pTrampoline, PRESENT_STUB_SIZE); 383 | } 384 | 385 | void CleanupD3D() { 386 | WriteMem(originalPresentFcn, originalPresentBytes, PRESENT_STUB_SIZE); 387 | //VirtualFree((void*)ogPresentTramp, 0x1000, MEM_RELEASE); 388 | VirtualFree((void*)ogPresentTramp, 0, MEM_RELEASE); 389 | safe_release(pVertexBuffer); 390 | safe_release(pIndexBuffer); 391 | safe_release(pConstantBuffer); 392 | safe_release(pPixelShader); 393 | safe_release(pVertexShader); 394 | safe_release(pVertexLayout); 395 | } 396 | 397 | HRESULT __stdcall hookedPresent(IDXGISwapChain* pThis, UINT SyncInterval, UINT Flags) 398 | { 399 | pSwapchain = pThis; 400 | 401 | if (!pDevice) 402 | { 403 | if (!InitD3DHook(pThis)) 404 | return 0; 405 | } 406 | 407 | Render(); 408 | return ogPresentTramp(pThis, SyncInterval, Flags); 409 | } -------------------------------------------------------------------------------- /WT/d3dSpecific.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #pragma comment(lib, "d3d11.lib") 10 | #pragma comment(lib, "d3dcompiler.lib") 11 | #include "D2DBaseTypes.h" 12 | #define safe_release(p) if (p) { p->Release(); p = nullptr; } 13 | #define VMT_PRESENT (UINT)IDXGISwapChainVMT::Present 14 | #define PRESENT_STUB_SIZE 5 15 | 16 | constexpr const char* szShadez = R"( 17 | // Constant buffer 18 | cbuffer ConstantBuffer : register(b0) 19 | { 20 | matrix projection; 21 | } 22 | 23 | // PSI (PixelShaderInput) 24 | struct PSI 25 | { 26 | float4 pos : SV_POSITION; 27 | float4 color : COLOR; 28 | }; 29 | 30 | // VertexShader 31 | PSI VS( float4 pos : POSITION, float4 color : COLOR ) 32 | { 33 | PSI psi; 34 | psi.color = color; 35 | pos = mul( pos, projection ); 36 | psi.pos = pos; 37 | return psi; 38 | } 39 | 40 | // PixelShader 41 | float4 PS(PSI psi) : SV_TARGET 42 | { 43 | return psi.color; 44 | } 45 | )"; 46 | 47 | enum class IDXGISwapChainVMT { 48 | QueryInterface, 49 | AddRef, 50 | Release, 51 | SetPrivateData, 52 | SetPrivateDataInterface, 53 | GetPrivateData, 54 | GetParent, 55 | GetDevice, 56 | Present, 57 | GetBuffer, 58 | SetFullscreenState, 59 | GetFullscreenState, 60 | GetDesc, 61 | ResizeBuffers, 62 | ResizeTarget, 63 | GetContainingOutput, 64 | GetFrameStatistics, 65 | GetLastPresentCount, 66 | }; 67 | 68 | enum class ID3D11DeviceVMT { 69 | QueryInterface, 70 | AddRef, 71 | Release, 72 | CreateVideoDecoder, 73 | CreateVideoProcessor, 74 | CreateAuthenticatedChannel, 75 | CreateCryptoSession, 76 | CreateVideoDecoderOutputView, 77 | CreateVideoProcessorInputView, 78 | CreateVideoProcessorOutputView, 79 | CreateVideoProcessorEnumerator, 80 | GetVideoDecoderProfileCount, 81 | GetVideoDecoderProfile, 82 | CheckVideoDecoderFormat, 83 | GetVideoDecoderConfigCount, 84 | GetVideoDecoderConfig, 85 | GetContentProtectionCaps, 86 | CheckCryptoKeyExchange, 87 | SetPrivateData, 88 | SetPrivateDataInterface, 89 | }; 90 | 91 | enum class ID3D11DeviceContextVMT { 92 | QueryInterface, 93 | AddRef, 94 | Release, 95 | GetDevice, 96 | GetPrivateData, 97 | SetPrivateData, 98 | SetPrivateDataInterface, 99 | VSSetConstantBuffers, 100 | PSSetShaderResources, 101 | PSSetShader, 102 | PSSetSamplers, 103 | VSSetShader, 104 | DrawIndexed, 105 | Draw, 106 | Map, 107 | Unmap, 108 | PSSetConstantBuffers, 109 | IASetInputLayout, 110 | IASetVertexBuffers, 111 | IASetIndexBuffer, 112 | DrawIndexedInstanced, 113 | DrawInstanced, 114 | GSSetConstantBuffers, 115 | GSSetShader, 116 | IASetPrimitiveTopology, 117 | VSSetShaderResources, 118 | VSSetSamplers, 119 | Begin, 120 | End, 121 | GetData, 122 | SetPredication, 123 | GSSetShaderResources, 124 | GSSetSamplers, 125 | OMSetRenderTargets, 126 | OMSetRenderTargetsAndUnorderedAccessViews, 127 | OMSetBlendState, 128 | OMSetDepthStencilState, 129 | SOSetTargets, 130 | DrawAuto, 131 | DrawIndexedInstancedIndirect, 132 | DrawInstancedIndirect, 133 | Dispatch, 134 | DispatchIndirect, 135 | RSSetState, 136 | RSSetViewports, 137 | RSSetScissorRects, 138 | CopySubresourceRegion, 139 | CopyResource, 140 | UpdateSubresource, 141 | CopyStructureCount, 142 | ClearRenderTargetView, 143 | ClearUnorderedAccessViewUint, 144 | ClearUnorderedAccessViewFloat, 145 | ClearDepthStencilView, 146 | GenerateMips, 147 | SetResourceMinLOD, 148 | GetResourceMinLOD, 149 | ResolveSubresource, 150 | ExecuteCommandList, 151 | HSSetShaderResources, 152 | HSSetShader, 153 | HSSetSamplers, 154 | HSSetConstantBuffers, 155 | DSSetShaderResources, 156 | DSSetShader, 157 | DSSetSamplers, 158 | DSSetConstantBuffers, 159 | CSSetShaderResources, 160 | CSSetUnorderedAccessViews, 161 | CSSetShader, 162 | CSSetSamplers, 163 | CSSetConstantBuffers, 164 | VSGetConstantBuffers, 165 | PSGetShaderResources, 166 | PSGetShader, 167 | PSGetSamplers, 168 | VSGetShader, 169 | PSGetConstantBuffers, 170 | IAGetInputLayout, 171 | IAGetVertexBuffers, 172 | IAGetIndexBuffer, 173 | GSGetConstantBuffers, 174 | GSGetShader, 175 | IAGetPrimitiveTopology, 176 | VSGetShaderResources, 177 | VSGetSamplers, 178 | GetPredication, 179 | GSGetShaderResources, 180 | GSGetSamplers, 181 | OMGetRenderTargets, 182 | OMGetRenderTargetsAndUnorderedAccessViews, 183 | OMGetBlendState, 184 | OMGetDepthStencilState, 185 | SOGetTargets, 186 | RSGetState, 187 | RSGetViewports, 188 | RSGetScissorRects, 189 | HSGetShaderResources, 190 | HSGetShader, 191 | HSGetSamplers, 192 | HSGetConstantBuffers, 193 | DSGetShaderResources, 194 | DSGetShader, 195 | DSGetSamplers, 196 | DSGetConstantBuffers, 197 | CSGetShaderResources, 198 | CSGetUnorderedAccessViews, 199 | CSGetShader, 200 | CSGetSamplers, 201 | CSGetConstantBuffers, 202 | ClearState, 203 | Flush, 204 | GetType, 205 | GetContextFlags, 206 | FinishCommandList, 207 | }; 208 | 209 | bool installD3DHook(); 210 | void CleanupD3D(); 211 | 212 | struct Matrix44 { 213 | float m[4][4]; 214 | }; 215 | 216 | struct D3DX11Matricies 217 | { 218 | Matrix44 ViewMatrix; 219 | Matrix44 WorldMatrix; 220 | Matrix44 ProjectionMatrix; 221 | }; 222 | 223 | extern ID3D11Device* pDevice = nullptr; 224 | extern IDXGISwapChain* pSwapchain = nullptr; 225 | extern ID3D11DeviceContext* pContext = nullptr; 226 | extern ID3D11RenderTargetView* pRenderTargetView = nullptr; 227 | extern ID3D11VertexShader* pVertexShader = nullptr; 228 | extern ID3D11InputLayout* pVertexLayout = nullptr; 229 | extern ID3D11PixelShader* pPixelShader = nullptr; 230 | extern ID3D11Buffer* pVertexBuffer = nullptr; 231 | extern ID3D11Buffer* pIndexBuffer = nullptr; 232 | extern ID3D11Buffer* pConstantBuffer = nullptr; -------------------------------------------------------------------------------- /WT/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include 3 | #include 4 | #include "offsets.h" 5 | #include "d3d11hook.h" 6 | #include "coreNotGameSpecific.h" 7 | #include "rD3D11.h" 8 | #include "d3d11hook.h" 9 | #include "ESP.h" 10 | 11 | #pragma comment(lib, "libMinHook-x64-v140-mdd.lib") 12 | 13 | MasterClass MC; 14 | 15 | void mainCheatThread(uintptr_t exeBase, uintptr_t playerListBase, HMODULE dllHandle) { 16 | 17 | MC.InitD3DHook(dllHandle); 18 | 19 | printf("mainCheatThread()\r\n"); 20 | printf("Windows Size: %d %d\r\n", esp.rect.right, esp.rect.bottom); 21 | while (true){ 22 | if (GetAsyncKeyState(VK_INSERT)) 23 | break; 24 | if (GetAsyncKeyState(VK_F9)) 25 | esp.drawTracers != esp.drawTracers; 26 | if (GetAsyncKeyState(VK_NUMPAD9)) { 27 | esp.k += 1; 28 | Sleep(200); 29 | } 30 | if (GetAsyncKeyState(VK_NUMPAD6)) { 31 | esp.k -= 1; 32 | Sleep(200); 33 | } 34 | esp.update(); 35 | Sleep(50); 36 | } 37 | 38 | mainDettach(dllHandle); 39 | 40 | return; 41 | } 42 | 43 | DWORD WINAPI Main(HMODULE dllHandle) { 44 | 45 | 46 | allocConsole(); 47 | 48 | MC.exeBase = (uintptr_t) GetModuleHandleA("aces.exe"); 49 | printf("exeBase at %llx\r\n", MC.exeBase); 50 | 51 | uintptr_t playerListBase = *(uintptr_t*)(MC.exeBase + playerListOffset); 52 | printf("playerListBase at %llx\r\n", playerListBase); 53 | 54 | MC.viewMatrix = MC.exeBase + viewMatrixOffset; 55 | printf("MC.viewMatrix at %llx\r\n", MC.viewMatrix); 56 | 57 | MC.pToGameInfo = MC.exeBase + gameInfoOffset; 58 | printf("MC.pToGameInfo = %llx\r\n", MC.pToGameInfo); 59 | 60 | esp.gameInfo = *(GameInfo**)(MC.pToGameInfo); 61 | 62 | mainCheatThread(MC.exeBase, playerListBase, dllHandle); 63 | 64 | return 0; 65 | } 66 | 67 | BOOL APIENTRY DllMain( HMODULE hModule, 68 | DWORD ul_reason_for_call, 69 | LPVOID lpReserved) { 70 | switch (ul_reason_for_call) { 71 | case DLL_PROCESS_ATTACH: 72 | DisableThreadLibraryCalls(hModule); 73 | CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Main, hModule, 0, 0); 74 | break; 75 | case DLL_THREAD_ATTACH: 76 | case DLL_THREAD_DETACH: 77 | case DLL_PROCESS_DETACH: 78 | break; 79 | } 80 | return TRUE; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /WT/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // Selten verwendete Komponenten aus Windows-Headern ausschließen 4 | // Windows-Headerdateien 5 | #include 6 | -------------------------------------------------------------------------------- /WT/imconfig.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI 3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. 4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. 5 | //----------------------------------------------------------------------------- 6 | // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it) 7 | // B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template. 8 | //----------------------------------------------------------------------------- 9 | // You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp 10 | // files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. 11 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. 12 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. 13 | //----------------------------------------------------------------------------- 14 | 15 | #pragma once 16 | 17 | //---- Define assertion handler. Defaults to calling assert(). 18 | // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. 19 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 20 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts 21 | 22 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows 23 | // Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. 24 | //#define IMGUI_API __declspec( dllexport ) 25 | //#define IMGUI_API __declspec( dllimport ) 26 | 27 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. 28 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 29 | 30 | //---- Disable all of Dear ImGui or don't implement standard windows. 31 | // It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp. 32 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. 33 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended. 34 | //#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger window: ShowMetricsWindow() will be empty. 35 | 36 | //---- Don't implement some functions to reduce linkage requirements. 37 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. 38 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow. 39 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). 40 | //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). 41 | //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) 42 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. 43 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. 44 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). 45 | 46 | //---- Include imgui_user.h at the end of imgui.h as a convenience 47 | //#define IMGUI_INCLUDE_IMGUI_USER_H 48 | 49 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) 50 | //#define IMGUI_USE_BGRA_PACKED_COLOR 51 | 52 | //---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...) 53 | //#define IMGUI_USE_WCHAR32 54 | 55 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 56 | // By default the embedded implementations are declared static and not available outside of imgui cpp files. 57 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 58 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 59 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 60 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 61 | 62 | //---- Unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined, use the much faster STB sprintf library implementation of vsnprintf instead of the one from the default C library. 63 | // Note that stb_sprintf.h is meant to be provided by the user and available in the include path at compile time. Also, the compatibility checks of the arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf. 64 | // #define IMGUI_USE_STB_SPRINTF 65 | 66 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 67 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 68 | /* 69 | #define IM_VEC2_CLASS_EXTRA \ 70 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ 71 | operator MyVec2() const { return MyVec2(x,y); } 72 | 73 | #define IM_VEC4_CLASS_EXTRA \ 74 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ 75 | operator MyVec4() const { return MyVec4(x,y,z,w); } 76 | */ 77 | 78 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. 79 | // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices). 80 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. 81 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. 82 | //#define ImDrawIdx unsigned int 83 | 84 | //---- Override ImDrawCallback signature (will need to modify renderer backends accordingly) 85 | //struct ImDrawList; 86 | //struct ImDrawCmd; 87 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); 88 | //#define ImDrawCallback MyImDrawCallback 89 | 90 | //---- Debug Tools: Macro to break in Debugger 91 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) 92 | //#define IM_DEBUG_BREAK IM_ASSERT(0) 93 | //#define IM_DEBUG_BREAK __debugbreak() 94 | 95 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(), 96 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.) 97 | // This adds a small runtime cost which is why it is not enabled by default. 98 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX 99 | 100 | //---- Debug Tools: Enable slower asserts 101 | //#define IMGUI_DEBUG_PARANOID 102 | 103 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 104 | /* 105 | namespace ImGui 106 | { 107 | void MyFunction(const char* name, const MyMatrix44& v); 108 | } 109 | */ 110 | -------------------------------------------------------------------------------- /WT/imgui_impl_dx11.cpp: -------------------------------------------------------------------------------- 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: Support for large meshes (64k+ vertices) with 16-bit indices. 7 | 8 | // You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 9 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 10 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 11 | 12 | // CHANGELOG 13 | // (minor and older changes stripped away, please see git history for details) 14 | // 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled). 15 | // 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore. 16 | // 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. 17 | // 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. 18 | // 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). 19 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. 20 | // 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility. 21 | // 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions. 22 | // 2018-06-08: Misc: Extracted imgui_impl_dx11.cpp/.h away from the old combined DX11+Win32 example. 23 | // 2018-06-08: DirectX11: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. 24 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself. 25 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 26 | // 2016-05-07: DirectX11: Disabling depth-write. 27 | 28 | #include "imgui.h" 29 | #include "imgui_impl_dx11.h" 30 | 31 | // DirectX 32 | #include 33 | #include 34 | #include 35 | #ifdef _MSC_VER 36 | #pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below. 37 | #endif 38 | 39 | // DirectX data 40 | static ID3D11Device* g_pd3dDevice = NULL; 41 | static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; 42 | static IDXGIFactory* g_pFactory = NULL; 43 | static ID3D11Buffer* g_pVB = NULL; 44 | static ID3D11Buffer* g_pIB = NULL; 45 | static ID3D11VertexShader* g_pVertexShader = NULL; 46 | static ID3D11InputLayout* g_pInputLayout = NULL; 47 | static ID3D11Buffer* g_pVertexConstantBuffer = NULL; 48 | static ID3D11PixelShader* g_pPixelShader = NULL; 49 | static ID3D11SamplerState* g_pFontSampler = NULL; 50 | static ID3D11ShaderResourceView*g_pFontTextureView = NULL; 51 | static ID3D11RasterizerState* g_pRasterizerState = NULL; 52 | static ID3D11BlendState* g_pBlendState = NULL; 53 | static ID3D11DepthStencilState* g_pDepthStencilState = NULL; 54 | static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000; 55 | 56 | struct VERTEX_CONSTANT_BUFFER 57 | { 58 | float mvp[4][4]; 59 | }; 60 | 61 | static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx) 62 | { 63 | // Setup viewport 64 | D3D11_VIEWPORT vp; 65 | memset(&vp, 0, sizeof(D3D11_VIEWPORT)); 66 | vp.Width = draw_data->DisplaySize.x; 67 | vp.Height = draw_data->DisplaySize.y; 68 | vp.MinDepth = 0.0f; 69 | vp.MaxDepth = 1.0f; 70 | vp.TopLeftX = vp.TopLeftY = 0; 71 | ctx->RSSetViewports(1, &vp); 72 | 73 | // Setup shader and vertex buffers 74 | unsigned int stride = sizeof(ImDrawVert); 75 | unsigned int offset = 0; 76 | ctx->IASetInputLayout(g_pInputLayout); 77 | ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); 78 | ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); 79 | ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 80 | ctx->VSSetShader(g_pVertexShader, NULL, 0); 81 | ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); 82 | ctx->PSSetShader(g_pPixelShader, NULL, 0); 83 | ctx->PSSetSamplers(0, 1, &g_pFontSampler); 84 | ctx->GSSetShader(NULL, NULL, 0); 85 | ctx->HSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. 86 | ctx->DSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. 87 | ctx->CSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. 88 | 89 | // Setup blend state 90 | const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; 91 | ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff); 92 | ctx->OMSetDepthStencilState(g_pDepthStencilState, 0); 93 | ctx->RSSetState(g_pRasterizerState); 94 | } 95 | 96 | // Render function 97 | void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) 98 | { 99 | // Avoid rendering when minimized 100 | if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) 101 | return; 102 | 103 | ID3D11DeviceContext* ctx = g_pd3dDeviceContext; 104 | 105 | // Create and grow vertex/index buffers if needed 106 | if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) 107 | { 108 | if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } 109 | g_VertexBufferSize = draw_data->TotalVtxCount + 5000; 110 | D3D11_BUFFER_DESC desc; 111 | memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); 112 | desc.Usage = D3D11_USAGE_DYNAMIC; 113 | desc.ByteWidth = g_VertexBufferSize * sizeof(ImDrawVert); 114 | desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 115 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 116 | desc.MiscFlags = 0; 117 | if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVB) < 0) 118 | return; 119 | } 120 | if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount) 121 | { 122 | if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } 123 | g_IndexBufferSize = draw_data->TotalIdxCount + 10000; 124 | D3D11_BUFFER_DESC desc; 125 | memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); 126 | desc.Usage = D3D11_USAGE_DYNAMIC; 127 | desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); 128 | desc.BindFlags = D3D11_BIND_INDEX_BUFFER; 129 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 130 | if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pIB) < 0) 131 | return; 132 | } 133 | 134 | // Upload vertex/index data into a single contiguous GPU buffer 135 | D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; 136 | if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) 137 | return; 138 | if (ctx->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK) 139 | return; 140 | ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; 141 | ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData; 142 | for (int n = 0; n < draw_data->CmdListsCount; n++) 143 | { 144 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 145 | memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); 146 | memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); 147 | vtx_dst += cmd_list->VtxBuffer.Size; 148 | idx_dst += cmd_list->IdxBuffer.Size; 149 | } 150 | ctx->Unmap(g_pVB, 0); 151 | ctx->Unmap(g_pIB, 0); 152 | 153 | // Setup orthographic projection matrix into our constant buffer 154 | // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. 155 | { 156 | D3D11_MAPPED_SUBRESOURCE mapped_resource; 157 | if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) 158 | return; 159 | VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData; 160 | float L = draw_data->DisplayPos.x; 161 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; 162 | float T = draw_data->DisplayPos.y; 163 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; 164 | float mvp[4][4] = 165 | { 166 | { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, 167 | { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, 168 | { 0.0f, 0.0f, 0.5f, 0.0f }, 169 | { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, 170 | }; 171 | memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); 172 | ctx->Unmap(g_pVertexConstantBuffer, 0); 173 | } 174 | 175 | // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!) 176 | struct BACKUP_DX11_STATE 177 | { 178 | UINT ScissorRectsCount, ViewportsCount; 179 | D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; 180 | D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; 181 | ID3D11RasterizerState* RS; 182 | ID3D11BlendState* BlendState; 183 | FLOAT BlendFactor[4]; 184 | UINT SampleMask; 185 | UINT StencilRef; 186 | ID3D11DepthStencilState* DepthStencilState; 187 | ID3D11ShaderResourceView* PSShaderResource; 188 | ID3D11SamplerState* PSSampler; 189 | ID3D11PixelShader* PS; 190 | ID3D11VertexShader* VS; 191 | ID3D11GeometryShader* GS; 192 | UINT PSInstancesCount, VSInstancesCount, GSInstancesCount; 193 | ID3D11ClassInstance *PSInstances[256], *VSInstances[256], *GSInstances[256]; // 256 is max according to PSSetShader documentation 194 | D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology; 195 | ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer; 196 | UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset; 197 | DXGI_FORMAT IndexBufferFormat; 198 | ID3D11InputLayout* InputLayout; 199 | }; 200 | BACKUP_DX11_STATE old; 201 | old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; 202 | ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); 203 | ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); 204 | ctx->RSGetState(&old.RS); 205 | ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask); 206 | ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef); 207 | ctx->PSGetShaderResources(0, 1, &old.PSShaderResource); 208 | ctx->PSGetSamplers(0, 1, &old.PSSampler); 209 | old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256; 210 | ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount); 211 | ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount); 212 | ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer); 213 | ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount); 214 | 215 | ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology); 216 | ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset); 217 | ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); 218 | ctx->IAGetInputLayout(&old.InputLayout); 219 | 220 | // Setup desired DX state 221 | ImGui_ImplDX11_SetupRenderState(draw_data, ctx); 222 | 223 | // Render command lists 224 | // (Because we merged all buffers into a single one, we maintain our own offset into them) 225 | int global_idx_offset = 0; 226 | int global_vtx_offset = 0; 227 | ImVec2 clip_off = draw_data->DisplayPos; 228 | for (int n = 0; n < draw_data->CmdListsCount; n++) 229 | { 230 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 231 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 232 | { 233 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 234 | if (pcmd->UserCallback != NULL) 235 | { 236 | // User callback, registered via ImDrawList::AddCallback() 237 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) 238 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) 239 | ImGui_ImplDX11_SetupRenderState(draw_data, ctx); 240 | else 241 | pcmd->UserCallback(cmd_list, pcmd); 242 | } 243 | else 244 | { 245 | // Apply scissor/clipping rectangle 246 | const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) }; 247 | ctx->RSSetScissorRects(1, &r); 248 | 249 | // Bind texture, Draw 250 | ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->TextureId; 251 | ctx->PSSetShaderResources(0, 1, &texture_srv); 252 | ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset); 253 | } 254 | } 255 | global_idx_offset += cmd_list->IdxBuffer.Size; 256 | global_vtx_offset += cmd_list->VtxBuffer.Size; 257 | } 258 | 259 | // Restore modified DX state 260 | ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); 261 | ctx->RSSetViewports(old.ViewportsCount, old.Viewports); 262 | ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); 263 | ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); 264 | ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); 265 | ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); 266 | ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); 267 | ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release(); 268 | for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release(); 269 | ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release(); 270 | ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); 271 | ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release(); 272 | for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release(); 273 | ctx->IASetPrimitiveTopology(old.PrimitiveTopology); 274 | ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); 275 | ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); 276 | ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); 277 | } 278 | 279 | static void ImGui_ImplDX11_CreateFontsTexture() 280 | { 281 | // Build texture atlas 282 | ImGuiIO& io = ImGui::GetIO(); 283 | unsigned char* pixels; 284 | int width, height; 285 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); 286 | 287 | // Upload texture to graphics system 288 | { 289 | D3D11_TEXTURE2D_DESC desc; 290 | ZeroMemory(&desc, sizeof(desc)); 291 | desc.Width = width; 292 | desc.Height = height; 293 | desc.MipLevels = 1; 294 | desc.ArraySize = 1; 295 | desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 296 | desc.SampleDesc.Count = 1; 297 | desc.Usage = D3D11_USAGE_DEFAULT; 298 | desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; 299 | desc.CPUAccessFlags = 0; 300 | 301 | ID3D11Texture2D* pTexture = NULL; 302 | D3D11_SUBRESOURCE_DATA subResource; 303 | subResource.pSysMem = pixels; 304 | subResource.SysMemPitch = desc.Width * 4; 305 | subResource.SysMemSlicePitch = 0; 306 | g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); 307 | 308 | // Create texture view 309 | D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 310 | ZeroMemory(&srvDesc, sizeof(srvDesc)); 311 | srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 312 | srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 313 | srvDesc.Texture2D.MipLevels = desc.MipLevels; 314 | srvDesc.Texture2D.MostDetailedMip = 0; 315 | g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView); 316 | pTexture->Release(); 317 | } 318 | 319 | // Store our identifier 320 | io.Fonts->TexID = (ImTextureID)g_pFontTextureView; 321 | 322 | // Create texture sampler 323 | { 324 | D3D11_SAMPLER_DESC desc; 325 | ZeroMemory(&desc, sizeof(desc)); 326 | desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; 327 | desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; 328 | desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; 329 | desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; 330 | desc.MipLODBias = 0.f; 331 | desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; 332 | desc.MinLOD = 0.f; 333 | desc.MaxLOD = 0.f; 334 | g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler); 335 | } 336 | } 337 | 338 | bool ImGui_ImplDX11_CreateDeviceObjects() 339 | { 340 | if (!g_pd3dDevice) 341 | return false; 342 | if (g_pFontSampler) 343 | ImGui_ImplDX11_InvalidateDeviceObjects(); 344 | 345 | // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) 346 | // If you would like to use this DX11 sample code but remove this dependency you can: 347 | // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution] 348 | // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL. 349 | // See https://github.com/ocornut/imgui/pull/638 for sources and details. 350 | 351 | // Create the vertex shader 352 | { 353 | static const char* vertexShader = 354 | "cbuffer vertexBuffer : register(b0) \ 355 | {\ 356 | float4x4 ProjectionMatrix; \ 357 | };\ 358 | struct VS_INPUT\ 359 | {\ 360 | float2 pos : POSITION;\ 361 | float4 col : COLOR0;\ 362 | float2 uv : TEXCOORD0;\ 363 | };\ 364 | \ 365 | struct PS_INPUT\ 366 | {\ 367 | float4 pos : SV_POSITION;\ 368 | float4 col : COLOR0;\ 369 | float2 uv : TEXCOORD0;\ 370 | };\ 371 | \ 372 | PS_INPUT main(VS_INPUT input)\ 373 | {\ 374 | PS_INPUT output;\ 375 | output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ 376 | output.col = input.col;\ 377 | output.uv = input.uv;\ 378 | return output;\ 379 | }"; 380 | 381 | ID3DBlob* vertexShaderBlob; 382 | if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL))) 383 | return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! 384 | if (g_pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK) 385 | { 386 | vertexShaderBlob->Release(); 387 | return false; 388 | } 389 | 390 | // Create the input layout 391 | D3D11_INPUT_ELEMENT_DESC local_layout[] = 392 | { 393 | { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 394 | { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 395 | { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 396 | }; 397 | if (g_pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) 398 | { 399 | vertexShaderBlob->Release(); 400 | return false; 401 | } 402 | vertexShaderBlob->Release(); 403 | 404 | // Create the constant buffer 405 | { 406 | D3D11_BUFFER_DESC desc; 407 | desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); 408 | desc.Usage = D3D11_USAGE_DYNAMIC; 409 | desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; 410 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 411 | desc.MiscFlags = 0; 412 | g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer); 413 | } 414 | } 415 | 416 | // Create the pixel shader 417 | { 418 | static const char* pixelShader = 419 | "struct PS_INPUT\ 420 | {\ 421 | float4 pos : SV_POSITION;\ 422 | float4 col : COLOR0;\ 423 | float2 uv : TEXCOORD0;\ 424 | };\ 425 | sampler sampler0;\ 426 | Texture2D texture0;\ 427 | \ 428 | float4 main(PS_INPUT input) : SV_Target\ 429 | {\ 430 | float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ 431 | return out_col; \ 432 | }"; 433 | 434 | ID3DBlob* pixelShaderBlob; 435 | if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL))) 436 | return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! 437 | if (g_pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK) 438 | { 439 | pixelShaderBlob->Release(); 440 | return false; 441 | } 442 | pixelShaderBlob->Release(); 443 | } 444 | 445 | // Create the blending setup 446 | { 447 | D3D11_BLEND_DESC desc; 448 | ZeroMemory(&desc, sizeof(desc)); 449 | desc.AlphaToCoverageEnable = false; 450 | desc.RenderTarget[0].BlendEnable = true; 451 | desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; 452 | desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; 453 | desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; 454 | desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; 455 | desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; 456 | desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; 457 | desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; 458 | g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState); 459 | } 460 | 461 | // Create the rasterizer state 462 | { 463 | D3D11_RASTERIZER_DESC desc; 464 | ZeroMemory(&desc, sizeof(desc)); 465 | desc.FillMode = D3D11_FILL_SOLID; 466 | desc.CullMode = D3D11_CULL_NONE; 467 | desc.ScissorEnable = true; 468 | desc.DepthClipEnable = true; 469 | g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState); 470 | } 471 | 472 | // Create depth-stencil State 473 | { 474 | D3D11_DEPTH_STENCIL_DESC desc; 475 | ZeroMemory(&desc, sizeof(desc)); 476 | desc.DepthEnable = false; 477 | desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; 478 | desc.DepthFunc = D3D11_COMPARISON_ALWAYS; 479 | desc.StencilEnable = false; 480 | desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 481 | desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; 482 | desc.BackFace = desc.FrontFace; 483 | g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState); 484 | } 485 | 486 | ImGui_ImplDX11_CreateFontsTexture(); 487 | 488 | return true; 489 | } 490 | 491 | void ImGui_ImplDX11_InvalidateDeviceObjects() 492 | { 493 | if (!g_pd3dDevice) 494 | return; 495 | 496 | if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; } 497 | if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. 498 | if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } 499 | if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } 500 | 501 | if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; } 502 | if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; } 503 | if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } 504 | if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } 505 | if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; } 506 | if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; } 507 | if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; } 508 | } 509 | 510 | bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context) 511 | { 512 | // Setup backend capabilities flags 513 | ImGuiIO& io = ImGui::GetIO(); 514 | io.BackendRendererName = "imgui_impl_dx11"; 515 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. 516 | 517 | // Get factory from device 518 | IDXGIDevice* pDXGIDevice = NULL; 519 | IDXGIAdapter* pDXGIAdapter = NULL; 520 | IDXGIFactory* pFactory = NULL; 521 | 522 | if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK) 523 | if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK) 524 | if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK) 525 | { 526 | g_pd3dDevice = device; 527 | g_pd3dDeviceContext = device_context; 528 | g_pFactory = pFactory; 529 | } 530 | if (pDXGIDevice) pDXGIDevice->Release(); 531 | if (pDXGIAdapter) pDXGIAdapter->Release(); 532 | g_pd3dDevice->AddRef(); 533 | g_pd3dDeviceContext->AddRef(); 534 | 535 | return true; 536 | } 537 | 538 | void ImGui_ImplDX11_Shutdown() 539 | { 540 | ImGui_ImplDX11_InvalidateDeviceObjects(); 541 | if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; } 542 | if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } 543 | if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; } 544 | } 545 | 546 | void ImGui_ImplDX11_NewFrame() 547 | { 548 | if (!g_pFontSampler) 549 | ImGui_ImplDX11_CreateDeviceObjects(); 550 | } 551 | -------------------------------------------------------------------------------- /WT/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: Support for large meshes (64k+ vertices) with 16-bit indices. 7 | 8 | // You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 9 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 10 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 11 | 12 | #pragma once 13 | #include "imgui.h" // IMGUI_IMPL_API 14 | 15 | struct ID3D11Device; 16 | struct ID3D11DeviceContext; 17 | 18 | IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context); 19 | IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown(); 20 | IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame(); 21 | IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); 22 | 23 | // Use if you want to reset your rendering device without losing Dear ImGui state. 24 | IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects(); 25 | IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); 26 | -------------------------------------------------------------------------------- /WT/imgui_impl_win32.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Backend for Windows (standard windows API for 32 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 cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | 10 | // You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 11 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 12 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 13 | 14 | #include "imgui.h" 15 | #include "imgui_impl_win32.h" 16 | #ifndef WIN32_LEAN_AND_MEAN 17 | #define WIN32_LEAN_AND_MEAN 18 | #endif 19 | #include 20 | #include 21 | 22 | // Using XInput library for gamepad (with recent Windows SDK this may leads to executables which won't run on Windows 7) 23 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 24 | #include 25 | #else 26 | #define IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT 27 | #endif 28 | #if defined(_MSC_VER) && !defined(IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT) 29 | #pragma comment(lib, "xinput") 30 | //#pragma comment(lib, "Xinput9_1_0") 31 | #endif 32 | 33 | // CHANGELOG 34 | // (minor and older changes stripped away, please see git history for details) 35 | // 2020-12-04: Misc: Fixed setting of io.DisplaySize to invalid/uninitialized data when after hwnd has been closed. 36 | // 2020-03-03: Inputs: Calling AddInputCharacterUTF16() to support surrogate pairs leading to codepoint >= 0x10000 (for more complete CJK inputs) 37 | // 2020-02-17: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helper functions. 38 | // 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT. 39 | // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. 40 | // 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter(). 41 | // 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent. 42 | // 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages. 43 | // 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application). 44 | // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. 45 | // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. 46 | // 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads). 47 | // 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples. 48 | // 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag. 49 | // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). 50 | // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. 51 | // 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). 52 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 53 | // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. 54 | // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. 55 | // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. 56 | // 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read. 57 | // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. 58 | // 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set. 59 | 60 | // Win32 Data 61 | static HWND g_hWnd = NULL; 62 | static INT64 g_Time = 0; 63 | static INT64 g_TicksPerSecond = 0; 64 | static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; 65 | static bool g_HasGamepad = false; 66 | static bool g_WantUpdateHasGamepad = true; 67 | 68 | // Functions 69 | bool ImGui_ImplWin32_Init(void* hwnd) 70 | { 71 | if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&g_TicksPerSecond)) 72 | return false; 73 | if (!::QueryPerformanceCounter((LARGE_INTEGER*)&g_Time)) 74 | return false; 75 | 76 | // Setup backend capabilities flags 77 | g_hWnd = (HWND)hwnd; 78 | ImGuiIO& io = ImGui::GetIO(); 79 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) 80 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) 81 | io.BackendPlatformName = "imgui_impl_win32"; 82 | io.ImeWindowHandle = hwnd; 83 | 84 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime. 85 | io.KeyMap[ImGuiKey_Tab] = VK_TAB; 86 | io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; 87 | io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; 88 | io.KeyMap[ImGuiKey_UpArrow] = VK_UP; 89 | io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN; 90 | io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR; 91 | io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; 92 | io.KeyMap[ImGuiKey_Home] = VK_HOME; 93 | io.KeyMap[ImGuiKey_End] = VK_END; 94 | io.KeyMap[ImGuiKey_Insert] = VK_INSERT; 95 | io.KeyMap[ImGuiKey_Delete] = VK_DELETE; 96 | io.KeyMap[ImGuiKey_Backspace] = VK_BACK; 97 | io.KeyMap[ImGuiKey_Space] = VK_SPACE; 98 | io.KeyMap[ImGuiKey_Enter] = VK_RETURN; 99 | io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; 100 | io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN; 101 | io.KeyMap[ImGuiKey_A] = 'A'; 102 | io.KeyMap[ImGuiKey_C] = 'C'; 103 | io.KeyMap[ImGuiKey_V] = 'V'; 104 | io.KeyMap[ImGuiKey_X] = 'X'; 105 | io.KeyMap[ImGuiKey_Y] = 'Y'; 106 | io.KeyMap[ImGuiKey_Z] = 'Z'; 107 | 108 | return true; 109 | } 110 | 111 | void ImGui_ImplWin32_Shutdown() 112 | { 113 | g_hWnd = (HWND)0; 114 | } 115 | 116 | static bool ImGui_ImplWin32_UpdateMouseCursor() 117 | { 118 | ImGuiIO& io = ImGui::GetIO(); 119 | if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) 120 | return false; 121 | 122 | ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); 123 | if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) 124 | { 125 | // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor 126 | ::SetCursor(NULL); 127 | } 128 | else 129 | { 130 | // Show OS mouse cursor 131 | LPTSTR win32_cursor = IDC_ARROW; 132 | switch (imgui_cursor) 133 | { 134 | case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; 135 | case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; 136 | case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; 137 | case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; 138 | case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; 139 | case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; 140 | case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; 141 | case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break; 142 | case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break; 143 | } 144 | ::SetCursor(::LoadCursor(NULL, win32_cursor)); 145 | } 146 | return true; 147 | } 148 | 149 | static void ImGui_ImplWin32_UpdateMousePos() 150 | { 151 | ImGuiIO& io = ImGui::GetIO(); 152 | 153 | // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 154 | if (io.WantSetMousePos) 155 | { 156 | POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; 157 | if (::ClientToScreen(g_hWnd, &pos)) 158 | ::SetCursorPos(pos.x, pos.y); 159 | } 160 | 161 | // Set mouse position 162 | io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); 163 | POINT pos; 164 | if (HWND active_window = ::GetForegroundWindow()) 165 | if (active_window == g_hWnd || ::IsChild(active_window, g_hWnd)) 166 | if (::GetCursorPos(&pos) && ::ScreenToClient(g_hWnd, &pos)) 167 | io.MousePos = ImVec2((float)pos.x, (float)pos.y); 168 | } 169 | 170 | // Gamepad navigation mapping 171 | static void ImGui_ImplWin32_UpdateGamepads() 172 | { 173 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 174 | ImGuiIO& io = ImGui::GetIO(); 175 | memset(io.NavInputs, 0, sizeof(io.NavInputs)); 176 | if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) 177 | return; 178 | 179 | // Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow. 180 | // Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE. 181 | if (g_WantUpdateHasGamepad) 182 | { 183 | XINPUT_CAPABILITIES caps; 184 | g_HasGamepad = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS); 185 | g_WantUpdateHasGamepad = false; 186 | } 187 | 188 | XINPUT_STATE xinput_state; 189 | io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; 190 | if (g_HasGamepad && XInputGetState(0, &xinput_state) == ERROR_SUCCESS) 191 | { 192 | const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad; 193 | io.BackendFlags |= ImGuiBackendFlags_HasGamepad; 194 | 195 | #define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; } 196 | #define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; } 197 | MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A 198 | MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B 199 | MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X 200 | MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y 201 | MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left 202 | MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right 203 | MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up 204 | MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down 205 | MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB 206 | MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB 207 | MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB 208 | MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB 209 | MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); 210 | MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); 211 | MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); 212 | MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767); 213 | #undef MAP_BUTTON 214 | #undef MAP_ANALOG 215 | } 216 | #endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 217 | } 218 | 219 | void ImGui_ImplWin32_NewFrame() 220 | { 221 | ImGuiIO& io = ImGui::GetIO(); 222 | IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer backend. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."); 223 | 224 | // Setup display size (every frame to accommodate for window resizing) 225 | RECT rect = { 0, 0, 0, 0 }; 226 | ::GetClientRect(g_hWnd, &rect); 227 | io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); 228 | 229 | // Setup time step 230 | INT64 current_time = 0; 231 | ::QueryPerformanceCounter((LARGE_INTEGER*)¤t_time); 232 | io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond; 233 | g_Time = current_time; 234 | 235 | // Read keyboard modifiers inputs 236 | io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; 237 | io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; 238 | io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0; 239 | io.KeySuper = false; 240 | // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. 241 | 242 | // Update OS mouse position 243 | ImGui_ImplWin32_UpdateMousePos(); 244 | 245 | // Update OS mouse cursor with the cursor requested by imgui 246 | ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); 247 | if (g_LastMouseCursor != mouse_cursor) 248 | { 249 | g_LastMouseCursor = mouse_cursor; 250 | ImGui_ImplWin32_UpdateMouseCursor(); 251 | } 252 | 253 | // Update game controllers (if enabled and available) 254 | ImGui_ImplWin32_UpdateGamepads(); 255 | } 256 | 257 | // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. 258 | #ifndef WM_MOUSEHWHEEL 259 | #define WM_MOUSEHWHEEL 0x020E 260 | #endif 261 | #ifndef DBT_DEVNODES_CHANGED 262 | #define DBT_DEVNODES_CHANGED 0x0007 263 | #endif 264 | 265 | // Win32 message handler (process Win32 mouse/keyboard inputs, etc.) 266 | // Call from your application's message handler. 267 | // When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs. 268 | // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. 269 | // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. 270 | // Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags. 271 | // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds. 272 | // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. 273 | #if 0 274 | // Copy this line into your .cpp file to forward declare the function. 275 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 276 | #endif 277 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 278 | { 279 | if (ImGui::GetCurrentContext() == NULL) 280 | return 0; 281 | 282 | ImGuiIO& io = ImGui::GetIO(); 283 | switch (msg) 284 | { 285 | case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: 286 | case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: 287 | case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: 288 | case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: 289 | { 290 | int button = 0; 291 | if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; } 292 | if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } 293 | if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } 294 | if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } 295 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) 296 | ::SetCapture(hwnd); 297 | io.MouseDown[button] = true; 298 | return 0; 299 | } 300 | case WM_LBUTTONUP: 301 | case WM_RBUTTONUP: 302 | case WM_MBUTTONUP: 303 | case WM_XBUTTONUP: 304 | { 305 | int button = 0; 306 | if (msg == WM_LBUTTONUP) { button = 0; } 307 | if (msg == WM_RBUTTONUP) { button = 1; } 308 | if (msg == WM_MBUTTONUP) { button = 2; } 309 | if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } 310 | io.MouseDown[button] = false; 311 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) 312 | ::ReleaseCapture(); 313 | return 0; 314 | } 315 | case WM_MOUSEWHEEL: 316 | io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 317 | return 0; 318 | case WM_MOUSEHWHEEL: 319 | io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 320 | return 0; 321 | case WM_KEYDOWN: 322 | case WM_SYSKEYDOWN: 323 | if (wParam < 256) 324 | io.KeysDown[wParam] = 1; 325 | return 0; 326 | case WM_KEYUP: 327 | case WM_SYSKEYUP: 328 | if (wParam < 256) 329 | io.KeysDown[wParam] = 0; 330 | return 0; 331 | case WM_CHAR: 332 | // You can also use ToAscii()+GetKeyboardState() to retrieve characters. 333 | if (wParam > 0 && wParam < 0x10000) 334 | io.AddInputCharacterUTF16((unsigned short)wParam); 335 | return 0; 336 | case WM_SETCURSOR: 337 | if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor()) 338 | return 1; 339 | return 0; 340 | case WM_DEVICECHANGE: 341 | if ((UINT)wParam == DBT_DEVNODES_CHANGED) 342 | g_WantUpdateHasGamepad = true; 343 | return 0; 344 | } 345 | return 0; 346 | } 347 | 348 | 349 | //-------------------------------------------------------------------------------------------------------- 350 | // DPI-related helpers (optional) 351 | //-------------------------------------------------------------------------------------------------------- 352 | // - Use to enable DPI awareness without having to create an application manifest. 353 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. 354 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. 355 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, 356 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. 357 | //--------------------------------------------------------------------------------------------------------- 358 | // This is the scheme successfully used by GLFW (from which we borrowed some of the code) and other apps aiming to be highly portable. 359 | // ImGui_ImplWin32_EnableDpiAwareness() is just a helper called by main.cpp, we don't call it automatically. 360 | // If you are trying to implement your own backend for your own engine, you may ignore that noise. 361 | //--------------------------------------------------------------------------------------------------------- 362 | 363 | // Implement some of the functions and types normally declared in recent Windows SDK. 364 | #if !defined(_versionhelpers_H_INCLUDED_) && !defined(_INC_VERSIONHELPERS) 365 | static BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp) 366 | { 367 | OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, { 0 }, sp, 0, 0, 0, 0 }; 368 | DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR; 369 | ULONGLONG cond = ::VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); 370 | cond = ::VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); 371 | cond = ::VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); 372 | return ::VerifyVersionInfoW(&osvi, mask, cond); 373 | } 374 | #define IsWindows8Point1OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WINBLUE 375 | #endif 376 | 377 | #ifndef DPI_ENUMS_DECLARED 378 | typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS; 379 | typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE; 380 | #endif 381 | #ifndef _DPI_AWARENESS_CONTEXTS_ 382 | DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); 383 | #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3 384 | #endif 385 | #ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 386 | #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4 387 | #endif 388 | typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+ 389 | typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+ 390 | typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update) 391 | 392 | // Helper function to enable DPI awareness without setting up a manifest 393 | void ImGui_ImplWin32_EnableDpiAwareness() 394 | { 395 | // if (IsWindows10OrGreater()) // This needs a manifest to succeed. Instead we try to grab the function pointer! 396 | { 397 | static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process 398 | if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext")) 399 | { 400 | SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); 401 | return; 402 | } 403 | } 404 | if (IsWindows8Point1OrGreater()) 405 | { 406 | static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process 407 | if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness")) 408 | { 409 | SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE); 410 | return; 411 | } 412 | } 413 | #if _WIN32_WINNT >= 0x0600 414 | ::SetProcessDPIAware(); 415 | #endif 416 | } 417 | 418 | #if defined(_MSC_VER) && !defined(NOGDI) 419 | #pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps() 420 | #endif 421 | 422 | float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) 423 | { 424 | UINT xdpi = 96, ydpi = 96; 425 | static BOOL bIsWindows8Point1OrGreater = IsWindows8Point1OrGreater(); 426 | if (bIsWindows8Point1OrGreater) 427 | { 428 | static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process 429 | if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor")) 430 | GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi); 431 | } 432 | #ifndef NOGDI 433 | else 434 | { 435 | const HDC dc = ::GetDC(NULL); 436 | xdpi = ::GetDeviceCaps(dc, LOGPIXELSX); 437 | ydpi = ::GetDeviceCaps(dc, LOGPIXELSY); 438 | ::ReleaseDC(NULL, dc); 439 | } 440 | #endif 441 | IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert! 442 | return xdpi / 96.0f; 443 | } 444 | 445 | float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) 446 | { 447 | HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST); 448 | return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); 449 | } 450 | 451 | //--------------------------------------------------------------------------------------------------------- 452 | -------------------------------------------------------------------------------- /WT/imgui_impl_win32.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Backend for Windows (standard windows API for 32 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 cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | 10 | // You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 11 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 12 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 13 | 14 | #pragma once 15 | #include "imgui.h" // IMGUI_IMPL_API 16 | 17 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); 18 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); 19 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); 20 | 21 | // Configuration 22 | // - Disable gamepad support or linking with xinput.lib 23 | //#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 24 | //#define IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT 25 | 26 | // Win32 message handler your application need to call. 27 | // - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper. 28 | // - You should COPY the line below into your .cpp code to forward declare the function and then you can call it. 29 | #if 0 30 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 31 | #endif 32 | 33 | // DPI-related helpers (optional) 34 | // - Use to enable DPI awareness without having to create an application manifest. 35 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. 36 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. 37 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, 38 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. 39 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); 40 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd 41 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor 42 | -------------------------------------------------------------------------------- /WT/imstb_rectpack.h: -------------------------------------------------------------------------------- 1 | // [DEAR IMGUI] 2 | // This is a slightly modified version of stb_rect_pack.h 1.00. 3 | // Those changes would need to be pushed into nothings/stb: 4 | // - Added STBRP__CDECL 5 | // Grep for [DEAR IMGUI] to find the changes. 6 | 7 | // stb_rect_pack.h - v1.00 - public domain - rectangle packing 8 | // Sean Barrett 2014 9 | // 10 | // Useful for e.g. packing rectangular textures into an atlas. 11 | // Does not do rotation. 12 | // 13 | // Not necessarily the awesomest packing method, but better than 14 | // the totally naive one in stb_truetype (which is primarily what 15 | // this is meant to replace). 16 | // 17 | // Has only had a few tests run, may have issues. 18 | // 19 | // More docs to come. 20 | // 21 | // No memory allocations; uses qsort() and assert() from stdlib. 22 | // Can override those by defining STBRP_SORT and STBRP_ASSERT. 23 | // 24 | // This library currently uses the Skyline Bottom-Left algorithm. 25 | // 26 | // Please note: better rectangle packers are welcome! Please 27 | // implement them to the same API, but with a different init 28 | // function. 29 | // 30 | // Credits 31 | // 32 | // Library 33 | // Sean Barrett 34 | // Minor features 35 | // Martins Mozeiko 36 | // github:IntellectualKitty 37 | // 38 | // Bugfixes / warning fixes 39 | // Jeremy Jaussaud 40 | // Fabian Giesen 41 | // 42 | // Version history: 43 | // 44 | // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles 45 | // 0.99 (2019-02-07) warning fixes 46 | // 0.11 (2017-03-03) return packing success/fail result 47 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings 48 | // 0.09 (2016-08-27) fix compiler warnings 49 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) 50 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) 51 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort 52 | // 0.05: added STBRP_ASSERT to allow replacing assert 53 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support 54 | // 0.01: initial release 55 | // 56 | // LICENSE 57 | // 58 | // See end of file for license information. 59 | 60 | ////////////////////////////////////////////////////////////////////////////// 61 | // 62 | // INCLUDE SECTION 63 | // 64 | 65 | #ifndef STB_INCLUDE_STB_RECT_PACK_H 66 | #define STB_INCLUDE_STB_RECT_PACK_H 67 | 68 | #define STB_RECT_PACK_VERSION 1 69 | 70 | #ifdef STBRP_STATIC 71 | #define STBRP_DEF static 72 | #else 73 | #define STBRP_DEF extern 74 | #endif 75 | 76 | #ifdef __cplusplus 77 | extern "C" { 78 | #endif 79 | 80 | typedef struct stbrp_context stbrp_context; 81 | typedef struct stbrp_node stbrp_node; 82 | typedef struct stbrp_rect stbrp_rect; 83 | 84 | #ifdef STBRP_LARGE_RECTS 85 | typedef int stbrp_coord; 86 | #else 87 | typedef unsigned short stbrp_coord; 88 | #endif 89 | 90 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); 91 | // Assign packed locations to rectangles. The rectangles are of type 92 | // 'stbrp_rect' defined below, stored in the array 'rects', and there 93 | // are 'num_rects' many of them. 94 | // 95 | // Rectangles which are successfully packed have the 'was_packed' flag 96 | // set to a non-zero value and 'x' and 'y' store the minimum location 97 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left 98 | // if you imagine y increasing downwards). Rectangles which do not fit 99 | // have the 'was_packed' flag set to 0. 100 | // 101 | // You should not try to access the 'rects' array from another thread 102 | // while this function is running, as the function temporarily reorders 103 | // the array while it executes. 104 | // 105 | // To pack into another rectangle, you need to call stbrp_init_target 106 | // again. To continue packing into the same rectangle, you can call 107 | // this function again. Calling this multiple times with multiple rect 108 | // arrays will probably produce worse packing results than calling it 109 | // a single time with the full rectangle array, but the option is 110 | // available. 111 | // 112 | // The function returns 1 if all of the rectangles were successfully 113 | // packed and 0 otherwise. 114 | 115 | struct stbrp_rect 116 | { 117 | // reserved for your use: 118 | int id; 119 | 120 | // input: 121 | stbrp_coord w, h; 122 | 123 | // output: 124 | stbrp_coord x, y; 125 | int was_packed; // non-zero if valid packing 126 | 127 | }; // 16 bytes, nominally 128 | 129 | 130 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); 131 | // Initialize a rectangle packer to: 132 | // pack a rectangle that is 'width' by 'height' in dimensions 133 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long 134 | // 135 | // You must call this function every time you start packing into a new target. 136 | // 137 | // There is no "shutdown" function. The 'nodes' memory must stay valid for 138 | // the following stbrp_pack_rects() call (or calls), but can be freed after 139 | // the call (or calls) finish. 140 | // 141 | // Note: to guarantee best results, either: 142 | // 1. make sure 'num_nodes' >= 'width' 143 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' 144 | // 145 | // If you don't do either of the above things, widths will be quantized to multiples 146 | // of small integers to guarantee the algorithm doesn't run out of temporary storage. 147 | // 148 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm 149 | // may run out of temporary storage and be unable to pack some rectangles. 150 | 151 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); 152 | // Optionally call this function after init but before doing any packing to 153 | // change the handling of the out-of-temp-memory scenario, described above. 154 | // If you call init again, this will be reset to the default (false). 155 | 156 | 157 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); 158 | // Optionally select which packing heuristic the library should use. Different 159 | // heuristics will produce better/worse results for different data sets. 160 | // If you call init again, this will be reset to the default. 161 | 162 | enum 163 | { 164 | STBRP_HEURISTIC_Skyline_default=0, 165 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, 166 | STBRP_HEURISTIC_Skyline_BF_sortHeight 167 | }; 168 | 169 | 170 | ////////////////////////////////////////////////////////////////////////////// 171 | // 172 | // the details of the following structures don't matter to you, but they must 173 | // be visible so you can handle the memory allocations for them 174 | 175 | struct stbrp_node 176 | { 177 | stbrp_coord x,y; 178 | stbrp_node *next; 179 | }; 180 | 181 | struct stbrp_context 182 | { 183 | int width; 184 | int height; 185 | int align; 186 | int init_mode; 187 | int heuristic; 188 | int num_nodes; 189 | stbrp_node *active_head; 190 | stbrp_node *free_head; 191 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' 192 | }; 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif 197 | 198 | #endif 199 | 200 | ////////////////////////////////////////////////////////////////////////////// 201 | // 202 | // IMPLEMENTATION SECTION 203 | // 204 | 205 | #ifdef STB_RECT_PACK_IMPLEMENTATION 206 | #ifndef STBRP_SORT 207 | #include 208 | #define STBRP_SORT qsort 209 | #endif 210 | 211 | #ifndef STBRP_ASSERT 212 | #include 213 | #define STBRP_ASSERT assert 214 | #endif 215 | 216 | // [DEAR IMGUI] Added STBRP__CDECL 217 | #ifdef _MSC_VER 218 | #define STBRP__NOTUSED(v) (void)(v) 219 | #define STBRP__CDECL __cdecl 220 | #else 221 | #define STBRP__NOTUSED(v) (void)sizeof(v) 222 | #define STBRP__CDECL 223 | #endif 224 | 225 | enum 226 | { 227 | STBRP__INIT_skyline = 1 228 | }; 229 | 230 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) 231 | { 232 | switch (context->init_mode) { 233 | case STBRP__INIT_skyline: 234 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); 235 | context->heuristic = heuristic; 236 | break; 237 | default: 238 | STBRP_ASSERT(0); 239 | } 240 | } 241 | 242 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) 243 | { 244 | if (allow_out_of_mem) 245 | // if it's ok to run out of memory, then don't bother aligning them; 246 | // this gives better packing, but may fail due to OOM (even though 247 | // the rectangles easily fit). @TODO a smarter approach would be to only 248 | // quantize once we've hit OOM, then we could get rid of this parameter. 249 | context->align = 1; 250 | else { 251 | // if it's not ok to run out of memory, then quantize the widths 252 | // so that num_nodes is always enough nodes. 253 | // 254 | // I.e. num_nodes * align >= width 255 | // align >= width / num_nodes 256 | // align = ceil(width/num_nodes) 257 | 258 | context->align = (context->width + context->num_nodes-1) / context->num_nodes; 259 | } 260 | } 261 | 262 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) 263 | { 264 | int i; 265 | #ifndef STBRP_LARGE_RECTS 266 | STBRP_ASSERT(width <= 0xffff && height <= 0xffff); 267 | #endif 268 | 269 | for (i=0; i < num_nodes-1; ++i) 270 | nodes[i].next = &nodes[i+1]; 271 | nodes[i].next = NULL; 272 | context->init_mode = STBRP__INIT_skyline; 273 | context->heuristic = STBRP_HEURISTIC_Skyline_default; 274 | context->free_head = &nodes[0]; 275 | context->active_head = &context->extra[0]; 276 | context->width = width; 277 | context->height = height; 278 | context->num_nodes = num_nodes; 279 | stbrp_setup_allow_out_of_mem(context, 0); 280 | 281 | // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) 282 | context->extra[0].x = 0; 283 | context->extra[0].y = 0; 284 | context->extra[0].next = &context->extra[1]; 285 | context->extra[1].x = (stbrp_coord) width; 286 | #ifdef STBRP_LARGE_RECTS 287 | context->extra[1].y = (1<<30); 288 | #else 289 | context->extra[1].y = 65535; 290 | #endif 291 | context->extra[1].next = NULL; 292 | } 293 | 294 | // find minimum y position if it starts at x1 295 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) 296 | { 297 | stbrp_node *node = first; 298 | int x1 = x0 + width; 299 | int min_y, visited_width, waste_area; 300 | 301 | STBRP__NOTUSED(c); 302 | 303 | STBRP_ASSERT(first->x <= x0); 304 | 305 | #if 0 306 | // skip in case we're past the node 307 | while (node->next->x <= x0) 308 | ++node; 309 | #else 310 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency 311 | #endif 312 | 313 | STBRP_ASSERT(node->x <= x0); 314 | 315 | min_y = 0; 316 | waste_area = 0; 317 | visited_width = 0; 318 | while (node->x < x1) { 319 | if (node->y > min_y) { 320 | // raise min_y higher. 321 | // we've accounted for all waste up to min_y, 322 | // but we'll now add more waste for everything we've visted 323 | waste_area += visited_width * (node->y - min_y); 324 | min_y = node->y; 325 | // the first time through, visited_width might be reduced 326 | if (node->x < x0) 327 | visited_width += node->next->x - x0; 328 | else 329 | visited_width += node->next->x - node->x; 330 | } else { 331 | // add waste area 332 | int under_width = node->next->x - node->x; 333 | if (under_width + visited_width > width) 334 | under_width = width - visited_width; 335 | waste_area += under_width * (min_y - node->y); 336 | visited_width += under_width; 337 | } 338 | node = node->next; 339 | } 340 | 341 | *pwaste = waste_area; 342 | return min_y; 343 | } 344 | 345 | typedef struct 346 | { 347 | int x,y; 348 | stbrp_node **prev_link; 349 | } stbrp__findresult; 350 | 351 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) 352 | { 353 | int best_waste = (1<<30), best_x, best_y = (1 << 30); 354 | stbrp__findresult fr; 355 | stbrp_node **prev, *node, *tail, **best = NULL; 356 | 357 | // align to multiple of c->align 358 | width = (width + c->align - 1); 359 | width -= width % c->align; 360 | STBRP_ASSERT(width % c->align == 0); 361 | 362 | // if it can't possibly fit, bail immediately 363 | if (width > c->width || height > c->height) { 364 | fr.prev_link = NULL; 365 | fr.x = fr.y = 0; 366 | return fr; 367 | } 368 | 369 | node = c->active_head; 370 | prev = &c->active_head; 371 | while (node->x + width <= c->width) { 372 | int y,waste; 373 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); 374 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL 375 | // bottom left 376 | if (y < best_y) { 377 | best_y = y; 378 | best = prev; 379 | } 380 | } else { 381 | // best-fit 382 | if (y + height <= c->height) { 383 | // can only use it if it first vertically 384 | if (y < best_y || (y == best_y && waste < best_waste)) { 385 | best_y = y; 386 | best_waste = waste; 387 | best = prev; 388 | } 389 | } 390 | } 391 | prev = &node->next; 392 | node = node->next; 393 | } 394 | 395 | best_x = (best == NULL) ? 0 : (*best)->x; 396 | 397 | // if doing best-fit (BF), we also have to try aligning right edge to each node position 398 | // 399 | // e.g, if fitting 400 | // 401 | // ____________________ 402 | // |____________________| 403 | // 404 | // into 405 | // 406 | // | | 407 | // | ____________| 408 | // |____________| 409 | // 410 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned 411 | // 412 | // This makes BF take about 2x the time 413 | 414 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { 415 | tail = c->active_head; 416 | node = c->active_head; 417 | prev = &c->active_head; 418 | // find first node that's admissible 419 | while (tail->x < width) 420 | tail = tail->next; 421 | while (tail) { 422 | int xpos = tail->x - width; 423 | int y,waste; 424 | STBRP_ASSERT(xpos >= 0); 425 | // find the left position that matches this 426 | while (node->next->x <= xpos) { 427 | prev = &node->next; 428 | node = node->next; 429 | } 430 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); 431 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); 432 | if (y + height <= c->height) { 433 | if (y <= best_y) { 434 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { 435 | best_x = xpos; 436 | STBRP_ASSERT(y <= best_y); 437 | best_y = y; 438 | best_waste = waste; 439 | best = prev; 440 | } 441 | } 442 | } 443 | tail = tail->next; 444 | } 445 | } 446 | 447 | fr.prev_link = best; 448 | fr.x = best_x; 449 | fr.y = best_y; 450 | return fr; 451 | } 452 | 453 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) 454 | { 455 | // find best position according to heuristic 456 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); 457 | stbrp_node *node, *cur; 458 | 459 | // bail if: 460 | // 1. it failed 461 | // 2. the best node doesn't fit (we don't always check this) 462 | // 3. we're out of memory 463 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { 464 | res.prev_link = NULL; 465 | return res; 466 | } 467 | 468 | // on success, create new node 469 | node = context->free_head; 470 | node->x = (stbrp_coord) res.x; 471 | node->y = (stbrp_coord) (res.y + height); 472 | 473 | context->free_head = node->next; 474 | 475 | // insert the new node into the right starting point, and 476 | // let 'cur' point to the remaining nodes needing to be 477 | // stiched back in 478 | 479 | cur = *res.prev_link; 480 | if (cur->x < res.x) { 481 | // preserve the existing one, so start testing with the next one 482 | stbrp_node *next = cur->next; 483 | cur->next = node; 484 | cur = next; 485 | } else { 486 | *res.prev_link = node; 487 | } 488 | 489 | // from here, traverse cur and free the nodes, until we get to one 490 | // that shouldn't be freed 491 | while (cur->next && cur->next->x <= res.x + width) { 492 | stbrp_node *next = cur->next; 493 | // move the current node to the free list 494 | cur->next = context->free_head; 495 | context->free_head = cur; 496 | cur = next; 497 | } 498 | 499 | // stitch the list back in 500 | node->next = cur; 501 | 502 | if (cur->x < res.x + width) 503 | cur->x = (stbrp_coord) (res.x + width); 504 | 505 | #ifdef _DEBUG 506 | cur = context->active_head; 507 | while (cur->x < context->width) { 508 | STBRP_ASSERT(cur->x < cur->next->x); 509 | cur = cur->next; 510 | } 511 | STBRP_ASSERT(cur->next == NULL); 512 | 513 | { 514 | int count=0; 515 | cur = context->active_head; 516 | while (cur) { 517 | cur = cur->next; 518 | ++count; 519 | } 520 | cur = context->free_head; 521 | while (cur) { 522 | cur = cur->next; 523 | ++count; 524 | } 525 | STBRP_ASSERT(count == context->num_nodes+2); 526 | } 527 | #endif 528 | 529 | return res; 530 | } 531 | 532 | // [DEAR IMGUI] Added STBRP__CDECL 533 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b) 534 | { 535 | const stbrp_rect *p = (const stbrp_rect *) a; 536 | const stbrp_rect *q = (const stbrp_rect *) b; 537 | if (p->h > q->h) 538 | return -1; 539 | if (p->h < q->h) 540 | return 1; 541 | return (p->w > q->w) ? -1 : (p->w < q->w); 542 | } 543 | 544 | // [DEAR IMGUI] Added STBRP__CDECL 545 | static int STBRP__CDECL rect_original_order(const void *a, const void *b) 546 | { 547 | const stbrp_rect *p = (const stbrp_rect *) a; 548 | const stbrp_rect *q = (const stbrp_rect *) b; 549 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); 550 | } 551 | 552 | #ifdef STBRP_LARGE_RECTS 553 | #define STBRP__MAXVAL 0xffffffff 554 | #else 555 | #define STBRP__MAXVAL 0xffff 556 | #endif 557 | 558 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) 559 | { 560 | int i, all_rects_packed = 1; 561 | 562 | // we use the 'was_packed' field internally to allow sorting/unsorting 563 | for (i=0; i < num_rects; ++i) { 564 | rects[i].was_packed = i; 565 | } 566 | 567 | // sort according to heuristic 568 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); 569 | 570 | for (i=0; i < num_rects; ++i) { 571 | if (rects[i].w == 0 || rects[i].h == 0) { 572 | rects[i].x = rects[i].y = 0; // empty rect needs no space 573 | } else { 574 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); 575 | if (fr.prev_link) { 576 | rects[i].x = (stbrp_coord) fr.x; 577 | rects[i].y = (stbrp_coord) fr.y; 578 | } else { 579 | rects[i].x = rects[i].y = STBRP__MAXVAL; 580 | } 581 | } 582 | } 583 | 584 | // unsort 585 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); 586 | 587 | // set was_packed flags and all_rects_packed status 588 | for (i=0; i < num_rects; ++i) { 589 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); 590 | if (!rects[i].was_packed) 591 | all_rects_packed = 0; 592 | } 593 | 594 | // return the all_rects_packed status 595 | return all_rects_packed; 596 | } 597 | #endif 598 | 599 | /* 600 | ------------------------------------------------------------------------------ 601 | This software is available under 2 licenses -- choose whichever you prefer. 602 | ------------------------------------------------------------------------------ 603 | ALTERNATIVE A - MIT License 604 | Copyright (c) 2017 Sean Barrett 605 | Permission is hereby granted, free of charge, to any person obtaining a copy of 606 | this software and associated documentation files (the "Software"), to deal in 607 | the Software without restriction, including without limitation the rights to 608 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 609 | of the Software, and to permit persons to whom the Software is furnished to do 610 | so, subject to the following conditions: 611 | The above copyright notice and this permission notice shall be included in all 612 | copies or substantial portions of the Software. 613 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 614 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 615 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 616 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 617 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 618 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 619 | SOFTWARE. 620 | ------------------------------------------------------------------------------ 621 | ALTERNATIVE B - Public Domain (www.unlicense.org) 622 | This is free and unencumbered software released into the public domain. 623 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 624 | software, either in source code form or as a compiled binary, for any purpose, 625 | commercial or non-commercial, and by any means. 626 | In jurisdictions that recognize copyright laws, the author or authors of this 627 | software dedicate any and all copyright interest in the software to the public 628 | domain. We make this dedication for the benefit of the public at large and to 629 | the detriment of our heirs and successors. We intend this dedication to be an 630 | overt act of relinquishment in perpetuity of all present and future rights to 631 | this software under copyright law. 632 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 633 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 634 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 635 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 636 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 637 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 638 | ------------------------------------------------------------------------------ 639 | */ 640 | -------------------------------------------------------------------------------- /WT/mathStuff.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma once 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "imgui.h" 8 | #include 9 | #include 10 | #include 11 | 12 | #define CHECK_VALID(_v ) 0 13 | #define Assert( _exp ) ((void)0) 14 | 15 | #define M_PI 3.14159265358979323846f 16 | #define M_RADPI 57.295779513082f 17 | #define M_PI_F ((float)(M_PI)) // Shouldn't collide with anything. 18 | #define RAD2DEG( x ) ( (float)(x) * (float)(180.f / M_PI_F) ) 19 | #define DEG2RAD( x ) ( (float)(x) * (float)(M_PI_F / 180.f) ) 20 | 21 | class Vector; 22 | class Angle; 23 | 24 | namespace M 25 | { 26 | bool DirectXWorldToScreen(const Vector& point, Vector& screen); 27 | bool ScreenTransform(const Vector& point, ImVec2& screen); 28 | bool WorldToScreen(const Vector& origin, ImVec2& screen); 29 | bool WS2(const Vector& point, ImVec2& screen); 30 | //Vector VectorTransform(const Vector in, float *matrix); 31 | void VectorTransform(Vector& in1, Vector* in2, Vector& out); 32 | void MatrixAngles(const Vector matrix[3], Angle& Angles); 33 | 34 | void VectorAngles(const Vector& forward, Angle& angles); 35 | float GetFOV(const Angle& viewangles, const Angle& aimangles); 36 | 37 | void AngleVectors(const Angle& angles, Vector* forward); 38 | Angle CalcAngle(Vector src, Vector dst); 39 | 40 | void NormalizeAngles(Angle& angles); 41 | } 42 | 43 | class AngleByValue; 44 | class Angle 45 | { 46 | public: 47 | float x, y, z; 48 | 49 | Angle(void); 50 | Angle(float X, float Y, float Z); 51 | 52 | operator AngleByValue& () 53 | { 54 | return *((AngleByValue*)(this)); 55 | } 56 | 57 | operator const AngleByValue& () const 58 | { 59 | return *((const AngleByValue*)(this)); 60 | } 61 | 62 | void Init(float ix = 0.0f, float iy = 0.0f, float iz = 0.0f); 63 | void Random(float minVal, float maxVal); 64 | 65 | bool IsValid() const; 66 | void Invalidate(); 67 | 68 | bool IsZero() 69 | { 70 | CHECK_VALID(*this); 71 | if (this->x == 0.f && this->y == 0.f && this->z == 0.f) 72 | return true; 73 | 74 | return false; 75 | } 76 | 77 | float operator[](int i) const; 78 | float& operator[](int i); 79 | 80 | float* Base(); 81 | float const* Base() const; 82 | 83 | bool operator==(const Angle& v) const; 84 | bool operator!=(const Angle& v) const; 85 | 86 | Angle& operator+=(const Angle& v); 87 | Angle& operator-=(const Angle& v); 88 | Angle& operator*=(float s); 89 | Angle& operator/=(float s); 90 | 91 | float Length() const; 92 | float LengthSqr() const; 93 | 94 | Angle& operator=(const Angle& src); 95 | 96 | //Angle operator-(void) const; 97 | 98 | Angle operator+(const Angle& v) const; 99 | Angle operator-(const Angle& v) const; 100 | Angle operator*(float fl) const; 101 | Angle operator/(float fl) const; 102 | 103 | Angle Clamp(); 104 | Angle Mod(float N); 105 | 106 | inline auto Normalize() 107 | { 108 | auto x_rev = this->x / 360.f; 109 | if (this->x > 180.f || this->x < -180.f) 110 | { 111 | x_rev = std::abs(x_rev); 112 | x_rev = std::round(x_rev); 113 | 114 | if (this->x < 0.f) 115 | this->x = (this->x + 360.f * x_rev); 116 | 117 | else 118 | this->x = (this->x - 360.f * x_rev); 119 | } 120 | 121 | auto y_rev = this->y / 360.f; 122 | if (this->y > 180.f || this->y < -180.f) 123 | { 124 | y_rev = std::abs(y_rev); 125 | y_rev = std::round(y_rev); 126 | 127 | if (this->y < 0.f) 128 | this->y = (this->y + 360.f * y_rev); 129 | 130 | else 131 | this->y = (this->y - 360.f * y_rev); 132 | } 133 | 134 | auto z_rev = this->z / 360.f; 135 | if (this->z > 180.f || this->z < -180.f) 136 | { 137 | z_rev = std::abs(z_rev); 138 | z_rev = std::round(z_rev); 139 | 140 | if (this->z < 0.f) 141 | this->z = (this->z + 360.f * z_rev); 142 | 143 | else 144 | this->z = (this->z - 360.f * z_rev); 145 | } 146 | } 147 | 148 | Angle Normalized() 149 | { 150 | if (this->x != this->x) 151 | this->x = 0; 152 | if (this->y != this->y) 153 | this->y = 0; 154 | if (this->z != this->z) 155 | this->z = 0; 156 | 157 | if (this->x > 89.f) 158 | this->x = 89.f; 159 | if (this->x < -89.f) 160 | this->x = -89.f; 161 | 162 | while (this->y > 180) 163 | this->y -= 360; 164 | while (this->y <= -180) 165 | this->y += 360; 166 | 167 | if (this->y > 180.f) 168 | this->y = 180.f; 169 | if (this->y < -180.f) 170 | this->y = -180.f; 171 | 172 | this->z = 0; 173 | 174 | return *this; 175 | } 176 | 177 | std::string ToString(std::string per, unsigned prec = 2); 178 | }; 179 | 180 | inline std::string Angle::ToString(std::string per, unsigned prec) 181 | { 182 | std::stringstream ss; 183 | ss << std::fixed << std::setprecision(prec) << x << per << y << per << z; 184 | return ss.str(); 185 | } 186 | 187 | inline Angle::Angle(void) 188 | { 189 | #ifdef _DEBUG 190 | #ifdef VECTOR_PARANOIA 191 | // Initialize to NAN to catch errors 192 | x = y = z = float_NAN; 193 | #endif 194 | #endif 195 | } 196 | 197 | inline Angle::Angle(float X, float Y, float Z) 198 | { 199 | x = X; 200 | y = Y; 201 | z = Z; 202 | CHECK_VALID(*this); 203 | } 204 | 205 | //----------------------------------------------------------------------------- 206 | // initialization 207 | //----------------------------------------------------------------------------- 208 | inline void Angle::Init(float ix, float iy, float iz) 209 | { 210 | x = ix; 211 | y = iy; 212 | z = iz; 213 | CHECK_VALID(*this); 214 | } 215 | 216 | inline void Angle::Random(float minVal, float maxVal) 217 | { 218 | x = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); 219 | y = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); 220 | z = minVal + ((float)rand() / RAND_MAX) * (maxVal - minVal); 221 | CHECK_VALID(*this); 222 | } 223 | 224 | //----------------------------------------------------------------------------- 225 | // assignment 226 | //----------------------------------------------------------------------------- 227 | inline Angle& Angle::operator=(const Angle& vOther) 228 | { 229 | CHECK_VALID(vOther); 230 | x = vOther.x; 231 | y = vOther.y; 232 | z = vOther.z; 233 | return *this; 234 | } 235 | 236 | //----------------------------------------------------------------------------- 237 | // comparison 238 | //----------------------------------------------------------------------------- 239 | inline bool Angle::operator==(const Angle& src) const 240 | { 241 | CHECK_VALID(src); 242 | CHECK_VALID(*this); 243 | return (src.x == x) && (src.y == y) && (src.z == z); 244 | } 245 | 246 | inline bool Angle::operator!=(const Angle& src) const 247 | { 248 | CHECK_VALID(src); 249 | CHECK_VALID(*this); 250 | return (src.x != x) || (src.y != y) || (src.z != z); 251 | } 252 | 253 | //----------------------------------------------------------------------------- 254 | // standard math operations 255 | //----------------------------------------------------------------------------- 256 | inline Angle& Angle::operator+=(const Angle& v) 257 | { 258 | CHECK_VALID(*this); 259 | CHECK_VALID(v); 260 | x += v.x; 261 | y += v.y; 262 | z += v.z; 263 | return *this; 264 | } 265 | 266 | inline Angle& Angle::operator-=(const Angle& v) 267 | { 268 | CHECK_VALID(*this); 269 | CHECK_VALID(v); 270 | x -= v.x; 271 | y -= v.y; 272 | z -= v.z; 273 | return *this; 274 | } 275 | 276 | inline Angle& Angle::operator*=(float fl) 277 | { 278 | x *= fl; 279 | y *= fl; 280 | z *= fl; 281 | CHECK_VALID(*this); 282 | return *this; 283 | } 284 | 285 | inline Angle& Angle::operator/=(float fl) 286 | { 287 | Assert(fl != 0.0f); 288 | float oofl = 1.0f / fl; 289 | x *= oofl; 290 | y *= oofl; 291 | z *= oofl; 292 | CHECK_VALID(*this); 293 | return *this; 294 | } 295 | 296 | //----------------------------------------------------------------------------- 297 | // Base address... 298 | //----------------------------------------------------------------------------- 299 | inline float* Angle::Base() 300 | { 301 | return (float*)this; 302 | } 303 | 304 | inline float const* Angle::Base() const 305 | { 306 | return (float const*)this; 307 | } 308 | 309 | //----------------------------------------------------------------------------- 310 | // Array access 311 | //----------------------------------------------------------------------------- 312 | inline float& Angle::operator[](int i) 313 | { 314 | Assert((i >= 0) && (i < 3)); 315 | return ((float*)this)[i]; 316 | } 317 | 318 | inline float Angle::operator[](int i) const 319 | { 320 | Assert((i >= 0) && (i < 3)); 321 | return ((float*)this)[i]; 322 | } 323 | 324 | //----------------------------------------------------------------------------- 325 | // length 326 | //----------------------------------------------------------------------------- 327 | inline float Angle::Length() const 328 | { 329 | CHECK_VALID(*this); 330 | return (float)sqrt(LengthSqr()); //todo replace with fastsqrt 331 | } 332 | 333 | inline float Angle::LengthSqr() const 334 | { 335 | CHECK_VALID(*this); 336 | return x * x + y * y; 337 | } 338 | 339 | //inline Angle Angle::operator-(void) const 340 | //{ 341 | // return Angle(-x, -y, -z); 342 | //} 343 | 344 | inline Angle Angle::operator+(const Angle& v) const 345 | { 346 | Angle res; 347 | res.x = x + v.x; 348 | res.y = y + v.y; 349 | res.z = z + v.z; 350 | return res; 351 | } 352 | 353 | inline Angle Angle::operator-(const Angle& v) const 354 | { 355 | Angle res; 356 | res.x = x - v.x; 357 | res.y = y - v.y; 358 | res.z = z - v.z; 359 | return res; 360 | } 361 | 362 | inline Angle Angle::operator*(float fl) const 363 | { 364 | Angle res; 365 | res.x = x * fl; 366 | res.y = y * fl; 367 | res.z = z * fl; 368 | return res; 369 | } 370 | 371 | inline Angle Angle::operator/(float fl) const 372 | { 373 | Angle res; 374 | res.x = x / fl; 375 | res.y = y / fl; 376 | res.z = z / fl; 377 | return res; 378 | } 379 | 380 | inline Angle Angle::Clamp() 381 | { 382 | CHECK_VALID(*this); 383 | 384 | if (this->y < -89.0f) 385 | this->y = -89.0f; 386 | 387 | if (this->y > 89.0f) 388 | this->y = 89.0f; 389 | 390 | while (this->x < -180.0f) 391 | this->x += 360.0f; 392 | 393 | while (this->x > 180.0f) 394 | this->x -= 360.0f; 395 | 396 | this->z = 0.0f; 397 | 398 | return *this; 399 | } 400 | 401 | inline Angle Angle::Mod(float N) 402 | { 403 | CHECK_VALID(*this); 404 | this->x = fmod(x, N); 405 | this->y = fmod(y, N); 406 | this->z = fmod(z, N); 407 | 408 | return *this; 409 | } 410 | 411 | class Vector 412 | { 413 | public: 414 | float x, y, z; 415 | Vector(void); 416 | Vector(float X, float Y, float Z); 417 | Vector(float x, float y); 418 | Vector(ImVec2& v); 419 | Vector(float v[3]) 420 | { 421 | x = v[0]; 422 | y = v[1]; 423 | z = v[2]; 424 | } 425 | Vector(DirectX::XMVECTOR& v) 426 | { 427 | x = DirectX::XMVectorGetX(v); 428 | y = DirectX::XMVectorGetY(v); 429 | z = DirectX::XMVectorGetZ(v); 430 | } 431 | void Init(float ix = 0.f, float iy = 0.f, float iz = 0.f); 432 | float operator[](int i) const; 433 | float& operator[](int i); 434 | inline void Zero(); 435 | bool operator==(const Vector& v) const; 436 | bool operator!=(const Vector& v) const; 437 | __forceinline Vector& operator+=(const Vector& v); 438 | __forceinline Vector& operator-=(const Vector& v); 439 | __forceinline Vector& operator*=(const Vector& v); 440 | __forceinline Vector& operator*=(float s); 441 | __forceinline Vector& operator/=(const Vector& v); 442 | __forceinline Vector& operator/=(float s); 443 | __forceinline Vector& operator+=(float fl); 444 | __forceinline Vector& operator-=(float fl); 445 | inline float Length() const; 446 | operator DirectX::XMVECTOR() const 447 | { 448 | return DirectX::XMVectorSet(x, y, z, 0.f); 449 | } 450 | operator ImVec2() const 451 | { 452 | return ImVec2{ x, y }; 453 | } 454 | __forceinline float LengthSqr(void) const 455 | { 456 | CHECK_VALID(*this); 457 | return (x * x + y * y + z * z); 458 | } 459 | bool IsZero(float tolerance = 0.01f) const 460 | { 461 | return (x > -tolerance && x < tolerance&& 462 | y > -tolerance && y < tolerance&& 463 | z > -tolerance && z < tolerance); 464 | } 465 | Vector NormalizeInPlace(); 466 | Vector fNormalize(const float ir_frac); 467 | Vector Normalize(float coeff); 468 | __forceinline float DistToSqr(const Vector& vOther) const; 469 | float Dot(const Vector& vOther) const; 470 | float Length2D(void) const; 471 | float Length2DSqr(void) const; 472 | Vector& operator=(const Vector& vOther); 473 | Vector operator+(const Vector& v) const; 474 | Vector operator-(const Vector& v) const; 475 | Vector operator*(const Vector& v) const; 476 | Vector operator/(const Vector& v) const; 477 | Vector operator*(float fl) const; 478 | Vector operator/(float fl) const; 479 | 480 | void Rotate2D(const float& f); 481 | void Rotate(const Angle&); 482 | std::string ToString(unsigned prec = 2); 483 | }; 484 | 485 | inline std::string Vector::ToString(unsigned prec) 486 | { 487 | std::stringstream ss; 488 | ss << std::fixed << std::setprecision(prec) << x << "," << y << "," << z; 489 | return ss.str(); 490 | } 491 | 492 | inline void SinCos(const float& r, float& s, float& c) 493 | { 494 | s = sin(r); 495 | c = cos(r); 496 | } 497 | 498 | inline void Vector::Rotate(const Angle& e) 499 | { 500 | float _x, _y, _z; 501 | 502 | float s, c; 503 | 504 | SinCos(DEG2RAD(e.x), s, c); 505 | 506 | _y = y; 507 | _z = z; 508 | 509 | y = (_y * c) - (_z * s); 510 | z = (_y * s) + (_z * c); 511 | 512 | SinCos(DEG2RAD(e.y), s, c); 513 | 514 | _x = x; 515 | _z = z; 516 | 517 | x = (_x * c) + (_z * s); 518 | z = (-_x * s) + (_z * c); 519 | 520 | SinCos(DEG2RAD(e.z), s, c); 521 | 522 | _x = x; 523 | _y = y; 524 | 525 | x = (_x * c) - (_y * s); 526 | y = (_x * s) + (_y * c); 527 | } 528 | 529 | inline void Vector::Rotate2D(const float& f) 530 | { 531 | float _x, _y; 532 | 533 | float s, c; 534 | 535 | SinCos(DEG2RAD(f), s, c); 536 | 537 | _x = x; 538 | _y = y; 539 | 540 | x = (_x * c) - (_y * s); 541 | y = (_x * s) + (_y * c); 542 | } 543 | inline void Vector::Init(float ix, float iy, float iz) 544 | { 545 | x = ix; y = iy; z = iz; 546 | CHECK_VALID(*this); 547 | } 548 | inline Vector::Vector(float X, float Y, float Z) 549 | { 550 | x = X; y = Y; z = Z; 551 | CHECK_VALID(*this); 552 | } 553 | 554 | inline Vector::Vector(ImVec2& v) 555 | { 556 | x = v.x; 557 | y = v.y; 558 | z = 0.f; 559 | } 560 | 561 | inline Vector::Vector(float _x, float _y) 562 | { 563 | x = _x; 564 | y = _y; 565 | z = 0.f; 566 | } 567 | 568 | inline Vector::Vector(void) 569 | { 570 | } 571 | inline void Vector::Zero() 572 | { 573 | x = y = z = 0.f; 574 | } 575 | inline void VectorClear(Vector& a) 576 | { 577 | a.x = a.y = a.z = 0.f; 578 | } 579 | inline Vector& Vector::operator=(const Vector& vOther) 580 | { 581 | CHECK_VALID(vOther); 582 | x = vOther.x; y = vOther.y; z = vOther.z; 583 | return *this; 584 | } 585 | inline float& Vector::operator[](int i) 586 | { 587 | Assert((i >= 0) && (i < 3)); 588 | return ((float*)this)[i]; 589 | } 590 | inline float Vector::operator[](int i) const 591 | { 592 | Assert((i >= 0) && (i < 3)); 593 | return ((float*)this)[i]; 594 | } 595 | inline bool Vector::operator==(const Vector& src) const 596 | { 597 | CHECK_VALID(src); 598 | CHECK_VALID(*this); 599 | return (src.x == x) && (src.y == y) && (src.z == z); 600 | } 601 | inline bool Vector::operator!=(const Vector& src) const 602 | { 603 | CHECK_VALID(src); 604 | CHECK_VALID(*this); 605 | return (src.x != x) || (src.y != y) || (src.z != z); 606 | } 607 | __forceinline void VectorCopy(const Vector& src, Vector& dst) 608 | { 609 | CHECK_VALID(src); 610 | dst.x = src.x; 611 | dst.y = src.y; 612 | dst.z = src.z; 613 | } 614 | __forceinline Vector& Vector::operator+=(const Vector& v) 615 | { 616 | CHECK_VALID(*this); 617 | CHECK_VALID(v); 618 | x += v.x; y += v.y; z += v.z; 619 | return *this; 620 | } 621 | __forceinline Vector& Vector::operator-=(const Vector& v) 622 | { 623 | CHECK_VALID(*this); 624 | CHECK_VALID(v); 625 | x -= v.x; y -= v.y; z -= v.z; 626 | return *this; 627 | } 628 | __forceinline Vector& Vector::operator*=(float fl) 629 | { 630 | x *= fl; 631 | y *= fl; 632 | z *= fl; 633 | CHECK_VALID(*this); 634 | return *this; 635 | } 636 | __forceinline Vector& Vector::operator*=(const Vector& v) 637 | { 638 | CHECK_VALID(v); 639 | x *= v.x; 640 | y *= v.y; 641 | z *= v.z; 642 | CHECK_VALID(*this); 643 | return *this; 644 | } 645 | 646 | __forceinline Vector& Vector::operator+=(float fl) 647 | { 648 | x += fl; 649 | y += fl; 650 | z += fl; 651 | CHECK_VALID(*this); 652 | return *this; 653 | } 654 | 655 | __forceinline Vector& Vector::operator-=(float fl) 656 | { 657 | x -= fl; 658 | y -= fl; 659 | z -= fl; 660 | CHECK_VALID(*this); 661 | return *this; 662 | } 663 | 664 | __forceinline Vector& Vector::operator/=(float fl) 665 | { 666 | Assert(fl != 0.f); 667 | float oofl = 1.0f / fl; 668 | x *= oofl; 669 | y *= oofl; 670 | z *= oofl; 671 | CHECK_VALID(*this); 672 | return *this; 673 | } 674 | 675 | __forceinline Vector& Vector::operator/=(const Vector& v) 676 | { 677 | CHECK_VALID(v); 678 | Assert(v.x != 0.f && v.y != 0.f && v.z != 0.f); 679 | x /= v.x; 680 | y /= v.y; 681 | z /= v.z; 682 | CHECK_VALID(*this); 683 | return *this; 684 | } 685 | 686 | inline float Vector::Length(void) const 687 | { 688 | CHECK_VALID(*this); 689 | return std::sqrtf(x * x + y * y + z * z); 690 | } 691 | 692 | inline float Vector::Length2D(void) const 693 | { 694 | CHECK_VALID(*this); 695 | return std::sqrtf(x * x + z * z); 696 | //return std::sqrtf(x * x + y * y); 697 | } 698 | 699 | inline float Vector::Length2DSqr(void) const 700 | { 701 | return (x * x + y * y); 702 | } 703 | 704 | inline Vector CrossProduct(const Vector& a, const Vector& b) 705 | { 706 | return Vector(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); 707 | } 708 | 709 | float Vector::DistToSqr(const Vector& vOther) const 710 | { 711 | Vector delta; 712 | 713 | delta.x = x - vOther.x; 714 | delta.y = y - vOther.y; 715 | delta.z = z - vOther.z; 716 | 717 | return delta.LengthSqr(); 718 | } 719 | 720 | //Vector Vector::NormalizeInPlace(const float ir_frac) 721 | //{ 722 | // Vector& v = *this; 723 | // 724 | // float iradius = ir_frac / (this->Length() + 1.192092896e-07F); //FLT_EPSILON 725 | // 726 | // v.x *= iradius; 727 | // v.y *= iradius; 728 | // v.z *= iradius; 729 | // return v; 730 | //} 731 | 732 | inline Vector Vector::NormalizeInPlace() 733 | { 734 | Vector& v = *this; 735 | 736 | float iradius = 1.0f / (this->Length() + 1.192092896e-07F); //FLT_EPSILON 737 | 738 | v.x *= iradius; 739 | v.y *= iradius; 740 | v.z *= iradius; 741 | return v; 742 | } 743 | 744 | inline Vector Vector::fNormalize(const float ir_frac) 745 | { 746 | Vector vector; 747 | float length = this->Length(); 748 | 749 | if (length != 0) 750 | { 751 | vector.x = x * ir_frac / length; 752 | vector.y = y * ir_frac / length; 753 | vector.z = z * ir_frac / length; 754 | } 755 | else 756 | vector.x = vector.y = 0.0f; 757 | vector.z = 1.0f; 758 | 759 | return vector; 760 | } 761 | 762 | inline Vector Vector::Normalize(float coeff = 1.0f) 763 | { 764 | Vector vector; 765 | float length = this->Length(); 766 | 767 | if (length <= 0.000000001) 768 | { 769 | vector.x = x * (coeff / length); 770 | vector.y = y * (coeff / length); 771 | vector.z = z * (coeff / length); 772 | } 773 | else 774 | { 775 | vector.x = vector.z = 0.0f; 776 | vector.y = 1.0f; 777 | } 778 | 779 | return vector; 780 | } 781 | 782 | inline Vector Vector::operator+(const Vector& v) const 783 | { 784 | Vector res; 785 | res.x = x + v.x; 786 | res.y = y + v.y; 787 | res.z = z + v.z; 788 | return res; 789 | } 790 | 791 | inline Vector Vector::operator-(const Vector& v) const 792 | { 793 | Vector res; 794 | res.x = x - v.x; 795 | res.y = y - v.y; 796 | res.z = z - v.z; 797 | return res; 798 | } 799 | 800 | inline Vector Vector::operator*(float fl) const 801 | { 802 | Vector res; 803 | res.x = x * fl; 804 | res.y = y * fl; 805 | res.z = z * fl; 806 | return res; 807 | } 808 | 809 | inline Vector Vector::operator*(const Vector& v) const 810 | { 811 | Vector res; 812 | res.x = x * v.x; 813 | res.y = y * v.y; 814 | res.z = z * v.z; 815 | return res; 816 | } 817 | 818 | inline Vector Vector::operator/(float fl) const 819 | { 820 | Vector res; 821 | res.x = x / fl; 822 | res.y = y / fl; 823 | res.z = z / fl; 824 | return res; 825 | } 826 | 827 | inline Vector Vector::operator/(const Vector& v) const 828 | { 829 | Vector res; 830 | res.x = x / v.x; 831 | res.y = y / v.y; 832 | res.z = z / v.z; 833 | return res; 834 | } 835 | inline float Vector::Dot(const Vector& vOther) const 836 | { 837 | const Vector& a = *this; 838 | 839 | return(a.x * vOther.x + a.y * vOther.y + a.z * vOther.z); 840 | } -------------------------------------------------------------------------------- /WT/offsets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define gameVersion "2.3.0.64" 4 | 5 | #define playerListOffset 0x350A240 6 | #define playerCountOffset 0x350A248 7 | 8 | #define entitySignatureOffset 0x20 9 | #define playerNameOffset 0xB0 10 | #define entityUnitOffset 0x6D0 11 | #define unitCoordsOffset 0x818 12 | //#define unitVelocityOffset 0x15020 13 | #define unitVelocityOffset 0x1e778 14 | #define viewMatrixOffset 0x3F7BEB0 15 | #define teamIdOffset 0x230 16 | #define mLocalPlayerOffset 0x350A260 17 | #define entitySignature 0x54454E44 18 | #define gameInfoOffset 0x34A5D30 19 | #define isInFlightOffset 0xD3 20 | #define mainMenuLocalPlayerOffset 0x3505EE9 21 | #define bulletMuzzleVelocity 823 -------------------------------------------------------------------------------- /WT/rD3D11.cpp: -------------------------------------------------------------------------------- 1 | #include "rD3D11.h" 2 | #include "structs.h" 3 | #include "imgui_impl_dx11.h" 4 | #include "d3d11hook.h" 5 | 6 | BOOL CALLBACK EnumWindowsCallback(HWND hWnd, LPARAM lParam) 7 | { 8 | HandleData& data = *(HandleData*)lParam; 9 | DWORD pid = 0; 10 | GetWindowThreadProcessId(hWnd, &pid); 11 | if (pid == data.pid && GetWindow(hWnd, GW_OWNER) == HWND(0) && IsWindowVisible(hWnd)) 12 | { 13 | data.hWnd = hWnd; 14 | return FALSE; 15 | } 16 | 17 | return TRUE; 18 | } 19 | 20 | HWND FindMainWindow(DWORD dwPID) 21 | { 22 | HandleData handleData{ 0 }; 23 | handleData.pid = dwPID; 24 | EnumWindows(EnumWindowsCallback, (LPARAM)&handleData); 25 | return handleData.hWnd; 26 | } 27 | 28 | 29 | void MasterClass::InitD3DHook(HMODULE hModule) { 30 | ImplHookDX11_Init(hModule, FindMainWindow(GetCurrentProcessId())); 31 | } -------------------------------------------------------------------------------- /WT/rD3D11.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include // 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include // color https://github.com/microsoft/DirectXMath/ 8 | #include "w2sAndUtils.h" 9 | #include "offsets.h" 10 | 11 | 12 | #pragma comment(lib, "d3d11.lib") 13 | #pragma comment(lib, "d3dcompiler.lib") 14 | 15 | #define safe_release(p) if (p) { p->Release(); p = nullptr; } 16 | #define PRESENT_STUB_SIZE 5 17 | #define MAINVP 0 18 | #define VMT_PRESENT (UINT)IDXGISwapChainVMT::Present 19 | 20 | struct HandleData { 21 | DWORD pid; 22 | HWND hWnd; 23 | }; 24 | 25 | class MasterClass; 26 | 27 | class MasterClass 28 | { 29 | public: 30 | ID3D11Device* g_pd3dDevice = nullptr; 31 | IDXGISwapChain* pSwapchain = nullptr; 32 | ID3D11DeviceContext* pContext = nullptr; 33 | ID3D11RenderTargetView* pRenderTargetView = nullptr; 34 | ID3D11VertexShader* pVertexShader = nullptr; 35 | ID3D11InputLayout* pVertexLayout = nullptr; 36 | ID3D11PixelShader* pPixelShader = nullptr; 37 | ID3D11Buffer* pVertexBuffer = nullptr; 38 | ID3D11Buffer* pIndexBuffer = nullptr; 39 | ID3D11Buffer* pConstantBuffer = nullptr; 40 | 41 | HWND hWnd; 42 | RECT windowRect; 43 | 44 | uintptr_t exeBase; 45 | uintptr_t viewMatrix; 46 | uintptr_t pToGameInfo; 47 | 48 | D3D11_VIEWPORT pViewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]{ 0 }; 49 | D3D11_VIEWPORT myViewport; 50 | DirectX::XMMATRIX mOrtho; 51 | 52 | //hook stuff 53 | using fnPresent = HRESULT(__stdcall*)(IDXGISwapChain* pThis, UINT SyncInterval, UINT Flags); 54 | void* originalPresentFcn; // Pointer to the original Present function 55 | fnPresent ogPresentTramp; // Pointer to our trampoline 56 | 57 | void* pTrampoline = nullptr; // Pointer to jmp instruction in our trampoline that leads to hkPresent 58 | char originalPresentBytes[PRESENT_STUB_SIZE]; // Buffer to store original bytes from Present 59 | 60 | void InitD3DHook(HMODULE hModule); 61 | 62 | }; 63 | 64 | extern MasterClass MC; 65 | 66 | HWND FindMainWindow(DWORD dwPID); -------------------------------------------------------------------------------- /WT/stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralFire/WarThunderHack/92eb7bd80b004954f75ccafc3d02efd38a891c07/WT/stdafx.cpp -------------------------------------------------------------------------------- /WT/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralFire/WarThunderHack/92eb7bd80b004954f75ccafc3d02efd38a891c07/WT/stdafx.h -------------------------------------------------------------------------------- /WT/structs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "w2sAndUtils.h" 3 | 4 | class Unit 5 | { 6 | public: 7 | char pad_0000[2036]; //0x0000 8 | vec3 rotationMatricies[3]; //0x07F4 9 | vec3 position; //0x0818 10 | char pad_0824[1784]; //0x0824 11 | uint32_t N00000241; //0x0F1C 12 | uint32_t N00002F71; //0x0F20 13 | char pad_0F24[34]; //0x0F24 14 | class N00002F77* N00000246; //0x0F46 15 | char pad_0F4E[216]; //0x0F4E 16 | class N00002F8B* N00000262; //0x1026 17 | char pad_102E[92264]; //0x102E 18 | }; //Size: 0x17896 19 | 20 | 21 | class GameInfo { 22 | public: 23 | char pad_0000[208]; //0x0000 24 | bool N000000FC; //0x00D0 25 | bool N00000116; //0x00D1 26 | bool N0000011A; //0x00D2 27 | bool isInFlightPositive; //0x00D3 28 | bool N0000011B; //0x00D4 29 | bool isInFlightNegative; //0x00D5 30 | bool N00000121; //0x00D6 31 | bool N00000118; //0x00D7 32 | char pad_00D8[176]; //0x00D8 33 | }; //Size: 0x0188 34 | 35 | 36 | class CBaseEntity 37 | { 38 | public: 39 | char pad_0000[32]; //0x0000 40 | uint32_t sign; //0x0020 41 | char pad_0024[132]; //0x0024 42 | int64_t UID; //0x00A8 43 | char name[64]; //0x00B0 44 | char pad_00F0[276]; //0x00F0 45 | uint32_t N000000B6; //0x0204 46 | uint8_t teamId; //0x0208 47 | char pad_0209[35]; //0x0209 48 | uint32_t N000000BB; //0x022C 49 | uint8_t teasdasdamId; //0x0230 50 | char pad_0231[627]; //0x0231 51 | uint32_t N000001CB; //0x04A4 52 | uint8_t state; //0x04A8 53 | char pad_04A9[547]; //0x04A9 54 | uint32_t N000003B1; //0x06CC 55 | Unit* unit; //0x06D0 56 | char pad_06D8[56]; //0x06D8 57 | 58 | bool is_valid() const { return true; } 59 | 60 | //std::string GetName(); 61 | bool IsFriendly(); 62 | bool IsEnemy(); 63 | bool IsAlive(); 64 | //int GetState(); 65 | uint32_t GetTeam(); 66 | //EntityState GetState(); 67 | //int GetFlags(); 68 | float GetRespawnTime(); 69 | //Unit* GetUnit(); 70 | bool IsBot(); 71 | //bool IsVisible(); 72 | //bool IsDormant(); 73 | //Vector GetPosition(); 74 | }; //Size: 0x0e10 75 | 76 | class unit { 77 | 78 | }; -------------------------------------------------------------------------------- /WT/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralFire/WarThunderHack/92eb7bd80b004954f75ccafc3d02efd38a891c07/WT/targetver.h -------------------------------------------------------------------------------- /WT/w2sAndUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "w2sAndUtils.h" 2 | #include "DirectXMath.h" 3 | #include "stdio.h" 4 | 5 | vec3 Subtract(vec3 src, vec3 dst) { 6 | vec3 diff; 7 | diff.x = src.x - dst.x; 8 | diff.y = src.y - dst.y; 9 | diff.z = src.z - dst.z; 10 | return diff; 11 | } 12 | 13 | vec3 Divide(vec3 src, float num) { 14 | vec3 vec; 15 | vec.x = src.x / num; 16 | vec.y = src.y / num; 17 | vec.z = src.z / num; 18 | 19 | return vec; 20 | } 21 | 22 | float DotProduct(vec3 src, vec3 dst) 23 | { 24 | return src.x * dst.x + src.y * dst.y + src.z * dst.z; 25 | } 26 | 27 | DirectX::XMMATRIX Multiplier = { 1, 0, 0, 0, 28 | 0, 1, 0, 0, 29 | 0, 0, 1, 0, 30 | 0, 0, 0, 1 }; 31 | bool DirectXWorldToScreen(vec3 point, vec3& screen, D3DX11Matricies* matrixies, float width, float height) 32 | { 33 | DirectX::XMFLOAT3 out_2d; 34 | 35 | DirectX::XMVECTOR out = DirectX::XMVector3Project(DirectX::XMVectorSet(point.x, point.y, point.z, 0.f), 36 | 0, 0, width, height, 0, 1, XMMatrixMultiply(matrixies->ProjectionMatrix, Multiplier), 37 | matrixies->ViewMatrix, (matrixies->WorldMatrix)); 38 | 39 | DirectX::XMStoreFloat3(&out_2d, out); 40 | //printf("%4.2f %4.2f %4.2f\r\n", out_2d.x, out_2d.y, out_2d.z); 41 | float* matrix = (float*)matrixies; 42 | 43 | if (out_2d.z > 0.f) { 44 | screen.x = out_2d.x; 45 | screen.y = out_2d.y; 46 | //printf("%4.2f %4.2f %4.2f %4.2f -- %4.2f %4.2f\r\n", out_2d.x, out_2d.y, matrix[18], matrix[0], screen.x, screen.y); 47 | return true; 48 | } 49 | 50 | return false; 51 | } 52 | 53 | bool RotateDot(float* rotationMatrix, vec3 originDot, vec3& rotatedDot) { 54 | rotatedDot.x = originDot.x * rotationMatrix[0] + originDot.y * rotationMatrix[3] + originDot.z * rotationMatrix[6]; 55 | rotatedDot.y = originDot.x * rotationMatrix[1] + originDot.y * rotationMatrix[4] + originDot.z * rotationMatrix[7]; 56 | rotatedDot.z = originDot.x * rotationMatrix[2] + originDot.y * rotationMatrix[5] + originDot.z * rotationMatrix[8]; 57 | 58 | return true; 59 | } -------------------------------------------------------------------------------- /WT/w2sAndUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "imgui.h" 6 | 7 | #define P(x) (intptr_t*)x 8 | #define I(x) (intptr_t)x 9 | #define C(x) (char*)x 10 | #define UP(x) (uintptr_t*)x 11 | #define UI(x) (uintptr_t)x 12 | 13 | //game specific defines 14 | //angles 15 | #define YAW 0 //x 16 | #define ROLL 1 //y, normally this is Z 17 | #define PITCH 2 //z 18 | 19 | //position 20 | #define POS_FORWARD 0 //x 21 | #define POS_VERTICAL 1 //y, normally this is Z 22 | #define POS_STRAFE 2 //z 23 | 24 | class vec3 25 | { 26 | public: 27 | 28 | float x, y, z; 29 | 30 | vec3() { x = y = z = 0; } 31 | vec3(const float x, const float y, const float z) : x(x), y(y), z(z) {} 32 | vec3 operator + (const vec3& rhs) const { return vec3(x + rhs.x, y + rhs.y, z + rhs.z); } 33 | vec3 operator - (const vec3& rhs) const { return vec3(x - rhs.x, y - rhs.y, z - rhs.z); } 34 | vec3 operator * (const float& rhs) const { return vec3(x * rhs, y * rhs, z * rhs); } 35 | vec3 operator / (const float& rhs) const { return vec3(x / rhs, y / rhs, z / rhs); } 36 | vec3& operator += (const vec3& rhs) { return *this = *this + rhs; } 37 | vec3& operator -= (const vec3& rhs) { return *this = *this - rhs; } 38 | vec3& operator *= (const float& rhs) { return *this = *this * rhs; } 39 | vec3& operator /= (const float& rhs) { return *this = *this / rhs; } 40 | float operator[](int i) const { 41 | return ((float*)this)[i]; 42 | } 43 | float& operator[](int i); 44 | float dot() const { return x * x + y * y + z * z; } 45 | float Length() const { return sqrtf(dot()); } 46 | vec3 Normalize() const { return *this * (1 / Length()); } 47 | float Distance(const vec3& rhs) const { return (*this - rhs).Length(); } 48 | float calcAngle(vec3& vec1, vec3& vec2) { 49 | return acos((vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z) / (vec1.Length() * vec2.Length())); 50 | } 51 | }; 52 | 53 | using Vector3 = vec3; 54 | 55 | struct vec4 { float x, y, z, w; }; 56 | 57 | typedef struct { 58 | float element[4][4]; 59 | } Matrix44; 60 | 61 | 62 | struct D3DX11Matricies { 63 | DirectX::XMMATRIX ViewMatrix; 64 | DirectX::XMMATRIX WorldMatrix; 65 | DirectX::XMMATRIX ProjectionMatrix; 66 | }; 67 | 68 | 69 | bool DirectXWorldToScreen(vec3 point, vec3& screen, D3DX11Matricies* matrixies, float width, float height); 70 | bool RotateDot(float* rotationMatrix, vec3 originDot, vec3& rotatedDot); 71 | -------------------------------------------------------------------------------- /screenshots/2021-01-23_2-52-57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralFire/WarThunderHack/92eb7bd80b004954f75ccafc3d02efd38a891c07/screenshots/2021-01-23_2-52-57.png -------------------------------------------------------------------------------- /screenshots/2021-01-23_2-57-05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralFire/WarThunderHack/92eb7bd80b004954f75ccafc3d02efd38a891c07/screenshots/2021-01-23_2-57-05.png --------------------------------------------------------------------------------